mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-16 06:25:24 +00:00
Add: Cloud game support
This commit is contained in:
parent
5b7b226066
commit
c493292181
BIN
assets/share/login/LOGIN_CONFIRM.2.png
Normal file
BIN
assets/share/login/LOGIN_CONFIRM.2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
@ -62,6 +62,18 @@ class AzurLaneAutoScript:
|
|||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
def restart(self):
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
|
def goto_main(self):
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
def run(self, command):
|
def run(self, command):
|
||||||
try:
|
try:
|
||||||
self.device.screenshot()
|
self.device.screenshot()
|
||||||
@ -211,7 +223,7 @@ class AzurLaneAutoScript:
|
|||||||
method = self.config.Optimization_WhenTaskQueueEmpty
|
method = self.config.Optimization_WhenTaskQueueEmpty
|
||||||
if method == 'close_game':
|
if method == 'close_game':
|
||||||
logger.info('Close game during wait')
|
logger.info('Close game during wait')
|
||||||
self.device.app_stop()
|
self.run('stop')
|
||||||
release_resources()
|
release_resources()
|
||||||
self.device.release_during_wait()
|
self.device.release_during_wait()
|
||||||
if not self.wait_until(task.next_run):
|
if not self.wait_until(task.next_run):
|
||||||
|
@ -6,6 +6,7 @@ from module.base.timer import Timer
|
|||||||
from module.base.utils import *
|
from module.base.utils import *
|
||||||
from module.config.config import AzurLaneConfig
|
from module.config.config import AzurLaneConfig
|
||||||
from module.device.device import Device
|
from module.device.device import Device
|
||||||
|
from module.device.method.utils import HierarchyButton
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.webui.setting import cached_class_property
|
from module.webui.setting import cached_class_property
|
||||||
|
|
||||||
@ -132,9 +133,56 @@ class ModuleBase:
|
|||||||
|
|
||||||
return appear
|
return appear
|
||||||
|
|
||||||
appear = match_template
|
def xpath(self, xpath) -> HierarchyButton:
|
||||||
|
if isinstance(xpath, str):
|
||||||
|
return HierarchyButton(self.device.hierarchy, xpath)
|
||||||
|
else:
|
||||||
|
return xpath
|
||||||
|
|
||||||
|
def xpath_appear(self, xpath: str, interval=0):
|
||||||
|
button = self.xpath(xpath)
|
||||||
|
|
||||||
|
self.device.stuck_record_add(button)
|
||||||
|
|
||||||
|
if interval and not self.interval_is_reached(button, interval=interval):
|
||||||
|
return False
|
||||||
|
|
||||||
|
appear = bool(button)
|
||||||
|
|
||||||
|
if appear and interval:
|
||||||
|
self.interval_reset(button, interval=interval)
|
||||||
|
|
||||||
|
return appear
|
||||||
|
|
||||||
|
def appear(self, button, interval=0, similarity=0.85):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
button (Button, ButtonWrapper, HierarchyButton, str):
|
||||||
|
interval (int, float): interval between two active events.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool:
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
Template match:
|
||||||
|
```
|
||||||
|
self.device.screenshot()
|
||||||
|
self.appear(POPUP_CONFIRM)
|
||||||
|
```
|
||||||
|
|
||||||
|
Hierarchy detection (detect elements with xpath):
|
||||||
|
```
|
||||||
|
self.device.dump_hierarchy()
|
||||||
|
self.appear('//*[@resource-id="..."]')
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
if isinstance(button, (HierarchyButton, str)):
|
||||||
|
return self.xpath_appear(button, interval=interval)
|
||||||
|
else:
|
||||||
|
return self.match_template(button, interval=interval, similarity=similarity)
|
||||||
|
|
||||||
def appear_then_click(self, button, interval=5, similarity=0.85):
|
def appear_then_click(self, button, interval=5, similarity=0.85):
|
||||||
|
button = self.xpath(button)
|
||||||
appear = self.appear(button, interval=interval, similarity=similarity)
|
appear = self.appear(button, interval=interval, similarity=similarity)
|
||||||
if appear:
|
if appear:
|
||||||
self.device.click(button)
|
self.device.click(button)
|
||||||
|
@ -49,11 +49,14 @@ class AppControl(Adb, WSA, Uiautomator2):
|
|||||||
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.
|
||||||
"""
|
"""
|
||||||
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()
|
||||||
|
# else:
|
||||||
|
# self.hierarchy = self.dump_hierarchy_adb()
|
||||||
|
|
||||||
|
# Using uiautomator2
|
||||||
self.hierarchy = self.dump_hierarchy_uiautomator2()
|
self.hierarchy = self.dump_hierarchy_uiautomator2()
|
||||||
else:
|
|
||||||
self.hierarchy = self.dump_hierarchy_adb()
|
|
||||||
return self.hierarchy
|
return self.hierarchy
|
||||||
|
|
||||||
def xpath_to_button(self, xpath: str) -> HierarchyButton:
|
def xpath_to_button(self, xpath: str) -> HierarchyButton:
|
||||||
|
@ -18,9 +18,11 @@ except ImportError:
|
|||||||
# We expect `screencap | nc 192.168.0.1 20298` instead of `screencap '|' nc 192.168.80.1 20298`
|
# We expect `screencap | nc 192.168.0.1 20298` instead of `screencap '|' nc 192.168.80.1 20298`
|
||||||
import adbutils
|
import adbutils
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
adbutils._utils.list2cmdline = subprocess.list2cmdline
|
adbutils._utils.list2cmdline = subprocess.list2cmdline
|
||||||
adbutils._device.list2cmdline = subprocess.list2cmdline
|
adbutils._device.list2cmdline = subprocess.list2cmdline
|
||||||
|
|
||||||
|
|
||||||
# BaseDevice.shell() is missing a check_okay() call before reading output,
|
# BaseDevice.shell() is missing a check_okay() call before reading output,
|
||||||
# resulting in an `OKAY` prefix in output.
|
# resulting in an `OKAY` prefix in output.
|
||||||
def shell(self,
|
def shell(self,
|
||||||
@ -40,6 +42,7 @@ except ImportError:
|
|||||||
output = c.read_until_close()
|
output = c.read_until_close()
|
||||||
return output.rstrip() if rstrip else output
|
return output.rstrip() if rstrip else output
|
||||||
|
|
||||||
|
|
||||||
adbutils._device.BaseDevice.shell = shell
|
adbutils._device.BaseDevice.shell = shell
|
||||||
|
|
||||||
from module.base.decorator import cached_property
|
from module.base.decorator import cached_property
|
||||||
@ -323,7 +326,7 @@ class HierarchyButton:
|
|||||||
if res:
|
if res:
|
||||||
return res[0]
|
return res[0]
|
||||||
else:
|
else:
|
||||||
return 'HierarchyButton'
|
return self.xpath
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def count(self):
|
def count(self):
|
||||||
@ -333,10 +336,17 @@ class HierarchyButton:
|
|||||||
def exist(self):
|
def exist(self):
|
||||||
return self.count == 1
|
return self.count == 1
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def attrib(self):
|
||||||
|
if self.exist:
|
||||||
|
return self.nodes[0].attrib
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def area(self):
|
def area(self):
|
||||||
if self.exist:
|
if self.exist:
|
||||||
bounds = self.nodes[0].attrib.get("bounds")
|
bounds = self.attrib.get("bounds")
|
||||||
lx, ly, rx, ry = map(int, re.findall(r"\d+", bounds))
|
lx, ly, rx, ry = map(int, re.findall(r"\d+", bounds))
|
||||||
return lx, ly, rx, ry
|
return lx, ly, rx, ry
|
||||||
else:
|
else:
|
||||||
@ -355,6 +365,28 @@ class HierarchyButton:
|
|||||||
@cached_property
|
@cached_property
|
||||||
def focused(self):
|
def focused(self):
|
||||||
if self.exist:
|
if self.exist:
|
||||||
return self.nodes[0].attrib.get("focused").lower() == 'true'
|
return self.attrib.get("focused").lower() == 'true'
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def text(self):
|
||||||
|
if self.exist:
|
||||||
|
return self.attrib.get("text").strip()
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class AreaButton:
|
||||||
|
def __init__(self, area, name='AREA_BUTTON'):
|
||||||
|
self.area = area
|
||||||
|
self.color = ()
|
||||||
|
self.name = name
|
||||||
|
self.button = area
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
# Cannot appear
|
||||||
|
return False
|
||||||
|
4
src.py
4
src.py
@ -11,6 +11,10 @@ class StarRailCopilot(AzurLaneAutoScript):
|
|||||||
from tasks.login.login import Login
|
from tasks.login.login import Login
|
||||||
Login(self.config, device=self.device).app_start()
|
Login(self.config, device=self.device).app_start()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
from tasks.login.login import Login
|
||||||
|
Login(self.config, device=self.device).app_stop()
|
||||||
|
|
||||||
def goto_main(self):
|
def goto_main(self):
|
||||||
from tasks.login.login import Login
|
from tasks.login.login import Login
|
||||||
from tasks.base.ui import UI
|
from tasks.base.ui import UI
|
||||||
|
@ -5,13 +5,22 @@ from module.base.button import Button, ButtonWrapper
|
|||||||
|
|
||||||
LOGIN_CONFIRM = ButtonWrapper(
|
LOGIN_CONFIRM = ButtonWrapper(
|
||||||
name='LOGIN_CONFIRM',
|
name='LOGIN_CONFIRM',
|
||||||
share=Button(
|
share=[
|
||||||
|
Button(
|
||||||
file='./assets/share/login/LOGIN_CONFIRM.png',
|
file='./assets/share/login/LOGIN_CONFIRM.png',
|
||||||
area=(1188, 44, 1220, 74),
|
area=(1188, 44, 1220, 74),
|
||||||
search=(1168, 24, 1240, 94),
|
search=(1168, 24, 1240, 94),
|
||||||
color=(140, 124, 144),
|
color=(140, 124, 144),
|
||||||
button=(683, 327, 1143, 620),
|
button=(683, 327, 1143, 620),
|
||||||
),
|
),
|
||||||
|
Button(
|
||||||
|
file='./assets/share/login/LOGIN_CONFIRM.2.png',
|
||||||
|
area=(1109, 48, 1139, 73),
|
||||||
|
search=(1089, 28, 1159, 93),
|
||||||
|
color=(149, 145, 164),
|
||||||
|
button=(1109, 48, 1139, 73),
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
LOGIN_LOADING = ButtonWrapper(
|
LOGIN_LOADING = ButtonWrapper(
|
||||||
name='LOGIN_LOADING',
|
name='LOGIN_LOADING',
|
||||||
|
216
tasks/login/cloud.py
Normal file
216
tasks/login/cloud.py
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
from module.base.base import ModuleBase
|
||||||
|
from module.base.timer import Timer
|
||||||
|
from module.base.utils import area_offset
|
||||||
|
from module.device.method.utils import AreaButton
|
||||||
|
from module.exception import GameNotRunningError, RequestHumanTakeover
|
||||||
|
from module.logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
class XPath:
|
||||||
|
# 帐号登录界面的进入游戏按钮,有这按钮说明帐号没登录
|
||||||
|
ACCOUNT_LOGIN = '//*[@text="进入游戏"]'
|
||||||
|
# 登录后的弹窗,获得免费时长
|
||||||
|
GET_REWARD = '//*[@text="点击空白区域关闭"]'
|
||||||
|
# 补丁资源已更新,重启游戏可活动更好的游玩体验
|
||||||
|
# - 下次再说 - 关闭游戏
|
||||||
|
POPUP_TITLE = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/titleTv"]'
|
||||||
|
POPUP_CONFIRM = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/confirmTv"]'
|
||||||
|
POPUP_CANCEL = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/cancelTv"]'
|
||||||
|
# 畅玩卡的剩余时间
|
||||||
|
REMAIN_SEASON_PASS = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tvCardStatus"]'
|
||||||
|
# 星云币时长:0 分钟
|
||||||
|
REMAIN_PAID = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tvMiCoinDuration"]'
|
||||||
|
# 免费时长: 600 分钟
|
||||||
|
REMAIN_FREE = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tvRemainingFreeTime"]'
|
||||||
|
# 主界面的开始游戏按钮
|
||||||
|
START_GAME = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/btnLauncher"]'
|
||||||
|
# 悬浮窗
|
||||||
|
FLOAT_WINDOW = '//*[@class="android.widget.ImageView"]'
|
||||||
|
# 悬浮窗内的延迟
|
||||||
|
# 将这个区域向右偏移作为退出悬浮窗的按钮
|
||||||
|
FLOAT_DELAY = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tv_delay"]'
|
||||||
|
|
||||||
|
'//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/ivPingIcon"]'
|
||||||
|
'//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tv_ping"]'
|
||||||
|
|
||||||
|
|
||||||
|
class LoginAndroidCloud(ModuleBase):
|
||||||
|
def _cloud_start(self, skip_first=False):
|
||||||
|
"""
|
||||||
|
Pages:
|
||||||
|
out: START_GAME
|
||||||
|
"""
|
||||||
|
logger.hr('Cloud start')
|
||||||
|
update_checker = Timer(2)
|
||||||
|
while 1:
|
||||||
|
if skip_first:
|
||||||
|
skip_first = False
|
||||||
|
else:
|
||||||
|
self.device.dump_hierarchy()
|
||||||
|
|
||||||
|
# End
|
||||||
|
if self.appear(XPath.START_GAME):
|
||||||
|
logger.info('Login to cloud main page')
|
||||||
|
break
|
||||||
|
if self.appear(XPath.ACCOUNT_LOGIN):
|
||||||
|
logger.critical('Account not login, you must have login once before running')
|
||||||
|
raise RequestHumanTakeover
|
||||||
|
if update_checker.started() and update_checker.reached():
|
||||||
|
if not self.device.app_is_running():
|
||||||
|
logger.error('Detected hot fixes from game server, game died')
|
||||||
|
raise GameNotRunningError('Game not running')
|
||||||
|
update_checker.clear()
|
||||||
|
|
||||||
|
# Click
|
||||||
|
if self.appear_then_click(XPath.GET_REWARD):
|
||||||
|
continue
|
||||||
|
if self.appear_then_click(XPath.POPUP_CONFIRM):
|
||||||
|
update_checker.start()
|
||||||
|
continue
|
||||||
|
|
||||||
|
def _cloud_get_remain(self):
|
||||||
|
"""
|
||||||
|
Pages:
|
||||||
|
in: START_GAME
|
||||||
|
"""
|
||||||
|
regex = re.compile(r'(\d+)')
|
||||||
|
|
||||||
|
text = self.xpath(XPath.REMAIN_SEASON_PASS).text
|
||||||
|
logger.info(f'Remain season pass: {text}')
|
||||||
|
if res := regex.search(text):
|
||||||
|
season_pass = int(res.group(1))
|
||||||
|
else:
|
||||||
|
season_pass = 0
|
||||||
|
|
||||||
|
text = self.xpath(XPath.REMAIN_PAID).text
|
||||||
|
logger.info(f'Remain paid: {text}')
|
||||||
|
if res := regex.search(text):
|
||||||
|
paid = int(res.group(1))
|
||||||
|
else:
|
||||||
|
paid = 0
|
||||||
|
|
||||||
|
text = self.xpath(XPath.REMAIN_FREE).text
|
||||||
|
logger.info(f'Remain free: {text}')
|
||||||
|
if res := regex.search(text):
|
||||||
|
free = int(res.group(1))
|
||||||
|
else:
|
||||||
|
free = 0
|
||||||
|
|
||||||
|
logger.info(f'Cloud remain: season pass {season_pass} days, {paid} min paid, {free} min free')
|
||||||
|
with self.config.multi_set():
|
||||||
|
self.config.stored.CloudRemainSeasonPass = season_pass
|
||||||
|
self.config.stored.CloudRemainPaid = paid
|
||||||
|
self.config.stored.CloudRemainFree = free
|
||||||
|
|
||||||
|
def _cloud_enter(self, skip_first=False):
|
||||||
|
"""
|
||||||
|
Pages:
|
||||||
|
out: START_GAME
|
||||||
|
"""
|
||||||
|
logger.hr('Cloud enter')
|
||||||
|
while 1:
|
||||||
|
if skip_first:
|
||||||
|
skip_first = False
|
||||||
|
else:
|
||||||
|
self.device.dump_hierarchy()
|
||||||
|
|
||||||
|
# End
|
||||||
|
if self.appear(XPath.FLOAT_WINDOW):
|
||||||
|
logger.info('Cloud game entered')
|
||||||
|
break
|
||||||
|
|
||||||
|
# Click
|
||||||
|
if self.appear_then_click(XPath.START_GAME):
|
||||||
|
continue
|
||||||
|
if self.appear(XPath.POPUP_CONFIRM, interval=5):
|
||||||
|
# 计费提示
|
||||||
|
# 本次游戏将使用畅玩卡无限畅玩
|
||||||
|
# - 进入游戏(9s) - 退出游戏
|
||||||
|
title = self.xpath(XPath.POPUP_TITLE).text
|
||||||
|
logger.info(f'Popup: {title}')
|
||||||
|
if title == '计费提示':
|
||||||
|
self.device.click(self.xpath(XPath.POPUP_CONFIRM))
|
||||||
|
continue
|
||||||
|
# 连接中断
|
||||||
|
# 因为您长时间未操作游戏,已中断连接,错误码: -1022
|
||||||
|
# - 退出游戏
|
||||||
|
if title == '连接中断':
|
||||||
|
self.device.click(self.xpath(XPath.POPUP_CONFIRM))
|
||||||
|
continue
|
||||||
|
|
||||||
|
def _cloud_setting_enter(self, skip_first=True):
|
||||||
|
while 1:
|
||||||
|
if skip_first:
|
||||||
|
skip_first = False
|
||||||
|
else:
|
||||||
|
self.device.dump_hierarchy()
|
||||||
|
|
||||||
|
if self.appear(XPath.FLOAT_DELAY):
|
||||||
|
break
|
||||||
|
|
||||||
|
if self.appear_then_click(XPath.FLOAT_WINDOW, interval=3):
|
||||||
|
continue
|
||||||
|
|
||||||
|
def _cloud_setting_exit(self, skip_first=True):
|
||||||
|
while 1:
|
||||||
|
if skip_first:
|
||||||
|
skip_first = False
|
||||||
|
else:
|
||||||
|
self.device.dump_hierarchy()
|
||||||
|
|
||||||
|
if self.appear(XPath.FLOAT_WINDOW):
|
||||||
|
break
|
||||||
|
|
||||||
|
if self.appear(XPath.FLOAT_DELAY, interval=3):
|
||||||
|
area = self.xpath(XPath.FLOAT_DELAY).area
|
||||||
|
area = area_offset(area, offset=(150, 0))
|
||||||
|
button = AreaButton(area=area, name='CLOUD_SETTING_EXIT')
|
||||||
|
self.device.click(button)
|
||||||
|
continue
|
||||||
|
|
||||||
|
def cloud_ensure_ingame(self):
|
||||||
|
logger.hr('Cloud ensure ingame', level=1)
|
||||||
|
for _ in range(3):
|
||||||
|
if self.device.app_is_running():
|
||||||
|
logger.info('Cloud game is already running')
|
||||||
|
self.device.dump_hierarchy()
|
||||||
|
|
||||||
|
if self.appear(XPath.START_GAME):
|
||||||
|
logger.info('Cloud game is in main page')
|
||||||
|
self._cloud_get_remain()
|
||||||
|
self._cloud_enter()
|
||||||
|
return True
|
||||||
|
elif self.appear(XPath.FLOAT_WINDOW):
|
||||||
|
logger.info('Cloud game is in game')
|
||||||
|
return True
|
||||||
|
elif self.appear(XPath.FLOAT_DELAY):
|
||||||
|
logger.info('Cloud game is in game with float window expanded')
|
||||||
|
self._cloud_setting_exit()
|
||||||
|
return True
|
||||||
|
elif self.appear(XPath.POPUP_CONFIRM):
|
||||||
|
logger.info('Cloud game have a popup')
|
||||||
|
self._cloud_enter()
|
||||||
|
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
|
@ -3,10 +3,11 @@ from module.exception import GameNotRunningError
|
|||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from tasks.base.page import page_main
|
from tasks.base.page import page_main
|
||||||
from tasks.base.ui import UI
|
from tasks.base.ui import UI
|
||||||
from tasks.login.assets.assets_login import LOGIN_CONFIRM, USER_AGREEMENT_ACCEPT, LOGIN_LOADING
|
from tasks.login.assets.assets_login import LOGIN_CONFIRM, LOGIN_LOADING, USER_AGREEMENT_ACCEPT
|
||||||
|
from tasks.login.cloud import LoginAndroidCloud
|
||||||
|
|
||||||
|
|
||||||
class Login(UI):
|
class Login(UI, LoginAndroidCloud):
|
||||||
def _handle_app_login(self):
|
def _handle_app_login(self):
|
||||||
"""
|
"""
|
||||||
Pages:
|
Pages:
|
||||||
@ -86,12 +87,33 @@ class Login(UI):
|
|||||||
|
|
||||||
def app_start(self):
|
def app_start(self):
|
||||||
logger.hr('App start')
|
logger.hr('App start')
|
||||||
|
if self.config.is_cloud_game:
|
||||||
|
self.cloud_ensure_ingame()
|
||||||
|
else:
|
||||||
self.device.app_start()
|
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()
|
||||||
|
if self.config.is_cloud_game:
|
||||||
|
self.cloud_ensure_ingame()
|
||||||
|
else:
|
||||||
self.device.app_start()
|
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)
|
||||||
|
|
||||||
|
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()
|
||||||
|
Loading…
Reference in New Issue
Block a user