mirror of
https://gitee.com/sui-feng-cb/AzurLaneAutoScript1
synced 2026-06-03 00:25:19 +08:00
Merge branch 'master' of https://github.com/LmeSzinc/AzurLaneAutoScript
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
@@ -297,3 +297,4 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
|
|||||||
| 20260417 | event 20201126 cn | Vacation Lane Rerun | - | - | - | 復刻假日航線 |
|
| 20260417 | event 20201126 cn | Vacation Lane Rerun | - | - | - | 復刻假日航線 |
|
||||||
| 20260514 | event 20221222 cn | Parallel Superimposition | - | - | - | 復刻定向折疊 |
|
| 20260514 | event 20221222 cn | Parallel Superimposition | - | - | - | 復刻定向折疊 |
|
||||||
| 20260520 | event 20260520 cn | Alliance Before the Hagiobull | 圣印前的同盟 | Alliance Before the Hagiobull | 聖印前の同盟 | - |
|
| 20260520 | event 20260520 cn | Alliance Before the Hagiobull | 圣印前的同盟 | Alliance Before the Hagiobull | 聖印前の同盟 | - |
|
||||||
|
| 20260528 | event 20220818 cn | Operation Convergence | - | - | - | 復刻遠匯點作戰 |
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ class Config(ConfigBase):
|
|||||||
MAP_WALK_USE_CURRENT_FLEET = True
|
MAP_WALK_USE_CURRENT_FLEET = True
|
||||||
# ===== End of generated config =====
|
# ===== End of generated config =====
|
||||||
|
|
||||||
|
HOMO_STORAGE = ((8, 6), [(137.405, 104.804), (1046.044, 104.804), (-12.171, 652.093), (1166.717, 652.093)])
|
||||||
|
MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom-right'
|
||||||
|
|
||||||
|
|
||||||
class Campaign(CampaignBase):
|
class Campaign(CampaignBase):
|
||||||
MAP = MAP
|
MAP = MAP
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ class Config(ConfigBase):
|
|||||||
MAP_WALK_USE_CURRENT_FLEET = True
|
MAP_WALK_USE_CURRENT_FLEET = True
|
||||||
# ===== End of generated config =====
|
# ===== End of generated config =====
|
||||||
|
|
||||||
|
HOMO_STORAGE = ((8, 6), [(137.405, 104.804), (1046.044, 104.804), (-12.171, 652.093), (1166.717, 652.093)])
|
||||||
|
MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom-right'
|
||||||
|
|
||||||
|
|
||||||
class Campaign(CampaignBase):
|
class Campaign(CampaignBase):
|
||||||
MAP = MAP
|
MAP = MAP
|
||||||
|
|||||||
@@ -1975,7 +1975,7 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
@@ -1988,10 +1988,10 @@
|
|||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20221222_cn"
|
"event_20220818_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -2395,7 +2395,7 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
@@ -2408,10 +2408,10 @@
|
|||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20221222_cn"
|
"event_20220818_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -2809,7 +2809,7 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
@@ -2822,10 +2822,10 @@
|
|||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20221222_cn"
|
"event_20220818_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -4626,7 +4626,7 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
@@ -4639,10 +4639,10 @@
|
|||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20221222_cn"
|
"event_20220818_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -5058,7 +5058,7 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
@@ -5071,10 +5071,10 @@
|
|||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20221222_cn"
|
"event_20220818_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -5490,7 +5490,7 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
@@ -5503,10 +5503,10 @@
|
|||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20221222_cn"
|
"event_20220818_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -5922,7 +5922,7 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
@@ -5935,10 +5935,10 @@
|
|||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20221222_cn"
|
"event_20220818_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -6344,7 +6344,7 @@
|
|||||||
"type": "select",
|
"type": "select",
|
||||||
"value": "campaign_main",
|
"value": "campaign_main",
|
||||||
"option": [
|
"option": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_cn": [
|
"option_cn": [
|
||||||
@@ -6357,10 +6357,10 @@
|
|||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
],
|
],
|
||||||
"option_tw": [
|
"option_tw": [
|
||||||
"event_20221222_cn"
|
"event_20220818_cn"
|
||||||
],
|
],
|
||||||
"option_bold": [
|
"option_bold": [
|
||||||
"event_20221222_cn",
|
"event_20220818_cn",
|
||||||
"event_20260520_cn"
|
"event_20260520_cn"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -773,7 +773,7 @@
|
|||||||
"event_20220428_cn": "復刻虹彩的終幕曲",
|
"event_20220428_cn": "復刻虹彩的終幕曲",
|
||||||
"event_20220526_cn": "泠誓光庭",
|
"event_20220526_cn": "泠誓光庭",
|
||||||
"event_20220728_cn": "復刻雄鷹的敘事歌",
|
"event_20220728_cn": "復刻雄鷹的敘事歌",
|
||||||
"event_20220818_cn": "遠匯點作戰",
|
"event_20220818_cn": "復刻遠匯點作戰",
|
||||||
"event_20220915_cn": "復刻紫絳槿嵐",
|
"event_20220915_cn": "復刻紫絳槿嵐",
|
||||||
"event_20221124_cn": "復刻鍊金術士與秘密遺跡群島",
|
"event_20221124_cn": "復刻鍊金術士與秘密遺跡群島",
|
||||||
"event_20221222_cn": "復刻定向折疊",
|
"event_20221222_cn": "復刻定向折疊",
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ from module.config.server import VALID_CHANNEL_PACKAGE, VALID_PACKAGE, set_serve
|
|||||||
from module.device.connection_attr import ConnectionAttr
|
from module.device.connection_attr import ConnectionAttr
|
||||||
from module.device.env import IS_LINUX, IS_MACINTOSH, IS_WINDOWS
|
from module.device.env import IS_LINUX, IS_MACINTOSH, IS_WINDOWS
|
||||||
from module.device.method.pool import WORKER_POOL
|
from module.device.method.pool import WORKER_POOL
|
||||||
|
from module.device.method.remove_warning import remove_shell_warning
|
||||||
from module.device.method.utils import (PackageNotInstalled, RETRY_TRIES, get_serial_pair, handle_adb_error,
|
from module.device.method.utils import (PackageNotInstalled, RETRY_TRIES, get_serial_pair, handle_adb_error,
|
||||||
handle_unknown_host_service, possible_reasons, random_port, recv_all,
|
handle_unknown_host_service, possible_reasons, random_port, recv_all,
|
||||||
remove_shell_warning, retry_sleep)
|
retry_sleep)
|
||||||
from module.exception import EmulatorNotRunningError, RequestHumanTakeover
|
from module.exception import EmulatorNotRunningError, RequestHumanTakeover
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.map.map_grids import SelectedGrids
|
from module.map.map_grids import SelectedGrids
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ from lxml import etree
|
|||||||
from module.base.decorator import Config
|
from module.base.decorator import Config
|
||||||
from module.config.server import DICT_PACKAGE_TO_ACTIVITY
|
from module.config.server import DICT_PACKAGE_TO_ACTIVITY
|
||||||
from module.device.connection import Connection
|
from module.device.connection import Connection
|
||||||
|
from module.device.method.remove_warning import remove_screenshot_warning
|
||||||
from module.device.method.utils import (ImageTruncated, PackageNotInstalled, RETRY_TRIES, handle_adb_error,
|
from module.device.method.utils import (ImageTruncated, PackageNotInstalled, RETRY_TRIES, handle_adb_error,
|
||||||
handle_unknown_host_service, remove_prefix, retry_sleep)
|
handle_unknown_host_service, retry_sleep)
|
||||||
from module.exception import EmulatorNotRunningError, RequestHumanTakeover, ScriptError
|
from module.exception import EmulatorNotRunningError, RequestHumanTakeover, ScriptError
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
|
|
||||||
@@ -129,10 +130,7 @@ class Adb(Connection):
|
|||||||
else:
|
else:
|
||||||
raise ScriptError(f'Unknown method to load screenshots: {method}')
|
raise ScriptError(f'Unknown method to load screenshots: {method}')
|
||||||
|
|
||||||
# fix compatibility issues for adb screencap decode problem when the data is from vmos pro
|
screenshot = remove_screenshot_warning(screenshot)
|
||||||
# When use adb screencap for a screenshot from vmos pro, there would be a header more than that from emulator
|
|
||||||
# which would cause image decode problem. So i check and remove the header there.
|
|
||||||
screenshot = remove_prefix(screenshot, b'long long=8 fun*=10\n')
|
|
||||||
|
|
||||||
image = np.frombuffer(screenshot, np.uint8)
|
image = np.frombuffer(screenshot, np.uint8)
|
||||||
if image is None:
|
if image is None:
|
||||||
@@ -175,6 +173,7 @@ class Adb(Connection):
|
|||||||
@Config.when(DEVICE_OVER_HTTP=True)
|
@Config.when(DEVICE_OVER_HTTP=True)
|
||||||
def screenshot_adb(self):
|
def screenshot_adb(self):
|
||||||
data = self.adb_shell(['screencap'], stream=True)
|
data = self.adb_shell(['screencap'], stream=True)
|
||||||
|
data = remove_screenshot_warning(data)
|
||||||
if len(data) < 500:
|
if len(data) < 500:
|
||||||
logger.warning(f'Unexpected screenshot: {data}')
|
logger.warning(f'Unexpected screenshot: {data}')
|
||||||
|
|
||||||
@@ -183,6 +182,7 @@ class Adb(Connection):
|
|||||||
@retry
|
@retry
|
||||||
def screenshot_adb_nc(self):
|
def screenshot_adb_nc(self):
|
||||||
data = self.adb_shell_nc(['screencap'])
|
data = self.adb_shell_nc(['screencap'])
|
||||||
|
data = remove_screenshot_warning(data)
|
||||||
if len(data) < 500:
|
if len(data) < 500:
|
||||||
logger.warning(f'Unexpected screenshot: {data}')
|
logger.warning(f'Unexpected screenshot: {data}')
|
||||||
|
|
||||||
|
|||||||
122
module/device/method/remove_warning.py
Normal file
122
module/device/method/remove_warning.py
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
from typing import overload
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def remove_shell_warning(s: bytes) -> bytes: ...
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def remove_shell_warning(s: str) -> str: ...
|
||||||
|
|
||||||
|
|
||||||
|
def remove_shell_warning(s):
|
||||||
|
"""
|
||||||
|
Remove warnings from shell
|
||||||
|
|
||||||
|
1. Warnings in VMOS shell
|
||||||
|
https://github.com/LmeSzinc/AzurLaneAutoScript/issues/1425
|
||||||
|
|
||||||
|
WARNING: linker: [vdso]: unused DT entry: type 0x70000001 arg 0x0\n
|
||||||
|
\x89PNG\r\n\x1a\n\x00\x00\x00\rIH...
|
||||||
|
|
||||||
|
2. This linker thingy might appear multiple times when executing multiple commands
|
||||||
|
|
||||||
|
mek_8q:/dev # getprop | grep gnss
|
||||||
|
WARNING: linker: Warning: "[vdso]" unused DT entry: unknown processor-specific (type 0x70000001 arg 0x0) (ignoring)
|
||||||
|
WARNING: linker: Warning: "[vdso]" unused DT entry: unknown processor-specific (type 0x70000001 arg 0x0) (ignoring)
|
||||||
|
[init.svc.gnss_service]: [running]
|
||||||
|
[init.svc_debug_pid.gnss_service]: [406]
|
||||||
|
[ro.boottime.gnss_service]: [27308752875]
|
||||||
|
|
||||||
|
Args:
|
||||||
|
s (str | bytes): bytes or str
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str | bytes: Shell output with warnings removed
|
||||||
|
"""
|
||||||
|
if isinstance(s, bytes):
|
||||||
|
while 1:
|
||||||
|
if s.startswith(b'WARNING: linker:'):
|
||||||
|
_, _, s = s.partition(b'\n')
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
elif isinstance(s, str):
|
||||||
|
while 1:
|
||||||
|
if s.startswith('WARNING: linker:'):
|
||||||
|
_, _, s = s.partition('\n')
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def remove_screenshot_warning(s: bytes) -> bytes: ...
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def remove_screenshot_warning(s: str) -> str: ...
|
||||||
|
|
||||||
|
|
||||||
|
def remove_screenshot_warning(s):
|
||||||
|
"""
|
||||||
|
Remove warnings when taking screenshot
|
||||||
|
|
||||||
|
1. Errors in waydroid screencap render
|
||||||
|
https://github.com/LmeSzinc/AzurLaneAutoScript/issues/4760
|
||||||
|
|
||||||
|
Failed to create //.cache for shader cache (Read-only file system)---disabling.\n
|
||||||
|
|
||||||
|
2. Warning when taking screenshot from multiscreen device
|
||||||
|
|
||||||
|
[Warning] Multiple displays were found, but no display id was specified! Defaulting to the first display found,
|
||||||
|
however this default is not guaranteed to be consistent across captures.\n
|
||||||
|
A display id should be specified.\n
|
||||||
|
See "dumpsys SurfaceFlinger --display-id" for valid display IDs.\n
|
||||||
|
\x89PNG...
|
||||||
|
|
||||||
|
3. Another format of multiscreen warning
|
||||||
|
https://github.com/LmeSzinc/AzurLaneAutoScript/issues/5682
|
||||||
|
|
||||||
|
[Warning] Multiple displays were found, but no display id was specified! Defaulting to the first display found,
|
||||||
|
however this default is not guaranteed to be consistent across captures. A display id should be specified.\n
|
||||||
|
A display ID can be specified with the [-d display-id] option.\n
|
||||||
|
See "dumpsys SurfaceFlinger --display-id" for valid display IDs.\n
|
||||||
|
\x89PNG...
|
||||||
|
|
||||||
|
4. Unknown header on VMOS PRO screenshot
|
||||||
|
https://github.com/LmeSzinc/AzurLaneAutoScript/pull/940
|
||||||
|
|
||||||
|
long long=8 fun*=10\n\x89PNG...
|
||||||
|
|
||||||
|
Args:
|
||||||
|
s (str | bytes): bytes or str
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str | bytes: Screenshot data with warnings removed
|
||||||
|
"""
|
||||||
|
if isinstance(s, bytes):
|
||||||
|
if s.startswith(b'Failed to create'):
|
||||||
|
_, _, s = s.partition(b'\n')
|
||||||
|
if s.startswith(b'[Warning] Multiple displays'):
|
||||||
|
_, _, s = s.partition(b'\n')
|
||||||
|
if s.startswith(b'A display id') or s.startswith(b'A display ID'):
|
||||||
|
_, _, s = s.partition(b'\n')
|
||||||
|
if s.startswith(b'See "dumpsys'):
|
||||||
|
_, _, s = s.partition(b'\n')
|
||||||
|
if s.startswith(b'long long=8'):
|
||||||
|
_, _, s = s.partition(b'\n')
|
||||||
|
|
||||||
|
elif isinstance(s, str):
|
||||||
|
if s.startswith('Failed to create'):
|
||||||
|
_, _, s = s.partition('\n')
|
||||||
|
if s.startswith('[Warning] Multiple displays'):
|
||||||
|
_, _, s = s.partition('\n')
|
||||||
|
if s.startswith('A display id') or s.startswith('A display ID'):
|
||||||
|
_, _, s = s.partition('\n')
|
||||||
|
if s.startswith('See "dumpsys'):
|
||||||
|
_, _, s = s.partition('\n')
|
||||||
|
if s.startswith('long long=8'):
|
||||||
|
_, _, s = s.partition('\n')
|
||||||
|
|
||||||
|
return s
|
||||||
@@ -10,6 +10,8 @@ import uiautomator2cache
|
|||||||
from adbutils import AdbTimeout
|
from adbutils import AdbTimeout
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
|
|
||||||
|
from module.device.method.remove_warning import remove_shell_warning
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# adbutils 0.x
|
# adbutils 0.x
|
||||||
from adbutils import _AdbStreamConnection as AdbConnection
|
from adbutils import _AdbStreamConnection as AdbConnection
|
||||||
@@ -299,99 +301,52 @@ def get_serial_pair(serial):
|
|||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
def remove_prefix(s, prefix):
|
@t.overload
|
||||||
|
def removeprefix(s: str, prefix: str) -> str: ...
|
||||||
|
|
||||||
|
|
||||||
|
@t.overload
|
||||||
|
def removeprefix(s: bytes, prefix: bytes) -> bytes: ...
|
||||||
|
|
||||||
|
|
||||||
|
@t.overload
|
||||||
|
def removesuffix(s: str, suffix: str) -> str: ...
|
||||||
|
|
||||||
|
|
||||||
|
@t.overload
|
||||||
|
def removesuffix(s: bytes, suffix: bytes) -> bytes: ...
|
||||||
|
|
||||||
|
|
||||||
|
def removeprefix(s, prefix):
|
||||||
"""
|
"""
|
||||||
Remove prefix of a string or bytes like `string.removeprefix(prefix)`, which is on Python3.9+
|
Backport `string.removeprefix(prefix)`, which is on Python>=3.9
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
s (str, bytes):
|
s (str | bytes):
|
||||||
prefix (str, bytes):
|
prefix (str | bytes):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str, bytes:
|
str | bytes:
|
||||||
"""
|
"""
|
||||||
return s[len(prefix):] if s.startswith(prefix) else s
|
if s.startswith(prefix):
|
||||||
|
return s[len(prefix):]
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
def remove_suffix(s, suffix):
|
def removesuffix(s, suffix):
|
||||||
"""
|
"""
|
||||||
Remove suffix of a string or bytes like `string.removesuffix(suffix)`, which is on Python3.9+
|
Backport `string.removesuffix(suffix)`, which is on Python>=3.9
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
s (str, bytes):
|
s (str | bytes):
|
||||||
suffix (str, bytes):
|
suffix (str | bytes):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str, bytes:
|
str | bytes:
|
||||||
"""
|
"""
|
||||||
return s[:-len(suffix)] if s.endswith(suffix) else s
|
# s[:-0] is empty string, so we need to check if suffix is empty
|
||||||
|
if suffix and s.endswith(suffix):
|
||||||
|
return s[:-len(suffix)]
|
||||||
def remove_shell_warning(s):
|
|
||||||
"""
|
|
||||||
Remove warnings from shell
|
|
||||||
|
|
||||||
1. Warnings in VMOS shell
|
|
||||||
https://github.com/LmeSzinc/AzurLaneAutoScript/issues/1425
|
|
||||||
|
|
||||||
WARNING: linker: [vdso]: unused DT entry: type 0x70000001 arg 0x0\n\x89PNG\r\n\x1a\n\x00\x00\x00\rIH
|
|
||||||
|
|
||||||
2. This linker thingy might appear multiple times when executing multiple commands
|
|
||||||
|
|
||||||
mek_8q:/dev # getprop | grep gnss
|
|
||||||
WARNING: linker: Warning: "[vdso]" unused DT entry: unknown processor-specific (type 0x70000001 arg 0x0) (ignoring)
|
|
||||||
WARNING: linker: Warning: "[vdso]" unused DT entry: unknown processor-specific (type 0x70000001 arg 0x0) (ignoring)
|
|
||||||
[init.svc.gnss_service]: [running]
|
|
||||||
[init.svc_debug_pid.gnss_service]: [406]
|
|
||||||
[ro.boottime.gnss_service]: [27308752875]
|
|
||||||
|
|
||||||
3. Errors in waydroid screencap render
|
|
||||||
https://github.com/LmeSzinc/AzurLaneAutoScript/issues/4760
|
|
||||||
|
|
||||||
Failed to create //.cache for shader cache (Read-only file system)---disabling.\n
|
|
||||||
|
|
||||||
4. Warning when taking screenshot from multiscreen device
|
|
||||||
|
|
||||||
[Warning] Multiple displays were found, but no display id was specified! Defaulting to the first display found,
|
|
||||||
however this default is not guaranteed to be consistent across captures.\n
|
|
||||||
A display id should be specified.\n
|
|
||||||
See "dumpsys SurfaceFlinger --display-id" for valid display IDs.\n
|
|
||||||
\x89PNG...
|
|
||||||
|
|
||||||
Args:
|
|
||||||
s (T): bytes or str
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
T:
|
|
||||||
"""
|
|
||||||
if isinstance(s, bytes):
|
|
||||||
while 1:
|
|
||||||
if s.startswith(b'WARNING: linker:'):
|
|
||||||
_, _, s = s.partition(b'\n')
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
if s.startswith(b'Failed to create'):
|
|
||||||
_, _, s = s.partition(b'\n')
|
|
||||||
if s.startswith(b'[Warning] Multiple displays'):
|
|
||||||
_, _, s = s.partition(b'\n')
|
|
||||||
if s.startswith(b'A display id'):
|
|
||||||
_, _, s = s.partition(b'\n')
|
|
||||||
if s.startswith(b'See "dumpsys'):
|
|
||||||
_, _, s = s.partition(b'\n')
|
|
||||||
elif isinstance(s, str):
|
|
||||||
while 1:
|
|
||||||
if s.startswith('WARNING: linker:'):
|
|
||||||
_, _, s = s.partition('\n')
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
if s.startswith('Failed to create'):
|
|
||||||
_, _, s = s.partition('\n')
|
|
||||||
if s.startswith('[Warning] Multiple displays'):
|
|
||||||
_, _, s = s.partition('\n')
|
|
||||||
if s.startswith('A display id'):
|
|
||||||
_, _, s = s.partition('\n')
|
|
||||||
if s.startswith('See "dumpsys'):
|
|
||||||
_, _, s = s.partition('\n')
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ except KeyError:
|
|||||||
logger.error('Patch pkg_resources failed, patch module does not exists')
|
logger.error('Patch pkg_resources failed, patch module does not exists')
|
||||||
|
|
||||||
|
|
||||||
def remove_suffix(s, suffix):
|
def removesuffix(s, suffix):
|
||||||
"""
|
"""
|
||||||
Remove suffix of a string or bytes like `string.removesuffix(suffix)`, which is on Python3.9+
|
Remove suffix of a string or bytes like `string.removesuffix(suffix)`, which is on Python3.9+
|
||||||
|
|
||||||
@@ -36,7 +36,10 @@ def remove_suffix(s, suffix):
|
|||||||
Returns:
|
Returns:
|
||||||
str, bytes:
|
str, bytes:
|
||||||
"""
|
"""
|
||||||
return s[:-len(suffix)] if s.endswith(suffix) else s
|
# s[:-0] is empty string, so we need to check if suffix is empty
|
||||||
|
if suffix and s.endswith(suffix):
|
||||||
|
return s[:-len(suffix)]
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
class FakeDistributionObject:
|
class FakeDistributionObject:
|
||||||
@@ -71,7 +74,7 @@ class PackageCache:
|
|||||||
# adbutils-0.11.0-py3.7.egg-info
|
# adbutils-0.11.0-py3.7.egg-info
|
||||||
res = re.match(r'^([a-zA-Z0-9._]+)-([a-zA-Z0-9._]+)-', file)
|
res = re.match(r'^([a-zA-Z0-9._]+)-([a-zA-Z0-9._]+)-', file)
|
||||||
if res:
|
if res:
|
||||||
version = remove_suffix(res.group(2), '.dist')
|
version = removesuffix(res.group(2), '.dist')
|
||||||
# version = res.group(2)
|
# version = res.group(2)
|
||||||
obj = FakeDistributionObject(
|
obj = FakeDistributionObject(
|
||||||
dist=res.group(1),
|
dist=res.group(1),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from dataclasses import dataclass
|
|||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from module.base.decorator import cached_property
|
from module.base.decorator import cached_property
|
||||||
from module.device.method.utils import remove_prefix
|
from module.device.method.utils import removeprefix
|
||||||
|
|
||||||
REGEX_SETTING = re.compile(r'PlayerPrefs.Get(\w{1,10})\((.*)\)')
|
REGEX_SETTING = re.compile(r'PlayerPrefs.Get(\w{1,10})\((.*)\)')
|
||||||
REGEX_SETTING_KEY = re.compile(r'"(.*?)"')
|
REGEX_SETTING_KEY = re.compile(r'"(.*?)"')
|
||||||
@@ -173,7 +173,7 @@ class SettingExtractor:
|
|||||||
if not settings:
|
if not settings:
|
||||||
continue
|
continue
|
||||||
yield ''
|
yield ''
|
||||||
f = remove_prefix(file, folder).replace("\\", "/")
|
f = removeprefix(file, folder).replace("\\", "/")
|
||||||
yield f' # {f}'
|
yield f' # {f}'
|
||||||
for setting in settings:
|
for setting in settings:
|
||||||
if setting.key in dic_settings:
|
if setting.key in dic_settings:
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ LOGIN_RETURN_SIGN = Button(area={'cn': (1, 7, 104, 47), 'en': (1, 7, 118, 39), '
|
|||||||
MAINTENANCE_ANNOUNCE = Button(area={'cn': (923, 141, 990, 186), 'en': (923, 141, 990, 186), 'jp': (923, 141, 990, 186), 'tw': (923, 141, 990, 186)}, color={'cn': (207, 95, 91), 'en': (207, 95, 91), 'jp': (207, 95, 91), 'tw': (207, 95, 91)}, button={'cn': (923, 141, 990, 186), 'en': (923, 141, 990, 186), 'jp': (923, 141, 990, 186), 'tw': (923, 141, 990, 186)}, file={'cn': './assets/cn/handler/MAINTENANCE_ANNOUNCE.png', 'en': './assets/en/handler/MAINTENANCE_ANNOUNCE.png', 'jp': './assets/jp/handler/MAINTENANCE_ANNOUNCE.png', 'tw': './assets/tw/handler/MAINTENANCE_ANNOUNCE.png'})
|
MAINTENANCE_ANNOUNCE = Button(area={'cn': (923, 141, 990, 186), 'en': (923, 141, 990, 186), 'jp': (923, 141, 990, 186), 'tw': (923, 141, 990, 186)}, color={'cn': (207, 95, 91), 'en': (207, 95, 91), 'jp': (207, 95, 91), 'tw': (207, 95, 91)}, button={'cn': (923, 141, 990, 186), 'en': (923, 141, 990, 186), 'jp': (923, 141, 990, 186), 'tw': (923, 141, 990, 186)}, file={'cn': './assets/cn/handler/MAINTENANCE_ANNOUNCE.png', 'en': './assets/en/handler/MAINTENANCE_ANNOUNCE.png', 'jp': './assets/jp/handler/MAINTENANCE_ANNOUNCE.png', 'tw': './assets/tw/handler/MAINTENANCE_ANNOUNCE.png'})
|
||||||
MANJUU_AREA = Button(area={'cn': (520, 240, 760, 400), 'en': (520, 240, 760, 400), 'jp': (520, 240, 760, 400), 'tw': (520, 240, 760, 400)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (520, 240, 760, 400), 'en': (520, 240, 760, 400), 'jp': (520, 240, 760, 400), 'tw': (520, 240, 760, 400)}, file={'cn': './assets/cn/handler/MANJUU_AREA.png', 'en': './assets/cn/handler/MANJUU_AREA.png', 'jp': './assets/cn/handler/MANJUU_AREA.png', 'tw': './assets/cn/handler/MANJUU_AREA.png'})
|
MANJUU_AREA = Button(area={'cn': (520, 240, 760, 400), 'en': (520, 240, 760, 400), 'jp': (520, 240, 760, 400), 'tw': (520, 240, 760, 400)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (520, 240, 760, 400), 'en': (520, 240, 760, 400), 'jp': (520, 240, 760, 400), 'tw': (520, 240, 760, 400)}, file={'cn': './assets/cn/handler/MANJUU_AREA.png', 'en': './assets/cn/handler/MANJUU_AREA.png', 'jp': './assets/cn/handler/MANJUU_AREA.png', 'tw': './assets/cn/handler/MANJUU_AREA.png'})
|
||||||
MAP_AIR_RAID = Button(area={'cn': (350, 447, 1280, 472), 'en': (350, 447, 1280, 472), 'jp': (350, 447, 1280, 472), 'tw': (350, 447, 1280, 472)}, color={'cn': (154, 43, 46), 'en': (154, 43, 46), 'jp': (154, 43, 46), 'tw': (154, 43, 46)}, button={'cn': (350, 447, 1280, 472), 'en': (350, 447, 1280, 472), 'jp': (350, 447, 1280, 472), 'tw': (350, 447, 1280, 472)}, file={'cn': './assets/cn/handler/MAP_AIR_RAID.png', 'en': './assets/en/handler/MAP_AIR_RAID.png', 'jp': './assets/jp/handler/MAP_AIR_RAID.png', 'tw': './assets/tw/handler/MAP_AIR_RAID.png'})
|
MAP_AIR_RAID = Button(area={'cn': (350, 447, 1280, 472), 'en': (350, 447, 1280, 472), 'jp': (350, 447, 1280, 472), 'tw': (350, 447, 1280, 472)}, color={'cn': (154, 43, 46), 'en': (154, 43, 46), 'jp': (154, 43, 46), 'tw': (154, 43, 46)}, button={'cn': (350, 447, 1280, 472), 'en': (350, 447, 1280, 472), 'jp': (350, 447, 1280, 472), 'tw': (350, 447, 1280, 472)}, file={'cn': './assets/cn/handler/MAP_AIR_RAID.png', 'en': './assets/en/handler/MAP_AIR_RAID.png', 'jp': './assets/jp/handler/MAP_AIR_RAID.png', 'tw': './assets/tw/handler/MAP_AIR_RAID.png'})
|
||||||
MAP_AIR_STRIKE = Button(area={'cn': (0, 0, 1280, 720), 'en': (0, 0, 1280, 720), 'jp': (0, 0, 1280, 720), 'tw': (0, 0, 1280, 720)}, color={'cn': (20, 17, 17), 'en': (20, 17, 17), 'jp': (20, 17, 17), 'tw': (20, 17, 17)}, button={'cn': (0, 0, 1280, 720), 'en': (0, 0, 1280, 720), 'jp': (0, 0, 1280, 720), 'tw': (0, 0, 1280, 720)}, file={'cn': './assets/cn/handler/MAP_AIR_STRIKE.png', 'en': './assets/en/handler/MAP_AIR_STRIKE.png', 'jp': './assets/jp/handler/MAP_AIR_STRIKE.png', 'tw': './assets/tw/handler/MAP_AIR_STRIKE.png'})
|
MAP_AIR_STRIKE = Button(area={'cn': (351, 453, 1280, 477), 'en': (351, 453, 1280, 477), 'jp': (351, 453, 1280, 477), 'tw': (351, 453, 1280, 477)}, color={'cn': (170, 57, 63), 'en': (170, 57, 63), 'jp': (170, 57, 63), 'tw': (170, 57, 63)}, button={'cn': (351, 453, 1280, 477), 'en': (351, 453, 1280, 477), 'jp': (351, 453, 1280, 477), 'tw': (351, 453, 1280, 477)}, file={'cn': './assets/cn/handler/MAP_AIR_STRIKE.png', 'en': './assets/cn/handler/MAP_AIR_STRIKE.png', 'jp': './assets/cn/handler/MAP_AIR_STRIKE.png', 'tw': './assets/cn/handler/MAP_AIR_STRIKE.png'})
|
||||||
MAP_AMBUSH = Button(area={'cn': (261, 433, 1280, 449), 'en': (261, 433, 1280, 449), 'jp': (261, 433, 1280, 449), 'tw': (261, 433, 1280, 449)}, color={'cn': (161, 41, 43), 'en': (161, 41, 43), 'jp': (161, 41, 43), 'tw': (161, 41, 43)}, button={'cn': (261, 433, 1280, 449), 'en': (261, 433, 1280, 449), 'jp': (261, 433, 1280, 449), 'tw': (261, 433, 1280, 449)}, file={'cn': './assets/cn/handler/MAP_AMBUSH.png', 'en': './assets/en/handler/MAP_AMBUSH.png', 'jp': './assets/jp/handler/MAP_AMBUSH.png', 'tw': './assets/tw/handler/MAP_AMBUSH.png'})
|
MAP_AMBUSH = Button(area={'cn': (261, 433, 1280, 449), 'en': (261, 433, 1280, 449), 'jp': (261, 433, 1280, 449), 'tw': (261, 433, 1280, 449)}, color={'cn': (161, 41, 43), 'en': (161, 41, 43), 'jp': (161, 41, 43), 'tw': (161, 41, 43)}, button={'cn': (261, 433, 1280, 449), 'en': (261, 433, 1280, 449), 'jp': (261, 433, 1280, 449), 'tw': (261, 433, 1280, 449)}, file={'cn': './assets/cn/handler/MAP_AMBUSH.png', 'en': './assets/en/handler/MAP_AMBUSH.png', 'jp': './assets/jp/handler/MAP_AMBUSH.png', 'tw': './assets/tw/handler/MAP_AMBUSH.png'})
|
||||||
MAP_AMBUSH_ATTACK = Button(area={'cn': (804, 457, 876, 488), 'en': (791, 463, 888, 485), 'jp': (804, 457, 876, 488), 'tw': (804, 455, 876, 486)}, color={'cn': (139, 168, 210), 'en': (164, 187, 221), 'jp': (150, 175, 212), 'tw': (149, 175, 213)}, button={'cn': (755, 446, 925, 501), 'en': (753, 443, 927, 503), 'jp': (757, 447, 925, 501), 'tw': (762, 443, 927, 499)}, file={'cn': './assets/cn/handler/MAP_AMBUSH_ATTACK.png', 'en': './assets/en/handler/MAP_AMBUSH_ATTACK.png', 'jp': './assets/jp/handler/MAP_AMBUSH_ATTACK.png', 'tw': './assets/tw/handler/MAP_AMBUSH_ATTACK.png'})
|
MAP_AMBUSH_ATTACK = Button(area={'cn': (804, 457, 876, 488), 'en': (791, 463, 888, 485), 'jp': (804, 457, 876, 488), 'tw': (804, 455, 876, 486)}, color={'cn': (139, 168, 210), 'en': (164, 187, 221), 'jp': (150, 175, 212), 'tw': (149, 175, 213)}, button={'cn': (755, 446, 925, 501), 'en': (753, 443, 927, 503), 'jp': (757, 447, 925, 501), 'tw': (762, 443, 927, 499)}, file={'cn': './assets/cn/handler/MAP_AMBUSH_ATTACK.png', 'en': './assets/en/handler/MAP_AMBUSH_ATTACK.png', 'jp': './assets/jp/handler/MAP_AMBUSH_ATTACK.png', 'tw': './assets/tw/handler/MAP_AMBUSH_ATTACK.png'})
|
||||||
MAP_AMBUSH_EVADE = Button(area={'cn': (1029, 457, 1101, 487), 'en': (1021, 459, 1110, 483), 'jp': (1031, 458, 1101, 487), 'tw': (1071, 457, 1101, 487)}, color={'cn': (199, 195, 196), 'en': (200, 197, 198), 'jp': (239, 194, 138), 'tw': (247, 209, 164)}, button={'cn': (979, 444, 1152, 502), 'en': (978, 443, 1153, 503), 'jp': (979, 444, 1151, 502), 'tw': (979, 444, 1152, 502)}, file={'cn': './assets/cn/handler/MAP_AMBUSH_EVADE.png', 'en': './assets/en/handler/MAP_AMBUSH_EVADE.png', 'jp': './assets/jp/handler/MAP_AMBUSH_EVADE.png', 'tw': './assets/tw/handler/MAP_AMBUSH_EVADE.png'})
|
MAP_AMBUSH_EVADE = Button(area={'cn': (1029, 457, 1101, 487), 'en': (1021, 459, 1110, 483), 'jp': (1031, 458, 1101, 487), 'tw': (1071, 457, 1101, 487)}, color={'cn': (199, 195, 196), 'en': (200, 197, 198), 'jp': (239, 194, 138), 'tw': (247, 209, 164)}, button={'cn': (979, 444, 1152, 502), 'en': (978, 443, 1153, 503), 'jp': (979, 444, 1151, 502), 'tw': (979, 444, 1152, 502)}, file={'cn': './assets/cn/handler/MAP_AMBUSH_EVADE.png', 'en': './assets/en/handler/MAP_AMBUSH_EVADE.png', 'jp': './assets/jp/handler/MAP_AMBUSH_EVADE.png', 'tw': './assets/tw/handler/MAP_AMBUSH_EVADE.png'})
|
||||||
|
|||||||
@@ -268,8 +268,17 @@ class FleetOperator:
|
|||||||
|
|
||||||
# Cropping FLEET_*_IN_USE to avoid detecting info_bar, also do the trick.
|
# Cropping FLEET_*_IN_USE to avoid detecting info_bar, also do the trick.
|
||||||
# It also avoids wasting time on handling the info_bar.
|
# It also avoids wasting time on handling the info_bar.
|
||||||
image = rgb2gray(self.main.image_crop(self._in_use.button, copy=False))
|
image = self.main.image_crop(self._in_use.button, copy=False)
|
||||||
return np.std(image.flatten(), ddof=1) > self.FLEET_IN_USE_STD
|
|
||||||
|
# special fix for Perseus skin, which color is so flat
|
||||||
|
# https://github.com/LmeSzinc/AzurLaneAutoScript/issues/5678
|
||||||
|
# no ship is in color (71, 70, 63)
|
||||||
|
color = cv2.mean(image)[:3]
|
||||||
|
if color_similar(color, (224, 154, 114), threshold=30):
|
||||||
|
return True
|
||||||
|
|
||||||
|
gray = rgb2gray(image)
|
||||||
|
return np.std(gray.flatten(), ddof=1) > self.FLEET_IN_USE_STD
|
||||||
|
|
||||||
def bar_opened(self):
|
def bar_opened(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from scipy import signal
|
|||||||
|
|
||||||
from module.base.decorator import cached_property
|
from module.base.decorator import cached_property
|
||||||
from module.base.utils import *
|
from module.base.utils import *
|
||||||
from module.device.method.utils import remove_suffix
|
from module.device.method.utils import removesuffix
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.ocr.ocr import Duration, Ocr
|
from module.ocr.ocr import Duration, Ocr
|
||||||
from module.research.assets import *
|
from module.research.assets import *
|
||||||
@@ -364,7 +364,7 @@ def research_jp_detect(image):
|
|||||||
"""
|
"""
|
||||||
project = ResearchProjectJp()
|
project = ResearchProjectJp()
|
||||||
project.series = get_research_series_jp(image)
|
project.series = get_research_series_jp(image)
|
||||||
project.duration = remove_suffix(str(get_research_duration_jp(image) / 3600), '.0')
|
project.duration = removesuffix(str(get_research_duration_jp(image) / 3600), '.0')
|
||||||
if project.duration == '':
|
if project.duration == '':
|
||||||
project.duration = '0'
|
project.duration = '0'
|
||||||
project.genre = get_research_genre_jp(image)
|
project.genre = get_research_genre_jp(image)
|
||||||
|
|||||||
Reference in New Issue
Block a user