diff --git a/.gitignore b/.gitignore index 057160c81..61f4dd135 100644 --- a/.gitignore +++ b/.gitignore @@ -249,3 +249,6 @@ adb_port.ini !popup.exe *.zip .vscode/* + +# Pylance configuration file +pyrightconfig.json \ No newline at end of file diff --git a/assets/en/ui/ACADEMY_CHECK.png b/assets/en/ui/ACADEMY_CHECK.png index 67abb40fc..7e00c6d3b 100644 Binary files a/assets/en/ui/ACADEMY_CHECK.png and b/assets/en/ui/ACADEMY_CHECK.png differ diff --git a/campaign/Readme.md b/campaign/Readme.md index cbe2aa5d2..4adb53c05 100644 --- a/campaign/Readme.md +++ b/campaign/Readme.md @@ -169,4 +169,7 @@ To add a new event, add a new row in here, and run `python -m module.config.conf | 20231123 | event 20231123 cn | The Ninja Scrolls: Azur Flash | 苍闪忍法帖 | The Ninja Scrolls: Azur Flash | 蒼閃忍法帖 | - | | 20231130 | event 20231123 cn | The Ninja Scrolls: Azur Flash | - | - | - | 蒼閃忍法帖 | | 20221222 | event 20221222 cn | Parallel Superimposition | - | - | - | 定向折疊 | -| 20231221 | event 20231221 cn | Light-Chasing Sea of Stars | 星海逐光 | Light-Chasing Sea of Stars | 光追う星の海 | - | \ No newline at end of file +| 20231221 | event 20231221 cn | Light-Chasing Sea of Stars | 星海逐光 | Light-Chasing Sea of Stars | 光追う星の海 | - | +| 20240104 | event 20210225 cn | Khorovod of Dawn's Rime | - | - | - | 復刻破曉冰華 | +| 20240111 | event 20211229 cn | Tower of Transcendence Rerun | 复刻逆转彩虹之塔 | Tower of Transcendence Rerun | 遡望せし虹彩の塔(復刻)    | - | +| 20240111 | event 20230803 cn | Anthem of Remembrance | - | - | - | 奏響鳶尾之歌 | \ No newline at end of file diff --git a/module/campaign/gems_farming.py b/module/campaign/gems_farming.py index a29ab9946..5abe811eb 100644 --- a/module/campaign/gems_farming.py +++ b/module/campaign/gems_farming.py @@ -155,16 +155,17 @@ class GemsFarming(CampaignRun, Dock, EquipmentChange): self.campaign.ensure_campaign_ui(self.stage) button_area = self.campaign.ENTRANCE.button button = Button(name=str(self.stage), area=button_area, color=(0, 0, 0), button=button_area) - for _ in range(20): + for __ in range(5): self.campaign.ensure_campaign_ui(self.stage) self.ui_click(click_button=button, appear_button=BACK_ARROW, check_button=MAP_PREPARATION) - self.appear_then_click(MAP_PREPARATION) - self.device.sleep(0.5) - self.device.screenshot() - if Retirement(config=self.config, device=self.device).handle_retirement(): - continue - if self.appear(button=FLEET_PREPARATION, offset=(50, 50)): - return + for _ in range(30): + self.device.screenshot() + if self.appear_then_click(MAP_PREPARATION): + self.device.sleep(0.5) + if Retirement(config=self.config, device=self.device).handle_retirement(): + continue + if self.appear(button=FLEET_PREPARATION, offset=(50, 50)): + return from module.exception import GameStuckError raise GameStuckError diff --git a/module/campaign/os_run.py b/module/campaign/os_run.py index 260c1ef78..8f3f984b8 100644 --- a/module/campaign/os_run.py +++ b/module/campaign/os_run.py @@ -29,7 +29,7 @@ class OSCampaignRun(OSMapOperation): self.config.opsi_task_delay(ap_limit=True) def opsi_shop(self): - if self.config.SERVER in ['cn', 'en', 'jp']: + if self.config.SERVER in ['cn', 'en', 'jp', 'tw']: logger.info('Task OpsiShop is disabled before assets update') self.config.task_delay(server_update=True) self.config.task_stop() diff --git a/module/config/argument/args.json b/module/config/argument/args.json index 2eca7b6e1..109b0bbd8 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -1722,13 +1722,13 @@ ], "display": "hide", "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -2054,13 +2054,13 @@ "event_20231221_cn" ], "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -2501,13 +2501,13 @@ "event_20231221_cn" ], "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -2948,13 +2948,13 @@ "event_20231221_cn" ], "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -3357,8 +3357,8 @@ "raid_20230629" ], "option_bold": [ - "raid_20221027", - "raid_20230629" + "raid_20230629", + "raid_20221027" ], "cn": "raid_20230629", "en": "raid_20230629", @@ -4333,13 +4333,13 @@ "event_20231221_cn" ], "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -4797,13 +4797,13 @@ "event_20231221_cn" ], "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -5261,13 +5261,13 @@ "event_20231221_cn" ], "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -5725,13 +5725,13 @@ "event_20231221_cn" ], "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -6179,13 +6179,13 @@ "event_20231221_cn" ], "option_bold": [ - "event_20221222_cn", - "event_20231221_cn" + "event_20230803_cn", + "event_20211229_cn" ], - "cn": "event_20231221_cn", - "en": "event_20231221_cn", - "jp": "event_20231221_cn", - "tw": "event_20221222_cn" + "cn": "event_20211229_cn", + "en": "event_20211229_cn", + "jp": "event_20211229_cn", + "tw": "event_20230803_cn" }, "Mode": { "type": "select", @@ -6585,8 +6585,8 @@ "raid_20230629" ], "option_bold": [ - "raid_20221027", - "raid_20230629" + "raid_20230629", + "raid_20221027" ], "cn": "raid_20230629", "en": "raid_20230629", diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index be5aa8bfb..650fc1de9 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -707,7 +707,7 @@ "event_20211028_tw": "復刻光與影的鳶尾之華", "event_20211111_cn": "The Flame-Touched Dagger Rerun", "event_20211125_cn": "World-spanning Arclight Rerun", - "event_20211229_cn": "Tower of Transcendence", + "event_20211229_cn": "Tower of Transcendence Rerun", "event_20220210_cn": "Northern Overture Rerun", "event_20220224_cn": "Abyssal Refrain", "event_20220310_tw": "復刻斯圖爾特的硝煙", diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index d311770aa..b4d35ea0d 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -707,7 +707,7 @@ "event_20211028_tw": "復刻光與影的鳶尾之華", "event_20211111_cn": "復刻-燈火のシニエ", "event_20211125_cn": "弧光は交わる世界にて(復刻)", - "event_20211229_cn": "遡望せし虹彩の塔", + "event_20211229_cn": "遡望せし虹彩の塔(復刻)", "event_20220210_cn": "凍絶の北海(復刻)", "event_20220224_cn": "鳴動せし星霜の淵", "event_20220310_tw": "復刻斯圖爾特的硝煙", diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index 84b9af9c1..12069a807 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -707,7 +707,7 @@ "event_20211028_tw": "復刻光與影的鳶尾之華", "event_20211111_cn": "复刻杰诺瓦的焰火", "event_20211125_cn": "复刻交汇世界的弧光", - "event_20211229_cn": "逆转彩虹之塔", + "event_20211229_cn": "复刻逆转彩虹之塔", "event_20220210_cn": "复刻北境序曲", "event_20220224_cn": "深度回音", "event_20220310_tw": "復刻斯圖爾特的硝煙", diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index c357fd97b..423b11362 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -689,7 +689,7 @@ "event_20201126_cn": "假日航線", "event_20201229_cn": "復刻-負象限作戰", "event_20210121_cn": "復刻神聖的悲喜劇", - "event_20210225_cn": "破曉冰華", + "event_20210225_cn": "復刻破曉冰華", "event_20210225_tw": "北境序曲", "event_20210325_cn": "復刻箱庭療法", "event_20210415_tw": "復刻圍剿施佩伯爵", @@ -723,7 +723,7 @@ "event_20221222_cn": "定向折疊", "event_20230223_cn": "Revelations of Dust", "event_20230525_cn": "Confluence of Nothingness", - "event_20230803_cn": "Anthem of Remembrance", + "event_20230803_cn": "奏響鳶尾之歌", "event_20230817_cn": "The Fools Scales", "event_20230914_cn": "Effulgence Before Eclipse", "event_20231026_cn": "Tempesta and the Fountain of Youth", diff --git a/module/device/screenshot.py b/module/device/screenshot.py index 6dee79623..5d4fd3dbe 100644 --- a/module/device/screenshot.py +++ b/module/device/screenshot.py @@ -98,7 +98,14 @@ class Screenshot(Adb, WSA, DroidCast, AScreenCap, Scrcpy): @cached_property def screenshot_deque(self): - return deque(maxlen=int(self.config.Error_ScreenshotLength)) + try: + length = int(self.config.Error_ScreenshotLength) + except ValueError: + logger.error(f'Error_ScreenshotLength={self.config.Error_ScreenshotLength} is not an integer') + raise RequestHumanTakeover + # Limit in 1~300 + length = max(1, min(length, 300)) + return deque(maxlen=length) def save_screenshot(self, genre='items', interval=None, to_base_folder=False): """Save a screenshot. Use millisecond timestamp as file name. diff --git a/module/handler/info_handler.py b/module/handler/info_handler.py index 8488a5315..d88edd9d3 100644 --- a/module/handler/info_handler.py +++ b/module/handler/info_handler.py @@ -205,7 +205,9 @@ class InfoHandler(ModuleBase): Returns: bool: """ - return self.appear_then_click(VOTE_CANCEL, offset=(20, 20), interval=2) + # Vote popups are removed in 2023 + # return self.appear_then_click(VOTE_CANCEL, offset=(20, 20), interval=2) + return False def handle_get_skin(self): """ diff --git a/module/map/camera.py b/module/map/camera.py index 6f76dad02..bb2b6fcbf 100644 --- a/module/map/camera.py +++ b/module/map/camera.py @@ -6,7 +6,7 @@ from module.base.timer import Timer from module.base.utils import area_offset from module.combat.assets import GET_ITEMS_1, GET_ITEMS_1_RYZA from module.exception import CampaignEnd, GameNotRunningError, MapDetectionError -from module.handler.assets import AUTO_SEARCH_MENU_CONTINUE, GAME_TIPS +from module.handler.assets import AUTO_SEARCH_MENU_CONTINUE, GAME_TIPS, GET_MISSION from module.logger import logger from module.map.assets import MAP_PREPARATION from module.map.map_base import CampaignMap, location2node @@ -145,6 +145,10 @@ class Camera(MapOperation): logger.warning('Perspective error caused by story') self.ensure_no_story(skip_first_screenshot=False) return False + elif self.appear(GET_MISSION, offset=(20, 20)): + logger.warning('Perspective error caused by GET_MISSION') + self.device.click(GET_MISSION) + return False elif self.is_in_stage(): logger.warning('Image is in stage') raise CampaignEnd('Image is in stage') diff --git a/module/os/map.py b/module/os/map.py index 5a2ac4ca3..0ebbf181b 100644 --- a/module/os/map.py +++ b/module/os/map.py @@ -10,7 +10,7 @@ from module.exception import CampaignEnd, RequestHumanTakeover from module.exception import GameTooManyClickError from module.exception import MapWalkError, ScriptError from module.exercise.assets import QUIT_CONFIRM, QUIT_RECONFIRM -from module.handler.login import LoginHandler +from module.handler.login import LoginHandler, MAINTENANCE_ANNOUNCE from module.logger import logger from module.map.map import Map from module.os.assets import FLEET_EMP_DEBUFF, MAP_GOTO_GLOBE_FOG @@ -551,10 +551,13 @@ class OSMap(OSFleet, Map, GlobeCamera, StrategicSearchHandler): if self.appear_then_click(AUTO_SEARCH_REWARD, offset=(50, 50), interval=3): continue if self.appear_then_click(PAUSE, interval=0.5): + self.interval_reset(MAINTENANCE_ANNOUNCE) continue if self.appear_then_click(QUIT_CONFIRM, offset=(20, 20), interval=5): + self.interval_reset(MAINTENANCE_ANNOUNCE) continue if self.appear_then_click(QUIT_RECONFIRM, offset=True, interval=5): + self.interval_reset(MAINTENANCE_ANNOUNCE) continue if self.appear_then_click(GOTO_MAIN, offset=(20, 20), interval=3): diff --git a/module/ui/assets.py b/module/ui/assets.py index ed93293b0..1c1d8562b 100644 --- a/module/ui/assets.py +++ b/module/ui/assets.py @@ -4,7 +4,7 @@ from module.base.template import Template # This file was automatically generated by dev_tools/button_extract.py. # Don't modify it manually. -ACADEMY_CHECK = Button(area={'cn': (121, 14, 175, 39), 'en': (122, 19, 260, 35), 'jp': (121, 14, 174, 40), 'tw': (119, 12, 178, 44)}, color={'cn': (147, 163, 200), 'en': (133, 150, 191), 'jp': (159, 174, 208), 'tw': (125, 139, 176)}, button={'cn': (121, 14, 175, 39), 'en': (122, 19, 260, 35), 'jp': (121, 14, 174, 40), 'tw': (119, 12, 178, 44)}, file={'cn': './assets/cn/ui/ACADEMY_CHECK.png', 'en': './assets/en/ui/ACADEMY_CHECK.png', 'jp': './assets/jp/ui/ACADEMY_CHECK.png', 'tw': './assets/tw/ui/ACADEMY_CHECK.png'}) +ACADEMY_CHECK = Button(area={'cn': (121, 14, 175, 39), 'en': (120, 22, 234, 36), 'jp': (121, 14, 174, 40), 'tw': (119, 12, 178, 44)}, color={'cn': (147, 163, 200), 'en': (130, 147, 189), 'jp': (159, 174, 208), 'tw': (125, 139, 176)}, button={'cn': (121, 14, 175, 39), 'en': (120, 22, 234, 36), 'jp': (121, 14, 174, 40), 'tw': (119, 12, 178, 44)}, file={'cn': './assets/cn/ui/ACADEMY_CHECK.png', 'en': './assets/en/ui/ACADEMY_CHECK.png', 'jp': './assets/jp/ui/ACADEMY_CHECK.png', 'tw': './assets/tw/ui/ACADEMY_CHECK.png'}) ACADEMY_GOTO_GAME_ROOM = Button(area={'cn': (1074, 340, 1103, 374), 'en': (1074, 340, 1103, 374), 'jp': (1074, 340, 1103, 374), 'tw': (1074, 340, 1103, 374)}, color={'cn': (208, 185, 150), 'en': (208, 185, 150), 'jp': (208, 185, 150), 'tw': (208, 185, 150)}, button={'cn': (1074, 340, 1103, 374), 'en': (1074, 340, 1103, 374), 'jp': (1074, 340, 1103, 374), 'tw': (1074, 340, 1103, 374)}, file={'cn': './assets/cn/ui/ACADEMY_GOTO_GAME_ROOM.png', 'en': './assets/en/ui/ACADEMY_GOTO_GAME_ROOM.png', 'jp': './assets/jp/ui/ACADEMY_GOTO_GAME_ROOM.png', 'tw': './assets/tw/ui/ACADEMY_GOTO_GAME_ROOM.png'}) ACADEMY_GOTO_MUNITIONS = Button(area={'cn': (1046, 188, 1137, 210), 'en': (1039, 185, 1145, 209), 'jp': (1057, 188, 1126, 210), 'tw': (1044, 184, 1139, 213)}, color={'cn': (133, 135, 165), 'en': (115, 120, 153), 'jp': (129, 133, 162), 'tw': (113, 119, 149)}, button={'cn': (1046, 188, 1137, 210), 'en': (1039, 185, 1145, 209), 'jp': (1057, 188, 1126, 210), 'tw': (1044, 184, 1139, 213)}, file={'cn': './assets/cn/ui/ACADEMY_GOTO_MUNITIONS.png', 'en': './assets/en/ui/ACADEMY_GOTO_MUNITIONS.png', 'jp': './assets/jp/ui/ACADEMY_GOTO_MUNITIONS.png', 'tw': './assets/tw/ui/ACADEMY_GOTO_MUNITIONS.png'}) BACK_ARROW = Button(area={'cn': (33, 44, 47, 64), 'en': (33, 44, 47, 64), 'jp': (33, 44, 47, 64), 'tw': (33, 44, 47, 64)}, color={'cn': (112, 118, 152), 'en': (112, 118, 152), 'jp': (112, 118, 152), 'tw': (112, 118, 152)}, button={'cn': (33, 31, 81, 78), 'en': (33, 31, 81, 78), 'jp': (33, 31, 81, 78), 'tw': (33, 31, 81, 78)}, file={'cn': './assets/cn/ui/BACK_ARROW.png', 'en': './assets/en/ui/BACK_ARROW.png', 'jp': './assets/jp/ui/BACK_ARROW.png', 'tw': './assets/tw/ui/BACK_ARROW.png'}) diff --git a/module/ui/scroll.py b/module/ui/scroll.py index f23826ad7..8d8da96e1 100644 --- a/module/ui/scroll.py +++ b/module/ui/scroll.py @@ -189,10 +189,10 @@ class Scroll: multiply = self.length / (self.total - self.length) target = current + page * multiply target = round(min(max(target, 0), 1), 3) - self.set(target, main=main, random_range=random_range, skip_first_screenshot=True) + return self.set(target, main=main, random_range=random_range, skip_first_screenshot=True) def next_page(self, main, page=0.8, random_range=(-0.01, 0.01), skip_first_screenshot=True): - self.drag_page(page, main=main, random_range=random_range, skip_first_screenshot=skip_first_screenshot) + return self.drag_page(page, main=main, random_range=random_range, skip_first_screenshot=skip_first_screenshot) def prev_page(self, main, page=0.8, random_range=(-0.01, 0.01), skip_first_screenshot=True): - self.drag_page(-page, main=main, random_range=random_range, skip_first_screenshot=skip_first_screenshot) + return self.drag_page(-page, main=main, random_range=random_range, skip_first_screenshot=skip_first_screenshot)