Merge pull request #576 from LmeSzinc/dev

Bug fix
This commit is contained in:
LmeSzinc 2024-07-16 00:05:03 +08:00 committed by GitHub
commit 41bc376943
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 94 additions and 65 deletions

View File

@ -258,6 +258,7 @@ class AzurLaneAutoScript:
task = self.get_next_task() task = self.get_next_task()
# Init device and change server # Init device and change server
_ = self.device _ = self.device
self.device.config = self.config
# Skip first restart # Skip first restart
if self.is_first_task and task == 'Restart': if self.is_first_task and task == 'Restart':
logger.info('Skip task `Restart` at scheduler start') logger.info('Skip task `Restart` at scheduler start')

View File

@ -1,9 +1,11 @@
from lxml import etree from lxml import etree
from module.base.timer import Timer
from module.device.method.adb import Adb from module.device.method.adb import Adb
from module.device.method.uiautomator_2 import Uiautomator2 from module.device.method.uiautomator_2 import Uiautomator2
from module.device.method.utils import HierarchyButton from module.device.method.utils import HierarchyButton
from module.device.method.wsa import WSA from module.device.method.wsa import WSA
from module.exception import ScriptError
from module.logger import logger from module.logger import logger
@ -12,6 +14,7 @@ class AppControl(Adb, WSA, Uiautomator2):
# Use ADB for all # Use ADB for all
# See https://github.com/openatx/uiautomator2/issues/565 # See https://github.com/openatx/uiautomator2/issues/565
_app_u2_family = [] _app_u2_family = []
_hierarchy_interval = Timer(0.1)
def app_is_running(self) -> bool: def app_is_running(self) -> bool:
method = self.config.Emulator_ControlMethod method = self.config.Emulator_ControlMethod
@ -44,11 +47,28 @@ class AppControl(Adb, WSA, Uiautomator2):
else: else:
self.app_stop_adb() self.app_stop_adb()
def hierarchy_timer_set(self, interval=None):
if interval is None:
interval = 0.1
elif isinstance(interval, (int, float)):
# No limitation for manual set in code
pass
else:
logger.warning(f'Unknown hierarchy interval: {interval}')
raise ScriptError(f'Unknown hierarchy interval: {interval}')
if interval != self._hierarchy_interval.limit:
logger.info(f'Hierarchy interval set to {interval}s')
self._hierarchy_interval.limit = interval
def dump_hierarchy(self) -> etree._Element: def dump_hierarchy(self) -> etree._Element:
""" """
Returns: Returns:
etree._Element: Select elements with `self.hierarchy.xpath('//*[@text="Hermit"]')` for example. etree._Element: Select elements with `self.hierarchy.xpath('//*[@text="Hermit"]')` for example.
""" """
self._hierarchy_interval.wait()
self._hierarchy_interval.reset()
# method = self.config.Emulator_ControlMethod # method = self.config.Emulator_ControlMethod
# if method in AppControl._app_u2_family: # if method in AppControl._app_u2_family:
# self.hierarchy = self.dump_hierarchy_uiautomator2() # self.hierarchy = self.dump_hierarchy_uiautomator2()

View File

@ -1023,7 +1023,14 @@ class Connection(ConnectionAttr):
self.package = packages[0] self.package = packages[0]
# Set config # Set config
if set_config: if set_config:
self.config.Emulator_PackageName = server_.to_server(self.package) with self.config.multi_set():
self.config.Emulator_PackageName = server_.to_server(self.package)
if self.package in server_.VALID_CLOUD_PACKAGE:
if self.config.Emulator_GameClient != 'cloud_android':
self.config.Emulator_GameClient = 'cloud_android'
else:
if self.config.Emulator_GameClient != 'android':
self.config.Emulator_GameClient = 'android'
# Set server # Set server
# logger.info('Server changed, release resources') # logger.info('Server changed, release resources')
# set_server(self.package) # set_server(self.package)

View File

@ -1,6 +1,8 @@
import collections import collections
import itertools import itertools
from lxml import etree
# Patch pkg_resources before importing adbutils and uiautomator2 # Patch pkg_resources before importing adbutils and uiautomator2
from module.device.pkg_resources import get_distribution from module.device.pkg_resources import get_distribution
@ -157,6 +159,10 @@ class Device(Screenshot, Control, AppControl):
return self.image return self.image
def dump_hierarchy(self) -> etree._Element:
self.stuck_record_check()
return super().dump_hierarchy()
def release_during_wait(self): def release_during_wait(self):
# Scrcpy server is still sending video stream, # Scrcpy server is still sending video stream,
# stop it during wait # stop it during wait

View File

@ -98,8 +98,8 @@ class PlatformWindows(PlatformBase, EmulatorManager):
# Nox.exe -clone:Nox_1 # Nox.exe -clone:Nox_1
self.execute(f'"{exe}" -clone:{instance.name}') self.execute(f'"{exe}" -clone:{instance.name}')
elif instance == Emulator.BlueStacks5: elif instance == Emulator.BlueStacks5:
# HD-Player.exe -instance Pie64 # HD-Player.exe --instance Pie64
self.execute(f'"{exe}" -instance {instance.name}') self.execute(f'"{exe}" --instance {instance.name}')
elif instance == Emulator.BlueStacks4: elif instance == Emulator.BlueStacks4:
# BlueStacks\Client\Bluestacks.exe -vmname Android_1 # BlueStacks\Client\Bluestacks.exe -vmname Android_1
self.execute(f'"{exe}" -vmname {instance.name}') self.execute(f'"{exe}" -vmname {instance.name}')

View File

@ -61,7 +61,9 @@ class UI(MainPage):
def cloud_login(): def cloud_login():
if self.config.is_cloud_game: if self.config.is_cloud_game:
from tasks.login.login import Login from tasks.login.login import Login
Login(config=self.config, device=self.device).cloud_login() login = Login(config=self.config, device=self.device)
self.device.dump_hierarchy()
login.cloud_try_enter_game()
timeout = Timer(10, count=20).start() timeout = Timer(10, count=20).start()
while 1: while 1:

View File

@ -133,6 +133,9 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
return False return False
if not self.handle_combat_prepare(): if not self.handle_combat_prepare():
return False return False
if self.is_doing_planner and self.combat_wave_cost == 0:
logger.info('Free combat gets nothing cannot meet planner needs')
return False
self.device.click(COMBAT_PREPARE) self.device.click(COMBAT_PREPARE)
self.interval_reset(COMBAT_PREPARE) self.interval_reset(COMBAT_PREPARE)
trial += 1 trial += 1

View File

@ -72,7 +72,7 @@ class XPath:
悬浮窗及侧边栏元素 悬浮窗及侧边栏元素
""" """
# 悬浮窗 # 悬浮窗
FLOAT_WINDOW = '//*[@class="android.widget.ImageView"]' FLOAT_WINDOW = '//*[@package="com.miHoYo.cloudgames.hkrpg" and @class="android.widget.ImageView"]'
# 退出按钮,返回登录页面 # 退出按钮,返回登录页面
FLOAT_EXIT = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/iv_exit"]' FLOAT_EXIT = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/iv_exit"]'
# 弹出侧边栏的 节点信息 # 弹出侧边栏的 节点信息
@ -342,13 +342,16 @@ class LoginAndroidCloud(ModuleBase):
logger.attr('Net state', None) logger.attr('Net state', None)
return False return False
def cloud_ensure_ingame(self): def cloud_enter_game(self):
""" """
Note that cloud game needs to be started before calling,
hierarchy needs to be updated before calling
Pages: Pages:
in: Any in: Any page in cloud game
out: page_main out: page_main
""" """
logger.hr('Cloud ensure ingame', level=1) logger.hr('Cloud enter game', level=1)
with self.config.multi_set(): with self.config.multi_set():
if self.config.Emulator_GameClient != 'cloud_android': if self.config.Emulator_GameClient != 'cloud_android':
@ -358,48 +361,27 @@ class LoginAndroidCloud(ModuleBase):
if self.config.Optimization_WhenTaskQueueEmpty != 'close_game': if self.config.Optimization_WhenTaskQueueEmpty != 'close_game':
self.config.Optimization_WhenTaskQueueEmpty = 'close_game' self.config.Optimization_WhenTaskQueueEmpty = 'close_game'
for _ in range(3): if self.appear(XPath.START_GAME):
if self.device.app_is_running(): logger.info('Cloud game is in main page')
logger.info('Cloud game is already running') self._cloud_get_remain()
self.device.dump_hierarchy() self._cloud_enter()
return True
if self.appear(XPath.START_GAME): elif self.appear(XPath.FLOAT_WINDOW):
logger.info('Cloud game is in main page') logger.info('Cloud game is in game')
self._cloud_get_remain() return True
self._cloud_enter() elif self.appear(XPath.FLOAT_DELAY):
return True logger.info('Cloud game is in game with float window expanded')
elif self.appear(XPath.FLOAT_WINDOW): self._cloud_setting_exit()
logger.info('Cloud game is in game') return True
return True elif self.appear(XPath.POPUP_CONFIRM):
elif self.appear(XPath.FLOAT_DELAY): logger.info('Cloud game have a popup')
logger.info('Cloud game is in game with float window expanded') self._cloud_enter()
self._cloud_setting_exit() return True
return True else:
elif self.appear(XPath.POPUP_CONFIRM): self._cloud_start()
logger.info('Cloud game have a popup') self._cloud_get_remain()
self._cloud_enter() self._cloud_enter()
return True return True
else:
try:
self._cloud_start()
except GameNotRunningError:
continue
self._cloud_get_remain()
self._cloud_enter()
return True
else:
logger.info('Cloud game is not running')
self.device.app_start()
try:
self._cloud_start()
except GameNotRunningError:
continue
self._cloud_get_remain()
self._cloud_enter()
return True
logger.error('Failed to enter cloud game after 3 trials')
return False
def is_in_cloud_page(self): def is_in_cloud_page(self):
if self.appear(XPath.START_GAME): if self.appear(XPath.START_GAME):
@ -418,15 +400,16 @@ class LoginAndroidCloud(ModuleBase):
logger.info('Not in cloud page') logger.info('Not in cloud page')
return False return False
def cloud_login(self): def cloud_try_enter_game(self):
""" """
Note that hierarchy needs to be updated before calling
Pages: Pages:
in: Any page in cloud game in: Any page in cloud game
out: page_main out: page_main
""" """
self.device.dump_hierarchy()
if self.is_in_cloud_page(): if self.is_in_cloud_page():
self.cloud_ensure_ingame() self.cloud_enter_game()
return True return True
return False return False
@ -522,5 +505,7 @@ class LoginAndroidCloud(ModuleBase):
if __name__ == '__main__': if __name__ == '__main__':
self = LoginAndroidCloud('src') self = LoginAndroidCloud('src')
self.cloud_login() self.device.app_start()
self.device.dump_hierarchy()
self.cloud_enter_game()
self.cloud_keep_alive() self.cloud_keep_alive()

View File

@ -90,18 +90,23 @@ class Login(UI, LoginAndroidCloud):
def app_start(self): def app_start(self):
logger.hr('App start') logger.hr('App start')
self.device.app_start()
if self.config.is_cloud_game: if self.config.is_cloud_game:
self.cloud_ensure_ingame() self.device.dump_hierarchy()
self.cloud_enter_game()
else: else:
self.device.app_start()
self.handle_app_login() self.handle_app_login()
def app_restart(self): def app_restart(self):
logger.hr('App restart') logger.hr('App restart')
self.device.app_stop() self.device.app_stop()
self.device.app_start()
if self.config.is_cloud_game: if self.config.is_cloud_game:
self.cloud_ensure_ingame() self.device.dump_hierarchy()
self.cloud_enter_game()
else: else:
self.device.app_start()
self.handle_app_login() self.handle_app_login()
self.config.task_delay(server_update=True) self.config.task_delay(server_update=True)

View File

@ -375,13 +375,7 @@ class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonRogueUI
# Expired, do rogue # Expired, do rogue
pass pass
elif self.config.stored.SimulatedUniverse.is_full(): elif self.config.stored.SimulatedUniverse.is_full():
if self.config.RogueWorld_UseImmersifier and self.config.stored.Immersifier.value > 0: if self.config.RogueWorld_WeeklyFarming and not self.config.stored.SimulatedUniverseFarm.is_full():
logger.info(
'Reached weekly point limit but still have immersifiers left, continue to use them')
if ornament:
logger.info('Ornament enabled, skip farming rogue')
raise RogueReachedWeeklyPointLimit
elif self.config.RogueWorld_WeeklyFarming and not self.config.stored.SimulatedUniverseFarm.is_full():
logger.info( logger.info(
'Reached weekly point limit but still continue to farm materials') 'Reached weekly point limit but still continue to farm materials')
logger.attr( logger.attr(
@ -389,6 +383,12 @@ class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonRogueUI
if self.config.is_cloud_game and not self.config.stored.CloudRemainSeasonPass.value: if self.config.is_cloud_game and not self.config.stored.CloudRemainSeasonPass.value:
logger.warning('Running WeeklyFarming on cloud game without season pass may cause fee, skip') logger.warning('Running WeeklyFarming on cloud game without season pass may cause fee, skip')
raise RogueReachedWeeklyPointLimit raise RogueReachedWeeklyPointLimit
elif self.config.RogueWorld_UseImmersifier and self.config.stored.Immersifier.value > 0:
logger.info(
'Reached weekly point limit but still have immersifiers left, continue to use them')
if ornament:
logger.info('Ornament enabled, skip farming rogue')
raise RogueReachedWeeklyPointLimit
else: else:
raise RogueReachedWeeklyPointLimit raise RogueReachedWeeklyPointLimit
else: else: