Merge remote-tracking branch 'upstream/master'

This commit is contained in:
POLAR me 2025-04-11 02:32:39 +08:00
commit 3d98811716
16 changed files with 217 additions and 33 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -46,7 +46,7 @@ class AdbManager(DeployConfig):
logger.hr('ADB Connect', 1)
emulator.brute_force_connect()
if self.InstallUiautomator2:
if False:
logger.hr('Uiautomator2 Init', 1)
try:
import adbutils

View File

@ -1,4 +1,6 @@
import sys
import typing as t
from dataclasses import dataclass
from urllib.parse import urlparse
from deploy.config import DeployConfig
@ -6,15 +8,49 @@ from deploy.logger import logger
from deploy.utils import *
@dataclass
class DataDependency:
name: str
version: str
def __post_init__(self):
# uvicorn[standard] -> uvicorn
self.name = re.sub(r'\[.*\]', '', self.name)
# opencv_python -> opencv-python
self.name = self.name.replace('_', '-').strip()
# PyYaml -> pyyaml
self.name = self.name.lower()
self.version = self.version.strip()
self.version = re.sub(r'\.0$', '', self.version)
@cached_property
def pretty_name(self):
return f'{self.name}=={self.version}'
def __str__(self):
return self.pretty_name
__repr__ = __str__
def __eq__(self, other):
return str(self) == str(other)
def __hash__(self):
return hash(str(self))
class PipManager(DeployConfig):
@cached_property
def python(self):
exe = self.filepath("PythonExecutable")
if os.path.exists(exe):
return exe
def python(self) -> str:
# No need to read PythonExecutable
# since you run this code with python, current python is the python
# exe = self.filepath(self.PythonExecutable)
# if os.path.exists(exe):
# return exe
current = sys.executable.replace("\\", "/")
logger.warning(f'PythonExecutable: {exe} does not exist, use current python instead: {current}')
# logger.warning(f'PythonExecutable: {exe} does not exist, use current python instead: {current}')
return current
@cached_property
@ -28,6 +64,58 @@ class PipManager(DeployConfig):
def pip(self):
return f'"{self.python}" -m pip'
@cached_property
def python_site_packages(self) -> str:
import site
paths = site.getsitepackages()
# site-packages should be site-packages folder
for path in paths:
if path.endswith('site-packages'):
return path
# Otherwise pick first
return paths[0]
@cached_property
def set_installed_dependency(self) -> t.Set[DataDependency]:
data = []
regex = re.compile(r'(.*)-(.*).dist-info')
try:
for name in os.listdir(self.python_site_packages):
res = regex.search(name)
if res:
dep = DataDependency(name=res.group(1), version=res.group(2))
data.append(dep)
except FileNotFoundError:
logger.info(f'Directory not found: {self.python_site_packages}')
return set(data)
@cached_property
def set_required_dependency(self) -> t.Set[DataDependency]:
data = []
regex = re.compile('(.*)==(.*)[ ]*#')
file = self.requirements_file
try:
with open(file, 'r', encoding='utf-8') as f:
for line in f.readlines():
res = regex.search(line)
if res:
dep = DataDependency(name=res.group(1), version=res.group(2))
data.append(dep)
except FileNotFoundError:
logger.info(f'File not found: {file}')
return set(data)
@cached_property
def set_dependency_to_install(self) -> t.Set[DataDependency]:
"""
A poor dependency comparison, but much much faster than `pip install` and `pip list`
"""
data = []
for dep in self.set_required_dependency:
if dep not in self.set_installed_dependency:
data.append(dep)
return set(data)
def pip_install(self):
logger.hr('Update Dependencies', 0)
@ -35,6 +123,12 @@ class PipManager(DeployConfig):
logger.info('InstallDependencies is disabled, skip')
return
if not len(self.set_dependency_to_install):
logger.info('All dependencies installed')
return
else:
logger.info(f'Dependencies to install: {self.set_dependency_to_install}')
logger.hr('Check Python', 1)
self.execute(f'"{self.python}" --version')

View File

@ -3,7 +3,7 @@ from module.base.timer import Timer
from module.exception import ScriptError
from module.logger import logger
from module.ocr.ocr import Digit
from module.retire.dock import CARD_GRIDS, DOCK_EMPTY, Dock, SHIP_DETAIL_CHECK
from module.retire.dock import DOCK_EMPTY, Dock
from module.ui.assets import BACK_ARROW
from module.ui.page import page_dock, page_main
@ -346,8 +346,11 @@ class Awaken(Dock):
break
# page_dock -> SHIP_DETAIL_CHECK
self.ship_info_enter(
CARD_GRIDS[(0, 0)], check_button=SHIP_DETAIL_CHECK, long_click=False)
entered = self.dock_enter_first()
if not entered:
logger.info('awaken_run finished, no ships to awaken')
result = 'finish'
break
# is_in_awaken
result = self.awaken_ship(use_array)

View File

@ -108,6 +108,9 @@ class Combat(Level, HPBalancer, Retirement, SubmarineCall, CombatAuto, CombatMan
return PAUSE_Pharaoh
if PAUSE_Nurse.match_luma(self.device.image, offset=(10, 10)):
return PAUSE_Nurse
# PAUSE_Devil is in red
if PAUSE_Devil.match_template_color(self.device.image, offset=(10, 10)):
return PAUSE_Devil
return False
def handle_combat_quit(self, offset=(20, 20), interval=3):
@ -141,6 +144,7 @@ class Combat(Level, HPBalancer, Retirement, SubmarineCall, CombatAuto, CombatMan
self.device.click(QUIT_Nurse)
timer.reset()
return True
# Battle UI PAUSE_Devil uses QUIT_New
return False
def ensure_combat_oil_loaded(self):

View File

@ -8,6 +8,7 @@ PAUSE = Button(area={'cn': (1158, 40, 1199, 58), 'en': (1155, 38, 1216, 51), 'jp
PAUSE_Christmas = Button(area={'cn': (1234, 35, 1250, 56), 'en': (1234, 35, 1250, 56), 'jp': (1234, 35, 1250, 56), 'tw': (1234, 35, 1250, 56)}, color={'cn': (158, 181, 210), 'en': (158, 181, 210), 'jp': (158, 181, 210), 'tw': (158, 181, 210)}, button={'cn': (1234, 35, 1250, 56), 'en': (1234, 35, 1250, 56), 'jp': (1234, 35, 1250, 56), 'tw': (1234, 35, 1250, 56)}, file={'cn': './assets/cn/combat_ui/PAUSE_Christmas.png', 'en': './assets/cn/combat_ui/PAUSE_Christmas.png', 'jp': './assets/cn/combat_ui/PAUSE_Christmas.png', 'tw': './assets/cn/combat_ui/PAUSE_Christmas.png'})
PAUSE_Cyber = Button(area={'cn': (1231, 32, 1253, 59), 'en': (1231, 32, 1253, 59), 'jp': (1231, 32, 1253, 59), 'tw': (1231, 32, 1253, 59)}, color={'cn': (40, 140, 157), 'en': (40, 140, 157), 'jp': (40, 140, 157), 'tw': (40, 140, 157)}, button={'cn': (1231, 32, 1253, 59), 'en': (1231, 32, 1253, 59), 'jp': (1231, 32, 1253, 59), 'tw': (1231, 32, 1253, 59)}, file={'cn': './assets/cn/combat_ui/PAUSE_Cyber.png', 'en': './assets/cn/combat_ui/PAUSE_Cyber.png', 'jp': './assets/cn/combat_ui/PAUSE_Cyber.png', 'tw': './assets/cn/combat_ui/PAUSE_Cyber.png'})
PAUSE_DOUBLE_CHECK = Button(area={'cn': (1226, 35, 1231, 60), 'en': (1226, 35, 1231, 61), 'jp': (1226, 35, 1230, 60), 'tw': (1226, 35, 1231, 60)}, color={'cn': (96, 104, 136), 'en': (83, 98, 118), 'jp': (97, 102, 120), 'tw': (96, 104, 136)}, button={'cn': (1226, 35, 1231, 60), 'en': (1226, 35, 1231, 61), 'jp': (1226, 35, 1230, 60), 'tw': (1226, 35, 1231, 60)}, file={'cn': './assets/cn/combat_ui/PAUSE_DOUBLE_CHECK.png', 'en': './assets/en/combat_ui/PAUSE_DOUBLE_CHECK.png', 'jp': './assets/jp/combat_ui/PAUSE_DOUBLE_CHECK.png', 'tw': './assets/tw/combat_ui/PAUSE_DOUBLE_CHECK.png'})
PAUSE_Devil = Button(area={'cn': (1233, 35, 1250, 57), 'en': (1233, 35, 1250, 57), 'jp': (1233, 35, 1250, 57), 'tw': (1233, 35, 1250, 57)}, color={'cn': (193, 98, 108), 'en': (193, 98, 108), 'jp': (193, 98, 108), 'tw': (193, 98, 108)}, button={'cn': (1233, 35, 1250, 57), 'en': (1233, 35, 1250, 57), 'jp': (1233, 35, 1250, 57), 'tw': (1233, 35, 1250, 57)}, file={'cn': './assets/cn/combat_ui/PAUSE_Devil.png', 'en': './assets/cn/combat_ui/PAUSE_Devil.png', 'jp': './assets/cn/combat_ui/PAUSE_Devil.png', 'tw': './assets/cn/combat_ui/PAUSE_Devil.png'})
PAUSE_HolyLight = Button(area={'cn': (1233, 35, 1250, 57), 'en': (1233, 35, 1250, 57), 'jp': (1233, 35, 1250, 57), 'tw': (1233, 35, 1250, 57)}, color={'cn': (54, 40, 27), 'en': (54, 40, 27), 'jp': (54, 40, 27), 'tw': (54, 40, 27)}, button={'cn': (1233, 35, 1250, 57), 'en': (1233, 35, 1250, 57), 'jp': (1233, 35, 1250, 57), 'tw': (1233, 35, 1250, 57)}, file={'cn': './assets/cn/combat_ui/PAUSE_HolyLight.png', 'en': './assets/cn/combat_ui/PAUSE_HolyLight.png', 'jp': './assets/cn/combat_ui/PAUSE_HolyLight.png', 'tw': './assets/cn/combat_ui/PAUSE_HolyLight.png'})
PAUSE_Iridescent_Fantasy = Button(area={'cn': (1232, 33, 1252, 57), 'en': (1232, 33, 1252, 57), 'jp': (1232, 33, 1252, 57), 'tw': (1232, 33, 1252, 57)}, color={'cn': (124, 139, 190), 'en': (124, 139, 190), 'jp': (124, 139, 190), 'tw': (124, 139, 190)}, button={'cn': (1232, 33, 1252, 57), 'en': (1232, 33, 1252, 57), 'jp': (1232, 33, 1252, 57), 'tw': (1232, 33, 1252, 57)}, file={'cn': './assets/cn/combat_ui/PAUSE_Iridescent_Fantasy.png', 'en': './assets/en/combat_ui/PAUSE_Iridescent_Fantasy.png', 'jp': './assets/jp/combat_ui/PAUSE_Iridescent_Fantasy.png', 'tw': './assets/tw/combat_ui/PAUSE_Iridescent_Fantasy.png'})
PAUSE_Neon = Button(area={'cn': (1228, 32, 1250, 59), 'en': (1228, 32, 1250, 59), 'jp': (1228, 32, 1250, 59), 'tw': (1228, 32, 1250, 59)}, color={'cn': (106, 137, 80), 'en': (106, 137, 80), 'jp': (106, 137, 80), 'tw': (106, 137, 80)}, button={'cn': (1228, 32, 1250, 59), 'en': (1228, 32, 1250, 59), 'jp': (1228, 32, 1250, 59), 'tw': (1228, 32, 1250, 59)}, file={'cn': './assets/cn/combat_ui/PAUSE_Neon.png', 'en': './assets/cn/combat_ui/PAUSE_Neon.png', 'jp': './assets/cn/combat_ui/PAUSE_Neon.png', 'tw': './assets/cn/combat_ui/PAUSE_Neon.png'})

View File

@ -3,8 +3,7 @@ from module.base.decorator import cached_property
from module.base.timer import Timer
from module.equipment.assets import *
from module.logger import logger
from module.retire.assets import DOCK_CHECK
from module.retire.assets import EQUIP_CONFIRM as RETIRE_EQUIP_CONFIRM
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
@ -40,6 +39,9 @@ class Equipment(StorageHandler):
if self.appear(RETIRE_EQUIP_CONFIRM, offset=(30, 30)):
logger.info('RETIRE_EQUIP_CONFIRM popup in _ship_view_swipe()')
return False
# Popup when enhancing a NPC ship
if self.handle_popup_confirm('SHIP_VIEW_SWIPE'):
continue
swipe_count += 1
self.device.screenshot()

View File

@ -6,7 +6,7 @@ from module.event_hospital.clue import HospitalClue
from module.event_hospital.combat import HospitalCombat
from module.exception import OilExhausted, ScriptEnd
from module.logger import logger
from module.ui.page import page_hospital
from module.ui.page import page_hospital, page_campaign_menu
from module.ui.switch import Switch
@ -384,9 +384,17 @@ class Hospital(HospitalClue, HospitalCombat):
self.config.task_stop()
def run(self):
self.ui_ensure(page_hospital)
# Check if event available
if self.event_time_limit_triggered():
self.config.task_stop()
self.ui_ensure(page_campaign_menu)
if self.is_event_entrance_available():
self.ui_goto(page_hospital)
# Receive rewards
self.daily_reward_receive()
# Run
self.clue_enter()
delay = True
try:

View File

@ -53,6 +53,13 @@ class ExerciseCombat(HpDaemon, OpponentChoose, ExerciseEquipment, Combat):
while 1:
self.device.screenshot()
# End
if self._in_exercise() or self.appear(BATTLE_PREPARATION, offset=(20, 20)):
logger.hr('Combat end')
if not end:
logger.warning('Combat ended without end conditions detected')
break
p = self.is_combat_executing()
if p:
if end:
@ -108,13 +115,6 @@ class ExerciseCombat(HpDaemon, OpponentChoose, ExerciseEquipment, Combat):
show_hp_timer.reset()
self._show_hp()
# End
if self._in_exercise() or self.appear(BATTLE_PREPARATION, offset=(20, 20)):
logger.hr('Combat end')
if not end:
logger.warning('Combat ended without end conditions detected')
break
return success
def _choose_opponent(self, index, skip_first_screenshot=True):

View File

@ -2,7 +2,7 @@ from module.base.base import ModuleBase
from module.base.timer import Timer
from module.base.utils import color_bar_percentage
from module.combat_ui.assets import (PAUSE, PAUSE_Christmas, PAUSE_Cyber, PAUSE_HolyLight, PAUSE_Iridescent_Fantasy,
PAUSE_Neon, PAUSE_New, PAUSE_Nurse, PAUSE_Pharaoh)
PAUSE_Neon, PAUSE_New, PAUSE_Nurse, PAUSE_Pharaoh, PAUSE_Devil)
from module.exercise.assets import *
from module.logger import logger
@ -71,6 +71,7 @@ class HpDaemon(ModuleBase):
PAUSE_HolyLight,
PAUSE_Pharaoh,
PAUSE_Nurse,
PAUSE_Devil,
]:
self.attacker_hp = self._calculate_hp(image, area=ATTACKER_HP_AREA_New.area, reverse=True)
self.defender_hp = self._calculate_hp(image, area=DEFENDER_HP_AREA_New.area, reverse=True)

View File

@ -79,6 +79,8 @@ class MailWhite(UI):
continue
if self.ui_main_appear_then_click(page_mail, offset=(30, 30), interval=3):
continue
if self._handle_mail_reward():
continue
def _mail_quit(self, skip_first_screenshot=True):
"""
@ -197,6 +199,8 @@ class MailWhite(UI):
if self.handle_popup_confirm('MAIL_CLAIM'):
deleted = True
continue
if self._handle_mail_reward():
continue
# info_bar appears if mail success to delete and no mail deleted
return True

View File

@ -11,6 +11,7 @@ DOCK_CHECK = Button(area={'cn': (121, 14, 175, 39), 'en': (121, 17, 189, 39), 'j
DOCK_EMPTY = Button(area={'cn': (95, 347, 388, 378), 'en': (95, 318, 264, 339), 'jp': (96, 347, 252, 376), 'tw': (94, 347, 390, 379)}, color={'cn': (160, 154, 159), 'en': (106, 99, 106), 'jp': (159, 152, 156), 'tw': (163, 157, 162)}, button={'cn': (95, 347, 388, 378), 'en': (95, 318, 264, 339), 'jp': (96, 347, 252, 376), 'tw': (94, 347, 390, 379)}, file={'cn': './assets/cn/retire/DOCK_EMPTY.png', 'en': './assets/en/retire/DOCK_EMPTY.png', 'jp': './assets/jp/retire/DOCK_EMPTY.png', 'tw': './assets/tw/retire/DOCK_EMPTY.png'})
DOCK_FILTER = Button(area={'cn': (1099, 5, 1193, 48), 'en': (1098, 4, 1194, 49), 'jp': (1101, 6, 1192, 46), 'tw': (1099, 6, 1193, 47)}, color={'cn': (70, 87, 127), 'en': (73, 90, 128), 'jp': (67, 84, 125), 'tw': (78, 96, 137)}, button={'cn': (1099, 5, 1193, 48), 'en': (1098, 4, 1194, 49), 'jp': (1101, 6, 1192, 46), 'tw': (1099, 6, 1193, 47)}, file={'cn': './assets/cn/retire/DOCK_FILTER.png', 'en': './assets/en/retire/DOCK_FILTER.png', 'jp': './assets/jp/retire/DOCK_FILTER.png', 'tw': './assets/tw/retire/DOCK_FILTER.png'})
DOCK_FILTER_CONFIRM = Button(area={'cn': (714, 613, 886, 671), 'en': (718, 618, 883, 666), 'jp': (717, 618, 885, 668), 'tw': (715, 630, 884, 680)}, color={'cn': (86, 133, 192), 'en': (108, 148, 201), 'jp': (83, 128, 188), 'tw': (83, 130, 190)}, button={'cn': (714, 613, 886, 671), 'en': (718, 618, 883, 666), 'jp': (717, 618, 885, 668), 'tw': (715, 630, 884, 680)}, file={'cn': './assets/cn/retire/DOCK_FILTER_CONFIRM.png', 'en': './assets/en/retire/DOCK_FILTER_CONFIRM.png', 'jp': './assets/jp/retire/DOCK_FILTER_CONFIRM.png', 'tw': './assets/tw/retire/DOCK_FILTER_CONFIRM.png'})
DOCK_FIRST_NPC = Button(area={'cn': (96, 111, 123, 123), 'en': (96, 111, 123, 123), 'jp': (96, 111, 123, 123), 'tw': (96, 111, 123, 123)}, color={'cn': (184, 150, 150), 'en': (184, 150, 150), 'jp': (184, 150, 150), 'tw': (184, 150, 150)}, button={'cn': (96, 111, 123, 123), 'en': (96, 111, 123, 123), 'jp': (96, 111, 123, 123), 'tw': (96, 111, 123, 123)}, file={'cn': './assets/cn/retire/DOCK_FIRST_NPC.png', 'en': './assets/cn/retire/DOCK_FIRST_NPC.png', 'jp': './assets/cn/retire/DOCK_FIRST_NPC.png', 'tw': './assets/cn/retire/DOCK_FIRST_NPC.png'})
DOCK_SCROLL = Button(area={'cn': (1239, 76, 1248, 641), 'en': (1239, 76, 1248, 641), 'jp': (1237, 78, 1250, 628), 'tw': (1239, 76, 1248, 641)}, color={'cn': (47, 46, 37), 'en': (47, 46, 37), 'jp': (180, 156, 66), 'tw': (47, 46, 37)}, button={'cn': (1239, 76, 1248, 641), 'en': (1239, 76, 1248, 641), 'jp': (1237, 78, 1250, 628), 'tw': (1239, 76, 1248, 641)}, file={'cn': './assets/cn/retire/DOCK_SCROLL.png', 'en': './assets/en/retire/DOCK_SCROLL.png', 'jp': './assets/jp/retire/DOCK_SCROLL.png', 'tw': './assets/tw/retire/DOCK_SCROLL.png'})
DOCK_SELECTED = Button(area={'cn': (582, 662, 647, 685), 'en': (702, 660, 751, 686), 'jp': (603, 662, 655, 685), 'tw': (582, 662, 647, 685)}, color={'cn': (75, 75, 83), 'en': (84, 85, 93), 'jp': (84, 83, 92), 'tw': (75, 75, 83)}, button={'cn': (582, 662, 647, 685), 'en': (702, 660, 751, 686), 'jp': (603, 662, 655, 685), 'tw': (582, 662, 647, 685)}, file={'cn': './assets/cn/retire/DOCK_SELECTED.png', 'en': './assets/en/retire/DOCK_SELECTED.png', 'jp': './assets/jp/retire/DOCK_SELECTED.png', 'tw': './assets/tw/retire/DOCK_SELECTED.png'})
EMPTY_ENHANCE_SLOT_PLUS = Button(area={'cn': (737, 402, 773, 437), 'en': (737, 402, 773, 437), 'jp': (737, 402, 773, 437), 'tw': (737, 402, 773, 437)}, color={'cn': (46, 46, 46), 'en': (46, 46, 46), 'jp': (46, 46, 46), 'tw': (46, 46, 46)}, button={'cn': (737, 402, 773, 437), 'en': (737, 402, 773, 437), 'jp': (737, 402, 773, 437), 'tw': (737, 402, 773, 437)}, file={'cn': './assets/cn/retire/EMPTY_ENHANCE_SLOT_PLUS.png', 'en': './assets/en/retire/EMPTY_ENHANCE_SLOT_PLUS.png', 'jp': './assets/jp/retire/EMPTY_ENHANCE_SLOT_PLUS.png', 'tw': './assets/tw/retire/EMPTY_ENHANCE_SLOT_PLUS.png'})

View File

@ -1,6 +1,6 @@
import module.config.server as server
from module.base.button import ButtonGrid
from module.base.button import ButtonGrid, get_color, color_similar
from module.base.decorator import cached_property
from module.base.timer import Timer
from module.equipment.equipment import Equipment
@ -35,11 +35,24 @@ OCR_DOCK_SELECTED = DigitCounter(DOCK_SELECTED, threshold=64, name='OCR_DOCK_SEL
class Dock(Equipment):
def handle_dock_cards_loading(self):
# Poor implementation.
self.device.sleep((1, 1.5))
def handle_dock_cards_loading(self, skip_first_screenshot=True):
# Poor implementation
# confirm_timer method cannot be used
timeout = Timer(1.2, count=1).start()
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# Quick exit if dock is empty
if self.appear(DOCK_EMPTY):
logger.info('Dock empty')
break
# Otherwise we just wait 1.2s
if timeout.reached():
break
def dock_favourite_set(self, enable=False, wait_loading=True):
"""
Args:
@ -244,3 +257,57 @@ class Dock(Equipment):
continue
if self.handle_popup_confirm('DOCK_SELECT_CONFIRM'):
continue
def dock_enter_first(self, non_npc=True, skip_first_screenshot=True):
"""
Enter first ship in dock
Args:
non_npc: True to enter the second ship if first ship is NPC
skip_first_screenshot:
Returns:
bool: True if success to enter
False if dock empty
False if non_npc and only one NPC in dock
Pages:
in: page_dock
out: SHIP_DETAIL_CHECK
"""
logger.info('Dock enter first')
self.interval_clear(DOCK_CHECK, interval=3)
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
# End
if self.appear(SHIP_DETAIL_CHECK, offset=(20, 20)):
return True
if self.appear(DOCK_EMPTY, offset=(20, 20)):
logger.info('Dock empty')
return False
# Click
if self.appear(DOCK_CHECK, offset=(20, 20), interval=3):
if non_npc:
# Check NPC
if DOCK_FIRST_NPC.match_luma(self.device.image, offset=(20, 20)):
logger.info('First ship is NPC, select second')
button = CARD_GRIDS[(1, 0)]
# Check if there's second ship
color = get_color(self.device.image, button.area)
if color_similar(color, (34, 34, 42)):
logger.info('Second ship empty, dock empty')
return False
else:
button = CARD_GRIDS[(0, 0)]
else:
button = CARD_GRIDS[(0, 0)]
self.device.click(button)
continue
if self.handle_game_tips():
continue

View File

@ -54,9 +54,7 @@ class Enhancement(Dock):
if self.appear(DOCK_EMPTY, offset=(30, 30)):
return False
self.ship_info_enter(
CARD_GRIDS[(0, 0)], check_button=SHIP_DETAIL_CHECK, long_click=False)
return True
return self.dock_enter_first()
def _enhance_quit(self):
"""

View File

@ -422,11 +422,11 @@ class RewardTacticalClass(Dock):
# Tactical page, has empty position
if self.appear_then_click(ADD_NEW_STUDENT, offset=(800, 20), interval=1):
self.interval_reset([TACTICAL_CHECK, RAPID_TRAINING])
self.interval_clear([POPUP_CONFIRM, POPUP_CANCEL, GET_MISSION])
self.interval_clear([POPUP_CONFIRM, POPUP_CANCEL, GET_MISSION, DOCK_CHECK, SKILL_CONFIRM])
continue
if self.handle_rapid_training():
self.interval_reset(TACTICAL_CHECK)
self.interval_clear([POPUP_CONFIRM, POPUP_CANCEL, GET_MISSION])
self.interval_clear([POPUP_CONFIRM, POPUP_CANCEL, GET_MISSION, DOCK_CHECK, SKILL_CONFIRM])
continue
# Get finish time
@ -496,6 +496,7 @@ class RewardTacticalClass(Dock):
# so we need click BACK_ARROW to clear selected state
logger.info('Having pre-selected ship in dock, re-enter')
self.device.click(BACK_ARROW)
self.interval_reset([BOOK_EMPTY_POPUP, DOCK_CHECK], interval=3)
continue
# If not enable or can not fina a suitable ship
if self.config.AddNewStudent_Enable:
@ -508,7 +509,7 @@ class RewardTacticalClass(Dock):
logger.info('Not going to learn skill but in dock, close it')
study_finished = True
self.device.click(BACK_ARROW)
self.interval_reset([BOOK_EMPTY_POPUP])
self.interval_reset([BOOK_EMPTY_POPUP, DOCK_CHECK], interval=3)
continue
if self.appear(SKILL_CONFIRM, offset=(20, 20), interval=3):
# If not enable or can not find a skill
@ -522,7 +523,7 @@ class RewardTacticalClass(Dock):
logger.info('Not going to learn skill but having SKILL_CONFIRM, close it')
study_finished = True
self.device.click(BACK_ARROW)
self.interval_reset([BOOK_EMPTY_POPUP])
self.interval_reset([BOOK_EMPTY_POPUP, SKILL_CONFIRM], interval=3)
continue
if self.appear(TACTICAL_META, offset=(200, 20), interval=3):
# If meta's skill page, it's inappropriate