1
0
mirror of https://gitee.com/sui-feng-cb/AzurLaneAutoScript1 synced 2026-06-03 00:25:19 +08:00
This commit is contained in:
2026-05-31 01:31:04 +08:00
18 changed files with 217 additions and 120 deletions

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

View File

@@ -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 | - | - | - | 復刻遠匯點作戰 |

View File

@@ -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

View File

@@ -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

View File

@@ -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"
] ]
}, },

View File

@@ -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": "復刻定向折疊",

View File

@@ -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

View File

@@ -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}')

View 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

View File

@@ -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

View File

@@ -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),

View File

@@ -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:

View File

@@ -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'})

View File

@@ -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):
""" """

View File

@@ -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)