Fix: Actively exit cloud game instead of killing directly to avoid extra fee

This commit is contained in:
LmeSzinc 2024-05-30 12:16:25 +08:00
parent c6ff6f3f80
commit 1578913bbf
3 changed files with 65 additions and 24 deletions

View File

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

View File

@ -61,6 +61,8 @@ class XPath:
"""
# 悬浮窗
FLOAT_WINDOW = '//*[@class="android.widget.ImageView"]'
# 退出按钮,返回登录页面
FLOAT_EXIT = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/iv_exit"]'
# 弹出侧边栏的 节点信息
# 将这个区域向右偏移作为退出悬浮窗的按钮
FLOAT_DELAY = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tv_node_region"]'
@ -83,7 +85,7 @@ class LoginAndroidCloud(ModuleBase):
def _cloud_start(self, skip_first=False):
"""
Pages:
out: START_GAME
out: XPath.START_GAME
"""
logger.hr('Cloud start')
update_checker = Timer(2)
@ -129,7 +131,7 @@ class LoginAndroidCloud(ModuleBase):
def _cloud_get_remain(self):
"""
Pages:
in: START_GAME
in: XPath.START_GAME
"""
regex = re.compile(r'(\d+)')
@ -163,7 +165,7 @@ class LoginAndroidCloud(ModuleBase):
def _cloud_enter(self, skip_first=False):
"""
Pages:
in: START_GAME
in: XPath.START_GAME
out: page_main
"""
logger.hr('Cloud enter')
@ -224,6 +226,11 @@ class LoginAndroidCloud(ModuleBase):
Login(config=self.config, device=self.device).handle_app_login()
def _cloud_setting_enter(self, skip_first=True):
"""
Pages:
in: XPath.FLOAT_WINDOW
out: XPath.FLOAT_DELAY, setting aside expanded
"""
while 1:
if skip_first:
skip_first = False
@ -237,6 +244,11 @@ class LoginAndroidCloud(ModuleBase):
continue
def _cloud_setting_exit(self, skip_first=True):
"""
Pages:
in: XPath.FLOAT_DELAY, setting aside expanded
out: XPath.FLOAT_WINDOW
"""
while 1:
if skip_first:
skip_first = False
@ -255,6 +267,8 @@ class LoginAndroidCloud(ModuleBase):
def _cloud_setting_disable_net_state(self, skip_first=True):
"""
Disable net state display, or will cause detection error on COMBAT_AUTO, COMBAT_2X
Pages:
in: page_main
out: page_main
@ -382,9 +396,11 @@ class LoginAndroidCloud(ModuleBase):
return False
def cloud_login(self):
if not self.config.is_cloud_game:
return False
"""
Pages:
in: Any page in cloud game
out: page_main
"""
self.device.dump_hierarchy()
if self.is_in_cloud_page():
self.cloud_ensure_ingame()
@ -392,6 +408,43 @@ class LoginAndroidCloud(ModuleBase):
return False
def cloud_exit(self, skip_first=False):
"""
Exit cloud game, note that actively exit is recommended,
don't kill game directly, or will cause 3min extra fee because the sever side is still alive
Args:
skip_first: False by default because cloud_exit() is usually being called after running tasks,
existing hierarchy may be outdated
Pages:
in: XPath.FLOAT_WINDOW
out: XPath.START_GAME
"""
logger.hr('Cloud exit')
while 1:
if skip_first:
skip_first = False
else:
self.device.dump_hierarchy()
# End
if self.appear(XPath.START_GAME):
break
if self.appear_then_click(XPath.FLOAT_WINDOW, interval=3):
continue
if self.appear_then_click(XPath.FLOAT_EXIT, interval=3):
continue
# 提示
# 是否确认退出游戏
# - 继续游戏 - 退出游戏
if self.appear_then_click(XPath.POPUP_CONFIRM, interval=3):
continue
# Update remain
self._cloud_get_remain()
def cloud_keep_alive(self):
"""
Randomly do something to prevent being kicked
@ -410,5 +463,5 @@ class LoginAndroidCloud(ModuleBase):
if __name__ == '__main__':
self = LoginAndroidCloud('src')
self.cloud_ensure_ingame()
self.cloud_login()
self.cloud_keep_alive()

View File

@ -83,6 +83,8 @@ class Login(UI, LoginAndroidCloud):
def app_stop(self):
logger.hr('App stop')
if self.config.is_cloud_game:
self.cloud_exit()
self.device.app_stop()
def app_start(self):
@ -102,18 +104,3 @@ class Login(UI, LoginAndroidCloud):
self.device.app_start()
self.handle_app_login()
self.config.task_delay(server_update=True)
def cloud_start(self):
if not self.config.is_cloud_game:
return
logger.hr('Cloud start')
self.cloud_ensure_ingame()
self.handle_app_login()
def cloud_stop(self):
if not self.config.is_cloud_game:
return
logger.hr('Cloud stop')
self.app_stop()