Skip to content

Commit 20093e4

Browse files
committed
Upd: Fix bugs.
1 parent a061cbf commit 20093e4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2382
-347
lines changed

alas.py

Lines changed: 124 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def __init__(self, config_name='alas'):
2626
# Failure count of tasks
2727
# Key: str, task name, value: int, failure count
2828
self.failure_record = {}
29+
self.first_check = True
2930

3031
@cached_property
3132
def config(self):
@@ -62,11 +63,11 @@ def checker(self):
6263
logger.exception(e)
6364
exit(1)
6465

65-
def run(self, command, skip_first_screenshot=False):
66+
def run(self, command, *args, skip_first_screenshot=False, **kwargs):
6667
try:
6768
if not skip_first_screenshot:
6869
self.device.screenshot()
69-
self.__getattribute__(command)()
70+
getattr(self, command)(*args, **kwargs)
7071
return True
7172
except TaskEnd:
7273
return True
@@ -90,47 +91,42 @@ def run(self, command, skip_first_screenshot=False):
9091
self.config.task_call('Restart')
9192
self.device.sleep(10)
9293
return False
93-
except GamePageUnknownError:
94+
except GamePageUnknownError as e:
9495
logger.info('Game server may be under maintenance or network may be broken, check server status now')
9596
self.checker.check_now()
9697
if self.checker.is_available():
97-
logger.critical('Game page unknown')
98-
self.save_error_log()
99-
handle_notify(
100-
self.config.Error_OnePushConfig,
101-
title=f"Alas <{self.config_name}> crashed",
102-
content=f"<{self.config_name}> GamePageUnknownError",
103-
)
104-
exit(1)
105-
else:
106-
self.checker.wait_until_available()
107-
return False
98+
self.crash_exit(e, save=True)
99+
self.checker.wait_until_available()
100+
return False
108101
except ScriptError as e:
109-
logger.exception(e)
110-
logger.critical('This is likely to be a mistake of developers, but sometimes just random issues')
111-
handle_notify(
112-
self.config.Error_OnePushConfig,
113-
title=f"Alas <{self.config_name}> crashed",
114-
content=f"<{self.config_name}> ScriptError",
115-
)
116-
exit(1)
117-
except RequestHumanTakeover:
118-
logger.critical('Request human takeover')
119-
handle_notify(
120-
self.config.Error_OnePushConfig,
121-
title=f"Alas <{self.config_name}> crashed",
122-
content=f"<{self.config_name}> RequestHumanTakeover",
123-
)
124-
exit(1)
102+
self.crash_exit(e, 'This is likely to be a mistake of developers, but sometimes just random issues',
103+
log_exc=True)
104+
except ALASBaseError as e:
105+
if not self.device.emulator_check():
106+
self.reboot()
107+
return False
108+
self.crash_exit(e)
125109
except Exception as e:
110+
if not self.device.emulator_check():
111+
self.reboot()
112+
return False
113+
self.crash_exit(e, log_exc=True, save=True)
114+
115+
def crash_exit(self, e, *args, log_exc=False, save=False, msg=''):
116+
if log_exc:
126117
logger.exception(e)
118+
else:
119+
logger.critical(e)
120+
for arg in args:
121+
logger.critical(arg)
122+
if save:
127123
self.save_error_log()
128-
handle_notify(
129-
self.config.Error_OnePushConfig,
130-
title=f"Alas <{self.config_name}> crashed",
131-
content=f"<{self.config_name}> Exception occured",
132-
)
133-
exit(1)
124+
handle_notify(
125+
self.config.Error_OnePushConfig,
126+
title=f"Alas <{self.config_name}> crashed",
127+
content=f"<{self.config_name}> {e.__class__.__name__}{msg}"
128+
)
129+
exit(1)
134130

135131
def save_error_log(self):
136132
"""
@@ -162,7 +158,16 @@ def save_error_log(self):
162158
with open(f'{folder}/log.txt', 'w', encoding='utf-8') as f:
163159
f.writelines(lines)
164160

165-
def restart(self):
161+
def reboot(self, use_log=True):
162+
if use_log:
163+
logger.warning('Emulator is not running')
164+
self.device.emulator_stop()
165+
self.device.emulator_start()
166+
del_cached_property(self, 'config')
167+
168+
def restart(self, reboot=False):
169+
if reboot:
170+
self.reboot(use_log=False)
166171
from module.handler.login import LoginHandler
167172
LoginHandler(self.config, device=self.device).app_restart()
168173

@@ -455,42 +460,76 @@ def get_next_task(self):
455460
if self.config.task.command != 'Alas':
456461
release_resources(next_task=task.command)
457462

458-
if task.next_run > datetime.now():
459-
logger.info(f'Wait until {task.next_run} for task `{task.command}`')
460-
self.is_first_task = False
461-
method = self.config.Optimization_WhenTaskQueueEmpty
462-
if method == 'close_game':
463-
logger.info('Close game during wait')
464-
self.device.app_stop()
465-
release_resources()
466-
self.device.release_during_wait()
467-
if not self.wait_until(task.next_run):
468-
del_cached_property(self, 'config')
469-
continue
470-
if task.command != 'Restart':
471-
self.run('start')
472-
elif method == 'goto_main':
473-
logger.info('Goto main page during wait')
474-
self.run('goto_main')
475-
release_resources()
476-
self.device.release_during_wait()
477-
if not self.wait_until(task.next_run):
478-
del_cached_property(self, 'config')
479-
continue
480-
elif method == 'stay_there':
481-
logger.info('Stay there during wait')
482-
release_resources()
483-
self.device.release_during_wait()
484-
if not self.wait_until(task.next_run):
485-
del_cached_property(self, 'config')
486-
continue
487-
else:
488-
logger.warning(f'Invalid Optimization_WhenTaskQueueEmpty: {method}, fallback to stay_there')
489-
release_resources()
490-
self.device.release_during_wait()
491-
if not self.wait_until(task.next_run):
492-
del_cached_property(self, 'config')
493-
continue
463+
if task.next_run <= datetime.now():
464+
break
465+
466+
logger.info(f'Wait until {task.next_run} for task `{task.command}`')
467+
self.is_first_task = False
468+
469+
method: str = self.config.Optimization_WhenTaskQueueEmpty
470+
remainingtime: float = (task.next_run - datetime.now()).total_seconds() / 60
471+
buffertime: int = self.config.Optimization_ProcessBufferTime
472+
if (
473+
method == 'stop_emulator' and
474+
self.device.emulator_check() and
475+
remainingtime <= buffertime
476+
):
477+
method = self.config.Optimization_BufferMethod
478+
logger.info(
479+
f"The time to next task `{task.command}` is {remainingtime:.2f} minutes, "
480+
f"less than {buffertime} minutes, fallback to \"{method}\""
481+
)
482+
483+
if method == 'close_game':
484+
logger.info('Close game during wait')
485+
self.device.app_stop()
486+
release_resources()
487+
self.device.release_during_wait()
488+
if not self.wait_until(task.next_run):
489+
del_cached_property(self, 'config')
490+
continue
491+
if task.command != 'Restart':
492+
self.run('start')
493+
elif method == 'goto_main':
494+
logger.info('Goto main page during wait')
495+
self.run('goto_main')
496+
release_resources()
497+
self.device.release_during_wait()
498+
if not self.wait_until(task.next_run):
499+
del_cached_property(self, 'config')
500+
continue
501+
elif method == 'stay_there':
502+
logger.info('Stay there during wait')
503+
release_resources()
504+
self.device.release_during_wait()
505+
if not self.wait_until(task.next_run):
506+
del_cached_property(self, 'config')
507+
continue
508+
elif method == 'stop_emulator':
509+
logger.info('Stop emulator during wait')
510+
self.device.emulator_stop()
511+
release_resources()
512+
self.device.release_during_wait()
513+
if not self.wait_until(task.next_run):
514+
del_cached_property(self, 'config')
515+
method: str = self.config.Optimization_WhenTaskQueueEmpty
516+
if (
517+
not self.device.emulator_check() and
518+
method != 'stop_emulator'
519+
):
520+
self.run('reboot', skip_first_screenshot=True, use_log=False)
521+
continue
522+
if not self.device.emulator_check():
523+
self.run('reboot', skip_first_screenshot=True, use_log=False)
524+
self.run('start', skip_first_screenshot=True)
525+
else:
526+
logger.warning(f'Invalid Optimization_WhenTaskQueueEmpty: {method}, fallback to stay_there')
527+
release_resources()
528+
self.device.release_during_wait()
529+
if not self.wait_until(task.next_run):
530+
del_cached_property(self, 'config')
531+
continue
532+
494533
break
495534

496535
AzurLaneConfig.is_hoarding_task = False
@@ -502,11 +541,10 @@ def loop(self):
502541

503542
while 1:
504543
# Check update event from GUI
505-
if self.stop_event is not None:
506-
if self.stop_event.is_set():
507-
logger.info("Update event detected")
508-
logger.info(f"Alas [{self.config_name}] exited.")
509-
break
544+
if self.stop_event is not None and self.stop_event.is_set():
545+
logger.info("Update event detected")
546+
logger.info(f"Alas [{self.config_name}] exited.")
547+
break
510548
# Check game server maintenance
511549
self.checker.wait_until_available()
512550
if self.checker.is_recovered():
@@ -517,10 +555,14 @@ def loop(self):
517555
del_cached_property(self, 'config')
518556
logger.info('Server or network is recovered. Restart game client')
519557
self.config.task_call('Restart')
520-
# Get task
521-
task = self.get_next_task()
522558
# Init device and change server
523559
_ = self.device
560+
# Get task
561+
task = self.get_next_task()
562+
if self.first_check:
563+
if not self.device.emulator_check():
564+
self.run('reboot', skip_first_screenshot=True)
565+
self.first_check = False
524566
self.device.config = self.config
525567
# Skip first restart
526568
if self.is_first_task and task == 'Restart':
@@ -548,13 +590,8 @@ def loop(self):
548590
"Please read the help text of the options.")
549591
logger.critical("Possible reason #2: There is a problem with this task. "
550592
"Please contact developers or try to fix it yourself.")
551-
logger.critical('Request human takeover')
552-
handle_notify(
553-
self.config.Error_OnePushConfig,
554-
title=f"Alas <{self.config_name}> crashed",
555-
content=f"<{self.config_name}> RequestHumanTakeover\nTask `{task}` failed 3 or more times.",
556-
)
557-
exit(1)
593+
self.crash_exit(RequestHumanTakeover('Request human takeover'),
594+
msg=f"\nTask `{task}` failed 3 or more times.")
558595

559596
if success:
560597
del_cached_property(self, 'config')

campaign/campaign_war_archives/campaign_base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def ui_goto_archives_campaign(self, mode='ex'):
110110
else:
111111
logger.critical('Respective server may not yet support the chosen War Archives campaign, '
112112
'check back in the next app update')
113-
raise RequestHumanTakeover
113+
raise RequestHumanTakeover('Request human takeover')
114114

115115
# Subsequent runs all set False
116116
if self.first_run:

config/template.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"ScreenshotMethod": "auto",
88
"ControlMethod": "MaaTouch",
99
"ScreenshotDedithering": false,
10-
"AdbRestart": false
10+
"AdbRestart": false,
11+
"SilentStart": "normal"
1112
},
1213
"EmulatorInfo": {
1314
"Emulator": "auto",
@@ -24,7 +25,9 @@
2425
"ScreenshotInterval": 0.3,
2526
"CombatScreenshotInterval": 1.0,
2627
"TaskHoardingDuration": 0,
27-
"WhenTaskQueueEmpty": "goto_main"
28+
"WhenTaskQueueEmpty": "goto_main",
29+
"ProcessBufferTime": 10,
30+
"BufferMethod": "stay_there"
2831
},
2932
"DropRecord": {
3033
"SaveFolder": "./screenshots",

deploy/Windows/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66

77
from deploy.Windows.logger import logger
88
from deploy.Windows.utils import DEPLOY_CONFIG, DEPLOY_TEMPLATE, cached_property, poor_yaml_read, poor_yaml_write
9+
from module.exception import ALASBaseError
910

1011

11-
class ExecutionError(Exception):
12+
class ExecutionError(ALASBaseError):
1213
pass
1314

1415

deploy/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33

44
from deploy.logger import logger
55
from deploy.utils import *
6+
from module.exception import ALASBaseError
67

78

8-
class ExecutionError(Exception):
9+
class ExecutionError(ALASBaseError):
910
pass
1011

1112

module/campaign/run.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def load_campaign(self, name, folder='campaign_main'):
5959
logger.critical(f'Possible reason #1: This event ({folder}) does not have {name}')
6060
logger.critical(f'Possible reason #2: You are using an old Alas, '
6161
'please check for update, or make map files yourself using dev_tools/map_extractor.py')
62-
raise RequestHumanTakeover
62+
raise RequestHumanTakeover('Request human takeover')
6363

6464
config = copy.deepcopy(self.config).merge(self.module.Config())
6565
device = self.device

module/coalition/ui.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,19 +196,19 @@ def enter_map(self, event, stage, mode, skip_first_screenshot=True):
196196
if campaign_click > 5:
197197
logger.critical(f"Failed to enter {button}, too many click on {button}")
198198
logger.critical("Possible reason #1: You haven't cleared previous stage to unlock the stage.")
199-
raise RequestHumanTakeover
199+
raise RequestHumanTakeover('Request human takeover')
200200
if fleet_click > 5:
201201
logger.critical(f"Failed to enter {button}, too many click on FLEET_PREPARATION")
202202
logger.critical("Possible reason #1: "
203203
"Your fleets haven't satisfied the stat restrictions of this stage.")
204204
logger.critical("Possible reason #2: "
205205
"This stage can only be farmed once a day, "
206206
"but it's the second time that you are entering")
207-
raise RequestHumanTakeover
207+
raise RequestHumanTakeover('Request human takeover')
208208
if self.appear(FLEET_NOT_PREPARED, offset=(20, 20)):
209209
logger.critical('FLEET_NOT_PREPARED')
210210
logger.critical('Please prepare you fleets before running coalition battles')
211-
raise RequestHumanTakeover
211+
raise RequestHumanTakeover('Request human takeover')
212212

213213
# End
214214
if self.appear(BATTLE_PREPARATION, offset=(20, 20)):

module/combat/emotion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def get_recovered(self, expected_reduce=0):
132132
logger.critical(f'Fleet {self.fleet} Emotion Control=\"Keep Happy Bonus\" and '
133133
f'Fleet {self.fleet} Recover Location=\"Docks\" can not be used together, '
134134
'please check your emotion settings')
135-
raise RequestHumanTakeover
135+
raise RequestHumanTakeover('Request human takeover')
136136
# In 14-4 with 2X book, expected emotion reduce is 32, can't keep happy bonus (>120),
137137
# otherwise will infinite task delay
138138
if self.control == 'keep_exp_bonus' and expected_reduce >= 29:

0 commit comments

Comments
 (0)