1
0
mirror of https://github.com/sui-feng-cb/AzurLaneAutoScript1.git synced 2026-06-21 20:23:54 +08:00

Upd: GemsFarming

This commit is contained in:
2026-06-20 00:57:57 +08:00
parent 8cdb84adc6
commit b69311d96b
4 changed files with 206 additions and 427 deletions

View File

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

View File

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

View File

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

View File

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