diff --git a/module/campaign/gems_farming.py b/module/campaign/gems_farming.py index 0c9162ac3..6bf22f94f 100644 --- a/module/campaign/gems_farming.py +++ b/module/campaign/gems_farming.py @@ -1,4 +1,7 @@ +from datetime import datetime + from module.base.decorator import cached_property +from module.base.timer import Timer from module.campaign.campaign_base import CampaignBase from module.campaign.run import CampaignRun from module.combat.assets import BATTLE_PREPARATION @@ -16,8 +19,9 @@ from module.retire.assets import ( TEMPLATE_CASSIN_1, TEMPLATE_CASSIN_2, TEMPLATE_DOWNES_1, TEMPLATE_DOWNES_2, TEMPLATE_AULICK, TEMPLATE_FOOTE ) +from module.retire.dock import Dock # TEMPLATE_COMMON_CV and TEMPLATE_COMMON_DD are both used in function find_custom_candidates -from module.retire.retirement import Retirement, TEMPLATE_COMMON_CV, TEMPLATE_COMMON_DD +from module.retire.retirement import TEMPLATE_COMMON_CV, TEMPLATE_COMMON_DD from module.retire.scanner import ShipScanner from module.ui.assets import BACK_ARROW, FLEET_CHECK from module.ui.page import page_fleet @@ -47,7 +51,16 @@ class GemsEmotion(Emotion): raise CampaignEnd('Emotion control') def wait(self, fleet_index): - pass + """ + Override Emotion.wait to trigger stop condition when emotion is too low after battle. + """ + self.update() + self.record() + self.show() + fleet = self.fleets[fleet_index - 1] + recovered = fleet.get_recovered(expected_reduce=self.reduce_per_battle) + if recovered > datetime.now(): + self.config.GEMS_EMOTION_TRIGGERED = True class GemsCampaignOverride(CampaignBase): @@ -95,47 +108,7 @@ class GemsCampaignOverride(CampaignBase): raise CampaignEnd('Emotion withdraw') -class GemsEquipmentHandler(EquipmentCodeHandler): - - def __init__(self, config, device=None, task=None): - super().__init__(config=config, - device=device, - task=task, - key="GemsFarming.GemsFarming.EquipmentCode", - ships=['DD', 'bogue', 'hermes', 'langley', 'ranger']) - - def current_ship(self, skip_first_screenshot=True): - """ - Reuse templates in module.retire.assets, - which needs different rescaling to match each current flagship. - - Pages: - in: gear_code - """ - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - # End - if not self.appear(EMPTY_SHIP_R): - break - else: - logger.info('Waiting ship icon loading.') - - if TEMPLATE_BOGUE.match(self.device.image, scaling=1.46): # image has rotation - return 'bogue' - if TEMPLATE_HERMES.match(self.device.image, scaling=124/89): - return 'hermes' - if TEMPLATE_RANGER.match(self.device.image, scaling=4/3): - return 'ranger' - if TEMPLATE_LANGLEY.match(self.device.image, scaling=25/21): - return 'langley' - return 'DD' - - -class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): +class GemsFarming(CampaignRun, Dock): def hard_mode_override(self): if self.campaign.config.Campaign_Mode == 'hard': logger.info('Is in hard mode, switch ship changing method.') @@ -217,19 +190,25 @@ class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): def _fleet_detail_enter_hard(self, fleet): if self.appear(FLEET_PREPARATION, offset=(20, 50)): return - self.campaign.ensure_campaign_ui(self.stage) - self.ui_click(click_button=self.campaign.ENTRANCE, appear_button=BACK_ARROW, check_button=MAP_PREPARATION) - while 1: - self.device.screenshot() - - if self.appear_then_click(MAP_PREPARATION, interval=1): - continue - - if self.handle_retirement(): - continue - + self.campaign.ensure_campaign_ui(self.stage, 'hard') + self.campaign.ENTRANCE.area = self.campaign.ENTRANCE.button + campaign_timer = Timer(5) + map_timer = Timer(5) + for _ in self.loop(): if self.appear(FLEET_PREPARATION, offset=(20, 50)): break + if map_timer.reached() \ + and self.campaign.handle_map_mode_switch('hard') \ + and self.campaign.handle_map_preparation(): + self.device.click(MAP_PREPARATION) + map_timer.reset() + campaign_timer.reset() + # Retire + if self.campaign.handle_retirement(): + continue + if campaign_timer.reached() and self.appear_then_click(self.campaign.ENTRANCE): + campaign_timer.reset() + continue def _ship_detail_enter_hard(self, button): self.ship_info_enter(button) @@ -254,7 +233,7 @@ class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): if self.change_flagship_equip: logger.hr('Unmount flagship equipments', level=2) self._ship_detail_enter(self.fleet_detail_enter_flagship) - self.clear_all_equip() + self.ship_equipment_take_off() self._fleet_back() logger.hr('Change flagship', level=2) @@ -263,7 +242,7 @@ class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): if self.change_flagship_equip: logger.hr('Mount flagship equipments', level=2) self._ship_detail_enter(self.fleet_detail_enter_flagship) - self.apply_equip_code() + self.ship_equipment_take_on() self._fleet_back() return success @@ -281,7 +260,7 @@ class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): if self.change_vanguard_equip: logger.hr('Unmount vanguard equipments', level=2) self._ship_detail_enter(self.fleet_detail_enter) - self.clear_all_equip() + self.ship_equipment_take_off() self._fleet_back() logger.hr('Change vanguard', level=2) @@ -290,19 +269,14 @@ class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): if self.change_vanguard_equip: logger.hr('Mount vanguard equipments', level=2) self._ship_detail_enter(self.fleet_detail_enter) - self.apply_equip_code() + self.ship_equipment_take_on() self._fleet_back() return success - def _dock_reset(self): - self.dock_favourite_set(False, wait_loading=False) - self.dock_sort_method_dsc_set(wait_loading=False) - self.dock_filter_set() - def _ship_change_confirm(self, button): self.dock_select_one(button) - self._dock_reset() + self.dock_reset() self.dock_select_confirm(check_button=self.page_fleet_check_button) def get_common_rarity_cv(self, lv=31, emotion=16): @@ -480,7 +454,7 @@ class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): filter_string = self.config.__getattribute__(f'GemsFarming_Common{ship_type}Filter') sort_dsc_first = ship_type.lower() == 'dd' - common_ship = self.get_common_ship_filter(filter_string, ship_type=ship_type) + common_ship = self.campaign.get_common_ship_filter(filter_string, ship_type=ship_type) templates = globals()[f'TEMPLATE_COMMON_{ship_type}'] find_first = True common_ship_candidates = {} @@ -614,7 +588,7 @@ class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): else: if self.hard_mode: raise RequestHumanTakeover - self._dock_reset() + self.dock_reset() self.ui_back(check_button=self.page_fleet_check_button) return False @@ -659,7 +633,7 @@ class GemsFarming(CampaignRun, GemsEquipmentHandler, Retirement): else: if self.hard_mode: raise RequestHumanTakeover - self._dock_reset() + self.dock_reset() self.ui_back(check_button=self.page_fleet_check_button) return False diff --git a/module/equipment/equipment.py b/module/equipment/equipment.py index 39dcce389..9aafb6788 100644 --- a/module/equipment/equipment.py +++ b/module/equipment/equipment.py @@ -2,16 +2,11 @@ from module.base.button import ButtonGrid from module.base.decorator import cached_property from module.base.timer import Timer from module.equipment.assets import * +from module.equipment.equipment_code import EquipmentCodeHandler from module.logger import logger from module.retire.assets import DOCK_CHECK, EQUIP_CONFIRM as RETIRE_EQUIP_CONFIRM -from module.storage.storage import StorageHandler from module.ui.assets import BACK_ARROW from module.ui.navbar import Navbar -from module.ui.switch import Switch - -equipping_filter = Switch('Equiping_filter') -equipping_filter.add_state('on', check_button=EQUIPPING_ON) -equipping_filter.add_state('off', check_button=EQUIPPING_OFF) SWIPE_DISTANCE = 250 SWIPE_RANDOM_RANGE = (-40, -20, 40, 20) @@ -19,13 +14,9 @@ SWIPE_RANDOM_RANGE = (-40, -20, 40, 20) EQUIPMENT_OPEN.match = EQUIPMENT_OPEN.match_luma -class Equipment(StorageHandler): +class Equipment(EquipmentCodeHandler): equipment_has_take_on = False - def equipping_set(self, enable=False): - if equipping_filter.set('on' if enable else 'off', main=self): - self.wait_until_stable(SWIPE_AREA) - def _ship_view_swipe(self, distance, check_button=EQUIPMENT_OPEN): swipe_count = 0 swipe_timer = Timer(5, count=10) @@ -76,23 +67,23 @@ class Equipment(StorageHandler): def ship_view_prev(self, check_button=EQUIPMENT_OPEN): return self._ship_view_swipe(distance=SWIPE_DISTANCE, check_button=check_button) - def ship_info_enter(self, click_button, check_button=EQUIPMENT_OPEN, long_click=True, skil_first_screenshot=True): + def ship_info_enter(self, click_button, check_button=EQUIPMENT_OPEN, long_click=True, skip_first_screenshot=True): enter_timer = Timer(10) while 1: - if skil_first_screenshot: - skil_first_screenshot = False + if skip_first_screenshot: + skip_first_screenshot = False else: self.device.screenshot() # End - if self.appear(check_button): + if self.appear(check_button, offset=(5, 5)): break # Long click accidentally became normal click, exit from dock if long_click: if self.appear(DOCK_CHECK, offset=(20, 20), interval=3): - logger.info(f'equip_enter {DOCK_CHECK} -> {BACK_ARROW}') + logger.info(f'ship_info_enter {DOCK_CHECK} -> {BACK_ARROW}') self.device.click(BACK_ARROW) continue if enter_timer.reached(): @@ -168,120 +159,8 @@ class Equipment(StorageHandler): return True return False - def ship_equipment_take_off(self, skip_first_screenshot=True): - logger.info('Equipment take off') - bar_timer = Timer(5) - off_timer = Timer(5) - confirm_timer = Timer(5) + def ship_equipment_take_off(self, name=None): + self.code_clear(name=name) - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - # End - # if self.handle_info_bar(): - # break - if off_timer.started() and self.info_bar_count(): - break - - if self.handle_storage_full(): - continue - - if confirm_timer.reached() and self.handle_popup_confirm(): - confirm_timer.reset() - off_timer.reset() - bar_timer.reset() - continue - - if off_timer.reached(): - if not self.info_bar_count() and self.appear_then_click(EQUIP_OFF, offset=(20, 20)): - off_timer.reset() - bar_timer.reset() - continue - - if bar_timer.reached(): - if self.appear(EQUIPMENT_OPEN, offset=(20, 20)) and not self.appear(EQUIP_OFF, offset=(20, 20)): - self.device.click(EQUIPMENT_OPEN) - bar_timer.reset() - continue - - logger.info('Equipment take off ended') - - def fleet_equipment_take_off(self, enter, long_click, out): - """ - Args: - enter (Button): Button to edit equipment. - long_click (bool): How to click enter - out (Button): Button to confirm exit success. - """ - logger.hr('Equipment take off') - self.ship_info_enter(enter, long_click=long_click) - - while True: - self.ship_equipment_take_off() - self.ui_click(EQUIPMENT_CLOSE, check_button=EQUIPMENT_OPEN, skip_first_screenshot=True) - if not self.ship_view_next(): - break - - self.ui_back(out) - self.equipment_has_take_on = False - - def ship_equipment_take_on_preset(self, index, skip_first_screenshot=True): - logger.info('Equipment take on preset') - bar_timer = Timer(5) - on_timer = Timer(5) - - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - # End - # if self.handle_info_bar(): - # break - if on_timer.started() and self.info_bar_count(): - break - - if bar_timer.reached() and not self.appear(EQUIP_1, offset=10): - self.device.click(EQUIPMENT_OPEN) - # self.device.sleep(0.3) - bar_timer.reset() - continue - - if on_timer.reached() and self.appear(EQUIP_1, offset=10) and not self.info_bar_count(): - if index == 1: - self.device.click(EQUIP_1) - elif index == 2: - self.device.click(EQUIP_2) - elif index == 3: - self.device.click(EQUIP_3) - - on_timer.reset() - bar_timer.reset() - continue - - logger.info('Equipment take on ended') - - def fleet_equipment_take_on_preset(self, enter, out, fleet): - """ - Args: - enter (Button): Long click to edit equipment. - out (Button): Button to confirm exit success. - fleet (list[int]): list of equipment record. [3, 1, 1, 1, 1, 1] - """ - logger.hr('Equipment take on') - self.ship_info_enter(enter) - - for index in '9'.join([str(x) for x in fleet if x > 0]): - index = int(index) - if index == 9: - self.ship_view_next() - else: - self.ship_equipment_take_on_preset(index=index) - self.ui_click(click_button=EQUIPMENT_CLOSE, check_button=EQUIPMENT_OPEN, offset=None) - - self.ui_back(out) - self.equipment_has_take_on = True + def ship_equipment_take_on(self, name=None): + self.code_apply(name=name) diff --git a/module/equipment/equipment_code.py b/module/equipment/equipment_code.py index 26da9f903..99338bdf6 100644 --- a/module/equipment/equipment_code.py +++ b/module/equipment/equipment_code.py @@ -1,276 +1,197 @@ -import re import yaml -from module.config.config import AzurLaneConfig from module.equipment.assets import * -from module.exception import RequestHumanTakeover from module.logger import logger +from module.retire.assets import TEMPLATE_BOGUE, TEMPLATE_HERMES, TEMPLATE_RANGER, TEMPLATE_LANGLEY from module.storage.assets import EQUIPMENT_FULL from module.storage.storage import StorageHandler - -BASE64_REGEX = re.compile('^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$') -EMPTY_GEAR_CODE = "MC8wLzAvMC8wXDA=" - -def is_equip_code(string): - """ - Checks if current string is None or BASE64 string. - """ - if string is None: - return True - if not isinstance(string, str): - return False - return BASE64_REGEX.match(string) - - -class EquipmentCode: - config: AzurLaneConfig - config_key: str - coded_ships: list - - def __setattr__(self, key, value): - if key in ['config', 'config_key', 'coded_ships']: - super().__setattr__(key, value) - elif key in self.coded_ships: - if is_equip_code(value): - super().__setattr__(key, value) - else: - logger.error(f'{value} is not a gear code, skip setting {key}') - else: - logger.error(f'{key} is not in coded ships: {self.coded_ships}') - - def __init__(self, config, key, ships): - """ - Args: - config (AzurLaneConfig): - key: location of config containing gear code configs - ships (list of string): ships whose gear codes should be memorized - """ - self.config = config - self.config_key = key - self.coded_ships = ships - _config = config.cross_get(keys=key) - codes = dict([(ship, None) for ship in self.coded_ships]) - for line in _config.splitlines(): - try: - codes.update(yaml.safe_load(line)) - except Exception as e: - logger.error(f'Failed to parse current line of the config: "{line}", skipping') - for ship in self.coded_ships: - code: str = codes.pop(ship, None) - self.__setattr__(ship, code) - - def export_to_config(self): - """ - Export current ships' gear codes to location {self.config_key} of {self.config}. - """ - _config = {} - for ship in self.coded_ships: - _config.update({ship: self.__getattribute__(ship)}) - value = yaml.safe_dump(_config) - logger.info(f'Gear code configs to be exported: {value}') - self.config.cross_set(keys=self.config_key, value=value) - +EMPTY_CODE = "MC8wLzAvMC8wXDA=" +EQUIPMENT_PREVIEW = list([ + EQUIPMENT_CODE_EQUIP_0, + EQUIPMENT_CODE_EQUIP_1, + EQUIPMENT_CODE_EQUIP_2, + EQUIPMENT_CODE_EQUIP_3, + EQUIPMENT_CODE_EQUIP_4, + EQUIPMENT_CODE_EQUIP_5, +]) class EquipmentCodeHandler(StorageHandler): - codes: EquipmentCode + last_code: str = None - def __init__(self, config, key, ships, device=None, task=None): - super().__init__(config, device=device, task=task) - self.codes = EquipmentCode(self.config, key=key, ships=ships) + def get_code(self, name): + try: + config = {} + for item in yaml.safe_load_all(self.config.GemsFarming_EquipmentCode): + config.update(item) + except Exception: + logger.error("Fail to load equipment code config") + return None + try: + name: str = config.pop(name) + return name + except Exception: + logger.error(f"Config does not contain equipment code for {name}") + return None - def enter_equip_code_page(self, skip_first_screenshot=True): + def set_code(self, name, code): + config = {} + try: + for item in yaml.safe_load_all(self.config.GemsFarming_EquipmentCode): + config.update(item) + except Exception: + pass + try: + config.update({name: code}) + config_yaml = yaml.safe_dump(config) + self.config.GemsFarming_EquipmentCode = config_yaml + except Exception: + logger.error("Fail to set equipment code config") + + def current_ship(self): + """ + Currently, only supports common CV recognization + + Pages: + in: equipment_code + """ + for _ in self.loop(): + if not self.appear(EMPTY_SHIP_R): + break + if TEMPLATE_BOGUE.match(self.device.image, scaling=1.46): # image has rotation + return 'bogue' + elif TEMPLATE_HERMES.match(self.device.image, scaling=124 / 89): + return 'hermes' + elif TEMPLATE_RANGER.match(self.device.image, scaling=4 / 3): + return 'ranger' + elif TEMPLATE_LANGLEY.match(self.device.image, scaling=25 / 21): + return 'langley' + else: + return 'DD' + + def _code_enter(self): """ Pages: in: ship_detail - out: gear_code + out: equipment_code """ - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - # End + for _ in self.loop(): if self.appear(EQUIPMENT_CODE_PAGE_CHECK, offset=(5, 5)): break if self.appear_then_click(EQUIPMENT_CODE_ENTRANCE, offset=(5, 5), interval=2): continue - # def exit_equip_code_page(self): - # """ - # Pages: - # in: gear_code - # out: ship_detail - # """ - # self.ui_back(check_button=EQUIPMENT_CODE_ENTRANCE) - - def current_ship(self): - # Will be overridden in subclasses. - pass - - def click_export_button(self, skip_first_screenshot=True): - self.handle_info_bar() - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - # End - if self.info_bar_count(): - break - - if self.appear_then_click(EQUIPMENT_CODE_EXPORT, offset=(5, 5), interval=1): - continue - - def export_equip_code(self, ship=None): + def _code_exit(self): """ - Export current ship's gear code to config file. - This is done by first using "export" button - to export gear code to clipboard, - then update the config file using yaml.safe_dump(). + Pages: + in: equipment_code + out: ship_detail """ - code = self.device.clipboard - if code == EMPTY_GEAR_CODE: - logger.info('Detect 0/0/0/0/0\\0 code, continue exporting.') - logger.attr("Gear code", code) - if not ship in self.codes.coded_ships: - ship = self.current_ship() - logger.attr("Current ship", ship) - logger.info(f'Set gear code of {ship} to be {code}') - self.codes.__setattr__(ship, code) - self.codes.export_to_config() + self.ui_back(check_button=EQUIPMENT_CODE_ENTRANCE) - def equip_preview_empty(self): - if self.appear(EQUIPMENT_CODE_EQUIP_5_LOCKED): + def is_code_preview_loaded(self): + if self.appear(EQUIPMENT_CODE_EQUIP_5_LOCKED, offset=(5, 5)): max_index = 5 else: max_index = 6 for index in range(max_index): - if not self.appear(globals()['EQUIPMENT_CODE_EQUIP_{index}'.format(index=index)], offset=(5, 5)): - return False - - return True - - def clear_equip_preview(self, skip_first_screenshot=True): - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - # End - if self.equip_preview_empty(): - logger.info('Confirm equipment preview cleared.') - break - - if self.appear_then_click(EQUIPMENT_CODE_CLEAR, offset=(5, 5), interval=2): - continue - - def enter_equip_code_input_mode(self, skip_first_screenshot=True): - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - if self.appear(EQUIPMENT_CODE_ENTER, offset=(5, 5), interval=2): - self.device.click(EQUIPMENT_CODE_TEXTBOX) - continue - - # End - if self.device.ime_shown(): - break - - def confirm_equip_code(self, skip_first_screenshot=False): - check_counter = 0 - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() - - if self.appear_then_click(EQUIPMENT_CODE_ENTER, offset=(5, 5), interval=1): - continue - - # End - if not self.equip_preview_empty(): - logger.info('Confirm gear code loaded.') + if not self.appear(EQUIPMENT_PREVIEW[index], offset=(5, 5)): return True - else: - check_counter += 1 - if check_counter >= 5: - logger.error('Gear code load failed, retrying.') - return False - def confirm_equip_preview(self, skip_first_screenshot=True): - while 1: - if skip_first_screenshot: - skip_first_screenshot = False - else: - self.device.screenshot() + return False - if self.appear_then_click(EQUIPMENT_CODE_CONFIRM, offset=(5, 5), interval=5): + def _code_preview_clear(self): + for _ in self.loop(timeout=2): + if not self.is_code_preview_loaded(): + return True + + if self.appear_then_click(EQUIPMENT_CODE_CLEAR, offset=(5, 5)): continue + else: + return False - if self.handle_popup_confirm('EQUIPMENT_CODE'): + def _code_input(self, code): + logger.info(f"Code input: {code}") + d = self.device.u2 + for _ in self.loop(timeout=10): + _, shown = d.current_ime() + if shown: + break + self.device.click(EQUIPMENT_CODE_TEXTBOX) + else: + logger.warning("Equipment code load failed") + return False + d.send_keys(text=code, clear=True) + d.send_action(code="done") + self.device.sleep((0.3, 0.5)) + for _ in self.loop(timeout=10, skip_first=False): + _, shown = d.current_ime() + if shown: continue + if self.is_code_preview_loaded(): + return True + if self.appear_then_click(EQUIPMENT_CODE_ENTER, offset=(5, 5), interval=3): + continue + else: + logger.warning("Equipment code load failed") + return False - # End + def _code_confirm(self): + logger.info("Code apply") + for _ in self.loop(timeout=10): if self.appear(EQUIPMENT_CODE_ENTRANCE, offset=(5, 5)): return True if self.appear(EQUIPMENT_FULL, offset=(30, 30)): return False - - def clear_all_equip(self): - self.enter_equip_code_page() - ship = self.current_ship() - self.device.u2_set_fastinput_ime(True) - logger.attr("Current_ime", self.device.u2_current_ime()) - if self.codes.__getattribute__(ship) is None: - self.click_export_button() - self.export_equip_code(ship) - self.clear_equip_preview() - for _ in range(5): - success = self.confirm_equip_preview() - if success: - return True - else: - self.handle_storage_full() - self.clear_equip_preview() - - raise RequestHumanTakeover( - f'Failed to clear all equipment for {ship}, please check manually.' - ) - - def apply_equip_code(self, code=None): - self.enter_equip_code_page() - self.clear_equip_preview() - if code is None: - ship = self.current_ship() - code = self.codes.__getattribute__(ship) - if code is None: - code = self.device.clipboard # assuming clipboard is not modified - logger.info(f'Apply gear code {code} for {ship}') + if self.handle_popup_confirm("EQUIPMENT_CODE"): + continue + if self.appear_then_click(EQUIPMENT_CODE_CONFIRM, offset=(5, 5), interval=3): + continue else: - logger.info(f'Forcefully apply gear code {code} to current ship.') + return False + + def _code_apply(self, code=None): for _ in range(5): - if code is not None and code != EMPTY_GEAR_CODE: - self.enter_equip_code_input_mode() - self.device.text_input_and_confirm(code, clear=True) - success = self.confirm_equip_code() + self._code_preview_clear() + if code is not None and code != EMPTY_CODE: + success = self._code_input(code) if not success: continue - success = self.confirm_equip_preview() + success = self._code_confirm() if success: - logger.info("Gear code import complete.") + logger.info("Equipment code apply complete.") return True else: self.handle_storage_full() - self.clear_equip_preview() + else: + return False - raise RequestHumanTakeover( - f'Failed to apply equipment for {ship}, please check manually.' - ) + def _code_export(self): + self.handle_info_bar() + d = self.device.u2 + for _ in self.loop(timeout=10): + if self.info_bar_count(): + break + if self.appear_then_click(EQUIPMENT_CODE_EXPORT, offset=(5, 5), interval=3): + continue + code = d.clipboard + return code + + def code_clear(self, name=None): + self._code_enter() + if name is None: + name = self.current_ship() + if self.get_code(name=name) is None: + self.last_code = self._code_export() + self.set_code(name=name, code=self.last_code) + self._code_apply(code=None) + + def code_apply(self, name=None): + self._code_enter() + if name is None: + name = self.current_ship() + code = self.get_code(name=name) + if code is None: + code = self.last_code + self._code_apply(code=code) diff --git a/module/retire/dock.py b/module/retire/dock.py index c6dcbb0c1..8291bc62c 100644 --- a/module/retire/dock.py +++ b/module/retire/dock.py @@ -219,6 +219,11 @@ class Dock(Equipment): self.dock_filter.set(sort=sort, index=index, faction=faction, rarity=rarity, extra=extra) self.dock_filter_confirm(wait_loading=wait_loading) + def dock_reset(self): + self.dock_favourite_set(False, wait_loading=False) + self.dock_sort_method_dsc_set(wait_loading=False) + self.dock_filter_set() + def dock_select_one(self, button, skip_first_screenshot=True): """ Args: