Add: Game stuck handler

- Add ensure game running when running alas functions
This commit is contained in:
LmeSzinc 2020-08-01 17:53:00 +08:00
parent 63e8f80c37
commit 14c3966874
7 changed files with 104 additions and 33 deletions

71
alas.py
View File

@ -5,8 +5,10 @@ from datetime import datetime
from module.config.config import AzurLaneConfig
from module.device.device import Device
from module.logger import logger, pyw_name, log_file
from module.exception import *
from module.handler.login import LoginHandler
from module.handler.sensitive_info import handle_sensitive_image, handle_sensitive_logs
from module.logger import logger, pyw_name, log_file
class AzurLaneAutoScript:
@ -19,30 +21,51 @@ class AzurLaneAutoScript:
def run(self, command):
self.config.start_time = datetime.now()
try:
self.device = Device(config=self.config)
self.__getattribute__(command.lower())()
except Exception as e:
logger.exception(e)
self.device = Device(config=self.config)
while 1:
try:
self.__getattribute__(command.lower())()
break
except GameNotRunningError as e:
logger.warning(e)
az = LoginHandler(self.config, device=self.device)
az.app_restart()
az.ensure_no_unfinished_campaign()
continue
except GameStuckError as e:
logger.warning(e)
self.save_error_log()
az = LoginHandler(self.config, device=self.device)
az.handle_game_stuck()
continue
except Exception as e:
logger.exception(e)
self.save_error_log()
break
if self.config.ENABLE_ERROR_LOG_AND_SCREENSHOT_SAVE:
folder = f'./log/error/{int(time.time() * 1000)}'
logger.info(f'Saving error: {folder}')
os.mkdir(folder)
for data in logger.screenshot_deque:
image_time = datetime.strftime(data['time'], '%Y-%m-%d_%H-%M-%S-%f')
image = handle_sensitive_image(data['image'])
image.save(f'{folder}/{image_time}.png')
with open(log_file, 'r') as f:
start = 0
for index, line in enumerate(f.readlines()):
if re.search('\+-{15,}\+', line):
start = index
with open(log_file, 'r') as f:
text = f.readlines()[start - 2:]
text = handle_sensitive_logs(text)
with open(f'{folder}/log.txt', 'w') as f:
f.writelines(text)
def save_error_log(self):
"""
Save last 60 screenshots in ./log/error/<timestamp>
Save logs to ./log/error/<timestamp>/log.txt
"""
if self.config.ENABLE_ERROR_LOG_AND_SCREENSHOT_SAVE:
folder = f'./log/error/{int(time.time() * 1000)}'
logger.info(f'Saving error: {folder}')
os.mkdir(folder)
for data in logger.screenshot_deque:
image_time = datetime.strftime(data['time'], '%Y-%m-%d_%H-%M-%S-%f')
image = handle_sensitive_image(data['image'])
image.save(f'{folder}/{image_time}.png')
with open(log_file, 'r') as f:
start = 0
for index, line in enumerate(f.readlines()):
if re.search('\+-{15,}\+', line):
start = index
with open(log_file, 'r') as f:
text = f.readlines()[start - 2:]
text = handle_sensitive_logs(text)
with open(f'{folder}/log.txt', 'w') as f:
f.writelines(text)
def reward_when_finished(self):
from module.reward.reward import Reward

View File

@ -117,8 +117,10 @@ class AzurLaneConfig:
CAMPAIGN_NAME = 'default'
CAMPAIGN_MODE = 'normal'
ENABLE_STOP_CONDITION = True
ENABLE_EXCEPTION = True
ENABLE_GAME_STUCK_HANDLER = True
ENABLE_STOP_CONDITION = True
ENABLE_FAST_FORWARD = True
STOP_IF_OIL_LOWER_THAN = 5000
STOP_IF_COUNT_GREATER_THAN = 0

View File

@ -8,6 +8,9 @@ from module.exception import *
class AzurLaneDaemon(FleetPreparation, Combat, MysteryHandler):
def daemon(self):
self.config.ENABLE_GAME_STUCK_HANDLER = False
self.device.config.ENABLE_GAME_STUCK_HANDLER = False
while 1:
self.device.screenshot()

View File

@ -1,12 +1,13 @@
from datetime import datetime, timedelta
from module.base.timer import Timer
from module.base.utils import get_color
from module.device.app import AppControl
from module.device.control import Control
from module.device.screenshot import Screenshot
from module.exception import GameStuckError
from module.handler.assets import GET_MISSION
from module.logger import logger
from module.base.utils import get_color
class Device(Screenshot, Control, AppControl):
@ -107,3 +108,6 @@ class Device(Screenshot, Control, AppControl):
logger.warning('Wait too long')
logger.warning(f'Waiting for {self.stuck_record}')
self.stuck_record_clear()
if self.config.ENABLE_GAME_STUCK_HANDLER:
raise GameStuckError(f'Waiting for {self.stuck_record}')

View File

@ -6,10 +6,6 @@ class MapDetectionError(Exception):
pass
class PerspectiveError(Exception):
pass
class MapWalkError(Exception):
pass
@ -24,3 +20,11 @@ class ScriptError(Exception):
class ScriptEnd(Exception):
pass
class GameStuckError(Exception):
pass
class GameNotRunningError(Exception):
pass

View File

@ -4,7 +4,9 @@ from module.base.timer import Timer
from module.combat.combat import Combat
from module.handler.assets import *
from module.logger import logger
from module.ui.ui import MAIN_CHECK, EVENT_LIST_CHECK, BACK_ARROW, GOTO_MAIN
from module.map.assets import *
from module.ui.assets import *
from module.ui.ui import MAIN_CHECK
class LoginHandler(Combat):
@ -49,6 +51,7 @@ class LoginHandler(Combat):
else:
confirm_timer.reset()
self.config.start_time = datetime.now()
return True
def app_restart(self):
@ -56,7 +59,6 @@ class LoginHandler(Combat):
self.device.app_stop()
self.device.app_start()
self.handle_app_login()
self.config.start_time = datetime.now()
def app_ensure_start(self):
if not self.device.app_is_running():
@ -65,3 +67,32 @@ class LoginHandler(Combat):
return True
return False
def ensure_no_unfinished_campaign(self, confirm_wait=3):
"""
Pages:
in: page_main
out: page_main
"""
def ensure_campaign_retreat():
if self.appear_then_click(WITHDRAW, offset=(30, 30), interval=5):
return True
if self.handle_popup_confirm('WITHDRAW'):
return True
def in_campaign():
return self.appear(CAMPAIGN_CHECK, offset=(30, 30)) \
or self.appear(EVENT_CHECK, offset=(30, 30)) \
or self.appear(SP_CHECK, offset=(30, 30))
self.ui_click(MAIN_GOTO_CAMPAIGN, check_button=in_campaign, additional=ensure_campaign_retreat,
confirm_wait=confirm_wait, skip_first_screenshot=True)
self.ui_goto_main()
def handle_game_stuck(self):
logger.warning(f'{self.config.PACKAGE_NAME} will be restart in 10 seconds')
logger.warning('If you are playing by hand, please stop Alas')
self.device.sleep(10)
self.app_restart()
self.ensure_no_unfinished_campaign()

View File

@ -1,6 +1,7 @@
from module.base.button import Button
from module.base.timer import Timer
from module.combat.assets import *
from module.exception import GameNotRunningError
from module.handler.assets import *
from module.handler.info_handler import InfoHandler
from module.logger import logger
@ -96,7 +97,10 @@ class UI(InfoHandler):
logger.warning('Starting from current page is not supported')
logger.warning(f'Supported page: {[str(page) for page in self.ui_pages]}')
logger.warning(f'Supported page: Any page with a "HOME" button on the upper-right')
exit(1)
if not self.device.app_is_running():
raise GameNotRunningError('Game not running')
else:
exit(1)
def ui_goto(self, destination, skip_first_screenshot=False):
"""