From 79edef015f797380bb9c0b35ca3dd64b0b7f6940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9C=9E=E9=A3=9B?= Date: Fri, 28 Jun 2024 12:18:08 +0800 Subject: [PATCH] fix: handle sidebar disappear (#3930) * fix: handle OpsiShop disappear * docs: add a condition to OpsiShop * ref: remove useless loop * fix: exception * feat: skip to the next month if the new shop do not unlock --- module/config/i18n/en-US.json | 2 +- module/config/i18n/zh-CN.json | 2 +- module/config/i18n/zh-TW.json | 2 +- module/os/operation_siren.py | 20 +++++++++++++++----- module/os_handler/port.py | 19 ++++++++----------- module/os_shop/ui.py | 34 +++++++++++++++------------------- 6 files changed, 41 insertions(+), 38 deletions(-) diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index 4a042bb998..402d9d587a 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -2294,7 +2294,7 @@ "OpsiShop": { "_info": { "name": "OpSi Shop Settings", - "help": "Completes OpSi daily activities\nThe following must be satisfied:\n- OpSi story and practice battles must be complete\n- Task OpSi Explore enabled or consuming 5000 oil for special radar in OpSi voucher shop" + "help": "Completes OpSi daily activities\nThe following must be satisfied:\n- OpSi story and practice battles must be complete\n- Task OpSi Explore enabled or consuming 5000 oil for special radar in OpSi voucher shop\nAvailable only in the next month after clearing OpSi story, i.e., after the port shop becomes a new version of the shop" }, "PresetFilter": { "name": "OpSi Shop Filter", diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index 008a136792..89eb3ad009 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -2294,7 +2294,7 @@ "OpsiShop": { "_info": { "name": "大世界商店", - "help": "使用此功能前必须满足以下条件:\n- 通关大世界主线并完成模拟战+塞壬试验场\n- 启用大世界开荒任务或使用战役信息记录仪(5000油道具)" + "help": "使用此功能前必须满足以下条件:\n- 通关大世界主线并完成模拟战+塞壬试验场\n- 启用大世界开荒任务或使用战役信息记录仪(5000油道具)\n- 通关大世界主线后的下一个月,即港口商店变为新版商店后才可使用" }, "PresetFilter": { "name": "港口商店过滤器", diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 20b98a8c6a..58de47dfc9 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -2294,7 +2294,7 @@ "OpsiShop": { "_info": { "name": "大世界商店", - "help": "使用此功能前必須滿足以下條件:\n- 通關大世界主線任務+模擬戰\n- 開啟大世界開荒任務或使用戰役信息記錄儀(5000油道具)" + "help": "使用此功能前必須滿足以下條件:\n- 通關大世界主線任務+模擬戰\n- 開啟大世界開荒任務或使用戰役信息記錄儀(5000油道具)\n- 通關大世界主線後的下個月,也就是港口商店變成新版商店後才可使用" }, "PresetFilter": { "name": "港口商店過濾器", diff --git a/module/os/operation_siren.py b/module/os/operation_siren.py index 39770f5b0c..f8dca66705 100644 --- a/module/os/operation_siren.py +++ b/module/os/operation_siren.py @@ -15,8 +15,8 @@ from module.os.map import OSMap from module.os_handler.action_point import OCR_OS_ADAPTABILITY, ActionPointLimit from module.os_handler.assets import OS_MONTHBOSS_NORMAL, OS_MONTHBOSS_HARD, EXCHANGE_CHECK, EXCHANGE_ENTER +from module.os_shop.assets import OS_SHOP_CHECK from module.shop.shop_voucher import VoucherShop -from module.base.decorator import Config class OperationSiren(OSMap): @@ -242,13 +242,23 @@ def os_shop(self): logger.hr('OS port daily', level=1) if not self.zone.is_azur_port: self.globe_goto(self.zone_nearest_azur_port(self.zone)) + self.port_enter() - not_empty = self.port_supply_buy() + self.port_shop_enter() + + if self.appear(OS_SHOP_CHECK): + not_empty = self.handle_port_supply_buy() + next_reset = self._os_shop_delay(not_empty) + logger.info('OS port daily finished, delay to next reset') + logger.attr('OpsiShopNextReset', next_reset) + else: + next_reset = get_os_next_reset() + logger.warning('There is no shop in the port, skip to the next month.') + logger.attr('OpsiShopNextReset', next_reset) + + self.port_shop_quit() self.port_quit() - next_reset = self._os_shop_delay(not_empty) - logger.info('OS port daily finished, delay to next reset') - logger.attr('OpsiShopNextReset', next_reset) self.config.task_delay(target=next_reset) self.config.task_stop() diff --git a/module/os_handler/port.py b/module/os_handler/port.py index 148c63cb5c..ff5448ac8b 100644 --- a/module/os_handler/port.py +++ b/module/os_handler/port.py @@ -79,17 +79,11 @@ def port_mission_accept(self): self.ui_back(appear_button=PORT_MISSION_CHECK, check_button=PORT_CHECK, skip_first_screenshot=True) return success - def port_supply_buy(self): + def port_shop_enter(self): """ - Buy supply in port. - - Returns: - bool: True if success to buy any or no items found. - False if not enough coins to buy any. - Pages: in: PORT_CHECK - out: PORT_CHECK + out: PORT_SUPPLY_CHECK """ self.ui_click(PORT_GOTO_SUPPLY, appear_button=PORT_CHECK, check_button=PORT_SUPPLY_CHECK, skip_first_screenshot=True) @@ -97,10 +91,13 @@ def port_supply_buy(self): self.device.sleep(0.5) self.device.screenshot() - success = self.handle_port_supply_buy() - + def port_shop_quit(self): + """ + Pages: + in: PORT_SUPPLY_CHECK + out: PORT_CHECK + """ self.ui_back(appear_button=PORT_SUPPLY_CHECK, check_button=PORT_CHECK, skip_first_screenshot=True) - return success def port_dock_repair(self): """ diff --git a/module/os_shop/ui.py b/module/os_shop/ui.py index b13c39c163..9716177b88 100644 --- a/module/os_shop/ui.py +++ b/module/os_shop/ui.py @@ -3,8 +3,8 @@ from module.base.decorator import cached_property from module.base.timer import Timer from module.base.utils import random_rectangle_vector -from module.exception import ScriptError -from module.os_shop.assets import OS_SHOP_SAFE_AREA, OS_SHOP_SCROLL_AREA, PORT_SUPPLY_CHECK +from module.exception import GameStuckError +from module.os_shop.assets import OS_SHOP_CHECK, OS_SHOP_SAFE_AREA, OS_SHOP_SCROLL_AREA from module.logger import logger from module.ui.navbar import Navbar from module.ui.scroll import AdaptiveScroll @@ -42,13 +42,14 @@ def os_shop_load_ensure(self, skip_first_screenshot=True): self.device.screenshot() # End - if self.appear(PORT_SUPPLY_CHECK): + if self.appear(OS_SHOP_CHECK): return True + else: + logger.warning('OpsiShop is not appear, retrying.') # Exception if ensure_timeout.reached(): - logger.warning('Wait for loaded assets is incomplete, ensure not guaranteed') - return False + raise GameStuckError('Waiting too long for OpsiShop to appear.') @cached_property def _os_shop_side_navbar(self): @@ -94,14 +95,9 @@ def os_shop_side_navbar_ensure(self, upper=None, bottom=None): in: PORT_SUPPLY_CHECK out: PORT_SUPPLY_CHECK """ - retry = Timer(0, count=3) - retry.start() - while self._os_shop_side_navbar.get_active(main=self) + 1 not in [upper, bottom]: - logger.info(f'OS shop side navbar set to {upper or bottom}, setting') - self._os_shop_side_navbar.set(self, upper=upper, bottom=bottom) - self.os_shop_load_ensure() - if retry.reached(): - raise ScriptError('Side navbar set error.') + logger.info(f'OpsiShop side navbar set to {upper or bottom}') + self.os_shop_load_ensure() + self._os_shop_side_navbar.set(self, upper=upper, bottom=bottom) def init_slider(self) -> Tuple[float, float]: """Initialize the slider @@ -110,7 +106,7 @@ def init_slider(self) -> Tuple[float, float]: Tuple[float, float]: (pre_pos, cur_pos) """ if not OS_SHOP_SCROLL.appear(main=self): - logger.warning('ScriptError, Scroll does not appear, try to rescue slider') + logger.warning('Scroll does not appear, try to rescue slider') self.rescue_slider() retry = Timer(0, count=3) retry.start() @@ -118,7 +114,7 @@ def init_slider(self) -> Tuple[float, float]: logger.info('Scroll does not at top, try to scroll') OS_SHOP_SCROLL.set_top(main=self) if retry.reached(): - raise ScriptError('Scroll drag page error.') + raise GameStuckError('Scroll drag page error.') return -1.0, 0.0 def rescue_slider(self, distance=200): @@ -144,21 +140,21 @@ def pre_scroll(self, pre_pos, cur_pos) -> float: cur_pos: Current position """ if pre_pos == cur_pos: - logger.warning('ScriptError, Scroll drag page failed') + logger.warning('Scroll drag page failed') if not OS_SHOP_SCROLL.appear(main=self): - logger.warning('ScriptError, Scroll does not appear, try to rescue slider') + logger.warning('Scroll does not appear, try to rescue slider') self.rescue_slider() OS_SHOP_SCROLL.set(cur_pos, main=self) retry = Timer(0, count=3) retry.start() while True: - logger.warning('ScriptError, Scroll does not drag success, retrying scroll') + logger.warning('Scroll does not drag success, retrying scroll') OS_SHOP_SCROLL.next_page(main=self, page=0.5) cur_pos = OS_SHOP_SCROLL.cal_position(main=self) if pre_pos != cur_pos: logger.info(f'Scroll success drag page to {cur_pos}') return cur_pos if retry.reached(): - raise ScriptError('Scroll drag page error.') + raise GameStuckError('Scroll drag page error.') else: return cur_pos