From 9ea8396bede14b4965f8df3eaecee065924c8fc9 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Wed, 31 Aug 2022 10:59:12 +0800 Subject: [PATCH 01/21] Add: submodule management --- .gitmodules | 3 + alas.py | 288 ++++++++++++++++---------------- module/config/config.py | 175 +++++++++++++------ module/config/utils.py | 40 ++++- module/submodule/submodule.py | 28 ++++ module/submodule/utils.py | 61 +++++++ module/webui/app.py | 27 +-- module/webui/lang.py | 6 + module/webui/process_manager.py | 11 +- submodule/AlasMaaBridge | 1 + 10 files changed, 429 insertions(+), 211 deletions(-) create mode 100644 .gitmodules create mode 100644 module/submodule/submodule.py create mode 100644 module/submodule/utils.py create mode 160000 submodule/AlasMaaBridge diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..d375b25d7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "submodule/AlasMaaBridge"] + path = submodule/AlasMaaBridge + url = https://github.com/SaiCateDoan/AlasMaaBridge.git diff --git a/alas.py b/alas.py index f61061f31..88bca7549 100644 --- a/alas.py +++ b/alas.py @@ -15,7 +15,7 @@ from module.logger import logger from module.notify import handle_notify -class AzurLaneAutoScript: +class AutoScriptScheduler: stop_event: threading.Event = None def __init__(self, config_name='alas'): @@ -156,6 +156,150 @@ class AzurLaneAutoScript: with open(f'{folder}/log.txt', 'w', encoding='utf-8') as f: f.writelines(lines) + def wait_until(self, future): + """ + Wait until a specific time. + + Args: + future (datetime): + + Returns: + bool: True if wait finished, False if config changed. + """ + future = future + timedelta(seconds=1) + self.config.start_watching() + while 1: + if datetime.now() > future: + return True + if self.stop_event is not None: + if self.stop_event.is_set(): + logger.info("Update event detected") + logger.info(f"[{self.config_name}] exited. Reason: Update") + exit(0) + + time.sleep(5) + + if self.config.should_reload(): + return False + + def get_next_task(self): + """ + Returns: + str: Name of the next task. + """ + while 1: + task = self.config.get_next() + self.config.task = task + self.config.bind(task) + + from module.base.resource import release_resources + if self.config.task.command != 'Alas': + release_resources(next_task=task.command) + + if task.next_run > datetime.now(): + logger.info(f'Wait until {task.next_run} for task `{task.command}`') + method = self.config.Optimization_WhenTaskQueueEmpty + if method == 'close_game': + logger.info('Close game during wait') + self.device.app_stop() + release_resources() + if not self.wait_until(task.next_run): + del self.__dict__['config'] + continue + self.run('start') + elif method == 'goto_main': + logger.info('Goto main page during wait') + self.run('goto_main') + release_resources() + if not self.wait_until(task.next_run): + del self.__dict__['config'] + continue + elif method == 'stay_there': + logger.info('Stay there during wait') + release_resources() + if not self.wait_until(task.next_run): + del self.__dict__['config'] + continue + else: + logger.warning(f'Invalid Optimization_WhenTaskQueueEmpty: {method}, fallback to stay_there') + release_resources() + if not self.wait_until(task.next_run): + del self.__dict__['config'] + continue + break + + AzurLaneConfig.is_hoarding_task = False + return task.command + + def loop(self): + logger.set_file_logger(self.config_name) + logger.info(f'Start scheduler loop: {self.config_name}') + is_first = True + failure_record = {} + + while 1: + # Check update event from GUI + if self.stop_event is not None: + if self.stop_event.is_set(): + logger.info("Update event detected") + logger.info(f"Alas [{self.config_name}] exited.") + break + # Check game server maintenance + self.checker.wait_until_available() + if self.checker.is_recovered(): + # There is an accidental bug hard to reproduce + # Sometimes, config won't be updated due to blocking + # even though it has been changed + # So update it once recovered + del_cached_property(self, 'config') + logger.info('Server or network is recovered. Restart game client') + self.config.task_call('Restart') + # Get task + task = self.get_next_task() + # Init device and change server + _ = self.device + # Skip first restart + if is_first and task == 'Restart': + logger.info('Skip task `Restart` at scheduler start') + self.config.task_delay(server_update=True) + del self.__dict__['config'] + continue + + # Run + logger.info(f'Scheduler: Start task `{task}`') + self.device.stuck_record_clear() + self.device.click_record_clear() + logger.hr(task, level=0) + success = self.run(inflection.underscore(task)) + logger.info(f'Scheduler: End task `{task}`') + is_first = False + + # Check failures + failed = deep_get(failure_record, keys=task, default=0) + failed = 0 if success else failed + 1 + deep_set(failure_record, keys=task, value=failed) + if failed >= 3: + logger.critical(f"Task `{task}` failed 3 or more times.") + logger.critical("Possible reason #1: You haven't used it correctly. " + "Please read the help text of the options.") + logger.critical("Possible reason #2: There is a problem with this task. " + "Please contact developers or try to fix it yourself.") + logger.critical('Request human takeover') + exit(1) + + if success: + del self.__dict__['config'] + continue + elif self.config.Error_HandleError: + # self.config.task_delay(success=False) + del self.__dict__['config'] + self.checker.check_now() + continue + else: + break + + +class AzurLaneAutoScript(AutoScriptScheduler): def restart(self): from module.handler.login import LoginHandler LoginHandler(self.config, device=self.device).app_restart() @@ -372,148 +516,6 @@ class AzurLaneAutoScript: GemsFarming(config=self.config, device=self.device).run( name=self.config.Campaign_Name, folder=self.config.Campaign_Event, mode=self.config.Campaign_Mode) - def wait_until(self, future): - """ - Wait until a specific time. - - Args: - future (datetime): - - Returns: - bool: True if wait finished, False if config changed. - """ - future = future + timedelta(seconds=1) - self.config.start_watching() - while 1: - if datetime.now() > future: - return True - if self.stop_event is not None: - if self.stop_event.is_set(): - logger.info("Update event detected") - logger.info(f"[{self.config_name}] exited. Reason: Update") - exit(0) - - time.sleep(5) - - if self.config.should_reload(): - return False - - def get_next_task(self): - """ - Returns: - str: Name of the next task. - """ - while 1: - task = self.config.get_next() - self.config.task = task - self.config.bind(task) - - from module.base.resource import release_resources - if self.config.task.command != 'Alas': - release_resources(next_task=task.command) - - if task.next_run > datetime.now(): - logger.info(f'Wait until {task.next_run} for task `{task.command}`') - method = self.config.Optimization_WhenTaskQueueEmpty - if method == 'close_game': - logger.info('Close game during wait') - self.device.app_stop() - release_resources() - if not self.wait_until(task.next_run): - del self.__dict__['config'] - continue - self.run('start') - elif method == 'goto_main': - logger.info('Goto main page during wait') - self.run('goto_main') - release_resources() - if not self.wait_until(task.next_run): - del self.__dict__['config'] - continue - elif method == 'stay_there': - logger.info('Stay there during wait') - release_resources() - if not self.wait_until(task.next_run): - del self.__dict__['config'] - continue - else: - logger.warning(f'Invalid Optimization_WhenTaskQueueEmpty: {method}, fallback to stay_there') - release_resources() - if not self.wait_until(task.next_run): - del self.__dict__['config'] - continue - break - - AzurLaneConfig.is_hoarding_task = False - return task.command - - def loop(self): - logger.set_file_logger(self.config_name) - logger.info(f'Start scheduler loop: {self.config_name}') - is_first = True - failure_record = {} - - while 1: - # Check update event from GUI - if self.stop_event is not None: - if self.stop_event.is_set(): - logger.info("Update event detected") - logger.info(f"Alas [{self.config_name}] exited.") - break - # Check game server maintenance - self.checker.wait_until_available() - if self.checker.is_recovered(): - # There is an accidental bug hard to reproduce - # Sometimes, config won't be updated due to blocking - # even though it has been changed - # So update it once recovered - del_cached_property(self, 'config') - logger.info('Server or network is recovered. Restart game client') - self.config.task_call('Restart') - # Get task - task = self.get_next_task() - # Init device and change server - _ = self.device - # Skip first restart - if is_first and task == 'Restart': - logger.info('Skip task `Restart` at scheduler start') - self.config.task_delay(server_update=True) - del self.__dict__['config'] - continue - - # Run - logger.info(f'Scheduler: Start task `{task}`') - self.device.stuck_record_clear() - self.device.click_record_clear() - logger.hr(task, level=0) - success = self.run(inflection.underscore(task)) - logger.info(f'Scheduler: End task `{task}`') - is_first = False - - # Check failures - failed = deep_get(failure_record, keys=task, default=0) - failed = 0 if success else failed + 1 - deep_set(failure_record, keys=task, value=failed) - if failed >= 3: - logger.critical(f"Task `{task}` failed 3 or more times.") - logger.critical("Possible reason #1: You haven't used it correctly. " - "Please read the help text of the options.") - logger.critical("Possible reason #2: There is a problem with this task. " - "Please contact developers or try to fix it yourself.") - logger.critical('Request human takeover') - exit(1) - - if success: - del self.__dict__['config'] - continue - elif self.config.Error_HandleError: - # self.config.task_delay(success=False) - del self.__dict__['config'] - self.checker.check_now() - continue - else: - break - if __name__ == '__main__': alas = AzurLaneAutoScript() diff --git a/module/config/config.py b/module/config/config.py index 0e25ac4a8..f3cc184c6 100644 --- a/module/config/config.py +++ b/module/config/config.py @@ -56,7 +56,7 @@ def name_to_function(name): return function -class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher): +class GeneralConfig(ConfigWatcher): stop_event: threading.Event = None bound = {} @@ -416,6 +416,130 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher "Missing argument in delay_next_run, should set at least one" ) + def task_call(self, task, force_call=True): + """ + Call another task to run. + + That task will run when current task finished. + But it might not be run because: + - Other tasks should run first according to SCHEDULER_PRIORITY + - Task is disabled by user + + Args: + task (str): Task name to call, such as `Restart` + force_call (bool): + + Returns: + bool: If called. + """ + if deep_get(self.data, keys=f"{task}.Scheduler.NextRun", default=None) is None: + raise ScriptError(f"Task to call: `{task}` does not exist in user config") + + if force_call or deep_get( + self.data, keys=f"{task}.Scheduler.Enable", default=False + ): + logger.info(f"Task call: {task}") + self.modified[f"{task}.Scheduler.NextRun"] = datetime.now().replace( + microsecond=0 + ) + self.modified[f"{task}.Scheduler.Enable"] = True + self.update() + return True + else: + logger.info(f"Task call: {task} (skipped because disabled by user)") + return False + + @staticmethod + def task_stop(message=""): + """ + Stop current task + + Raises: + TaskEnd: + """ + if message: + raise TaskEnd(message) + else: + raise TaskEnd + + def task_switched(self): + """ + Check if needs to switch task. + + Raises: + bool: If task switched + """ + # Update event + if self.stop_event is not None: + if self.stop_event.is_set(): + return True + prev = self.task + self.load() + new = self.get_next() + if prev == new: + logger.info(f"Continue task `{new}`") + return False + else: + logger.info(f"Switch task `{prev}` to `{new}`") + return True + + def check_task_switch(self, message=""): + """ + Stop current task + + Raises: + TaskEnd: + """ + if self.task_switched(): + self.task_stop(message=message) + + """ + The following configs and methods are used to be compatible with the old. + """ + + def merge(self, other): + """ + Args: + other (AzurLaneConfig, Config): + + Returns: + AzurLaneConfig + """ + # Since all tasks run independently, there's no need to separate configs + # config = copy.copy(self) + config = self + + for attr in dir(config): + if attr.endswith("__"): + continue + if hasattr(other, attr): + value = other.__getattribute__(attr) + if value is not None: + config.__setattr__(attr, value) + + return config + + def temporary(self, **kwargs): + """ + Cover some settings, and recover later. + + Usage: + backup = self.config.cover(ENABLE_DAILY_REWARD=False) + # do_something() + backup.recover() + + Args: + **kwargs: + + Returns: + ConfigBackup: + """ + backup = ConfigBackup(config=self) + backup.cover(**kwargs) + return backup + + +class AzurLaneConfig(GeneralConfig, ConfigUpdater, ManualConfig, GeneratedConfig): def opsi_task_delay(self, recon_scan=False, submarine_call=False, ap_limit=False): """ Delay the NextRun of all OpSi tasks. @@ -602,32 +726,6 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher name += "_hard" return name - """ - The following configs and methods are used to be compatible with the old. - """ - - def merge(self, other): - """ - Args: - other (AzurLaneConfig, Config): - - Returns: - AzurLaneConfig - """ - # Since all tasks run independently, there's no need to separate configs - # config = copy.copy(self) - config = self - - for attr in dir(config): - if attr.endswith("__"): - continue - if hasattr(other, attr): - value = other.__getattribute__(attr) - if value is not None: - config.__setattr__(attr, value) - - return config - @property def DEVICE_SCREENSHOT_METHOD(self): return self.Emulator_ScreenshotMethod @@ -677,25 +775,6 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher def FLEET_BOSS(self, value): self._fleet_boss = value - def temporary(self, **kwargs): - """ - Cover some settings, and recover later. - - Usage: - backup = self.config.cover(ENABLE_DAILY_REWARD=False) - # do_something() - backup.recover() - - Args: - **kwargs: - - Returns: - ConfigBackup: - """ - backup = ConfigBackup(config=self) - backup.cover(**kwargs) - return backup - pywebio.output.Output = OutputConfig pywebio.pin.Output = OutputConfig @@ -705,7 +784,7 @@ class ConfigBackup: def __init__(self, config): """ Args: - config (AzurLaneConfig): + config (GeneralConfig): """ self.config = config self.backup = {} @@ -726,7 +805,7 @@ class MultiSetWrapper: def __init__(self, main): """ Args: - main (AzurLaneConfig): + main (GeneralConfig): """ self.main = main self.in_wrapper = False diff --git a/module/config/utils.py b/module/config/utils.py index 0a526a423..be782163b 100644 --- a/module/config/utils.py +++ b/module/config/utils.py @@ -9,6 +9,7 @@ from filelock import FileLock import module.config.server as server_ from module.config.atomicwrites import atomic_write +from module.submodule.utils import * LANGUAGES = ['zh-CN', 'en-US', 'ja-JP', 'zh-TW'] SERVER_TO_LANG = { @@ -38,20 +39,29 @@ yaml.add_representer(str, str_presenter) yaml.representer.SafeRepresenter.add_representer(str, str_presenter) -def filepath_args(filename='args'): - return f'./module/config/argument/{filename}.json' +def filepath_args(filename='args', mod_name='alas'): + if mod_name == 'alas': + return f'./module/config/argument/{filename}.json' + else: + return os.path.join(filepath_mod(mod_name), f'./module/config/argument/{filename}.json') def filepath_argument(filename): return f'./module/config/argument/{filename}.yaml' -def filepath_i18n(lang): - return os.path.join('./module/config/i18n', f'{lang}.json') +def filepath_i18n(lang, mod_name='alas'): + if mod_name == 'alas': + return os.path.join('./module/config/i18n', f'{lang}.json') + else: + return os.path.join(filepath_mod(mod_name), './module/config/i18n', f'{lang}.json') -def filepath_config(filename): - return os.path.join('./config', f'{filename}.json') +def filepath_config(filename, mod_name='alas'): + if mod_name == 'alas': + return os.path.join('./config', f'{filename}.json') + else: + return os.path.join(filepath_mod(mod_name), './config', f'{filename}.json') def filepath_code(): @@ -152,6 +162,22 @@ def iter_folder(folder, is_dir=False, ext=None): yield os.path.join(folder, file).replace('\\\\', '/').replace('\\', '/') +def alas_template(): + """ + Returns: + list[str]: Name of all Alas instances, except `template`. + """ + out = [] + for file in os.listdir('./config'): + name, extension = os.path.splitext(file) + if name == 'template' and extension == '.json': + out.append(name) + + out.extend(mod_template()) + + return out + + def alas_instance(): """ Returns: @@ -163,6 +189,8 @@ def alas_instance(): if name != 'template' and extension == '.json': out.append(name) + out.extend(mod_instance()) + if not len(out): out = ['alas'] diff --git a/module/submodule/submodule.py b/module/submodule/submodule.py new file mode 100644 index 000000000..9ff793fde --- /dev/null +++ b/module/submodule/submodule.py @@ -0,0 +1,28 @@ +import os +import importlib + +from module.config.config import AzurLaneConfig +from module.logger import logger +from module.submodule.utils import * + + +def load_mod(name): + for mod_name, dir_name in list_mod(): + if name == mod_name: + mod = importlib.import_module('.' + name, 'submodule.' + dir_name) + return mod + + logger.critical("No function matched") + + +def load_config(config_name): + mod_name = get_config_mod(config_name) + if mod_name == 'alas': + return AzurLaneConfig(config_name, '') + else: + config_lib = importlib.import_module( + '.config', + 'submodule.' + get_dir_name(mod_name) + '.module.config') + config = config_lib.load_config(config_name, '') + return config_lib.load_config(config_name, '') + diff --git a/module/submodule/utils.py b/module/submodule/utils.py new file mode 100644 index 000000000..83bc9998b --- /dev/null +++ b/module/submodule/utils.py @@ -0,0 +1,61 @@ +import os + +MOD_LIST = [] +MOD_CONFIG_DICT = [] + + +def list_mod(): + global MOD_LIST + if not MOD_LIST: + MOD_LIST = [] + for dir_name in os.listdir('./submodule'): + mod_path = os.path.join('./submodule', dir_name) + if os.path.isdir(mod_path): + for file_name in os.listdir(mod_path): + mod_name, ext = os.path.splitext(file_name) + if ext == '.py': + MOD_LIST.append((mod_name, dir_name)) + + return MOD_LIST + + +def get_dir_name(name): + for mod_name, dir_name in list_mod(): + if name == mod_name: + return dir_name + + +def filepath_mod(name): + return os.path.join('./submodule', get_dir_name(name)) + + +def mod_template(): + out = [] + for mod_name, dir_name in list_mod(): + for file in os.listdir(os.path.join('./submodule', dir_name, 'config')): + name, extension = os.path.splitext(file) + if name == 'template' and extension == '.json': + out.append(name) + + return out + + +def mod_instance(): + global MOD_CONFIG_DICT + MOD_CONFIG_DICT = {} + out = [] + for mod_name, dir_name in list_mod(): + for file in os.listdir(os.path.join('./submodule', dir_name, 'config')): + name, extension = os.path.splitext(file) + if name != 'template' and extension == '.json': + out.append(name) + MOD_CONFIG_DICT[name] = mod_name + + return out + + +def get_config_mod(config_name): + try: + return MOD_CONFIG_DICT[config_name] + except KeyError: + return 'alas' diff --git a/module/webui/app.py b/module/webui/app.py index a1810fca9..a700cd4d3 100644 --- a/module/webui/app.py +++ b/module/webui/app.py @@ -20,6 +20,8 @@ from module.config.utils import ( ) from module.logger import logger from module.ocr.rpc import start_ocr_server_process, stop_ocr_server_process +from module.submodule.submodule import load_config +from module.submodule.utils import get_config_mod from module.webui.base import Frame from module.webui.discord_presence import close_discord_rpc, init_discord_rpc from module.webui.fastapi import asgi_app @@ -86,10 +88,10 @@ class AlasGUI(Frame): ALAS_ARGS: Dict[str, Dict[str, Dict[str, Dict[str, str]]]] theme = "default" - @classmethod - def initial(cls) -> None: - cls.ALAS_MENU = read_file(filepath_args("menu")) - cls.ALAS_ARGS = read_file(filepath_args("args")) + def initial(self) -> None: + self.ALAS_MENU = read_file(filepath_args("menu", self.alas_mod)) + self.ALAS_ARGS = read_file(filepath_args("args", self.alas_mod)) + self._init_alas_config_watcher() def __init__(self) -> None: super().__init__() @@ -97,7 +99,9 @@ class AlasGUI(Frame): self.modified_config_queue = queue.Queue() # alas config name self.alas_name = "" + self.alas_mod = "alas" self.alas_config = AzurLaneConfig("template") + self.initial() @use_scope("aside", clear=True) def set_aside(self) -> None: @@ -217,7 +221,7 @@ class AlasGUI(Frame): content=[put_text(task_help).style("font-size: 1rem")], ) - config = State.config_updater.read_file(self.alas_name) + config = self.alas_config.read_file(self.alas_name) for group, arg_dict in deep_iter(self.ALAS_ARGS[task], depth=1): self.set_group(group, arg_dict, config, task) self.set_navigator(group) @@ -345,7 +349,7 @@ class AlasGUI(Frame): label_on=t("Gui.Button.Stop"), label_off=t("Gui.Button.Start"), onclick_on=lambda: self.alas.stop(), - onclick_off=lambda: self.alas.start("Alas", updater.event), + onclick_off=lambda: self.alas.start(None, updater.event), get_state=lambda: self.alas.alive, color_on="off", color_off="on", @@ -421,7 +425,7 @@ class AlasGUI(Frame): try: valid = [] invalid = [] - config = State.config_updater.read_file(config_name) + config = self.alas_config.read_file(self.alas_name) for k, v in modified.copy().items(): valuetype = deep_get(self.ALAS_ARGS, k + ".valuetype") v = parse_pin_value(v, valuetype) @@ -464,7 +468,7 @@ class AlasGUI(Frame): logger.info( f"Save config {filepath_config(config_name)}, {dict_to_kv(modified)}" ) - State.config_updater.write_file(config_name, config) + self.alas_config.write_file(config_name, config) except Exception as e: logger.exception(e) @@ -601,7 +605,7 @@ class AlasGUI(Frame): scope="log_scroll_btn", ) - config = State.config_updater.read_file(self.alas_name) + config = self.alas_config.read_file(self.alas_name) for group, arg_dict in deep_iter(self.ALAS_ARGS[task], depth=1): self.set_group(group, arg_dict, config, task) @@ -916,9 +920,11 @@ class AlasGUI(Frame): self.init_aside(name=config_name) clear("content") self.alas_name = config_name + self.alas_mod = get_config_mod(config_name) self.alas = ProcessManager.get_manager(config_name) - self.alas_config = AzurLaneConfig(config_name, "") + self.alas_config = load_config(config_name) self.state_switch.switch() + self.initial() self.alas_set_menu() def ui_add_alas(self) -> None: @@ -1136,7 +1142,6 @@ def debug(): def startup(): State.init() - AlasGUI.initial() lang.reload() updater.event = State.manager.Event() if updater.delay > 0: diff --git a/module/webui/lang.py b/module/webui/lang.py index 7f9b2def8..82cedfdb0 100644 --- a/module/webui/lang.py +++ b/module/webui/lang.py @@ -2,6 +2,7 @@ from typing import Dict from module.config.utils import * from module.webui.setting import State +from module.submodule.utils import list_mod LANG = "zh-CN" TRANSLATE_MODE = False @@ -55,6 +56,11 @@ def reload(): for lang in LANGUAGES: if lang not in dic_lang: dic_lang[lang] = {} + + for mod_name, dir_name in list_mod(): + for path, v in deep_iter(read_file(filepath_i18n(lang, mod_name)), depth=3): + dic_lang[lang][".".join(path)] = v + for path, v in deep_iter(read_file(filepath_i18n(lang)), depth=3): dic_lang[lang][".".join(path)] = v diff --git a/module/webui/process_manager.py b/module/webui/process_manager.py index 0ac8fc8ad..75060a4c7 100644 --- a/module/webui/process_manager.py +++ b/module/webui/process_manager.py @@ -7,6 +7,8 @@ from typing import Dict, List, Union from filelock import FileLock from module.config.utils import filepath_config from module.logger import logger, set_file_logger, set_func_logger +from module.submodule.submodule import load_mod +from module.submodule.utils import get_config_mod from module.webui.setting import State from rich.console import Console, ConsoleRenderable @@ -23,8 +25,10 @@ class ProcessManager: self._process: Process = None self.thd_log_queue_handler: threading.Thread = None - def start(self, func: str, ev: threading.Event = None) -> None: + def start(self, func, ev: threading.Event = None) -> None: if not self.alive: + if func is None: + func = get_config_mod(self.config_name) self._process = Process( target=ProcessManager.run_process, args=( @@ -124,7 +128,7 @@ class ProcessManager: AzurLaneConfig.stop_event = e try: # Run alas - if func == "Alas": + if func == "alas": from alas import AzurLaneAutoScript if e is not None: @@ -151,7 +155,8 @@ class ProcessManager: GameManager(config=config_name, task="GameManager").run() else: - logger.critical("No function matched") + mod = load_mod(func) + mod.loop(config_name=config_name) logger.info(f"[{config_name}] exited. Reason: Finish\n") except Exception as e: logger.exception(e) diff --git a/submodule/AlasMaaBridge b/submodule/AlasMaaBridge new file mode 160000 index 000000000..9560e1735 --- /dev/null +++ b/submodule/AlasMaaBridge @@ -0,0 +1 @@ +Subproject commit 9560e1735c18c3bab162a3388f511e1bbcaecfad From 764e216c985360c56b29215ad1d9e8947cff139c Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Thu, 1 Sep 2022 18:28:17 +0800 Subject: [PATCH 02/21] Add: First executable prototype --- alas.py | 8 +++++--- module/device/connection_attr.py | 2 +- submodule/AlasMaaBridge | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/alas.py b/alas.py index 88bca7549..7084061bf 100644 --- a/alas.py +++ b/alas.py @@ -59,7 +59,8 @@ class AutoScriptScheduler: def run(self, command): try: - self.device.screenshot() + if self.device: + self.device.screenshot() self.__getattribute__(command)() return True except TaskEnd: @@ -267,8 +268,9 @@ class AutoScriptScheduler: # Run logger.info(f'Scheduler: Start task `{task}`') - self.device.stuck_record_clear() - self.device.click_record_clear() + if self.device: + self.device.stuck_record_clear() + self.device.click_record_clear() logger.hr(task, level=0) success = self.run(inflection.underscore(task)) logger.info(f'Scheduler: End task `{task}`') diff --git a/module/device/connection_attr.py b/module/device/connection_attr.py index 9c7baadd7..3e4c66865 100644 --- a/module/device/connection_attr.py +++ b/module/device/connection_attr.py @@ -52,7 +52,7 @@ class ConnectionAttr: if 'proxy' in k[0].split('_')[-1].lower(): del os.environ[k[0]] else: - su = super(AzurLaneConfig, self.config) + su = super(self.config.__class__, self.config) for k, v in deep_iter(su.__dict__, depth=1): if not isinstance(v, str): continue diff --git a/submodule/AlasMaaBridge b/submodule/AlasMaaBridge index 9560e1735..eea1dbbe5 160000 --- a/submodule/AlasMaaBridge +++ b/submodule/AlasMaaBridge @@ -1 +1 @@ -Subproject commit 9560e1735c18c3bab162a3388f511e1bbcaecfad +Subproject commit eea1dbbe5364aa5cc2b73b8d7137b2090184c9f1 From 4b620853fe861ccb7c82017604fe7530cb62f6b4 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Thu, 1 Sep 2022 22:13:47 +0800 Subject: [PATCH 03/21] Add: Add new config --- module/config/config.py | 4 ++-- module/config/config_updater.py | 5 +++-- module/config/utils.py | 2 +- module/submodule/utils.py | 12 +++++++++--- module/webui/app.py | 7 ++++--- submodule/AlasMaaBridge | 2 +- 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/module/config/config.py b/module/config/config.py index f3cc184c6..a5101ce67 100644 --- a/module/config/config.py +++ b/module/config/config.py @@ -234,7 +234,7 @@ class GeneralConfig(ConfigWatcher): logger.critical("Please enable at least one task") raise RequestHumanTakeover - def save(self): + def save(self, mod_name='alas'): if not self.modified: return False @@ -242,7 +242,7 @@ class GeneralConfig(ConfigWatcher): deep_set(self.data, keys=path, value=value) logger.info( - f"Save config {filepath_config(self.config_name)}, {dict_to_kv(self.modified)}" + f"Save config {filepath_config(self.config_name, mod_name)}, {dict_to_kv(self.modified)}" ) # Don't use self.modified = {}, that will create a new object. self.modified.clear() diff --git a/module/config/config_updater.py b/module/config/config_updater.py index 3ee58477a..e26dfd5a2 100644 --- a/module/config/config_updater.py +++ b/module/config/config_updater.py @@ -593,15 +593,16 @@ class ConfigUpdater: return self.config_update(old, is_template=is_template) @staticmethod - def write_file(config_name, data): + def write_file(config_name, data, mod_name='alas'): """ Write config file. Args: config_name (str): ./config/{file}.json data (dict): + mod_name (str): """ - write_file(filepath_config(config_name), data) + write_file(filepath_config(config_name, mod_name), data) @timer def update_file(self, config_name, is_template=False): diff --git a/module/config/utils.py b/module/config/utils.py index be782163b..9790a44b4 100644 --- a/module/config/utils.py +++ b/module/config/utils.py @@ -171,7 +171,7 @@ def alas_template(): for file in os.listdir('./config'): name, extension = os.path.splitext(file) if name == 'template' and extension == '.json': - out.append(name) + out.append(f'{name}-alas') out.extend(mod_template()) diff --git a/module/submodule/utils.py b/module/submodule/utils.py index 83bc9998b..63be28765 100644 --- a/module/submodule/utils.py +++ b/module/submodule/utils.py @@ -1,7 +1,7 @@ import os MOD_LIST = [] -MOD_CONFIG_DICT = [] +MOD_CONFIG_DICT = {} def list_mod(): @@ -35,14 +35,14 @@ def mod_template(): for file in os.listdir(os.path.join('./submodule', dir_name, 'config')): name, extension = os.path.splitext(file) if name == 'template' and extension == '.json': - out.append(name) + out.append(f'{name}-{mod_name}') return out def mod_instance(): global MOD_CONFIG_DICT - MOD_CONFIG_DICT = {} + MOD_CONFIG_DICT.clear() out = [] for mod_name, dir_name in list_mod(): for file in os.listdir(os.path.join('./submodule', dir_name, 'config')): @@ -55,6 +55,12 @@ def mod_instance(): def get_config_mod(config_name): + """ + Args: + config_name (str): + """ + if config_name.startswith('template-'): + return config_name.replace('template-', '') try: return MOD_CONFIG_DICT[config_name] except KeyError: diff --git a/module/webui/app.py b/module/webui/app.py index a700cd4d3..c79aa922f 100644 --- a/module/webui/app.py +++ b/module/webui/app.py @@ -9,6 +9,7 @@ from typing import Dict, List, Optional import module.webui.lang as lang from module.config.config import AzurLaneConfig, Function from module.config.utils import ( + alas_template, alas_instance, deep_get, deep_iter, @@ -944,7 +945,7 @@ class AlasGUI(Frame): if name not in alas_instance(): r = State.config_updater.read_file(origin) - State.config_updater.write_file(name, r) + State.config_updater.write_file(name, r, get_config_mod(origin)) self.set_aside() self.active_button("aside", self.alas_name) close_popup() @@ -963,8 +964,8 @@ class AlasGUI(Frame): put_select( name="AddAlas_copyfrom", label=t("Gui.AddAlas.CopyFrom"), - options=["template"] + alas_instance(), - value=origin or "template", + options=alas_template() + alas_instance(), + value=origin or "template-alas", scope=s, ), put_button(label=t("Gui.AddAlas.Confirm"), onclick=add, scope=s) diff --git a/submodule/AlasMaaBridge b/submodule/AlasMaaBridge index eea1dbbe5..298fd8d49 160000 --- a/submodule/AlasMaaBridge +++ b/submodule/AlasMaaBridge @@ -1 +1 @@ -Subproject commit eea1dbbe5364aa5cc2b73b8d7137b2090184c9f1 +Subproject commit 298fd8d494e836fc1c6130b5f0ae70c568cdda66 From 6db4945c1898bb78e8cae869e34c8fdc188218af Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Sun, 4 Sep 2022 15:50:30 +0800 Subject: [PATCH 04/21] Add: Tools of MAA --- .gitignore | 1 + module/webui/process_manager.py | 5 ++++- submodule/AlasMaaBridge | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index fe95faf23..27e024abe 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ config/reloadflag config/reloadalas test.py test/ +debug/ # Created by .ignore support plugin (hsz.mobi) diff --git a/module/webui/process_manager.py b/module/webui/process_manager.py index 75060a4c7..7e1bd640e 100644 --- a/module/webui/process_manager.py +++ b/module/webui/process_manager.py @@ -154,9 +154,12 @@ class ProcessManager: from module.daemon.game_manager import GameManager GameManager(config=config_name, task="GameManager").run() + elif func == "MaaCopilot": + mod = load_mod('maa') + mod.maa_copilot(config_name) else: mod = load_mod(func) - mod.loop(config_name=config_name) + mod.loop(config_name) logger.info(f"[{config_name}] exited. Reason: Finish\n") except Exception as e: logger.exception(e) diff --git a/submodule/AlasMaaBridge b/submodule/AlasMaaBridge index 298fd8d49..6531275a8 160000 --- a/submodule/AlasMaaBridge +++ b/submodule/AlasMaaBridge @@ -1 +1 @@ -Subproject commit 298fd8d494e836fc1c6130b5f0ae70c568cdda66 +Subproject commit 6531275a848eb28f555d1cfdf1fbf79ecd9c6f91 From b980ef10f7cbff81320db840439295a254efeae0 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Mon, 12 Sep 2022 17:55:08 +0800 Subject: [PATCH 05/21] Add: Update Submodule --- .gitignore | 1 + .gitmodules | 3 --- config/deploy.template-AidLux-cn.yaml | 3 +++ config/deploy.template-AidLux.yaml | 3 +++ config/deploy.template-cn.yaml | 3 +++ config/deploy.template-docker-cn.yaml | 3 +++ config/deploy.template-docker.yaml | 3 +++ config/deploy.template.yaml | 3 +++ deploy/config.py | 3 +++ deploy/git.py | 17 +++++++++++++++++ deploy/template | 3 +++ submodule/AlasMaaBridge | 1 - 12 files changed, 42 insertions(+), 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 submodule/AlasMaaBridge diff --git a/.gitignore b/.gitignore index 27e024abe..e8376eed9 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ config/reloadalas test.py test/ debug/ +submodule # Created by .ignore support plugin (hsz.mobi) diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d375b25d7..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "submodule/AlasMaaBridge"] - path = submodule/AlasMaaBridge - url = https://github.com/SaiCateDoan/AlasMaaBridge.git diff --git a/config/deploy.template-AidLux-cn.yaml b/config/deploy.template-AidLux-cn.yaml index 81368a621..c2fd55dac 100644 --- a/config/deploy.template-AidLux-cn.yaml +++ b/config/deploy.template-AidLux-cn.yaml @@ -25,6 +25,9 @@ Deploy: # [Other] Use false KeepLocalChanges: false + Plugins: + MaaAssistantArknights: false + Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template-AidLux.yaml b/config/deploy.template-AidLux.yaml index b12c6f38e..735a76317 100644 --- a/config/deploy.template-AidLux.yaml +++ b/config/deploy.template-AidLux.yaml @@ -25,6 +25,9 @@ Deploy: # [Other] Use false KeepLocalChanges: false + Plugins: + MaaAssistantArknights: false + Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template-cn.yaml b/config/deploy.template-cn.yaml index 16cb831aa..d5f1af92a 100644 --- a/config/deploy.template-cn.yaml +++ b/config/deploy.template-cn.yaml @@ -25,6 +25,9 @@ Deploy: # [Other] Use false KeepLocalChanges: false + Plugins: + MaaAssistantArknights: false + Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template-docker-cn.yaml b/config/deploy.template-docker-cn.yaml index 0a2e0ceb2..953f30476 100644 --- a/config/deploy.template-docker-cn.yaml +++ b/config/deploy.template-docker-cn.yaml @@ -25,6 +25,9 @@ Deploy: # [Other] Use false KeepLocalChanges: false + Plugins: + MaaAssistantArknights: false + Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template-docker.yaml b/config/deploy.template-docker.yaml index 1454a3e86..dce8a0ae9 100644 --- a/config/deploy.template-docker.yaml +++ b/config/deploy.template-docker.yaml @@ -25,6 +25,9 @@ Deploy: # [Other] Use false KeepLocalChanges: false + Plugins: + MaaAssistantArknights: false + Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template.yaml b/config/deploy.template.yaml index 0669a55ce..9a0fca340 100644 --- a/config/deploy.template.yaml +++ b/config/deploy.template.yaml @@ -25,6 +25,9 @@ Deploy: # [Other] Use false KeepLocalChanges: false + Plugins: + MaaAssistantArknights: false + Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/deploy/config.py b/deploy/config.py index cc9a42b49..6ac64b03f 100644 --- a/deploy/config.py +++ b/deploy/config.py @@ -18,6 +18,9 @@ class ConfigModel: AutoUpdate: bool = True KeepLocalChanges: bool = False + # Plugins + MaaAssistantArknights: bool = False + # Python PythonExecutable: str = "./toolkit/python.exe" PypiMirror: Optional[bool] = None diff --git a/deploy/git.py b/deploy/git.py index 759e4b085..cda03c91b 100644 --- a/deploy/git.py +++ b/deploy/git.py @@ -1,3 +1,5 @@ +import os + from deploy.config import DeployConfig from deploy.logger import logger from deploy.utils import * @@ -66,3 +68,18 @@ class GitManager(DeployConfig): proxy=self.GitProxy, keep_changes=self.KeepLocalChanges, ) + logger.hr('Update Submodule', 0) + if self.MaaAssistantArknights: + repo = 'https://github.com/SaiCateDoan/AlasMaaBridge' + folder = './submodule/AlasMaaBridge' + os.makedirs(folder, exist_ok=True) + prev = os.getcwd() + os.chdir(folder) + self.git_repository_init( + repo=repo, + source='origin', + branch='master', + proxy=self.GitProxy, + keep_changes=self.KeepLocalChanges + ) + os.chdir(prev) diff --git a/deploy/template b/deploy/template index 5b029e40c..e28f4f682 100644 --- a/deploy/template +++ b/deploy/template @@ -25,6 +25,9 @@ Deploy: # [Other] Use false KeepLocalChanges: false + Plugins: + MaaAssistantArknights: false + Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/submodule/AlasMaaBridge b/submodule/AlasMaaBridge deleted file mode 160000 index 6531275a8..000000000 --- a/submodule/AlasMaaBridge +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6531275a848eb28f555d1cfdf1fbf79ecd9c6f91 From f2a5f57e01e1c60ce2f1d5b13ff200b561c73c05 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Mon, 12 Sep 2022 19:08:04 +0800 Subject: [PATCH 06/21] Fix: FileNotFoundError when './submodule' not exists --- module/submodule/utils.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/module/submodule/utils.py b/module/submodule/utils.py index 63be28765..e1479e7e6 100644 --- a/module/submodule/utils.py +++ b/module/submodule/utils.py @@ -8,13 +8,14 @@ def list_mod(): global MOD_LIST if not MOD_LIST: MOD_LIST = [] - for dir_name in os.listdir('./submodule'): - mod_path = os.path.join('./submodule', dir_name) - if os.path.isdir(mod_path): - for file_name in os.listdir(mod_path): - mod_name, ext = os.path.splitext(file_name) - if ext == '.py': - MOD_LIST.append((mod_name, dir_name)) + if os.path.exists('./submodule'): + for dir_name in os.listdir('./submodule'): + mod_path = os.path.join('./submodule', dir_name) + if os.path.isdir(mod_path): + for file_name in os.listdir(mod_path): + mod_name, ext = os.path.splitext(file_name) + if ext == '.py': + MOD_LIST.append((mod_name, dir_name)) return MOD_LIST From 782eebbb8c3567cf038f689a12851d1ac71eee22 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Tue, 13 Sep 2022 16:22:27 +0800 Subject: [PATCH 07/21] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index e8376eed9..27e024abe 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ config/reloadalas test.py test/ debug/ -submodule # Created by .ignore support plugin (hsz.mobi) From 79dad6a6b00024193cdfd2a413babc7995752167 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Tue, 13 Sep 2022 16:35:13 +0800 Subject: [PATCH 08/21] Add: AlasMaaBridge init --- .gitignore | 3 + submodule/AlasMaaBridge/config/template.json | 174 +++++ submodule/AlasMaaBridge/maa.py | 103 +++ .../module/config/argument/args.json | 605 ++++++++++++++++++ .../module/config/argument/argument.yaml | 117 ++++ .../module/config/argument/default.yaml | 8 + .../module/config/argument/menu.json | 20 + .../module/config/argument/override.yaml | 43 ++ .../module/config/argument/task.yaml | 51 ++ .../AlasMaaBridge/module/config/config.py | 62 ++ .../module/config/config_generated.py | 77 +++ .../module/config/config_manual.py | 33 + .../module/config/config_updater.py | 123 ++++ .../module/config/i18n/en-US.json | 341 ++++++++++ .../module/config/i18n/ja-JP.json | 341 ++++++++++ .../module/config/i18n/zh-CN.json | 341 ++++++++++ .../module/config/i18n/zh-TW.json | 341 ++++++++++ .../AlasMaaBridge/module/handler/handler.py | 226 +++++++ 18 files changed, 3009 insertions(+) create mode 100644 submodule/AlasMaaBridge/config/template.json create mode 100644 submodule/AlasMaaBridge/maa.py create mode 100644 submodule/AlasMaaBridge/module/config/argument/args.json create mode 100644 submodule/AlasMaaBridge/module/config/argument/argument.yaml create mode 100644 submodule/AlasMaaBridge/module/config/argument/default.yaml create mode 100644 submodule/AlasMaaBridge/module/config/argument/menu.json create mode 100644 submodule/AlasMaaBridge/module/config/argument/override.yaml create mode 100644 submodule/AlasMaaBridge/module/config/argument/task.yaml create mode 100644 submodule/AlasMaaBridge/module/config/config.py create mode 100644 submodule/AlasMaaBridge/module/config/config_generated.py create mode 100644 submodule/AlasMaaBridge/module/config/config_manual.py create mode 100644 submodule/AlasMaaBridge/module/config/config_updater.py create mode 100644 submodule/AlasMaaBridge/module/config/i18n/en-US.json create mode 100644 submodule/AlasMaaBridge/module/config/i18n/ja-JP.json create mode 100644 submodule/AlasMaaBridge/module/config/i18n/zh-CN.json create mode 100644 submodule/AlasMaaBridge/module/config/i18n/zh-TW.json create mode 100644 submodule/AlasMaaBridge/module/handler/handler.py diff --git a/.gitignore b/.gitignore index 27e024abe..fff55960c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ config/*.yaml config/*.json config/tmp* !config/template.json +submodule/AlasMaaBridge/config/*.json +submodule/AlasMaaBridge/config/tmp* +!submodule/AlasMaaBridge/config/template.json *.pyw dev_tools/debug_tools .idea diff --git a/submodule/AlasMaaBridge/config/template.json b/submodule/AlasMaaBridge/config/template.json new file mode 100644 index 000000000..d27ffab6c --- /dev/null +++ b/submodule/AlasMaaBridge/config/template.json @@ -0,0 +1,174 @@ +{ + "Maa": { + "Emulator": { + "Serial": "127.0.0.1:5555", + "PackageName": "Official", + "Server": "CN", + "MaaPath": "D:/Program Files/MAA", + "ServerName": "disabled" + }, + "Record": { + "ReportToPenguin": false, + "PenguinID": null + } + }, + "MaaStartup": { + "Scheduler": { + "Enable": true, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaStartup", + "SuccessInterval": 0, + "FailureInterval": 0, + "ServerUpdate": "04:00" + } + }, + "MaaAnnihilation": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaAnnihilation", + "SuccessInterval": 480, + "FailureInterval": 120, + "ServerUpdate": "04:00" + }, + "Fight": { + "Stage": "Annihilation", + "Medicine": 0, + "Stone": 0, + "Times": 5, + "Drops": null, + "DrGrandet": false + } + }, + "MaaMaterial": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaMaterial", + "SuccessInterval": 60, + "FailureInterval": 120, + "ServerUpdate": "04:00" + }, + "Fight": { + "Stage": "1-7", + "Medicine": 0, + "Stone": 0, + "Times": 0, + "Drops": null, + "DrGrandet": false + } + }, + "MaaFight": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaFight", + "SuccessInterval": 480, + "FailureInterval": 120, + "ServerUpdate": "04:00" + }, + "Fight": { + "Stage": "1-7", + "Medicine": 0, + "Stone": 0, + "Times": 0, + "Drops": null, + "DrGrandet": false + } + }, + "MaaRecruit": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaRecruit", + "SuccessInterval": 540, + "FailureInterval": 120, + "ServerUpdate": "04:00" + }, + "Recruit": { + "Refresh": true, + "SkipRobot": true, + "Select3": true, + "Select4": true, + "Select5": true, + "Times": 4, + "Expedite": false + } + }, + "MaaInfrast": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaInfrast", + "SuccessInterval": 1200, + "FailureInterval": 120, + "ServerUpdate": "04:00" + }, + "Infrast": { + "Facility": "Mfg > Trade > Power > Control > Reception > Office > Dorm", + "Drones": "Money", + "Threshold": 0.3, + "Replenish": false + } + }, + "MaaVisit": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaVisit", + "SuccessInterval": 60, + "FailureInterval": 120, + "ServerUpdate": "04:00" + } + }, + "MaaMall": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaMall", + "SuccessInterval": 60, + "FailureInterval": 120, + "ServerUpdate": "04:00" + }, + "Mall": { + "Shopping": true, + "BuyFirst": "招聘许可 > 龙门币", + "BlackList": "碳 > 家具" + } + }, + "MaaAward": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaAward", + "SuccessInterval": 60, + "FailureInterval": 120, + "ServerUpdate": "04:00" + } + }, + "MaaRoguelike": { + "Scheduler": { + "Enable": false, + "NextRun": "2020-01-01 00:00:00", + "Command": "MaaRoguelike", + "SuccessInterval": 60, + "FailureInterval": 120, + "ServerUpdate": "04:00" + }, + "Roguelike": { + "Mode": 0, + "StartsCount": 9999999, + "InvestmentsCount": 9999999, + "StopWhenInvestmentFull": false, + "Squad": "指挥分队", + "Roles": "取长补短", + "CoreChar": null + } + }, + "MaaCopilot": { + "Copilot": { + "FileName": null, + "Formation": false + } + } +} \ No newline at end of file diff --git a/submodule/AlasMaaBridge/maa.py b/submodule/AlasMaaBridge/maa.py new file mode 100644 index 000000000..e699331ac --- /dev/null +++ b/submodule/AlasMaaBridge/maa.py @@ -0,0 +1,103 @@ +import os +import json +from cached_property import cached_property + +from alas import AutoScriptScheduler +from deploy.config import DeployConfig +from module.exception import RequestHumanTakeover +from module.logger import logger + +from submodule.AlasMaaBridge.module.config.config import ArknightsConfig +from submodule.AlasMaaBridge.module.handler.handler import AssistantHandler + + +class ArknightsAutoScript(AutoScriptScheduler): + @cached_property + def device(self): + return None + + @cached_property + def config(self): + try: + config = ArknightsConfig(config_name=self.config_name) + return config + except RequestHumanTakeover: + logger.critical('Request human takeover') + exit(1) + except Exception as e: + logger.exception(e) + exit(1) + + @cached_property + def asst(self): + if self.config.task.command not in ['MaaStartup', 'Maa']: + self.config.task_call('MaaStartup', True) + self.config.task_stop() + + AssistantHandler.load(self.config.Emulator_MaaPath) + + @AssistantHandler.Asst.CallBackType + def callback(msg, details, arg): + """ + Args: + msg (int): + details (bytes): + arg (c_void_p): + """ + m = AssistantHandler.Message(msg) + d = details.decode('utf-8', 'ignore') + logger.info(f'{m} {d}') + handler = AssistantHandler.ASST_HANDLER + if handler: + handler.callback_timer.reset() + for func in handler.callback_list: + func(m, json.loads(d)) + + self.callback = callback + asst = AssistantHandler.Asst(callback) + + if not asst.connect(os.path.abspath(DeployConfig().AdbExecutable), self.config.Emulator_Serial): + logger.critical('Adb connect failed') + raise RequestHumanTakeover + + return asst + + def maa_startup(self): + AssistantHandler(config=self.config, asst=self.asst).startup() + + def maa_annihilation(self): + AssistantHandler(config=self.config, asst=self.asst).fight() + + def maa_material(self): + AssistantHandler(config=self.config, asst=self.asst).fight() + + def maa_fight(self): + AssistantHandler(config=self.config, asst=self.asst).fight() + + def maa_recruit(self): + AssistantHandler(config=self.config, asst=self.asst).recruit() + + def maa_infrast(self): + AssistantHandler(config=self.config, asst=self.asst).infrast() + + def maa_visit(self): + AssistantHandler(config=self.config, asst=self.asst).visit() + + def maa_mall(self): + AssistantHandler(config=self.config, asst=self.asst).mall() + + def maa_award(self): + AssistantHandler(config=self.config, asst=self.asst).award() + + def maa_roguelike(self): + AssistantHandler(config=self.config, asst=self.asst).roguelike() + + +def loop(config_name): + ArknightsAutoScript(config_name).loop() + + +def maa_copilot(config_name): + script = ArknightsAutoScript(config_name) + script.config.bind('MaaCopilot') + AssistantHandler(config=script.config, asst=script.asst).copilot() diff --git a/submodule/AlasMaaBridge/module/config/argument/args.json b/submodule/AlasMaaBridge/module/config/argument/args.json new file mode 100644 index 000000000..2f80b4ddf --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/argument/args.json @@ -0,0 +1,605 @@ +{ + "Maa": { + "Emulator": { + "Serial": { + "type": "input", + "value": "127.0.0.1:5555", + "valuetype": "str" + }, + "PackageName": { + "type": "select", + "value": "Official", + "option": [ + "Official", + "Bilibili" + ] + }, + "Server": { + "type": "select", + "value": "CN", + "option": [ + "CN", + "US", + "JP", + "KR" + ] + }, + "MaaPath": { + "type": "textarea", + "value": "D:/Program Files/MAA" + }, + "ServerName": { + "type": "input", + "value": "disabled", + "display": "hide" + } + }, + "Record": { + "ReportToPenguin": { + "type": "checkbox", + "value": false + }, + "PenguinID": { + "type": "input", + "value": null + } + } + }, + "MaaStartup": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": true, + "display": "disabled" + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaStartup", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 0, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 0, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + } + }, + "MaaAnnihilation": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaAnnihilation", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 480, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + }, + "Fight": { + "Stage": { + "type": "input", + "value": "Annihilation", + "valuetype": "str", + "display": "hide" + }, + "Medicine": { + "type": "input", + "value": 0, + "display": "hide" + }, + "Stone": { + "type": "input", + "value": 0, + "display": "hide" + }, + "Times": { + "type": "input", + "value": 5, + "display": "hide" + }, + "Drops": { + "type": "textarea", + "value": null, + "display": "hide" + }, + "DrGrandet": { + "type": "checkbox", + "value": false, + "display": "hide" + } + } + }, + "MaaMaterial": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaMaterial", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 60, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + }, + "Fight": { + "Stage": { + "type": "input", + "value": "1-7", + "valuetype": "str" + }, + "Medicine": { + "type": "input", + "value": 0 + }, + "Stone": { + "type": "input", + "value": 0 + }, + "Times": { + "type": "input", + "value": 0 + }, + "Drops": { + "type": "textarea", + "value": null + }, + "DrGrandet": { + "type": "checkbox", + "value": false + } + } + }, + "MaaFight": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaFight", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 480, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + }, + "Fight": { + "Stage": { + "type": "input", + "value": "1-7", + "valuetype": "str" + }, + "Medicine": { + "type": "input", + "value": 0, + "display": "hide" + }, + "Stone": { + "type": "input", + "value": 0, + "display": "hide" + }, + "Times": { + "type": "input", + "value": 0, + "display": "hide" + }, + "Drops": { + "type": "textarea", + "value": null, + "display": "hide" + }, + "DrGrandet": { + "type": "checkbox", + "value": false + } + } + }, + "MaaRecruit": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaRecruit", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 540, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + }, + "Recruit": { + "Refresh": { + "type": "checkbox", + "value": true + }, + "SkipRobot": { + "type": "checkbox", + "value": true + }, + "Select3": { + "type": "checkbox", + "value": true + }, + "Select4": { + "type": "checkbox", + "value": true + }, + "Select5": { + "type": "checkbox", + "value": true + }, + "Times": { + "type": "input", + "value": 4 + }, + "Expedite": { + "type": "checkbox", + "value": false + } + } + }, + "MaaInfrast": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaInfrast", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 1200, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + }, + "Infrast": { + "Facility": { + "type": "textarea", + "value": "Mfg > Trade > Power > Control > Reception > Office > Dorm" + }, + "Drones": { + "type": "select", + "value": "Money", + "option": [ + "_NotUse", + "Money", + "SyntheticJade", + "CombatRecord", + "PureGold", + "OriginStone", + "Chip" + ] + }, + "Threshold": { + "type": "input", + "value": 0.3 + }, + "Replenish": { + "type": "checkbox", + "value": false + } + } + }, + "MaaVisit": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaVisit", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 60, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + } + }, + "MaaMall": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaMall", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 60, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + }, + "Mall": { + "Shopping": { + "type": "checkbox", + "value": true + }, + "BuyFirst": { + "type": "textarea", + "value": "招聘许可 > 龙门币" + }, + "BlackList": { + "type": "textarea", + "value": "碳 > 家具" + } + } + }, + "MaaAward": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaAward", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 60, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + } + }, + "MaaRoguelike": { + "Scheduler": { + "Enable": { + "type": "checkbox", + "value": false + }, + "NextRun": { + "type": "datetime", + "value": "2020-01-01 00:00:00", + "validate": "datetime" + }, + "Command": { + "type": "input", + "value": "MaaRoguelike", + "display": "hide" + }, + "SuccessInterval": { + "type": "input", + "value": 60, + "display": "hide" + }, + "FailureInterval": { + "type": "input", + "value": 120, + "display": "hide" + }, + "ServerUpdate": { + "type": "input", + "value": "04:00", + "display": "hide" + } + }, + "Roguelike": { + "Mode": { + "type": "select", + "value": 0, + "option": [ + 0, + 1 + ] + }, + "StartsCount": { + "type": "input", + "value": 9999999 + }, + "InvestmentsCount": { + "type": "input", + "value": 9999999 + }, + "StopWhenInvestmentFull": { + "type": "checkbox", + "value": false + }, + "Squad": { + "type": "select", + "value": "指挥分队", + "option": [ + "指挥分队", + "集群分队", + "后勤分队", + "矛头分队", + "突击战术分队", + "堡垒战术分队", + "远程战术分队", + "破坏战术分队", + "研究分队", + "高规格分队" + ] + }, + "Roles": { + "type": "select", + "value": "取长补短", + "option": [ + "先手必胜", + "稳扎稳打", + "取长补短", + "随心所欲" + ] + }, + "CoreChar": { + "type": "input", + "value": null + } + } + }, + "MaaCopilot": { + "Copilot": { + "FileName": { + "type": "textarea", + "value": null + }, + "Formation": { + "type": "checkbox", + "value": false + } + } + } +} \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/argument/argument.yaml b/submodule/AlasMaaBridge/module/config/argument/argument.yaml new file mode 100644 index 000000000..7b7f029c8 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/argument/argument.yaml @@ -0,0 +1,117 @@ +# -------------------- +# Define arguments. +# -------------------- + +# ==================== Maa ==================== + +Scheduler: + Enable: false + NextRun: 2020-01-01 00:00:00 + Command: Maa + SuccessInterval: + value: 60 + display: hide + FailureInterval: + value: 120 + display: hide + ServerUpdate: + value: 04:00 + display: hide + +Emulator: + Serial: + value: 127.0.0.1:5555 + valuetype: str + PackageName: + value: Official + option: [Official, Bilibili] + Server: + value: CN + option: [CN, US, JP, KR] + MaaPath: + value: D:/Program Files/MAA + type: textarea + ServerName: + value: disabled + display: hide +Record: + ReportToPenguin: false + PenguinID: null + +Error: + SaveError: + value: false + display: hide + OnePushConfig: + mode: yaml + value: 'provider: null' + display: hide +Optimization: + WhenTaskQueueEmpty: + value: stay_there + display: hide + +Fight: + Stage: + value: 1-7 + valuetype: str + Medicine: 0 + Stone: 0 + Times: 0 + Drops: + value: null + type: textarea + DrGrandet: false + +Recruit: + Refresh: true + SkipRobot: true + Select3: true + Select4: true + Select5: true + Times: 4 + Expedite: false + +Infrast: + Facility: + value: Mfg > Trade > Power > Control > Reception > Office > Dorm + type: textarea + Drones: + value: Money + option: [_NotUse, Money, SyntheticJade, CombatRecord, PureGold, OriginStone, Chip] + Threshold: 0.3 + Replenish: false + +Mall: + Shopping: true + BuyFirst: + value: 招聘许可 > 龙门币 + type: textarea + BlackList: + value: 碳 > 家具 + type: textarea + +Roguelike: + Mode: + value: 0 + option: [0, 1] + StartsCount: 9999999 + InvestmentsCount: 9999999 + StopWhenInvestmentFull: false + Squad: + value: 指挥分队 + option: [指挥分队, 集群分队, 后勤分队, 矛头分队, 突击战术分队, 堡垒战术分队, 远程战术分队, 破坏战术分队, 研究分队, 高规格分队] + Roles: + value: 取长补短 + option: [先手必胜, 稳扎稳打, 取长补短, 随心所欲] + CoreChar: null + +# ==================== Tool ==================== + +Copilot: + FileName: + value: null + type: textarea + Formation: false + + diff --git a/submodule/AlasMaaBridge/module/config/argument/default.yaml b/submodule/AlasMaaBridge/module/config/argument/default.yaml new file mode 100644 index 000000000..83c72493b --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/argument/default.yaml @@ -0,0 +1,8 @@ +# -------------------- +# Define default values +# -------------------- + +# ==================== Maa ==================== +MaaStartup: + Scheduler: + Enable: true diff --git a/submodule/AlasMaaBridge/module/config/argument/menu.json b/submodule/AlasMaaBridge/module/config/argument/menu.json new file mode 100644 index 000000000..3ac0afd72 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/argument/menu.json @@ -0,0 +1,20 @@ +{ + "Task": { + "Maa": [ + "Maa", + "MaaStartup", + "MaaAnnihilation", + "MaaMaterial", + "MaaFight", + "MaaRecruit", + "MaaInfrast", + "MaaVisit", + "MaaMall", + "MaaAward", + "MaaRoguelike" + ], + "Tool": [ + "MaaCopilot" + ] + } +} \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/argument/override.yaml b/submodule/AlasMaaBridge/module/config/argument/override.yaml new file mode 100644 index 000000000..aefd22ecf --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/argument/override.yaml @@ -0,0 +1,43 @@ +# -------------------- +# Define non-modifiable values +# -------------------- + +# ==================== Maa ==================== + +MaaStartup: + Scheduler: + Enable: + value: true + display: disabled + SuccessInterval: 0 + FailureInterval: 0 + ServerUpdate: 04:00 + +MaaAnnihilation: + Scheduler: + SuccessInterval: 480 + Fight: + Stage: Annihilation + Medicine: 0 + Stone: 0 + Times: 5 + Drops: null + DrGrandet: false + +MaaFight: + Scheduler: + SuccessInterval: 480 + Fight: + Medicine: 0 + Stone: 0 + Times: 0 + Drops: null + +MaaRecruit: + Scheduler: + SuccessInterval: 540 + +MaaInfrast: + Scheduler: + SuccessInterval: 1200 + diff --git a/submodule/AlasMaaBridge/module/config/argument/task.yaml b/submodule/AlasMaaBridge/module/config/argument/task.yaml new file mode 100644 index 000000000..d346890a3 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/argument/task.yaml @@ -0,0 +1,51 @@ +# -------------------- +# Define argument group of tasks. +# -------------------- + +# ==================== Maa ==================== + +Maa: + - Emulator + - Record + +MaaStartup: + - Scheduler + +MaaAnnihilation: + - Scheduler + - Fight + +MaaMaterial: + - Scheduler + - Fight + +MaaFight: + - Scheduler + - Fight + +MaaRecruit: + - Scheduler + - Recruit + +MaaInfrast: + - Scheduler + - Infrast + +MaaVisit: + - Scheduler + +MaaMall: + - Scheduler + - Mall + +MaaAward: + - Scheduler + +MaaRoguelike: + - Scheduler + - Roguelike + +# ==================== Tool ==================== + +MaaCopilot: + - Copilot \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/config.py b/submodule/AlasMaaBridge/module/config/config.py new file mode 100644 index 000000000..40bd630d2 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/config.py @@ -0,0 +1,62 @@ +import os +from datetime import datetime + +from module.config.config import GeneralConfig, Function, name_to_function +from module.config.utils import path_to_arg, filepath_config +from module.logger import logger + +from submodule.AlasMaaBridge.module.config.config_generated import GeneratedConfig +from submodule.AlasMaaBridge.module.config.config_manual import ManualConfig +from submodule.AlasMaaBridge.module.config.config_updater import ConfigUpdater + + +class ArknightsConfig(GeneralConfig, ConfigUpdater, ManualConfig, GeneratedConfig): + def __init__(self, config_name, task=None): + super().__init__(config_name, task) + if task is None: + task = name_to_function("Maa") + self.bind(task) + self.task = task + self.save() + + def bind(self, func): + """ + Args: + func (str, Function): Function to run + """ + if isinstance(func, Function): + func = func.command + func_set = {func, "Maa"} + + logger.info(f"Bind task {func_set}") + + # Bind arguments + visited = set() + self.bound.clear() + for func in func_set: + func_data = self.data.get(func, {}) + for group, group_data in func_data.items(): + for arg, value in group_data.items(): + path = f"{group}.{arg}" + if path in visited: + continue + arg = path_to_arg(path) + super().__setattr__(arg, value) + self.bound[arg] = f"{func}.{path}" + visited.add(path) + + # Override arguments + for arg, value in self.overridden.items(): + super().__setattr__(arg, value) + + def save(self, mod_name='maa'): + super().save(mod_name) + + def get_mtime(self) -> datetime: + timestamp = os.stat(filepath_config(self.config_name, mod_name='maa')).st_mtime + mtime = datetime.fromtimestamp(timestamp).replace(microsecond=0) + return mtime + + +def load_config(config_name, task): + return ArknightsConfig(config_name, task) diff --git a/submodule/AlasMaaBridge/module/config/config_generated.py b/submodule/AlasMaaBridge/module/config/config_generated.py new file mode 100644 index 000000000..7c39fa55b --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/config_generated.py @@ -0,0 +1,77 @@ +import datetime + +# This file was automatically generated by module/config/config_updater.py. +# Don't modify it manually. + + +class GeneratedConfig: + """ + Auto generated configuration + """ + + # Group `Scheduler` + Scheduler_Enable = False + Scheduler_NextRun = datetime.datetime(2020, 1, 1, 0, 0) + Scheduler_Command = 'Maa' + Scheduler_SuccessInterval = 60 + Scheduler_FailureInterval = 120 + Scheduler_ServerUpdate = '04:00' + + # Group `Emulator` + Emulator_Serial = '127.0.0.1:5555' + Emulator_PackageName = 'Official' # Official, Bilibili + Emulator_Server = 'CN' # CN, US, JP, KR + Emulator_MaaPath = 'D:/Program Files/MAA' + Emulator_ServerName = 'disabled' + + # Group `Record` + Record_ReportToPenguin = False + Record_PenguinID = None + + # Group `Error` + Error_SaveError = False + Error_OnePushConfig = 'provider: null' + + # Group `Optimization` + Optimization_WhenTaskQueueEmpty = 'stay_there' + + # Group `Fight` + Fight_Stage = '1-7' + Fight_Medicine = 0 + Fight_Stone = 0 + Fight_Times = 0 + Fight_Drops = None + Fight_DrGrandet = False + + # Group `Recruit` + Recruit_Refresh = True + Recruit_SkipRobot = True + Recruit_Select3 = True + Recruit_Select4 = True + Recruit_Select5 = True + Recruit_Times = 4 + Recruit_Expedite = False + + # Group `Infrast` + Infrast_Facility = 'Mfg > Trade > Power > Control > Reception > Office > Dorm' + Infrast_Drones = 'Money' # _NotUse, Money, SyntheticJade, CombatRecord, PureGold, OriginStone, Chip + Infrast_Threshold = 0.3 + Infrast_Replenish = False + + # Group `Mall` + Mall_Shopping = True + Mall_BuyFirst = '招聘许可 > 龙门币' + Mall_BlackList = '碳 > 家具' + + # Group `Roguelike` + Roguelike_Mode = 0 # 0, 1 + Roguelike_StartsCount = 9999999 + Roguelike_InvestmentsCount = 9999999 + Roguelike_StopWhenInvestmentFull = False + Roguelike_Squad = '指挥分队' # 指挥分队, 集群分队, 后勤分队, 矛头分队, 突击战术分队, 堡垒战术分队, 远程战术分队, 破坏战术分队, 研究分队, 高规格分队 + Roguelike_Roles = '取长补短' # 先手必胜, 稳扎稳打, 取长补短, 随心所欲 + Roguelike_CoreChar = None + + # Group `Copilot` + Copilot_FileName = None + Copilot_Formation = False diff --git a/submodule/AlasMaaBridge/module/config/config_manual.py b/submodule/AlasMaaBridge/module/config/config_manual.py new file mode 100644 index 000000000..547bbaab5 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/config_manual.py @@ -0,0 +1,33 @@ +from pywebio.io_ctrl import Output + +import module.config.server as server + + +class ManualConfig: + @property + def SERVER(self): + return server.server + + SCHEDULER_PRIORITY = """ + MaaStartup + > MaaRecruit > MaaInfrast + > MaaVisit > MaaMall > MaaAward + > MaaAnnihilation > MaaMaterial + > MaaFight > MaaRoguelike + """ + + """ + module.device + """ + DEVICE_OVER_HTTP = False + FORWARD_PORT_RANGE = (20000, 21000) + REVERSE_SERVER_PORT = 7903 + ASCREENCAP_FILEPATH_LOCAL = './bin/ascreencap' + ASCREENCAP_FILEPATH_REMOTE = '/data/local/tmp/ascreencap' + MINITOUCH_FILEPATH_REMOTE = '/data/local/tmp/minitouch' + HERMIT_FILEPATH_LOCAL = './bin/hermit/hermit.apk' + + +class OutputConfig(Output, ManualConfig): + def __init__(self, spec, on_embed=None): + super().__init__(spec, on_embed) diff --git a/submodule/AlasMaaBridge/module/config/config_updater.py b/submodule/AlasMaaBridge/module/config/config_updater.py new file mode 100644 index 000000000..fae957491 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/config_updater.py @@ -0,0 +1,123 @@ +from cached_property import cached_property + +from module.base.timer import timer +from module.config import config_updater +from module.config.utils import * + + +class ConfigGenerator(config_updater.ConfigGenerator): + @timer + def generate(self): + _ = self.args + _ = self.menu + write_file(filepath_args(), self.args) + write_file(filepath_args('menu'), self.menu) + self.generate_code() + for lang in LANGUAGES: + self.generate_i18n(lang) + + @timer + def generate_i18n(self, lang): + """ + Load old translations and generate new translation file. + + args.json ---+-----> i18n/.json + (old) i18n/.json ---+ + + """ + new = {} + old = read_file(filepath_i18n(lang)) + + def deep_load(keys, default=True, words=('name', 'help')): + for word in words: + k = keys + [str(word)] + d = ".".join(k) if default else str(word) + v = deep_get(old, keys=k, default=d) + deep_set(new, keys=k, value=v) + + # Menu + for path, data in deep_iter(self.menu, depth=2): + func, group = path + deep_load(['Menu', func]) + deep_load(['Menu', group]) + for task in data: + deep_load([func, task]) + # Arguments + visited_group = set() + for path, data in deep_iter(self.argument, depth=2): + if path[0] not in visited_group: + deep_load([path[0], '_info']) + visited_group.add(path[0]) + deep_load(path) + if 'option' in data: + deep_load(path, words=data['option'], default=False) + + # GUI i18n + for path, _ in deep_iter(self.gui, depth=2): + group, key = path + deep_load(keys=['Gui', group], words=(key,)) + + write_file(filepath_i18n(lang), new) + + +class ConfigUpdater(config_updater.ConfigUpdater): + redirection = [] + + @cached_property + def args(self): + return read_file(filepath_args(mod_name='maa')) + + def read_file(self, config_name, is_template=False): + old = read_file(filepath_config(config_name, 'maa')) + return self.config_update(old, is_template=is_template) + + @staticmethod + def write_file(config_name, data, mod_name='maa'): + write_file(filepath_config(config_name, mod_name), data) + + def config_update(self, old, is_template=False): + """ + Args: + old (dict): + is_template (bool): + + Returns: + dict: + """ + new = {} + + def deep_load(keys): + data = deep_get(self.args, keys=keys, default={}) + value = deep_get(old, keys=keys, default=data['value']) + if value is None or value == '' or data['type'] in ['lock'] or is_template: + value = data['value'] + value = parse_value(value, data=data) + deep_set(new, keys=keys, value=value) + + for path, _ in deep_iter(self.args, depth=3): + deep_load(path) + + if not is_template: + new = self.config_redirect(old, new) + + return new + + +if __name__ == '__main__': + """ + Process the whole config generation. + + task.yaml -+----------------> menu.json + argument.yaml -+-> args.json ---> config_generated.py + override.yaml -+ | + gui.yaml --------\| + || + (old) i18n/.json --------\\========> i18n/.json + (old) template.json ---------\========> template.json + """ + # Ensure running in mod root folder + import os + os.chdir('../../') + ConfigGenerator().generate() + os.chdir('../../') + ConfigUpdater().update_file('template', is_template=True) diff --git a/submodule/AlasMaaBridge/module/config/i18n/en-US.json b/submodule/AlasMaaBridge/module/config/i18n/en-US.json new file mode 100644 index 000000000..3dfeafd46 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/i18n/en-US.json @@ -0,0 +1,341 @@ +{ + "Menu": { + "Task": { + "name": "", + "help": "" + }, + "Maa": { + "name": "Menu.Maa.name", + "help": "Menu.Maa.help" + }, + "Tool": { + "name": "Menu.Tool.name", + "help": "Menu.Tool.help" + } + }, + "Task": { + "Maa": { + "name": "Task.Maa.name", + "help": "Task.Maa.help" + }, + "MaaStartup": { + "name": "Task.MaaStartup.name", + "help": "Task.MaaStartup.help" + }, + "MaaAnnihilation": { + "name": "Task.MaaAnnihilation.name", + "help": "Task.MaaAnnihilation.help" + }, + "MaaMaterial": { + "name": "Task.MaaMaterial.name", + "help": "Task.MaaMaterial.help" + }, + "MaaFight": { + "name": "Task.MaaFight.name", + "help": "Task.MaaFight.help" + }, + "MaaRecruit": { + "name": "Task.MaaRecruit.name", + "help": "Task.MaaRecruit.help" + }, + "MaaInfrast": { + "name": "Task.MaaInfrast.name", + "help": "Task.MaaInfrast.help" + }, + "MaaVisit": { + "name": "Task.MaaVisit.name", + "help": "Task.MaaVisit.help" + }, + "MaaMall": { + "name": "Task.MaaMall.name", + "help": "Task.MaaMall.help" + }, + "MaaAward": { + "name": "Task.MaaAward.name", + "help": "Task.MaaAward.help" + }, + "MaaRoguelike": { + "name": "Task.MaaRoguelike.name", + "help": "Task.MaaRoguelike.help" + }, + "MaaCopilot": { + "name": "Task.MaaCopilot.name", + "help": "Task.MaaCopilot.help" + } + }, + "Scheduler": { + "_info": { + "name": "Scheduler", + "help": "" + }, + "Enable": { + "name": "Enable Task", + "help": "Join this task to scheduler.\nTask commission, research, reward are force to enable." + }, + "NextRun": { + "name": "Next Run", + "help": "Updated automatically after completing the task to set next scheduled run, typically not manually modified\nHowever you can force immediate scheduling if you clear this text field" + }, + "Command": { + "name": "Command", + "help": "" + }, + "SuccessInterval": { + "name": "Success Interval", + "help": "After successful, postpone next run for X minutes" + }, + "FailureInterval": { + "name": "Failure Interval", + "help": "After failure, postpone next run for X minutes" + }, + "ServerUpdate": { + "name": "Server Update", + "help": "Series of server refresh time(s) as to when this task will next run, this is automatically converted to respective time zone, generally do not need to modify" + } + }, + "Emulator": { + "_info": { + "name": "Emulator Settings", + "help": "" + }, + "Serial": { + "name": "Serial", + "help": "Use \"auto\" to auto-detect emulators, but serial must be filled if multiple emulators are running\nDefault serial for select emulators:\n- BlueStacks 127.0.0.1:5555\n- BlueStacks4 Hyper-V use \"bluestacks4-hyperv\", \"bluestacks4-hyperv-2\" for multi instance, and so on\n- BlueStacks5 Hyper-V use \"bluestacks5-hyperv\", \"bluestacks5-hyperv-1\" for multi instance, and so on\n- NoxPlayer 127.0.0.1:62001\n- NoxPlayer64bit 127.0.0.1:59865\n- MuMuPlayer 127.0.0.1:7555\n- MemuPlayer 127.0.0.1:21503\n- LDPlayer emulator-5554 or 127.0.0.1:5555\n- WSA use \"wsa-0\" to make the game run in the background, which needs to be controlled or closed by third-party software\nIf there are multiple emulator instances running, the default is reserved for one of them and the others will use different serials to avoid conflicts\nOpen console.bat and run `adb devices` to find what they are" + }, + "PackageName": { + "name": "Game Server", + "help": "Manual select is required if multiple game clients are installed on emulator", + "Official": "Official", + "Bilibili": "Bilibili" + }, + "Server": { + "name": "Emulator.Server.name", + "help": "Emulator.Server.help", + "CN": "CN", + "US": "US", + "JP": "JP", + "KR": "KR" + }, + "MaaPath": { + "name": "Emulator.MaaPath.name", + "help": "Emulator.MaaPath.help" + }, + "ServerName": { + "name": "Emulator.ServerName.name", + "help": "Emulator.ServerName.help" + } + }, + "Record": { + "_info": { + "name": "Record._info.name", + "help": "Record._info.help" + }, + "ReportToPenguin": { + "name": "Record.ReportToPenguin.name", + "help": "Record.ReportToPenguin.help" + }, + "PenguinID": { + "name": "Record.PenguinID.name", + "help": "Record.PenguinID.help" + } + }, + "Error": { + "_info": { + "name": "Error._info.name", + "help": "Error._info.help" + }, + "SaveError": { + "name": "Error.SaveError.name", + "help": "Error.SaveError.help" + }, + "OnePushConfig": { + "name": "Error.OnePushConfig.name", + "help": "Error.OnePushConfig.help" + } + }, + "Optimization": { + "_info": { + "name": "Optimization Settings", + "help": "" + }, + "WhenTaskQueueEmpty": { + "name": "When Task Queue is Empty", + "help": "Close AL when there are no pending tasks, can help reduce CPU" + } + }, + "Fight": { + "_info": { + "name": "Fight._info.name", + "help": "Fight._info.help" + }, + "Stage": { + "name": "Fight.Stage.name", + "help": "Fight.Stage.help" + }, + "Medicine": { + "name": "Fight.Medicine.name", + "help": "Fight.Medicine.help" + }, + "Stone": { + "name": "Fight.Stone.name", + "help": "Fight.Stone.help" + }, + "Times": { + "name": "Fight.Times.name", + "help": "Fight.Times.help" + }, + "Drops": { + "name": "Fight.Drops.name", + "help": "Fight.Drops.help" + }, + "DrGrandet": { + "name": "Fight.DrGrandet.name", + "help": "Fight.DrGrandet.help" + } + }, + "Recruit": { + "_info": { + "name": "Recruit._info.name", + "help": "Recruit._info.help" + }, + "Refresh": { + "name": "Recruit.Refresh.name", + "help": "Recruit.Refresh.help" + }, + "SkipRobot": { + "name": "Recruit.SkipRobot.name", + "help": "Recruit.SkipRobot.help" + }, + "Select3": { + "name": "Recruit.Select3.name", + "help": "Recruit.Select3.help" + }, + "Select4": { + "name": "Recruit.Select4.name", + "help": "Recruit.Select4.help" + }, + "Select5": { + "name": "Recruit.Select5.name", + "help": "Recruit.Select5.help" + }, + "Times": { + "name": "Recruit.Times.name", + "help": "Recruit.Times.help" + }, + "Expedite": { + "name": "Recruit.Expedite.name", + "help": "Recruit.Expedite.help" + } + }, + "Infrast": { + "_info": { + "name": "Infrast._info.name", + "help": "Infrast._info.help" + }, + "Facility": { + "name": "Infrast.Facility.name", + "help": "Infrast.Facility.help" + }, + "Drones": { + "name": "Infrast.Drones.name", + "help": "Infrast.Drones.help", + "_NotUse": "_NotUse", + "Money": "Money", + "SyntheticJade": "SyntheticJade", + "CombatRecord": "CombatRecord", + "PureGold": "PureGold", + "OriginStone": "OriginStone", + "Chip": "Chip" + }, + "Threshold": { + "name": "Infrast.Threshold.name", + "help": "Infrast.Threshold.help" + }, + "Replenish": { + "name": "Infrast.Replenish.name", + "help": "Infrast.Replenish.help" + } + }, + "Mall": { + "_info": { + "name": "Mall._info.name", + "help": "Mall._info.help" + }, + "Shopping": { + "name": "Mall.Shopping.name", + "help": "Mall.Shopping.help" + }, + "BuyFirst": { + "name": "Mall.BuyFirst.name", + "help": "Mall.BuyFirst.help" + }, + "BlackList": { + "name": "Mall.BlackList.name", + "help": "Mall.BlackList.help" + } + }, + "Roguelike": { + "_info": { + "name": "Roguelike._info.name", + "help": "Roguelike._info.help" + }, + "Mode": { + "name": "Roguelike.Mode.name", + "help": "Roguelike.Mode.help", + "0": "0", + "1": "1" + }, + "StartsCount": { + "name": "Roguelike.StartsCount.name", + "help": "Roguelike.StartsCount.help" + }, + "InvestmentsCount": { + "name": "Roguelike.InvestmentsCount.name", + "help": "Roguelike.InvestmentsCount.help" + }, + "StopWhenInvestmentFull": { + "name": "Roguelike.StopWhenInvestmentFull.name", + "help": "Roguelike.StopWhenInvestmentFull.help" + }, + "Squad": { + "name": "Roguelike.Squad.name", + "help": "Roguelike.Squad.help", + "指挥分队": "指挥分队", + "集群分队": "集群分队", + "后勤分队": "后勤分队", + "矛头分队": "矛头分队", + "突击战术分队": "突击战术分队", + "堡垒战术分队": "堡垒战术分队", + "远程战术分队": "远程战术分队", + "破坏战术分队": "破坏战术分队", + "研究分队": "研究分队", + "高规格分队": "高规格分队" + }, + "Roles": { + "name": "Roguelike.Roles.name", + "help": "Roguelike.Roles.help", + "先手必胜": "先手必胜", + "稳扎稳打": "稳扎稳打", + "取长补短": "取长补短", + "随心所欲": "随心所欲" + }, + "CoreChar": { + "name": "Roguelike.CoreChar.name", + "help": "Roguelike.CoreChar.help" + } + }, + "Copilot": { + "_info": { + "name": "Copilot._info.name", + "help": "Copilot._info.help" + }, + "FileName": { + "name": "Copilot.FileName.name", + "help": "Copilot.FileName.help" + }, + "Formation": { + "name": "Copilot.Formation.name", + "help": "Copilot.Formation.help" + } + } +} \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json b/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json new file mode 100644 index 000000000..7c425e8e4 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json @@ -0,0 +1,341 @@ +{ + "Menu": { + "Task": { + "name": "Menu.Task.name", + "help": "Menu.Task.help" + }, + "Maa": { + "name": "Menu.Maa.name", + "help": "Menu.Maa.help" + }, + "Tool": { + "name": "Menu.Tool.name", + "help": "Menu.Tool.help" + } + }, + "Task": { + "Maa": { + "name": "Task.Maa.name", + "help": "Task.Maa.help" + }, + "MaaStartup": { + "name": "Task.MaaStartup.name", + "help": "Task.MaaStartup.help" + }, + "MaaAnnihilation": { + "name": "Task.MaaAnnihilation.name", + "help": "Task.MaaAnnihilation.help" + }, + "MaaMaterial": { + "name": "Task.MaaMaterial.name", + "help": "Task.MaaMaterial.help" + }, + "MaaFight": { + "name": "Task.MaaFight.name", + "help": "Task.MaaFight.help" + }, + "MaaRecruit": { + "name": "Task.MaaRecruit.name", + "help": "Task.MaaRecruit.help" + }, + "MaaInfrast": { + "name": "Task.MaaInfrast.name", + "help": "Task.MaaInfrast.help" + }, + "MaaVisit": { + "name": "Task.MaaVisit.name", + "help": "Task.MaaVisit.help" + }, + "MaaMall": { + "name": "Task.MaaMall.name", + "help": "Task.MaaMall.help" + }, + "MaaAward": { + "name": "Task.MaaAward.name", + "help": "Task.MaaAward.help" + }, + "MaaRoguelike": { + "name": "Task.MaaRoguelike.name", + "help": "Task.MaaRoguelike.help" + }, + "MaaCopilot": { + "name": "Task.MaaCopilot.name", + "help": "Task.MaaCopilot.help" + } + }, + "Scheduler": { + "_info": { + "name": "Scheduler._info.name", + "help": "Scheduler._info.help" + }, + "Enable": { + "name": "Scheduler.Enable.name", + "help": "Scheduler.Enable.help" + }, + "NextRun": { + "name": "Scheduler.NextRun.name", + "help": "Scheduler.NextRun.help" + }, + "Command": { + "name": "Scheduler.Command.name", + "help": "Scheduler.Command.help" + }, + "SuccessInterval": { + "name": "Scheduler.SuccessInterval.name", + "help": "Scheduler.SuccessInterval.help" + }, + "FailureInterval": { + "name": "Scheduler.FailureInterval.name", + "help": "Scheduler.FailureInterval.help" + }, + "ServerUpdate": { + "name": "Scheduler.ServerUpdate.name", + "help": "Scheduler.ServerUpdate.help" + } + }, + "Emulator": { + "_info": { + "name": "Emulator._info.name", + "help": "Emulator._info.help" + }, + "Serial": { + "name": "Emulator.Serial.name", + "help": "Emulator.Serial.help" + }, + "PackageName": { + "name": "Emulator.PackageName.name", + "help": "Emulator.PackageName.help", + "Official": "Official", + "Bilibili": "Bilibili" + }, + "Server": { + "name": "Emulator.Server.name", + "help": "Emulator.Server.help", + "CN": "CN", + "US": "US", + "JP": "JP", + "KR": "KR" + }, + "MaaPath": { + "name": "Emulator.MaaPath.name", + "help": "Emulator.MaaPath.help" + }, + "ServerName": { + "name": "Emulator.ServerName.name", + "help": "Emulator.ServerName.help" + } + }, + "Record": { + "_info": { + "name": "Record._info.name", + "help": "Record._info.help" + }, + "ReportToPenguin": { + "name": "Record.ReportToPenguin.name", + "help": "Record.ReportToPenguin.help" + }, + "PenguinID": { + "name": "Record.PenguinID.name", + "help": "Record.PenguinID.help" + } + }, + "Error": { + "_info": { + "name": "Error._info.name", + "help": "Error._info.help" + }, + "SaveError": { + "name": "Error.SaveError.name", + "help": "Error.SaveError.help" + }, + "OnePushConfig": { + "name": "Error.OnePushConfig.name", + "help": "Error.OnePushConfig.help" + } + }, + "Optimization": { + "_info": { + "name": "Optimization._info.name", + "help": "Optimization._info.help" + }, + "WhenTaskQueueEmpty": { + "name": "Optimization.WhenTaskQueueEmpty.name", + "help": "Optimization.WhenTaskQueueEmpty.help" + } + }, + "Fight": { + "_info": { + "name": "Fight._info.name", + "help": "Fight._info.help" + }, + "Stage": { + "name": "Fight.Stage.name", + "help": "Fight.Stage.help" + }, + "Medicine": { + "name": "Fight.Medicine.name", + "help": "Fight.Medicine.help" + }, + "Stone": { + "name": "Fight.Stone.name", + "help": "Fight.Stone.help" + }, + "Times": { + "name": "Fight.Times.name", + "help": "Fight.Times.help" + }, + "Drops": { + "name": "Fight.Drops.name", + "help": "Fight.Drops.help" + }, + "DrGrandet": { + "name": "Fight.DrGrandet.name", + "help": "Fight.DrGrandet.help" + } + }, + "Recruit": { + "_info": { + "name": "Recruit._info.name", + "help": "Recruit._info.help" + }, + "Refresh": { + "name": "Recruit.Refresh.name", + "help": "Recruit.Refresh.help" + }, + "SkipRobot": { + "name": "Recruit.SkipRobot.name", + "help": "Recruit.SkipRobot.help" + }, + "Select3": { + "name": "Recruit.Select3.name", + "help": "Recruit.Select3.help" + }, + "Select4": { + "name": "Recruit.Select4.name", + "help": "Recruit.Select4.help" + }, + "Select5": { + "name": "Recruit.Select5.name", + "help": "Recruit.Select5.help" + }, + "Times": { + "name": "Recruit.Times.name", + "help": "Recruit.Times.help" + }, + "Expedite": { + "name": "Recruit.Expedite.name", + "help": "Recruit.Expedite.help" + } + }, + "Infrast": { + "_info": { + "name": "Infrast._info.name", + "help": "Infrast._info.help" + }, + "Facility": { + "name": "Infrast.Facility.name", + "help": "Infrast.Facility.help" + }, + "Drones": { + "name": "Infrast.Drones.name", + "help": "Infrast.Drones.help", + "_NotUse": "_NotUse", + "Money": "Money", + "SyntheticJade": "SyntheticJade", + "CombatRecord": "CombatRecord", + "PureGold": "PureGold", + "OriginStone": "OriginStone", + "Chip": "Chip" + }, + "Threshold": { + "name": "Infrast.Threshold.name", + "help": "Infrast.Threshold.help" + }, + "Replenish": { + "name": "Infrast.Replenish.name", + "help": "Infrast.Replenish.help" + } + }, + "Mall": { + "_info": { + "name": "Mall._info.name", + "help": "Mall._info.help" + }, + "Shopping": { + "name": "Mall.Shopping.name", + "help": "Mall.Shopping.help" + }, + "BuyFirst": { + "name": "Mall.BuyFirst.name", + "help": "Mall.BuyFirst.help" + }, + "BlackList": { + "name": "Mall.BlackList.name", + "help": "Mall.BlackList.help" + } + }, + "Roguelike": { + "_info": { + "name": "Roguelike._info.name", + "help": "Roguelike._info.help" + }, + "Mode": { + "name": "Roguelike.Mode.name", + "help": "Roguelike.Mode.help", + "0": "0", + "1": "1" + }, + "StartsCount": { + "name": "Roguelike.StartsCount.name", + "help": "Roguelike.StartsCount.help" + }, + "InvestmentsCount": { + "name": "Roguelike.InvestmentsCount.name", + "help": "Roguelike.InvestmentsCount.help" + }, + "StopWhenInvestmentFull": { + "name": "Roguelike.StopWhenInvestmentFull.name", + "help": "Roguelike.StopWhenInvestmentFull.help" + }, + "Squad": { + "name": "Roguelike.Squad.name", + "help": "Roguelike.Squad.help", + "指挥分队": "指挥分队", + "集群分队": "集群分队", + "后勤分队": "后勤分队", + "矛头分队": "矛头分队", + "突击战术分队": "突击战术分队", + "堡垒战术分队": "堡垒战术分队", + "远程战术分队": "远程战术分队", + "破坏战术分队": "破坏战术分队", + "研究分队": "研究分队", + "高规格分队": "高规格分队" + }, + "Roles": { + "name": "Roguelike.Roles.name", + "help": "Roguelike.Roles.help", + "先手必胜": "先手必胜", + "稳扎稳打": "稳扎稳打", + "取长补短": "取长补短", + "随心所欲": "随心所欲" + }, + "CoreChar": { + "name": "Roguelike.CoreChar.name", + "help": "Roguelike.CoreChar.help" + } + }, + "Copilot": { + "_info": { + "name": "Copilot._info.name", + "help": "Copilot._info.help" + }, + "FileName": { + "name": "Copilot.FileName.name", + "help": "Copilot.FileName.help" + }, + "Formation": { + "name": "Copilot.Formation.name", + "help": "Copilot.Formation.help" + } + } +} \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json new file mode 100644 index 000000000..617cec2b0 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json @@ -0,0 +1,341 @@ +{ + "Menu": { + "Task": { + "name": "", + "help": "" + }, + "Maa": { + "name": "Maa", + "help": "" + }, + "Tool": { + "name": "Menu.Tool.name", + "help": "Menu.Tool.help" + } + }, + "Task": { + "Maa": { + "name": "Maa设置", + "help": "" + }, + "MaaStartup": { + "name": "开始唤醒", + "help": "" + }, + "MaaAnnihilation": { + "name": "剿灭作战", + "help": "" + }, + "MaaMaterial": { + "name": "刷材料", + "help": "" + }, + "MaaFight": { + "name": "刷理智", + "help": "" + }, + "MaaRecruit": { + "name": "自动公招", + "help": "" + }, + "MaaInfrast": { + "name": "基建换班", + "help": "" + }, + "MaaVisit": { + "name": "访问好友", + "help": "" + }, + "MaaMall": { + "name": "收取信用及购物", + "help": "" + }, + "MaaAward": { + "name": "领取日常奖励", + "help": "" + }, + "MaaRoguelike": { + "name": "自动肉鸽", + "help": "" + }, + "MaaCopilot": { + "name": "自动战斗", + "help": "" + } + }, + "Scheduler": { + "_info": { + "name": "任务设置", + "help": "" + }, + "Enable": { + "name": "启用该功能", + "help": "将这个任务加入调度器\n委托、科研、收获任务是强制打开的" + }, + "NextRun": { + "name": "下一次运行时间", + "help": "自动计算的数值,不需要手动修改。清空后将立即运行" + }, + "Command": { + "name": "内部任务名称", + "help": "" + }, + "SuccessInterval": { + "name": "运行成功后,推迟下一次运行 X 分钟", + "help": "" + }, + "FailureInterval": { + "name": "运行失败后,推迟下一次运行 X 分钟", + "help": "" + }, + "ServerUpdate": { + "name": "服务器刷新时间", + "help": "一些任务运行成功后,将推迟下一次运行至服务器刷新时间\n自动换算时区,一般不需要修改" + } + }, + "Emulator": { + "_info": { + "name": "模拟器设置", + "help": "" + }, + "Serial": { + "name": "模拟器 Serial", + "help": "模拟器默认 Serial:\n- 蓝叠模拟器 127.0.0.1:5555\n- 蓝叠模拟器4 Hyper-v版,填\"bluestacks4-hyperv\"自动连接,多开填\"bluestacks4-hyperv-2\"以此类推\n- 蓝叠模拟器5 Hyper-v版,填\"bluestacks5-hyperv\"自动连接,多开填\"bluestacks5-hyperv-1\"以此类推\n- 夜神模拟器 127.0.0.1:62001\n- 夜神模拟器64位 127.0.0.1:59865\n- MuMu模拟器 127.0.0.1:7555\n- 逍遥模拟器 127.0.0.1:21503\n- 雷电模拟器 emulator-5554 或 127.0.0.1:5555\n- WSA,填\"wsa-0\"使游戏在后台运行,需要使用第三方软件操控或关闭(建议使用scrcpy操控)\n如果你有多个模拟器,它们的 Serial 将不是默认的,可以在 console.bat 中执行 `adb devices` 查询" + }, + "PackageName": { + "name": "游戏服务器", + "help": "模拟器上装有多个游戏客户端时,需要手动选择服务器", + "Official": "官服", + "Bilibili": "Bilibili服" + }, + "Server": { + "name": "服务器", + "help": "会影响掉落和上传", + "CN": "CN", + "US": "US", + "JP": "JP", + "KR": "KR" + }, + "MaaPath": { + "name": "MAA安装路径", + "help": "" + }, + "ServerName": { + "name": "游戏内服务器(碧蓝航线)", + "help": "不显示在界面,仅用于和ALAS接轨" + } + }, + "Record": { + "_info": { + "name": "掉落记录", + "help": "" + }, + "ReportToPenguin": { + "name": "上传到企鹅物流", + "help": "" + }, + "PenguinID": { + "name": "企鹅物流ID", + "help": "留空即可,第一次上传后会自动生成" + } + }, + "Error": { + "_info": { + "name": "调试设置", + "help": "" + }, + "SaveError": { + "name": "出错时保存 Log", + "help": "" + }, + "OnePushConfig": { + "name": "Error.OnePushConfig.name", + "help": "不显示在界面,仅用于和ALAS接轨" + } + }, + "Optimization": { + "_info": { + "name": "优化设置", + "help": "" + }, + "WhenTaskQueueEmpty": { + "name": "当任务队列清空后", + "help": "无任务时关闭游戏,能在收菜期间降低 CPU 占用" + } + }, + "Fight": { + "_info": { + "name": "战斗设置", + "help": "" + }, + "Stage": { + "name": "关卡选择", + "help": "" + }, + "Medicine": { + "name": "吃理智药", + "help": "" + }, + "Stone": { + "name": "吃源石", + "help": "" + }, + "Times": { + "name": "指定次数", + "help": "" + }, + "Drops": { + "name": "指定掉落", + "help": "以\"掉落物:数量 > 掉落物:数量\"的形式,支持中文名称和物品ID" + }, + "DrGrandet": { + "name": "节省理智碎石模式", + "help": "在碎石确认界面等待,直到当前的 1 点理智恢复完成后再立刻碎石" + } + }, + "Recruit": { + "_info": { + "name": "公招设置", + "help": "" + }, + "Refresh": { + "name": "自动刷新3星 Tag", + "help": "" + }, + "SkipRobot": { + "name": "手动确认1星", + "help": "" + }, + "Select3": { + "name": "自动确认3星", + "help": "" + }, + "Select4": { + "name": "自动确认4星", + "help": "" + }, + "Select5": { + "name": "自动确认5星", + "help": "" + }, + "Times": { + "name": "最大招募次数", + "help": "" + }, + "Expedite": { + "name": "自动使用加急许可", + "help": "" + } + }, + "Infrast": { + "_info": { + "name": "基建设置", + "help": "" + }, + "Facility": { + "name": "换班设施顺序", + "help": "会影响多功能干员的工作位置" + }, + "Drones": { + "name": "无人机用途", + "help": "", + "_NotUse": "不使用无人机", + "Money": "贸易站-龙门币", + "SyntheticJade": "贸易站-合成玉", + "CombatRecord": "制造站-经验书", + "PureGold": "制造站-赤金", + "OriginStone": "制造站-源石碎片", + "Chip": "制造站-芯片组" + }, + "Threshold": { + "name": "基建工作心情阈值", + "help": "取值范围0 - 1.0" + }, + "Replenish": { + "name": "源石碎片自动补货", + "help": "" + } + }, + "Mall": { + "_info": { + "name": "信用商店", + "help": "" + }, + "Shopping": { + "name": "信用购物", + "help": "" + }, + "BuyFirst": { + "name": "优先购买", + "help": "" + }, + "BlackList": { + "name": "黑名单", + "help": "" + } + }, + "Roguelike": { + "_info": { + "name": "肉鸽设置", + "help": "" + }, + "Mode": { + "name": "策略", + "help": "", + "0": "刷蜡烛", + "1": "刷源石锭" + }, + "StartsCount": { + "name": "开始探索X次后停止任务", + "help": "" + }, + "InvestmentsCount": { + "name": "投资X个源石锭后停止任务", + "help": "" + }, + "StopWhenInvestmentFull": { + "name": "储备源石锭达到上限时停止", + "help": "" + }, + "Squad": { + "name": "开局分队", + "help": "", + "指挥分队": "指挥分队", + "集群分队": "集群分队", + "后勤分队": "后勤分队", + "矛头分队": "矛头分队", + "突击战术分队": "突击战术分队", + "堡垒战术分队": "堡垒战术分队", + "远程战术分队": "远程战术分队", + "破坏战术分队": "破坏战术分队", + "研究分队": "研究分队", + "高规格分队": "高规格分队" + }, + "Roles": { + "name": "开局职业组", + "help": "", + "先手必胜": "先手必胜", + "稳扎稳打": "稳扎稳打", + "取长补短": "取长补短", + "随心所欲": "随心所欲" + }, + "CoreChar": { + "name": "开局干员", + "help": "仅支持单个干员中文名,不填写则默认选择" + } + }, + "Copilot": { + "_info": { + "name": "作业设置", + "help": "请在有“开始行动”界面的按钮使用本功能\n更多作业下载见https://prts.plus/" + }, + "FileName": { + "name": "作业路径", + "help": "" + }, + "Formation": { + "name": "自动编队", + "help": "" + } + } +} \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json b/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json new file mode 100644 index 000000000..1f155e014 --- /dev/null +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json @@ -0,0 +1,341 @@ +{ + "Menu": { + "Task": { + "name": "", + "help": "" + }, + "Maa": { + "name": "Menu.Maa.name", + "help": "Menu.Maa.help" + }, + "Tool": { + "name": "Menu.Tool.name", + "help": "Menu.Tool.help" + } + }, + "Task": { + "Maa": { + "name": "Task.Maa.name", + "help": "Task.Maa.help" + }, + "MaaStartup": { + "name": "Task.MaaStartup.name", + "help": "Task.MaaStartup.help" + }, + "MaaAnnihilation": { + "name": "Task.MaaAnnihilation.name", + "help": "Task.MaaAnnihilation.help" + }, + "MaaMaterial": { + "name": "Task.MaaMaterial.name", + "help": "Task.MaaMaterial.help" + }, + "MaaFight": { + "name": "Task.MaaFight.name", + "help": "Task.MaaFight.help" + }, + "MaaRecruit": { + "name": "Task.MaaRecruit.name", + "help": "Task.MaaRecruit.help" + }, + "MaaInfrast": { + "name": "Task.MaaInfrast.name", + "help": "Task.MaaInfrast.help" + }, + "MaaVisit": { + "name": "Task.MaaVisit.name", + "help": "Task.MaaVisit.help" + }, + "MaaMall": { + "name": "Task.MaaMall.name", + "help": "Task.MaaMall.help" + }, + "MaaAward": { + "name": "Task.MaaAward.name", + "help": "Task.MaaAward.help" + }, + "MaaRoguelike": { + "name": "Task.MaaRoguelike.name", + "help": "Task.MaaRoguelike.help" + }, + "MaaCopilot": { + "name": "Task.MaaCopilot.name", + "help": "Task.MaaCopilot.help" + } + }, + "Scheduler": { + "_info": { + "name": "任務設定", + "help": "" + }, + "Enable": { + "name": "啟用該功能", + "help": "將這個任務加入調度器\n委託、科研、收穫任務是強制打開的" + }, + "NextRun": { + "name": "下一次執行時間", + "help": "自動計算的數值,不需要手動修改。清空後將立刻執行" + }, + "Command": { + "name": "內部任務名稱", + "help": "" + }, + "SuccessInterval": { + "name": "執行成功後,推遲下一次執行 X 分鐘", + "help": "" + }, + "FailureInterval": { + "name": "執行失敗後,推遲下一次執行 X 分鐘", + "help": "" + }, + "ServerUpdate": { + "name": "伺服器更新時間", + "help": "一些任務執行成功後,將推遲下一次執行伺服器更新的時間\n自動換算時區,一般不需要修改" + } + }, + "Emulator": { + "_info": { + "name": "模擬器設定", + "help": "" + }, + "Serial": { + "name": "模擬器 Serial", + "help": "填 \"auto\" 自動檢測模擬器,有多個模擬器正在運行時必須手動填寫 Serial\n模擬器預設 Serial:\n- 藍疊模擬器 127.0.0.1:5555\n- 藍疊模擬器4 Hyper-v版,填\"bluestacks4-hyperv\"自動連接,多開填\"bluestacks4-hyperv-2\"以此類推\n- 藍疊模擬器5 Hyper-v版,填\"bluestacks5-hyperv\"自動連接,多開填\"bluestacks5-hyperv-1\"以此類推\n- 夜神模擬器 127.0.0.1:62001\n- 夜神模擬器64位元 127.0.0.1:59865\n- MuMu模擬器 127.0.0.1:7555\n- 逍遙模擬器 127.0.0.1:21503\n- 雷電模擬器 emulator-5554 或 127.0.0.1:5555\n- WSA,填\"wsa-0\"使遊戲在後臺運行,需要使用第三方軟件操控或關閉\n如果你有多個模擬器,他們的 Serial 將不是預設的,可以在 console.bat 中執行 `adb devices` 查詢" + }, + "PackageName": { + "name": "遊戲伺服器", + "help": "模擬器上裝有多個遊戲客戶端時,需要手動選擇伺服器", + "Official": "Official", + "Bilibili": "Bilibili" + }, + "Server": { + "name": "Emulator.Server.name", + "help": "Emulator.Server.help", + "CN": "CN", + "US": "US", + "JP": "JP", + "KR": "KR" + }, + "MaaPath": { + "name": "Emulator.MaaPath.name", + "help": "Emulator.MaaPath.help" + }, + "ServerName": { + "name": "Emulator.ServerName.name", + "help": "Emulator.ServerName.help" + } + }, + "Record": { + "_info": { + "name": "Record._info.name", + "help": "Record._info.help" + }, + "ReportToPenguin": { + "name": "Record.ReportToPenguin.name", + "help": "Record.ReportToPenguin.help" + }, + "PenguinID": { + "name": "Record.PenguinID.name", + "help": "Record.PenguinID.help" + } + }, + "Error": { + "_info": { + "name": "Error._info.name", + "help": "Error._info.help" + }, + "SaveError": { + "name": "Error.SaveError.name", + "help": "Error.SaveError.help" + }, + "OnePushConfig": { + "name": "Error.OnePushConfig.name", + "help": "Error.OnePushConfig.help" + } + }, + "Optimization": { + "_info": { + "name": "優化設定", + "help": "" + }, + "WhenTaskQueueEmpty": { + "name": "當任務隊列清空後", + "help": "無任務時關閉遊戲,能在收菜期間降低 CPU 佔用" + } + }, + "Fight": { + "_info": { + "name": "Fight._info.name", + "help": "Fight._info.help" + }, + "Stage": { + "name": "Fight.Stage.name", + "help": "Fight.Stage.help" + }, + "Medicine": { + "name": "Fight.Medicine.name", + "help": "Fight.Medicine.help" + }, + "Stone": { + "name": "Fight.Stone.name", + "help": "Fight.Stone.help" + }, + "Times": { + "name": "Fight.Times.name", + "help": "Fight.Times.help" + }, + "Drops": { + "name": "Fight.Drops.name", + "help": "Fight.Drops.help" + }, + "DrGrandet": { + "name": "Fight.DrGrandet.name", + "help": "Fight.DrGrandet.help" + } + }, + "Recruit": { + "_info": { + "name": "Recruit._info.name", + "help": "Recruit._info.help" + }, + "Refresh": { + "name": "Recruit.Refresh.name", + "help": "Recruit.Refresh.help" + }, + "SkipRobot": { + "name": "Recruit.SkipRobot.name", + "help": "Recruit.SkipRobot.help" + }, + "Select3": { + "name": "Recruit.Select3.name", + "help": "Recruit.Select3.help" + }, + "Select4": { + "name": "Recruit.Select4.name", + "help": "Recruit.Select4.help" + }, + "Select5": { + "name": "Recruit.Select5.name", + "help": "Recruit.Select5.help" + }, + "Times": { + "name": "Recruit.Times.name", + "help": "Recruit.Times.help" + }, + "Expedite": { + "name": "Recruit.Expedite.name", + "help": "Recruit.Expedite.help" + } + }, + "Infrast": { + "_info": { + "name": "Infrast._info.name", + "help": "Infrast._info.help" + }, + "Facility": { + "name": "Infrast.Facility.name", + "help": "Infrast.Facility.help" + }, + "Drones": { + "name": "Infrast.Drones.name", + "help": "Infrast.Drones.help", + "_NotUse": "_NotUse", + "Money": "Money", + "SyntheticJade": "SyntheticJade", + "CombatRecord": "CombatRecord", + "PureGold": "PureGold", + "OriginStone": "OriginStone", + "Chip": "Chip" + }, + "Threshold": { + "name": "Infrast.Threshold.name", + "help": "Infrast.Threshold.help" + }, + "Replenish": { + "name": "Infrast.Replenish.name", + "help": "Infrast.Replenish.help" + } + }, + "Mall": { + "_info": { + "name": "Mall._info.name", + "help": "Mall._info.help" + }, + "Shopping": { + "name": "Mall.Shopping.name", + "help": "Mall.Shopping.help" + }, + "BuyFirst": { + "name": "Mall.BuyFirst.name", + "help": "Mall.BuyFirst.help" + }, + "BlackList": { + "name": "Mall.BlackList.name", + "help": "Mall.BlackList.help" + } + }, + "Roguelike": { + "_info": { + "name": "Roguelike._info.name", + "help": "Roguelike._info.help" + }, + "Mode": { + "name": "Roguelike.Mode.name", + "help": "Roguelike.Mode.help", + "0": "0", + "1": "1" + }, + "StartsCount": { + "name": "Roguelike.StartsCount.name", + "help": "Roguelike.StartsCount.help" + }, + "InvestmentsCount": { + "name": "Roguelike.InvestmentsCount.name", + "help": "Roguelike.InvestmentsCount.help" + }, + "StopWhenInvestmentFull": { + "name": "Roguelike.StopWhenInvestmentFull.name", + "help": "Roguelike.StopWhenInvestmentFull.help" + }, + "Squad": { + "name": "Roguelike.Squad.name", + "help": "Roguelike.Squad.help", + "指挥分队": "指挥分队", + "集群分队": "集群分队", + "后勤分队": "后勤分队", + "矛头分队": "矛头分队", + "突击战术分队": "突击战术分队", + "堡垒战术分队": "堡垒战术分队", + "远程战术分队": "远程战术分队", + "破坏战术分队": "破坏战术分队", + "研究分队": "研究分队", + "高规格分队": "高规格分队" + }, + "Roles": { + "name": "Roguelike.Roles.name", + "help": "Roguelike.Roles.help", + "先手必胜": "先手必胜", + "稳扎稳打": "稳扎稳打", + "取长补短": "取长补短", + "随心所欲": "随心所欲" + }, + "CoreChar": { + "name": "Roguelike.CoreChar.name", + "help": "Roguelike.CoreChar.help" + } + }, + "Copilot": { + "_info": { + "name": "Copilot._info.name", + "help": "Copilot._info.help" + }, + "FileName": { + "name": "Copilot.FileName.name", + "help": "Copilot.FileName.help" + }, + "Formation": { + "name": "Copilot.Formation.name", + "help": "Copilot.Formation.help" + } + } +} \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/handler/handler.py b/submodule/AlasMaaBridge/module/handler/handler.py new file mode 100644 index 000000000..423a41d2b --- /dev/null +++ b/submodule/AlasMaaBridge/module/handler/handler.py @@ -0,0 +1,226 @@ +import os +import sys +import time +from importlib import import_module +from typing import Any + +from module.base.timer import Timer +from module.config.utils import read_file +from module.exception import RequestHumanTakeover +from module.logger import logger + +from submodule.AlasMaaBridge.module.config.config import ArknightsConfig + + +class AssistantHandler: + config: ArknightsConfig + Asst: Any + Message: Any + ASST_HANDLER: Any + + @staticmethod + def load(path): + sys.path.append(path) + asst_module = import_module('.asst', 'Python') + AssistantHandler.Asst = asst_module.Asst + AssistantHandler.Message = asst_module.Message + AssistantHandler.Asst.load(path) + AssistantHandler.ASST_HANDLER = None + + def __init__(self, config, asst, task=None): + """ + Args: + config (ArknightsConfig, str): Name of the user config under ./config + asst (Asst): + task (str): Bind a task only for dev purpose. Usually to be None for auto task scheduling. + """ + if isinstance(config, str): + self.config = ArknightsConfig(config, task=task) + else: + self.config = config + self.interval_timer = {} + AssistantHandler.ASST_HANDLER = self + self.asst = asst + self.callback_timer = Timer(3600) + self.signal = None + self.params = None + self.task_id = None + self.callback_list = [] + + @staticmethod + def split_filter(string, sep='>'): + return [f.strip(' \t\r\n') for f in string.split(sep)] + + def maa_start(self, task_name, params): + self.task_id = self.asst.append_task(task_name, params) + self.params = params + self.callback_list.append(self.generic_callback) + self.callback_timer.reset() + self.asst.start() + while 1: + if self.callback_timer.reached(): + logger.critical('MAA no respond, probably stuck') + raise RequestHumanTakeover + + if self.signal == self.Message.AllTasksCompleted: + self.signal = None + self.task_id = None + self.callback_list.clear() + self.asst.stop() + return + + time.sleep(0.5) + + def generic_callback(self, m, d): + if m == self.Message.AllTasksCompleted: + self.signal = self.Message.AllTasksCompleted + + def penguin_id_callback(self, m, d): + if not self.config.Record_PenguinID \ + and m == self.Message.SubTaskExtraInfo \ + and d.get('what') == 'PenguinId': + self.config.Record_PenguinID = d["details"]["id"] + self.params["penguin_id"] = self.config.Record_PenguinID + self.asst.set_task_params(self.task_id, self.params) + self.callback_list.remove(self.penguin_id_callback) + + def annihilation_callback(self, m, d): + if m == self.Message.SubTaskError: + self.signal = self.Message.AllTasksCompleted + + def startup(self): + self.maa_start('StartUp', { + "client_type": self.config.Emulator_PackageName, + "start_game_enabled": True + }) + self.config.task_delay(server_update=True) + + def fight(self): + args = { + "stage": self.config.Fight_Stage, + "report_to_penguin": self.config.Record_ReportToPenguin, + "server": self.config.Emulator_Server, + "client_type": self.config.Emulator_PackageName, + "DrGrandet": self.config.Fight_DrGrandet, + } + + if self.config.Fight_Medicine != 0: + args["medicine"] = self.config.Fight_Medicine + if self.config.Fight_Stone != 0: + args["stone"] = self.config.Fight_Stone + if self.config.Fight_Times != 0: + args["times"] = self.config.Fight_Times + + if self.config.Fight_Drops: + old = read_file(os.path.join(self.config.Emulator_MaaPath, './resource/item_index.json')) + new = {} + for key, value in old.items(): + new[value['name']] = key + drops = {} + drops_filter = self.split_filter(self.config.Fight_Drops) + for drop in drops_filter: + drop = self.split_filter(drop, sep=':') + try: + drops[new[drop[0]]] = int(drop[1]) + except KeyError: + drops[drop[0]] = int(drop[1]) + args['drops'] = drops + + if self.config.Record_ReportToPenguin and self.config.Record_PenguinID: + args["penguin_id"] = self.config.Record_PenguinID + elif self.config.Record_ReportToPenguin and not self.config.Record_PenguinID: + self.callback_list.append(self.penguin_id_callback) + + if self.config.task.command == 'MaaAnnihilation': + self.callback_list.append(self.annihilation_callback) + + self.maa_start('Fight', args) + + if self.config.task.command == 'MaaAnnihilation': + self.config.task_delay(server_update=True) + elif self.config.task.command == 'MaaMaterial': + self.config.Scheduler_Enable = False + else: + self.config.task_delay(success=True) + + def recruit(self): + select = [] + if self.config.Recruit_Select3: + select.append(3) + if self.config.Recruit_Select4: + select.append(4) + if self.config.Recruit_Select5: + select.append(5) + + args = { + "refresh": self.config.Recruit_Refresh, + "select": select, + "confirm": select, + "times": self.config.Recruit_Times, + "expedite": self.config.Recruit_Expedite, + "skip_robot": self.config.Recruit_SkipRobot + } + + if self.config.Record_ReportToPenguin and self.config.Record_PenguinID: + args["penguin_id"] = self.config.Record_PenguinID + elif self.config.Record_ReportToPenguin and not self.config.Record_PenguinID: + self.callback_list.append(self.penguin_id_callback) + + self.maa_start('Recruit', args) + self.config.task_delay(success=True) + + def infrast(self): + facility = self.split_filter(self.config.Infrast_Facility) + self.maa_start('Infrast', { + "facility": facility, + "drones": self.config.Infrast_Drones, + "threshold": self.config.Infrast_Threshold + }) + self.config.task_delay(success=True) + + def visit(self): + self.maa_start('Visit', { + "enable": True + }) + self.config.task_delay(server_update=True) + + def mall(self): + buy_first = self.split_filter(self.config.Mall_BuyFirst) + blacklist = self.split_filter(self.config.Mall_BlackList) + self.maa_start('Mall', { + "shopping": self.config.Mall_Shopping, + "buy_first": buy_first, + "blacklist": blacklist + }) + self.config.task_delay(server_update=True) + + def award(self): + self.maa_start('Award', { + "enable": True + }) + self.config.task_delay(server_update=True) + + def roguelike(self): + args = { + "mode": self.config.Roguelike_Mode, + "starts_count": self.config.Roguelike_StartsCount, + "investments_count": self.config.Roguelike_InvestmentsCount, + "stop_when_investment_full": self.config.Roguelike_StopWhenInvestmentFull, + "squad": self.config.Roguelike_Squad, + "roles": self.config.Roguelike_Roles + } + if self.config.Roguelike_CoreChar: + args["core_char"] = self.config.Roguelike_CoreChar + + self.maa_start('Roguelike', args) + self.config.task_delay(success=True) + + def copilot(self): + path = self.config.Copilot_FileName + homework = read_file(path) + + self.maa_start('Copilot', { + "stage_name": homework['stage_name'], + "filename": path, + "formation": self.config.Copilot_Formation + }) From 51582cdcb493fe9a4e71a282ffab71c98267a384 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Tue, 13 Sep 2022 16:41:01 +0800 Subject: [PATCH 09/21] Upd: Remove option in deploy.yaml --- config/deploy.template-AidLux-cn.yaml | 3 --- config/deploy.template-AidLux.yaml | 3 --- config/deploy.template-cn.yaml | 3 --- config/deploy.template-docker-cn.yaml | 3 --- config/deploy.template-docker.yaml | 3 --- config/deploy.template.yaml | 3 --- deploy/config.py | 3 --- deploy/git.py | 15 --------------- deploy/template | 3 --- 9 files changed, 39 deletions(-) diff --git a/config/deploy.template-AidLux-cn.yaml b/config/deploy.template-AidLux-cn.yaml index c2fd55dac..81368a621 100644 --- a/config/deploy.template-AidLux-cn.yaml +++ b/config/deploy.template-AidLux-cn.yaml @@ -25,9 +25,6 @@ Deploy: # [Other] Use false KeepLocalChanges: false - Plugins: - MaaAssistantArknights: false - Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template-AidLux.yaml b/config/deploy.template-AidLux.yaml index 735a76317..b12c6f38e 100644 --- a/config/deploy.template-AidLux.yaml +++ b/config/deploy.template-AidLux.yaml @@ -25,9 +25,6 @@ Deploy: # [Other] Use false KeepLocalChanges: false - Plugins: - MaaAssistantArknights: false - Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template-cn.yaml b/config/deploy.template-cn.yaml index d5f1af92a..16cb831aa 100644 --- a/config/deploy.template-cn.yaml +++ b/config/deploy.template-cn.yaml @@ -25,9 +25,6 @@ Deploy: # [Other] Use false KeepLocalChanges: false - Plugins: - MaaAssistantArknights: false - Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template-docker-cn.yaml b/config/deploy.template-docker-cn.yaml index 953f30476..0a2e0ceb2 100644 --- a/config/deploy.template-docker-cn.yaml +++ b/config/deploy.template-docker-cn.yaml @@ -25,9 +25,6 @@ Deploy: # [Other] Use false KeepLocalChanges: false - Plugins: - MaaAssistantArknights: false - Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template-docker.yaml b/config/deploy.template-docker.yaml index dce8a0ae9..1454a3e86 100644 --- a/config/deploy.template-docker.yaml +++ b/config/deploy.template-docker.yaml @@ -25,9 +25,6 @@ Deploy: # [Other] Use false KeepLocalChanges: false - Plugins: - MaaAssistantArknights: false - Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/config/deploy.template.yaml b/config/deploy.template.yaml index 9a0fca340..0669a55ce 100644 --- a/config/deploy.template.yaml +++ b/config/deploy.template.yaml @@ -25,9 +25,6 @@ Deploy: # [Other] Use false KeepLocalChanges: false - Plugins: - MaaAssistantArknights: false - Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' diff --git a/deploy/config.py b/deploy/config.py index 6ac64b03f..cc9a42b49 100644 --- a/deploy/config.py +++ b/deploy/config.py @@ -18,9 +18,6 @@ class ConfigModel: AutoUpdate: bool = True KeepLocalChanges: bool = False - # Plugins - MaaAssistantArknights: bool = False - # Python PythonExecutable: str = "./toolkit/python.exe" PypiMirror: Optional[bool] = None diff --git a/deploy/git.py b/deploy/git.py index cda03c91b..91159f0f9 100644 --- a/deploy/git.py +++ b/deploy/git.py @@ -68,18 +68,3 @@ class GitManager(DeployConfig): proxy=self.GitProxy, keep_changes=self.KeepLocalChanges, ) - logger.hr('Update Submodule', 0) - if self.MaaAssistantArknights: - repo = 'https://github.com/SaiCateDoan/AlasMaaBridge' - folder = './submodule/AlasMaaBridge' - os.makedirs(folder, exist_ok=True) - prev = os.getcwd() - os.chdir(folder) - self.git_repository_init( - repo=repo, - source='origin', - branch='master', - proxy=self.GitProxy, - keep_changes=self.KeepLocalChanges - ) - os.chdir(prev) diff --git a/deploy/template b/deploy/template index e28f4f682..5b029e40c 100644 --- a/deploy/template +++ b/deploy/template @@ -25,9 +25,6 @@ Deploy: # [Other] Use false KeepLocalChanges: false - Plugins: - MaaAssistantArknights: false - Python: # Filepath of python executable `python.exe` # [Easy installer] Use './toolkit/python.exe' From 4372c81fcd3331d040fc55fa7ecb1b805ba60216 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Tue, 13 Sep 2022 19:35:12 +0800 Subject: [PATCH 10/21] Upd: Revert change of config and scheduler --- alas.py | 290 +++++++++--------- module/config/config.py | 186 +++-------- module/submodule/submodule.py | 1 - module/submodule/utils.py | 23 +- module/webui/process_manager.py | 6 +- submodule/AlasMaaBridge/maa.py | 21 +- .../AlasMaaBridge/module/config/config.py | 49 +-- .../module/config/config_manual.py | 33 -- 8 files changed, 233 insertions(+), 376 deletions(-) delete mode 100644 submodule/AlasMaaBridge/module/config/config_manual.py diff --git a/alas.py b/alas.py index 7084061bf..c5f8211f0 100644 --- a/alas.py +++ b/alas.py @@ -15,7 +15,7 @@ from module.logger import logger from module.notify import handle_notify -class AutoScriptScheduler: +class AzurLaneAutoScript: stop_event: threading.Event = None def __init__(self, config_name='alas'): @@ -59,8 +59,7 @@ class AutoScriptScheduler: def run(self, command): try: - if self.device: - self.device.screenshot() + self.device.screenshot() self.__getattribute__(command)() return True except TaskEnd: @@ -157,151 +156,6 @@ class AutoScriptScheduler: with open(f'{folder}/log.txt', 'w', encoding='utf-8') as f: f.writelines(lines) - def wait_until(self, future): - """ - Wait until a specific time. - - Args: - future (datetime): - - Returns: - bool: True if wait finished, False if config changed. - """ - future = future + timedelta(seconds=1) - self.config.start_watching() - while 1: - if datetime.now() > future: - return True - if self.stop_event is not None: - if self.stop_event.is_set(): - logger.info("Update event detected") - logger.info(f"[{self.config_name}] exited. Reason: Update") - exit(0) - - time.sleep(5) - - if self.config.should_reload(): - return False - - def get_next_task(self): - """ - Returns: - str: Name of the next task. - """ - while 1: - task = self.config.get_next() - self.config.task = task - self.config.bind(task) - - from module.base.resource import release_resources - if self.config.task.command != 'Alas': - release_resources(next_task=task.command) - - if task.next_run > datetime.now(): - logger.info(f'Wait until {task.next_run} for task `{task.command}`') - method = self.config.Optimization_WhenTaskQueueEmpty - if method == 'close_game': - logger.info('Close game during wait') - self.device.app_stop() - release_resources() - if not self.wait_until(task.next_run): - del self.__dict__['config'] - continue - self.run('start') - elif method == 'goto_main': - logger.info('Goto main page during wait') - self.run('goto_main') - release_resources() - if not self.wait_until(task.next_run): - del self.__dict__['config'] - continue - elif method == 'stay_there': - logger.info('Stay there during wait') - release_resources() - if not self.wait_until(task.next_run): - del self.__dict__['config'] - continue - else: - logger.warning(f'Invalid Optimization_WhenTaskQueueEmpty: {method}, fallback to stay_there') - release_resources() - if not self.wait_until(task.next_run): - del self.__dict__['config'] - continue - break - - AzurLaneConfig.is_hoarding_task = False - return task.command - - def loop(self): - logger.set_file_logger(self.config_name) - logger.info(f'Start scheduler loop: {self.config_name}') - is_first = True - failure_record = {} - - while 1: - # Check update event from GUI - if self.stop_event is not None: - if self.stop_event.is_set(): - logger.info("Update event detected") - logger.info(f"Alas [{self.config_name}] exited.") - break - # Check game server maintenance - self.checker.wait_until_available() - if self.checker.is_recovered(): - # There is an accidental bug hard to reproduce - # Sometimes, config won't be updated due to blocking - # even though it has been changed - # So update it once recovered - del_cached_property(self, 'config') - logger.info('Server or network is recovered. Restart game client') - self.config.task_call('Restart') - # Get task - task = self.get_next_task() - # Init device and change server - _ = self.device - # Skip first restart - if is_first and task == 'Restart': - logger.info('Skip task `Restart` at scheduler start') - self.config.task_delay(server_update=True) - del self.__dict__['config'] - continue - - # Run - logger.info(f'Scheduler: Start task `{task}`') - if self.device: - self.device.stuck_record_clear() - self.device.click_record_clear() - logger.hr(task, level=0) - success = self.run(inflection.underscore(task)) - logger.info(f'Scheduler: End task `{task}`') - is_first = False - - # Check failures - failed = deep_get(failure_record, keys=task, default=0) - failed = 0 if success else failed + 1 - deep_set(failure_record, keys=task, value=failed) - if failed >= 3: - logger.critical(f"Task `{task}` failed 3 or more times.") - logger.critical("Possible reason #1: You haven't used it correctly. " - "Please read the help text of the options.") - logger.critical("Possible reason #2: There is a problem with this task. " - "Please contact developers or try to fix it yourself.") - logger.critical('Request human takeover') - exit(1) - - if success: - del self.__dict__['config'] - continue - elif self.config.Error_HandleError: - # self.config.task_delay(success=False) - del self.__dict__['config'] - self.checker.check_now() - continue - else: - break - - -class AzurLaneAutoScript(AutoScriptScheduler): def restart(self): from module.handler.login import LoginHandler LoginHandler(self.config, device=self.device).app_restart() @@ -518,6 +372,146 @@ class AzurLaneAutoScript(AutoScriptScheduler): GemsFarming(config=self.config, device=self.device).run( name=self.config.Campaign_Name, folder=self.config.Campaign_Event, mode=self.config.Campaign_Mode) + def wait_until(self, future): + """ + Wait until a specific time. + Args: + future (datetime): + Returns: + bool: True if wait finished, False if config changed. + """ + future = future + timedelta(seconds=1) + self.config.start_watching() + while 1: + if datetime.now() > future: + return True + if self.stop_event is not None: + if self.stop_event.is_set(): + logger.info("Update event detected") + logger.info(f"[{self.config_name}] exited. Reason: Update") + exit(0) + + time.sleep(5) + + if self.config.should_reload(): + return False + + def get_next_task(self): + """ + Returns: + str: Name of the next task. + """ + while 1: + task = self.config.get_next() + self.config.task = task + self.config.bind(task) + + from module.base.resource import release_resources + if self.config.task.command != 'Alas': + release_resources(next_task=task.command) + + if task.next_run > datetime.now(): + logger.info(f'Wait until {task.next_run} for task `{task.command}`') + method = self.config.Optimization_WhenTaskQueueEmpty + if method == 'close_game': + logger.info('Close game during wait') + self.device.app_stop() + release_resources() + if not self.wait_until(task.next_run): + del self.__dict__['config'] + continue + self.run('start') + elif method == 'goto_main': + logger.info('Goto main page during wait') + self.run('goto_main') + release_resources() + if not self.wait_until(task.next_run): + del self.__dict__['config'] + continue + elif method == 'stay_there': + logger.info('Stay there during wait') + release_resources() + if not self.wait_until(task.next_run): + del self.__dict__['config'] + continue + else: + logger.warning(f'Invalid Optimization_WhenTaskQueueEmpty: {method}, fallback to stay_there') + release_resources() + if not self.wait_until(task.next_run): + del self.__dict__['config'] + continue + break + + AzurLaneConfig.is_hoarding_task = False + return task.command + + def loop(self): + logger.set_file_logger(self.config_name) + logger.info(f'Start scheduler loop: {self.config_name}') + is_first = True + failure_record = {} + + while 1: + # Check update event from GUI + if self.stop_event is not None: + if self.stop_event.is_set(): + logger.info("Update event detected") + logger.info(f"Alas [{self.config_name}] exited.") + break + # Check game server maintenance + self.checker.wait_until_available() + if self.checker.is_recovered(): + # There is an accidental bug hard to reproduce + # Sometimes, config won't be updated due to blocking + # even though it has been changed + # So update it once recovered + del_cached_property(self, 'config') + logger.info('Server or network is recovered. Restart game client') + self.config.task_call('Restart') + # Get task + task = self.get_next_task() + # Init device and change server + _ = self.device + # Skip first restart + if is_first and task == 'Restart': + logger.info('Skip task `Restart` at scheduler start') + self.config.task_delay(server_update=True) + del self.__dict__['config'] + continue + + # Run + logger.info(f'Scheduler: Start task `{task}`') + self.device.stuck_record_clear() + self.device.click_record_clear() + logger.hr(task, level=0) + success = self.run(inflection.underscore(task)) + logger.info(f'Scheduler: End task `{task}`') + is_first = False + + # Check failures + failed = deep_get(failure_record, keys=task, default=0) + failed = 0 if success else failed + 1 + deep_set(failure_record, keys=task, value=failed) + if failed >= 3: + logger.critical(f"Task `{task}` failed 3 or more times.") + logger.critical("Possible reason #1: You haven't used it correctly. " + "Please read the help text of the options.") + logger.critical("Possible reason #2: There is a problem with this task. " + "Please contact developers or try to fix it yourself.") + logger.critical('Request human takeover') + exit(1) + + if success: + del self.__dict__['config'] + continue + elif self.config.Error_HandleError: + # self.config.task_delay(success=False) + del self.__dict__['config'] + self.checker.check_now() + continue + else: + break + if __name__ == '__main__': alas = AzurLaneAutoScript() diff --git a/module/config/config.py b/module/config/config.py index a5101ce67..e96fe3bb1 100644 --- a/module/config/config.py +++ b/module/config/config.py @@ -46,7 +46,6 @@ def name_to_function(name): """ Args: name (str): - Returns: Function: """ @@ -56,7 +55,7 @@ def name_to_function(name): return function -class GeneralConfig(ConfigWatcher): +class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher): stop_event: threading.Event = None bound = {} @@ -120,14 +119,17 @@ class GeneralConfig(ConfigWatcher): for path, value in self.modified.items(): deep_set(self.data, keys=path, value=value) - def bind(self, func): + def bind(self, func, func_set=None): """ Args: func (str, Function): Function to run + func_set (set): Set of tasks to be bound """ + if func_set is None: + func_set = {"General", "Alas"} if isinstance(func, Function): func = func.command - func_set = {func, "General", "Alas"} + func_set.add(func) if func.startswith("Opsi"): func_set.add("OpsiGeneral") if ( @@ -316,7 +318,6 @@ class GeneralConfig(ConfigWatcher): def multi_set(self): """ Set multiple arguments but save once. - Examples: with self.config.multi_set(): self.config.foo1 = 1 @@ -327,11 +328,9 @@ class GeneralConfig(ConfigWatcher): def cross_get(self, keys, default=None): """ Get configs from other tasks - Args: keys (str, list[str]): Such as `{task}.Scheduler.Enable` default: - Returns: Any: """ @@ -340,11 +339,9 @@ class GeneralConfig(ConfigWatcher): def cross_set(self, keys, value): """ Set configs to other tasks - Args: keys (str, list[str]): Such as `{task}.Scheduler.Enable` value (Any): - Returns: Any: """ @@ -357,7 +354,6 @@ class GeneralConfig(ConfigWatcher): Set Scheduler.NextRun Should set at least one arguments. If multiple arguments are set, use the nearest. - Args: success (bool): If True, delay Scheduler.SuccessInterval @@ -416,134 +412,9 @@ class GeneralConfig(ConfigWatcher): "Missing argument in delay_next_run, should set at least one" ) - def task_call(self, task, force_call=True): - """ - Call another task to run. - - That task will run when current task finished. - But it might not be run because: - - Other tasks should run first according to SCHEDULER_PRIORITY - - Task is disabled by user - - Args: - task (str): Task name to call, such as `Restart` - force_call (bool): - - Returns: - bool: If called. - """ - if deep_get(self.data, keys=f"{task}.Scheduler.NextRun", default=None) is None: - raise ScriptError(f"Task to call: `{task}` does not exist in user config") - - if force_call or deep_get( - self.data, keys=f"{task}.Scheduler.Enable", default=False - ): - logger.info(f"Task call: {task}") - self.modified[f"{task}.Scheduler.NextRun"] = datetime.now().replace( - microsecond=0 - ) - self.modified[f"{task}.Scheduler.Enable"] = True - self.update() - return True - else: - logger.info(f"Task call: {task} (skipped because disabled by user)") - return False - - @staticmethod - def task_stop(message=""): - """ - Stop current task - - Raises: - TaskEnd: - """ - if message: - raise TaskEnd(message) - else: - raise TaskEnd - - def task_switched(self): - """ - Check if needs to switch task. - - Raises: - bool: If task switched - """ - # Update event - if self.stop_event is not None: - if self.stop_event.is_set(): - return True - prev = self.task - self.load() - new = self.get_next() - if prev == new: - logger.info(f"Continue task `{new}`") - return False - else: - logger.info(f"Switch task `{prev}` to `{new}`") - return True - - def check_task_switch(self, message=""): - """ - Stop current task - - Raises: - TaskEnd: - """ - if self.task_switched(): - self.task_stop(message=message) - - """ - The following configs and methods are used to be compatible with the old. - """ - - def merge(self, other): - """ - Args: - other (AzurLaneConfig, Config): - - Returns: - AzurLaneConfig - """ - # Since all tasks run independently, there's no need to separate configs - # config = copy.copy(self) - config = self - - for attr in dir(config): - if attr.endswith("__"): - continue - if hasattr(other, attr): - value = other.__getattribute__(attr) - if value is not None: - config.__setattr__(attr, value) - - return config - - def temporary(self, **kwargs): - """ - Cover some settings, and recover later. - - Usage: - backup = self.config.cover(ENABLE_DAILY_REWARD=False) - # do_something() - backup.recover() - - Args: - **kwargs: - - Returns: - ConfigBackup: - """ - backup = ConfigBackup(config=self) - backup.cover(**kwargs) - return backup - - -class AzurLaneConfig(GeneralConfig, ConfigUpdater, ManualConfig, GeneratedConfig): def opsi_task_delay(self, recon_scan=False, submarine_call=False, ap_limit=False): """ Delay the NextRun of all OpSi tasks. - Args: recon_scan (bool): True to delay all tasks requiring recon scan 27 min. submarine_call (bool): True to delay all tasks requiring submarine call 60 min. @@ -726,6 +597,31 @@ class AzurLaneConfig(GeneralConfig, ConfigUpdater, ManualConfig, GeneratedConfig name += "_hard" return name + """ + The following configs and methods are used to be compatible with the old. + """ + + def merge(self, other): + """ + Args: + other (AzurLaneConfig, Config): + Returns: + AzurLaneConfig + """ + # Since all tasks run independently, there's no need to separate configs + # config = copy.copy(self) + config = self + + for attr in dir(config): + if attr.endswith("__"): + continue + if hasattr(other, attr): + value = other.__getattribute__(attr) + if value is not None: + config.__setattr__(attr, value) + + return config + @property def DEVICE_SCREENSHOT_METHOD(self): return self.Emulator_ScreenshotMethod @@ -775,6 +671,22 @@ class AzurLaneConfig(GeneralConfig, ConfigUpdater, ManualConfig, GeneratedConfig def FLEET_BOSS(self, value): self._fleet_boss = value + def temporary(self, **kwargs): + """ + Cover some settings, and recover later. + Usage: + backup = self.config.cover(ENABLE_DAILY_REWARD=False) + # do_something() + backup.recover() + Args: + **kwargs: + Returns: + ConfigBackup: + """ + backup = ConfigBackup(config=self) + backup.cover(**kwargs) + return backup + pywebio.output.Output = OutputConfig pywebio.pin.Output = OutputConfig @@ -784,7 +696,7 @@ class ConfigBackup: def __init__(self, config): """ Args: - config (GeneralConfig): + config (AzurLaneConfig): """ self.config = config self.backup = {} @@ -805,7 +717,7 @@ class MultiSetWrapper: def __init__(self, main): """ Args: - main (GeneralConfig): + main (AzurLaneConfig): """ self.main = main self.in_wrapper = False diff --git a/module/submodule/submodule.py b/module/submodule/submodule.py index 9ff793fde..67f18cba5 100644 --- a/module/submodule/submodule.py +++ b/module/submodule/submodule.py @@ -1,4 +1,3 @@ -import os import importlib from module.config.config import AzurLaneConfig diff --git a/module/submodule/utils.py b/module/submodule/utils.py index e1479e7e6..ad72189cf 100644 --- a/module/submodule/utils.py +++ b/module/submodule/utils.py @@ -1,29 +1,18 @@ import os -MOD_LIST = [] +MOD_DICT = {'maa': 'AlasMaaBridge'} MOD_CONFIG_DICT = {} def list_mod(): - global MOD_LIST - if not MOD_LIST: - MOD_LIST = [] - if os.path.exists('./submodule'): - for dir_name in os.listdir('./submodule'): - mod_path = os.path.join('./submodule', dir_name) - if os.path.isdir(mod_path): - for file_name in os.listdir(mod_path): - mod_name, ext = os.path.splitext(file_name) - if ext == '.py': - MOD_LIST.append((mod_name, dir_name)) - - return MOD_LIST + out = [] + for item in MOD_DICT.items(): + out.append(item) + return out def get_dir_name(name): - for mod_name, dir_name in list_mod(): - if name == mod_name: - return dir_name + return MOD_DICT[name] def filepath_mod(name): diff --git a/module/webui/process_manager.py b/module/webui/process_manager.py index 7e1bd640e..8e032c97f 100644 --- a/module/webui/process_manager.py +++ b/module/webui/process_manager.py @@ -154,12 +154,14 @@ class ProcessManager: from module.daemon.game_manager import GameManager GameManager(config=config_name, task="GameManager").run() + elif func == 'maa': + mod = load_mod('maa') + mod.loop(config_name) elif func == "MaaCopilot": mod = load_mod('maa') mod.maa_copilot(config_name) else: - mod = load_mod(func) - mod.loop(config_name) + logger.critical("No function matched") logger.info(f"[{config_name}] exited. Reason: Finish\n") except Exception as e: logger.exception(e) diff --git a/submodule/AlasMaaBridge/maa.py b/submodule/AlasMaaBridge/maa.py index e699331ac..73e003963 100644 --- a/submodule/AlasMaaBridge/maa.py +++ b/submodule/AlasMaaBridge/maa.py @@ -2,7 +2,7 @@ import os import json from cached_property import cached_property -from alas import AutoScriptScheduler +from alas import AzurLaneAutoScript from deploy.config import DeployConfig from module.exception import RequestHumanTakeover from module.logger import logger @@ -11,10 +11,19 @@ from submodule.AlasMaaBridge.module.config.config import ArknightsConfig from submodule.AlasMaaBridge.module.handler.handler import AssistantHandler -class ArknightsAutoScript(AutoScriptScheduler): +class FakeDevice: + @staticmethod + def empty_func(*args, **kwargs): + pass + + def __getattr__(self, item): + return FakeDevice.empty_func + + +class ArknightsAutoScript(AzurLaneAutoScript): @cached_property def device(self): - return None + return FakeDevice() @cached_property def config(self): @@ -28,6 +37,10 @@ class ArknightsAutoScript(AutoScriptScheduler): logger.exception(e) exit(1) + @staticmethod + def callback(self): + pass + @cached_property def asst(self): if self.config.task.command not in ['MaaStartup', 'Maa']: @@ -53,7 +66,7 @@ class ArknightsAutoScript(AutoScriptScheduler): for func in handler.callback_list: func(m, json.loads(d)) - self.callback = callback + ArknightsAutoScript.callback = callback asst = AssistantHandler.Asst(callback) if not asst.connect(os.path.abspath(DeployConfig().AdbExecutable), self.config.Emulator_Serial): diff --git a/submodule/AlasMaaBridge/module/config/config.py b/submodule/AlasMaaBridge/module/config/config.py index 40bd630d2..16ac5f1e8 100644 --- a/submodule/AlasMaaBridge/module/config/config.py +++ b/submodule/AlasMaaBridge/module/config/config.py @@ -1,16 +1,22 @@ import os from datetime import datetime -from module.config.config import GeneralConfig, Function, name_to_function -from module.config.utils import path_to_arg, filepath_config -from module.logger import logger +from module.config.config import AzurLaneConfig, name_to_function +from module.config.utils import filepath_config from submodule.AlasMaaBridge.module.config.config_generated import GeneratedConfig -from submodule.AlasMaaBridge.module.config.config_manual import ManualConfig from submodule.AlasMaaBridge.module.config.config_updater import ConfigUpdater -class ArknightsConfig(GeneralConfig, ConfigUpdater, ManualConfig, GeneratedConfig): +class ArknightsConfig(AzurLaneConfig, ConfigUpdater, GeneratedConfig): + SCHEDULER_PRIORITY = """ + MaaStartup + > MaaRecruit > MaaInfrast + > MaaVisit > MaaMall > MaaAward + > MaaAnnihilation > MaaMaterial + > MaaFight > MaaRoguelike + """ + def __init__(self, config_name, task=None): super().__init__(config_name, task) if task is None: @@ -19,35 +25,10 @@ class ArknightsConfig(GeneralConfig, ConfigUpdater, ManualConfig, GeneratedConfi self.task = task self.save() - def bind(self, func): - """ - Args: - func (str, Function): Function to run - """ - if isinstance(func, Function): - func = func.command - func_set = {func, "Maa"} - - logger.info(f"Bind task {func_set}") - - # Bind arguments - visited = set() - self.bound.clear() - for func in func_set: - func_data = self.data.get(func, {}) - for group, group_data in func_data.items(): - for arg, value in group_data.items(): - path = f"{group}.{arg}" - if path in visited: - continue - arg = path_to_arg(path) - super().__setattr__(arg, value) - self.bound[arg] = f"{func}.{path}" - visited.add(path) - - # Override arguments - for arg, value in self.overridden.items(): - super().__setattr__(arg, value) + def bind(self, func, func_set=None): + if func_set is None: + func_set = {'Maa'} + super().bind(func, func_set) def save(self, mod_name='maa'): super().save(mod_name) diff --git a/submodule/AlasMaaBridge/module/config/config_manual.py b/submodule/AlasMaaBridge/module/config/config_manual.py deleted file mode 100644 index 547bbaab5..000000000 --- a/submodule/AlasMaaBridge/module/config/config_manual.py +++ /dev/null @@ -1,33 +0,0 @@ -from pywebio.io_ctrl import Output - -import module.config.server as server - - -class ManualConfig: - @property - def SERVER(self): - return server.server - - SCHEDULER_PRIORITY = """ - MaaStartup - > MaaRecruit > MaaInfrast - > MaaVisit > MaaMall > MaaAward - > MaaAnnihilation > MaaMaterial - > MaaFight > MaaRoguelike - """ - - """ - module.device - """ - DEVICE_OVER_HTTP = False - FORWARD_PORT_RANGE = (20000, 21000) - REVERSE_SERVER_PORT = 7903 - ASCREENCAP_FILEPATH_LOCAL = './bin/ascreencap' - ASCREENCAP_FILEPATH_REMOTE = '/data/local/tmp/ascreencap' - MINITOUCH_FILEPATH_REMOTE = '/data/local/tmp/minitouch' - HERMIT_FILEPATH_LOCAL = './bin/hermit/hermit.apk' - - -class OutputConfig(Output, ManualConfig): - def __init__(self, spec, on_embed=None): - super().__init__(spec, on_embed) From f513f0fa91e052d96933ea0cf221e60ee5d02f25 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Tue, 13 Sep 2022 21:01:00 +0800 Subject: [PATCH 11/21] Opt: Rename arguments to avoid possible conflicts --- submodule/AlasMaaBridge/config/template.json | 23 +- submodule/AlasMaaBridge/maa.py | 8 +- .../module/config/argument/args.json | 25 +- .../module/config/argument/argument.yaml | 45 ++-- .../module/config/argument/override.yaml | 4 +- .../module/config/argument/task.yaml | 20 +- .../module/config/config_generated.py | 88 +++---- .../module/config/i18n/en-US.json | 230 +++++++++--------- .../module/config/i18n/ja-JP.json | 230 +++++++++--------- .../module/config/i18n/zh-CN.json | 90 +++---- .../module/config/i18n/zh-TW.json | 230 +++++++++--------- .../AlasMaaBridge/module/handler/handler.py | 116 +++++---- 12 files changed, 573 insertions(+), 536 deletions(-) diff --git a/submodule/AlasMaaBridge/config/template.json b/submodule/AlasMaaBridge/config/template.json index d27ffab6c..53ce2b492 100644 --- a/submodule/AlasMaaBridge/config/template.json +++ b/submodule/AlasMaaBridge/config/template.json @@ -1,13 +1,12 @@ { "Maa": { - "Emulator": { + "MaaEmulator": { "Serial": "127.0.0.1:5555", "PackageName": "Official", "Server": "CN", - "MaaPath": "D:/Program Files/MAA", - "ServerName": "disabled" + "MaaPath": "D:/Program Files/MAA" }, - "Record": { + "MaaRecord": { "ReportToPenguin": false, "PenguinID": null } @@ -31,7 +30,7 @@ "FailureInterval": 120, "ServerUpdate": "04:00" }, - "Fight": { + "MaaFight": { "Stage": "Annihilation", "Medicine": 0, "Stone": 0, @@ -49,7 +48,7 @@ "FailureInterval": 120, "ServerUpdate": "04:00" }, - "Fight": { + "MaaFight": { "Stage": "1-7", "Medicine": 0, "Stone": 0, @@ -67,7 +66,7 @@ "FailureInterval": 120, "ServerUpdate": "04:00" }, - "Fight": { + "MaaFight": { "Stage": "1-7", "Medicine": 0, "Stone": 0, @@ -85,7 +84,7 @@ "FailureInterval": 120, "ServerUpdate": "04:00" }, - "Recruit": { + "MaaRecruit": { "Refresh": true, "SkipRobot": true, "Select3": true, @@ -104,7 +103,7 @@ "FailureInterval": 120, "ServerUpdate": "04:00" }, - "Infrast": { + "MaaInfrast": { "Facility": "Mfg > Trade > Power > Control > Reception > Office > Dorm", "Drones": "Money", "Threshold": 0.3, @@ -130,7 +129,7 @@ "FailureInterval": 120, "ServerUpdate": "04:00" }, - "Mall": { + "MaaMall": { "Shopping": true, "BuyFirst": "招聘许可 > 龙门币", "BlackList": "碳 > 家具" @@ -155,7 +154,7 @@ "FailureInterval": 120, "ServerUpdate": "04:00" }, - "Roguelike": { + "MaaRoguelike": { "Mode": 0, "StartsCount": 9999999, "InvestmentsCount": 9999999, @@ -166,7 +165,7 @@ } }, "MaaCopilot": { - "Copilot": { + "MaaCopilot": { "FileName": null, "Formation": false } diff --git a/submodule/AlasMaaBridge/maa.py b/submodule/AlasMaaBridge/maa.py index 73e003963..eeedabbcb 100644 --- a/submodule/AlasMaaBridge/maa.py +++ b/submodule/AlasMaaBridge/maa.py @@ -47,7 +47,7 @@ class ArknightsAutoScript(AzurLaneAutoScript): self.config.task_call('MaaStartup', True) self.config.task_stop() - AssistantHandler.load(self.config.Emulator_MaaPath) + AssistantHandler.load(self.config.MaaEmulator_MaaPath) @AssistantHandler.Asst.CallBackType def callback(msg, details, arg): @@ -58,18 +58,18 @@ class ArknightsAutoScript(AzurLaneAutoScript): arg (c_void_p): """ m = AssistantHandler.Message(msg) - d = details.decode('utf-8', 'ignore') + d = json.loads(details.decode('utf-8', 'ignore')) logger.info(f'{m} {d}') handler = AssistantHandler.ASST_HANDLER if handler: handler.callback_timer.reset() for func in handler.callback_list: - func(m, json.loads(d)) + func(m, d) ArknightsAutoScript.callback = callback asst = AssistantHandler.Asst(callback) - if not asst.connect(os.path.abspath(DeployConfig().AdbExecutable), self.config.Emulator_Serial): + if not asst.connect(os.path.abspath(DeployConfig().AdbExecutable), self.config.MaaEmulator_Serial): logger.critical('Adb connect failed') raise RequestHumanTakeover diff --git a/submodule/AlasMaaBridge/module/config/argument/args.json b/submodule/AlasMaaBridge/module/config/argument/args.json index 2f80b4ddf..f5291df16 100644 --- a/submodule/AlasMaaBridge/module/config/argument/args.json +++ b/submodule/AlasMaaBridge/module/config/argument/args.json @@ -1,6 +1,6 @@ { "Maa": { - "Emulator": { + "MaaEmulator": { "Serial": { "type": "input", "value": "127.0.0.1:5555", @@ -27,14 +27,9 @@ "MaaPath": { "type": "textarea", "value": "D:/Program Files/MAA" - }, - "ServerName": { - "type": "input", - "value": "disabled", - "display": "hide" } }, - "Record": { + "MaaRecord": { "ReportToPenguin": { "type": "checkbox", "value": false @@ -111,7 +106,7 @@ "display": "hide" } }, - "Fight": { + "MaaFight": { "Stage": { "type": "input", "value": "Annihilation", @@ -177,7 +172,7 @@ "display": "hide" } }, - "Fight": { + "MaaFight": { "Stage": { "type": "input", "value": "1-7", @@ -237,7 +232,7 @@ "display": "hide" } }, - "Fight": { + "MaaFight": { "Stage": { "type": "input", "value": "1-7", @@ -301,7 +296,7 @@ "display": "hide" } }, - "Recruit": { + "MaaRecruit": { "Refresh": { "type": "checkbox", "value": true @@ -364,7 +359,7 @@ "display": "hide" } }, - "Infrast": { + "MaaInfrast": { "Facility": { "type": "textarea", "value": "Mfg > Trade > Power > Control > Reception > Office > Dorm" @@ -457,7 +452,7 @@ "display": "hide" } }, - "Mall": { + "MaaMall": { "Shopping": { "type": "checkbox", "value": true @@ -537,7 +532,7 @@ "display": "hide" } }, - "Roguelike": { + "MaaRoguelike": { "Mode": { "type": "select", "value": 0, @@ -591,7 +586,7 @@ } }, "MaaCopilot": { - "Copilot": { + "MaaCopilot": { "FileName": { "type": "textarea", "value": null diff --git a/submodule/AlasMaaBridge/module/config/argument/argument.yaml b/submodule/AlasMaaBridge/module/config/argument/argument.yaml index 7b7f029c8..b62de6dac 100644 --- a/submodule/AlasMaaBridge/module/config/argument/argument.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/argument.yaml @@ -19,25 +19,9 @@ Scheduler: display: hide Emulator: - Serial: - value: 127.0.0.1:5555 - valuetype: str - PackageName: - value: Official - option: [Official, Bilibili] - Server: - value: CN - option: [CN, US, JP, KR] - MaaPath: - value: D:/Program Files/MAA - type: textarea ServerName: value: disabled display: hide -Record: - ReportToPenguin: false - PenguinID: null - Error: SaveError: value: false @@ -51,7 +35,24 @@ Optimization: value: stay_there display: hide -Fight: +MaaEmulator: + Serial: + value: 127.0.0.1:5555 + valuetype: str + PackageName: + value: Official + option: [Official, Bilibili] + Server: + value: CN + option: [CN, US, JP, KR] + MaaPath: + value: D:/Program Files/MAA + type: textarea +MaaRecord: + ReportToPenguin: false + PenguinID: null + +MaaFight: Stage: value: 1-7 valuetype: str @@ -63,7 +64,7 @@ Fight: type: textarea DrGrandet: false -Recruit: +MaaRecruit: Refresh: true SkipRobot: true Select3: true @@ -72,7 +73,7 @@ Recruit: Times: 4 Expedite: false -Infrast: +MaaInfrast: Facility: value: Mfg > Trade > Power > Control > Reception > Office > Dorm type: textarea @@ -82,7 +83,7 @@ Infrast: Threshold: 0.3 Replenish: false -Mall: +MaaMall: Shopping: true BuyFirst: value: 招聘许可 > 龙门币 @@ -91,7 +92,7 @@ Mall: value: 碳 > 家具 type: textarea -Roguelike: +MaaRoguelike: Mode: value: 0 option: [0, 1] @@ -108,7 +109,7 @@ Roguelike: # ==================== Tool ==================== -Copilot: +MaaCopilot: FileName: value: null type: textarea diff --git a/submodule/AlasMaaBridge/module/config/argument/override.yaml b/submodule/AlasMaaBridge/module/config/argument/override.yaml index aefd22ecf..3aeb75d33 100644 --- a/submodule/AlasMaaBridge/module/config/argument/override.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/override.yaml @@ -16,7 +16,7 @@ MaaStartup: MaaAnnihilation: Scheduler: SuccessInterval: 480 - Fight: + MaaFight: Stage: Annihilation Medicine: 0 Stone: 0 @@ -27,7 +27,7 @@ MaaAnnihilation: MaaFight: Scheduler: SuccessInterval: 480 - Fight: + MaaFight: Medicine: 0 Stone: 0 Times: 0 diff --git a/submodule/AlasMaaBridge/module/config/argument/task.yaml b/submodule/AlasMaaBridge/module/config/argument/task.yaml index d346890a3..03be8fe7a 100644 --- a/submodule/AlasMaaBridge/module/config/argument/task.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/task.yaml @@ -5,47 +5,47 @@ # ==================== Maa ==================== Maa: - - Emulator - - Record + - MaaEmulator + - MaaRecord MaaStartup: - Scheduler MaaAnnihilation: - Scheduler - - Fight + - MaaFight MaaMaterial: - Scheduler - - Fight + - MaaFight MaaFight: - Scheduler - - Fight + - MaaFight MaaRecruit: - Scheduler - - Recruit + - MaaRecruit MaaInfrast: - Scheduler - - Infrast + - MaaInfrast MaaVisit: - Scheduler MaaMall: - Scheduler - - Mall + - MaaMall MaaAward: - Scheduler MaaRoguelike: - Scheduler - - Roguelike + - MaaRoguelike # ==================== Tool ==================== MaaCopilot: - - Copilot \ No newline at end of file + - MaaCopilot \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/config_generated.py b/submodule/AlasMaaBridge/module/config/config_generated.py index 7c39fa55b..41e310ebd 100644 --- a/submodule/AlasMaaBridge/module/config/config_generated.py +++ b/submodule/AlasMaaBridge/module/config/config_generated.py @@ -18,16 +18,8 @@ class GeneratedConfig: Scheduler_ServerUpdate = '04:00' # Group `Emulator` - Emulator_Serial = '127.0.0.1:5555' - Emulator_PackageName = 'Official' # Official, Bilibili - Emulator_Server = 'CN' # CN, US, JP, KR - Emulator_MaaPath = 'D:/Program Files/MAA' Emulator_ServerName = 'disabled' - # Group `Record` - Record_ReportToPenguin = False - Record_PenguinID = None - # Group `Error` Error_SaveError = False Error_OnePushConfig = 'provider: null' @@ -35,43 +27,53 @@ class GeneratedConfig: # Group `Optimization` Optimization_WhenTaskQueueEmpty = 'stay_there' - # Group `Fight` - Fight_Stage = '1-7' - Fight_Medicine = 0 - Fight_Stone = 0 - Fight_Times = 0 - Fight_Drops = None - Fight_DrGrandet = False + # Group `MaaEmulator` + MaaEmulator_Serial = '127.0.0.1:5555' + MaaEmulator_PackageName = 'Official' # Official, Bilibili + MaaEmulator_Server = 'CN' # CN, US, JP, KR + MaaEmulator_MaaPath = 'D:/Program Files/MAA' - # Group `Recruit` - Recruit_Refresh = True - Recruit_SkipRobot = True - Recruit_Select3 = True - Recruit_Select4 = True - Recruit_Select5 = True - Recruit_Times = 4 - Recruit_Expedite = False + # Group `MaaRecord` + MaaRecord_ReportToPenguin = False + MaaRecord_PenguinID = None - # Group `Infrast` - Infrast_Facility = 'Mfg > Trade > Power > Control > Reception > Office > Dorm' - Infrast_Drones = 'Money' # _NotUse, Money, SyntheticJade, CombatRecord, PureGold, OriginStone, Chip - Infrast_Threshold = 0.3 - Infrast_Replenish = False + # Group `MaaFight` + MaaFight_Stage = '1-7' + MaaFight_Medicine = 0 + MaaFight_Stone = 0 + MaaFight_Times = 0 + MaaFight_Drops = None + MaaFight_DrGrandet = False - # Group `Mall` - Mall_Shopping = True - Mall_BuyFirst = '招聘许可 > 龙门币' - Mall_BlackList = '碳 > 家具' + # Group `MaaRecruit` + MaaRecruit_Refresh = True + MaaRecruit_SkipRobot = True + MaaRecruit_Select3 = True + MaaRecruit_Select4 = True + MaaRecruit_Select5 = True + MaaRecruit_Times = 4 + MaaRecruit_Expedite = False - # Group `Roguelike` - Roguelike_Mode = 0 # 0, 1 - Roguelike_StartsCount = 9999999 - Roguelike_InvestmentsCount = 9999999 - Roguelike_StopWhenInvestmentFull = False - Roguelike_Squad = '指挥分队' # 指挥分队, 集群分队, 后勤分队, 矛头分队, 突击战术分队, 堡垒战术分队, 远程战术分队, 破坏战术分队, 研究分队, 高规格分队 - Roguelike_Roles = '取长补短' # 先手必胜, 稳扎稳打, 取长补短, 随心所欲 - Roguelike_CoreChar = None + # Group `MaaInfrast` + MaaInfrast_Facility = 'Mfg > Trade > Power > Control > Reception > Office > Dorm' + MaaInfrast_Drones = 'Money' # _NotUse, Money, SyntheticJade, CombatRecord, PureGold, OriginStone, Chip + MaaInfrast_Threshold = 0.3 + MaaInfrast_Replenish = False - # Group `Copilot` - Copilot_FileName = None - Copilot_Formation = False + # Group `MaaMall` + MaaMall_Shopping = True + MaaMall_BuyFirst = '招聘许可 > 龙门币' + MaaMall_BlackList = '碳 > 家具' + + # Group `MaaRoguelike` + MaaRoguelike_Mode = 0 # 0, 1 + MaaRoguelike_StartsCount = 9999999 + MaaRoguelike_InvestmentsCount = 9999999 + MaaRoguelike_StopWhenInvestmentFull = False + MaaRoguelike_Squad = '指挥分队' # 指挥分队, 集群分队, 后勤分队, 矛头分队, 突击战术分队, 堡垒战术分队, 远程战术分队, 破坏战术分队, 研究分队, 高规格分队 + MaaRoguelike_Roles = '取长补短' # 先手必胜, 稳扎稳打, 取长补短, 随心所欲 + MaaRoguelike_CoreChar = None + + # Group `MaaCopilot` + MaaCopilot_FileName = None + MaaCopilot_Formation = False diff --git a/submodule/AlasMaaBridge/module/config/i18n/en-US.json b/submodule/AlasMaaBridge/module/config/i18n/en-US.json index 3dfeafd46..35e538276 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/en-US.json +++ b/submodule/AlasMaaBridge/module/config/i18n/en-US.json @@ -98,47 +98,11 @@ "name": "Emulator Settings", "help": "" }, - "Serial": { - "name": "Serial", - "help": "Use \"auto\" to auto-detect emulators, but serial must be filled if multiple emulators are running\nDefault serial for select emulators:\n- BlueStacks 127.0.0.1:5555\n- BlueStacks4 Hyper-V use \"bluestacks4-hyperv\", \"bluestacks4-hyperv-2\" for multi instance, and so on\n- BlueStacks5 Hyper-V use \"bluestacks5-hyperv\", \"bluestacks5-hyperv-1\" for multi instance, and so on\n- NoxPlayer 127.0.0.1:62001\n- NoxPlayer64bit 127.0.0.1:59865\n- MuMuPlayer 127.0.0.1:7555\n- MemuPlayer 127.0.0.1:21503\n- LDPlayer emulator-5554 or 127.0.0.1:5555\n- WSA use \"wsa-0\" to make the game run in the background, which needs to be controlled or closed by third-party software\nIf there are multiple emulator instances running, the default is reserved for one of them and the others will use different serials to avoid conflicts\nOpen console.bat and run `adb devices` to find what they are" - }, - "PackageName": { - "name": "Game Server", - "help": "Manual select is required if multiple game clients are installed on emulator", - "Official": "Official", - "Bilibili": "Bilibili" - }, - "Server": { - "name": "Emulator.Server.name", - "help": "Emulator.Server.help", - "CN": "CN", - "US": "US", - "JP": "JP", - "KR": "KR" - }, - "MaaPath": { - "name": "Emulator.MaaPath.name", - "help": "Emulator.MaaPath.help" - }, "ServerName": { "name": "Emulator.ServerName.name", "help": "Emulator.ServerName.help" } }, - "Record": { - "_info": { - "name": "Record._info.name", - "help": "Record._info.help" - }, - "ReportToPenguin": { - "name": "Record.ReportToPenguin.name", - "help": "Record.ReportToPenguin.help" - }, - "PenguinID": { - "name": "Record.PenguinID.name", - "help": "Record.PenguinID.help" - } - }, "Error": { "_info": { "name": "Error._info.name", @@ -163,82 +127,124 @@ "help": "Close AL when there are no pending tasks, can help reduce CPU" } }, - "Fight": { + "MaaEmulator": { "_info": { - "name": "Fight._info.name", - "help": "Fight._info.help" + "name": "MaaEmulator._info.name", + "help": "MaaEmulator._info.help" + }, + "Serial": { + "name": "MaaEmulator.Serial.name", + "help": "MaaEmulator.Serial.help" + }, + "PackageName": { + "name": "MaaEmulator.PackageName.name", + "help": "MaaEmulator.PackageName.help", + "Official": "Official", + "Bilibili": "Bilibili" + }, + "Server": { + "name": "MaaEmulator.Server.name", + "help": "MaaEmulator.Server.help", + "CN": "CN", + "US": "US", + "JP": "JP", + "KR": "KR" + }, + "MaaPath": { + "name": "MaaEmulator.MaaPath.name", + "help": "MaaEmulator.MaaPath.help" + } + }, + "MaaRecord": { + "_info": { + "name": "MaaRecord._info.name", + "help": "MaaRecord._info.help" + }, + "ReportToPenguin": { + "name": "MaaRecord.ReportToPenguin.name", + "help": "MaaRecord.ReportToPenguin.help" + }, + "PenguinID": { + "name": "MaaRecord.PenguinID.name", + "help": "MaaRecord.PenguinID.help" + } + }, + "MaaFight": { + "_info": { + "name": "MaaFight._info.name", + "help": "MaaFight._info.help" }, "Stage": { - "name": "Fight.Stage.name", - "help": "Fight.Stage.help" + "name": "MaaFight.Stage.name", + "help": "MaaFight.Stage.help" }, "Medicine": { - "name": "Fight.Medicine.name", - "help": "Fight.Medicine.help" + "name": "MaaFight.Medicine.name", + "help": "MaaFight.Medicine.help" }, "Stone": { - "name": "Fight.Stone.name", - "help": "Fight.Stone.help" + "name": "MaaFight.Stone.name", + "help": "MaaFight.Stone.help" }, "Times": { - "name": "Fight.Times.name", - "help": "Fight.Times.help" + "name": "MaaFight.Times.name", + "help": "MaaFight.Times.help" }, "Drops": { - "name": "Fight.Drops.name", - "help": "Fight.Drops.help" + "name": "MaaFight.Drops.name", + "help": "MaaFight.Drops.help" }, "DrGrandet": { - "name": "Fight.DrGrandet.name", - "help": "Fight.DrGrandet.help" + "name": "MaaFight.DrGrandet.name", + "help": "MaaFight.DrGrandet.help" } }, - "Recruit": { + "MaaRecruit": { "_info": { - "name": "Recruit._info.name", - "help": "Recruit._info.help" + "name": "MaaRecruit._info.name", + "help": "MaaRecruit._info.help" }, "Refresh": { - "name": "Recruit.Refresh.name", - "help": "Recruit.Refresh.help" + "name": "MaaRecruit.Refresh.name", + "help": "MaaRecruit.Refresh.help" }, "SkipRobot": { - "name": "Recruit.SkipRobot.name", - "help": "Recruit.SkipRobot.help" + "name": "MaaRecruit.SkipRobot.name", + "help": "MaaRecruit.SkipRobot.help" }, "Select3": { - "name": "Recruit.Select3.name", - "help": "Recruit.Select3.help" + "name": "MaaRecruit.Select3.name", + "help": "MaaRecruit.Select3.help" }, "Select4": { - "name": "Recruit.Select4.name", - "help": "Recruit.Select4.help" + "name": "MaaRecruit.Select4.name", + "help": "MaaRecruit.Select4.help" }, "Select5": { - "name": "Recruit.Select5.name", - "help": "Recruit.Select5.help" + "name": "MaaRecruit.Select5.name", + "help": "MaaRecruit.Select5.help" }, "Times": { - "name": "Recruit.Times.name", - "help": "Recruit.Times.help" + "name": "MaaRecruit.Times.name", + "help": "MaaRecruit.Times.help" }, "Expedite": { - "name": "Recruit.Expedite.name", - "help": "Recruit.Expedite.help" + "name": "MaaRecruit.Expedite.name", + "help": "MaaRecruit.Expedite.help" } }, - "Infrast": { + "MaaInfrast": { "_info": { - "name": "Infrast._info.name", - "help": "Infrast._info.help" + "name": "MaaInfrast._info.name", + "help": "MaaInfrast._info.help" }, "Facility": { - "name": "Infrast.Facility.name", - "help": "Infrast.Facility.help" + "name": "MaaInfrast.Facility.name", + "help": "MaaInfrast.Facility.help" }, "Drones": { - "name": "Infrast.Drones.name", - "help": "Infrast.Drones.help", + "name": "MaaInfrast.Drones.name", + "help": "MaaInfrast.Drones.help", "_NotUse": "_NotUse", "Money": "Money", "SyntheticJade": "SyntheticJade", @@ -248,58 +254,58 @@ "Chip": "Chip" }, "Threshold": { - "name": "Infrast.Threshold.name", - "help": "Infrast.Threshold.help" + "name": "MaaInfrast.Threshold.name", + "help": "MaaInfrast.Threshold.help" }, "Replenish": { - "name": "Infrast.Replenish.name", - "help": "Infrast.Replenish.help" + "name": "MaaInfrast.Replenish.name", + "help": "MaaInfrast.Replenish.help" } }, - "Mall": { + "MaaMall": { "_info": { - "name": "Mall._info.name", - "help": "Mall._info.help" + "name": "MaaMall._info.name", + "help": "MaaMall._info.help" }, "Shopping": { - "name": "Mall.Shopping.name", - "help": "Mall.Shopping.help" + "name": "MaaMall.Shopping.name", + "help": "MaaMall.Shopping.help" }, "BuyFirst": { - "name": "Mall.BuyFirst.name", - "help": "Mall.BuyFirst.help" + "name": "MaaMall.BuyFirst.name", + "help": "MaaMall.BuyFirst.help" }, "BlackList": { - "name": "Mall.BlackList.name", - "help": "Mall.BlackList.help" + "name": "MaaMall.BlackList.name", + "help": "MaaMall.BlackList.help" } }, - "Roguelike": { + "MaaRoguelike": { "_info": { - "name": "Roguelike._info.name", - "help": "Roguelike._info.help" + "name": "MaaRoguelike._info.name", + "help": "MaaRoguelike._info.help" }, "Mode": { - "name": "Roguelike.Mode.name", - "help": "Roguelike.Mode.help", + "name": "MaaRoguelike.Mode.name", + "help": "MaaRoguelike.Mode.help", "0": "0", "1": "1" }, "StartsCount": { - "name": "Roguelike.StartsCount.name", - "help": "Roguelike.StartsCount.help" + "name": "MaaRoguelike.StartsCount.name", + "help": "MaaRoguelike.StartsCount.help" }, "InvestmentsCount": { - "name": "Roguelike.InvestmentsCount.name", - "help": "Roguelike.InvestmentsCount.help" + "name": "MaaRoguelike.InvestmentsCount.name", + "help": "MaaRoguelike.InvestmentsCount.help" }, "StopWhenInvestmentFull": { - "name": "Roguelike.StopWhenInvestmentFull.name", - "help": "Roguelike.StopWhenInvestmentFull.help" + "name": "MaaRoguelike.StopWhenInvestmentFull.name", + "help": "MaaRoguelike.StopWhenInvestmentFull.help" }, "Squad": { - "name": "Roguelike.Squad.name", - "help": "Roguelike.Squad.help", + "name": "MaaRoguelike.Squad.name", + "help": "MaaRoguelike.Squad.help", "指挥分队": "指挥分队", "集群分队": "集群分队", "后勤分队": "后勤分队", @@ -312,30 +318,30 @@ "高规格分队": "高规格分队" }, "Roles": { - "name": "Roguelike.Roles.name", - "help": "Roguelike.Roles.help", + "name": "MaaRoguelike.Roles.name", + "help": "MaaRoguelike.Roles.help", "先手必胜": "先手必胜", "稳扎稳打": "稳扎稳打", "取长补短": "取长补短", "随心所欲": "随心所欲" }, "CoreChar": { - "name": "Roguelike.CoreChar.name", - "help": "Roguelike.CoreChar.help" + "name": "MaaRoguelike.CoreChar.name", + "help": "MaaRoguelike.CoreChar.help" } }, - "Copilot": { + "MaaCopilot": { "_info": { - "name": "Copilot._info.name", - "help": "Copilot._info.help" + "name": "MaaCopilot._info.name", + "help": "MaaCopilot._info.help" }, "FileName": { - "name": "Copilot.FileName.name", - "help": "Copilot.FileName.help" + "name": "MaaCopilot.FileName.name", + "help": "MaaCopilot.FileName.help" }, "Formation": { - "name": "Copilot.Formation.name", - "help": "Copilot.Formation.help" + "name": "MaaCopilot.Formation.name", + "help": "MaaCopilot.Formation.help" } } } \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json b/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json index 7c425e8e4..788cd7aca 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json +++ b/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json @@ -98,47 +98,11 @@ "name": "Emulator._info.name", "help": "Emulator._info.help" }, - "Serial": { - "name": "Emulator.Serial.name", - "help": "Emulator.Serial.help" - }, - "PackageName": { - "name": "Emulator.PackageName.name", - "help": "Emulator.PackageName.help", - "Official": "Official", - "Bilibili": "Bilibili" - }, - "Server": { - "name": "Emulator.Server.name", - "help": "Emulator.Server.help", - "CN": "CN", - "US": "US", - "JP": "JP", - "KR": "KR" - }, - "MaaPath": { - "name": "Emulator.MaaPath.name", - "help": "Emulator.MaaPath.help" - }, "ServerName": { "name": "Emulator.ServerName.name", "help": "Emulator.ServerName.help" } }, - "Record": { - "_info": { - "name": "Record._info.name", - "help": "Record._info.help" - }, - "ReportToPenguin": { - "name": "Record.ReportToPenguin.name", - "help": "Record.ReportToPenguin.help" - }, - "PenguinID": { - "name": "Record.PenguinID.name", - "help": "Record.PenguinID.help" - } - }, "Error": { "_info": { "name": "Error._info.name", @@ -163,82 +127,124 @@ "help": "Optimization.WhenTaskQueueEmpty.help" } }, - "Fight": { + "MaaEmulator": { "_info": { - "name": "Fight._info.name", - "help": "Fight._info.help" + "name": "MaaEmulator._info.name", + "help": "MaaEmulator._info.help" + }, + "Serial": { + "name": "MaaEmulator.Serial.name", + "help": "MaaEmulator.Serial.help" + }, + "PackageName": { + "name": "MaaEmulator.PackageName.name", + "help": "MaaEmulator.PackageName.help", + "Official": "Official", + "Bilibili": "Bilibili" + }, + "Server": { + "name": "MaaEmulator.Server.name", + "help": "MaaEmulator.Server.help", + "CN": "CN", + "US": "US", + "JP": "JP", + "KR": "KR" + }, + "MaaPath": { + "name": "MaaEmulator.MaaPath.name", + "help": "MaaEmulator.MaaPath.help" + } + }, + "MaaRecord": { + "_info": { + "name": "MaaRecord._info.name", + "help": "MaaRecord._info.help" + }, + "ReportToPenguin": { + "name": "MaaRecord.ReportToPenguin.name", + "help": "MaaRecord.ReportToPenguin.help" + }, + "PenguinID": { + "name": "MaaRecord.PenguinID.name", + "help": "MaaRecord.PenguinID.help" + } + }, + "MaaFight": { + "_info": { + "name": "MaaFight._info.name", + "help": "MaaFight._info.help" }, "Stage": { - "name": "Fight.Stage.name", - "help": "Fight.Stage.help" + "name": "MaaFight.Stage.name", + "help": "MaaFight.Stage.help" }, "Medicine": { - "name": "Fight.Medicine.name", - "help": "Fight.Medicine.help" + "name": "MaaFight.Medicine.name", + "help": "MaaFight.Medicine.help" }, "Stone": { - "name": "Fight.Stone.name", - "help": "Fight.Stone.help" + "name": "MaaFight.Stone.name", + "help": "MaaFight.Stone.help" }, "Times": { - "name": "Fight.Times.name", - "help": "Fight.Times.help" + "name": "MaaFight.Times.name", + "help": "MaaFight.Times.help" }, "Drops": { - "name": "Fight.Drops.name", - "help": "Fight.Drops.help" + "name": "MaaFight.Drops.name", + "help": "MaaFight.Drops.help" }, "DrGrandet": { - "name": "Fight.DrGrandet.name", - "help": "Fight.DrGrandet.help" + "name": "MaaFight.DrGrandet.name", + "help": "MaaFight.DrGrandet.help" } }, - "Recruit": { + "MaaRecruit": { "_info": { - "name": "Recruit._info.name", - "help": "Recruit._info.help" + "name": "MaaRecruit._info.name", + "help": "MaaRecruit._info.help" }, "Refresh": { - "name": "Recruit.Refresh.name", - "help": "Recruit.Refresh.help" + "name": "MaaRecruit.Refresh.name", + "help": "MaaRecruit.Refresh.help" }, "SkipRobot": { - "name": "Recruit.SkipRobot.name", - "help": "Recruit.SkipRobot.help" + "name": "MaaRecruit.SkipRobot.name", + "help": "MaaRecruit.SkipRobot.help" }, "Select3": { - "name": "Recruit.Select3.name", - "help": "Recruit.Select3.help" + "name": "MaaRecruit.Select3.name", + "help": "MaaRecruit.Select3.help" }, "Select4": { - "name": "Recruit.Select4.name", - "help": "Recruit.Select4.help" + "name": "MaaRecruit.Select4.name", + "help": "MaaRecruit.Select4.help" }, "Select5": { - "name": "Recruit.Select5.name", - "help": "Recruit.Select5.help" + "name": "MaaRecruit.Select5.name", + "help": "MaaRecruit.Select5.help" }, "Times": { - "name": "Recruit.Times.name", - "help": "Recruit.Times.help" + "name": "MaaRecruit.Times.name", + "help": "MaaRecruit.Times.help" }, "Expedite": { - "name": "Recruit.Expedite.name", - "help": "Recruit.Expedite.help" + "name": "MaaRecruit.Expedite.name", + "help": "MaaRecruit.Expedite.help" } }, - "Infrast": { + "MaaInfrast": { "_info": { - "name": "Infrast._info.name", - "help": "Infrast._info.help" + "name": "MaaInfrast._info.name", + "help": "MaaInfrast._info.help" }, "Facility": { - "name": "Infrast.Facility.name", - "help": "Infrast.Facility.help" + "name": "MaaInfrast.Facility.name", + "help": "MaaInfrast.Facility.help" }, "Drones": { - "name": "Infrast.Drones.name", - "help": "Infrast.Drones.help", + "name": "MaaInfrast.Drones.name", + "help": "MaaInfrast.Drones.help", "_NotUse": "_NotUse", "Money": "Money", "SyntheticJade": "SyntheticJade", @@ -248,58 +254,58 @@ "Chip": "Chip" }, "Threshold": { - "name": "Infrast.Threshold.name", - "help": "Infrast.Threshold.help" + "name": "MaaInfrast.Threshold.name", + "help": "MaaInfrast.Threshold.help" }, "Replenish": { - "name": "Infrast.Replenish.name", - "help": "Infrast.Replenish.help" + "name": "MaaInfrast.Replenish.name", + "help": "MaaInfrast.Replenish.help" } }, - "Mall": { + "MaaMall": { "_info": { - "name": "Mall._info.name", - "help": "Mall._info.help" + "name": "MaaMall._info.name", + "help": "MaaMall._info.help" }, "Shopping": { - "name": "Mall.Shopping.name", - "help": "Mall.Shopping.help" + "name": "MaaMall.Shopping.name", + "help": "MaaMall.Shopping.help" }, "BuyFirst": { - "name": "Mall.BuyFirst.name", - "help": "Mall.BuyFirst.help" + "name": "MaaMall.BuyFirst.name", + "help": "MaaMall.BuyFirst.help" }, "BlackList": { - "name": "Mall.BlackList.name", - "help": "Mall.BlackList.help" + "name": "MaaMall.BlackList.name", + "help": "MaaMall.BlackList.help" } }, - "Roguelike": { + "MaaRoguelike": { "_info": { - "name": "Roguelike._info.name", - "help": "Roguelike._info.help" + "name": "MaaRoguelike._info.name", + "help": "MaaRoguelike._info.help" }, "Mode": { - "name": "Roguelike.Mode.name", - "help": "Roguelike.Mode.help", + "name": "MaaRoguelike.Mode.name", + "help": "MaaRoguelike.Mode.help", "0": "0", "1": "1" }, "StartsCount": { - "name": "Roguelike.StartsCount.name", - "help": "Roguelike.StartsCount.help" + "name": "MaaRoguelike.StartsCount.name", + "help": "MaaRoguelike.StartsCount.help" }, "InvestmentsCount": { - "name": "Roguelike.InvestmentsCount.name", - "help": "Roguelike.InvestmentsCount.help" + "name": "MaaRoguelike.InvestmentsCount.name", + "help": "MaaRoguelike.InvestmentsCount.help" }, "StopWhenInvestmentFull": { - "name": "Roguelike.StopWhenInvestmentFull.name", - "help": "Roguelike.StopWhenInvestmentFull.help" + "name": "MaaRoguelike.StopWhenInvestmentFull.name", + "help": "MaaRoguelike.StopWhenInvestmentFull.help" }, "Squad": { - "name": "Roguelike.Squad.name", - "help": "Roguelike.Squad.help", + "name": "MaaRoguelike.Squad.name", + "help": "MaaRoguelike.Squad.help", "指挥分队": "指挥分队", "集群分队": "集群分队", "后勤分队": "后勤分队", @@ -312,30 +318,30 @@ "高规格分队": "高规格分队" }, "Roles": { - "name": "Roguelike.Roles.name", - "help": "Roguelike.Roles.help", + "name": "MaaRoguelike.Roles.name", + "help": "MaaRoguelike.Roles.help", "先手必胜": "先手必胜", "稳扎稳打": "稳扎稳打", "取长补短": "取长补短", "随心所欲": "随心所欲" }, "CoreChar": { - "name": "Roguelike.CoreChar.name", - "help": "Roguelike.CoreChar.help" + "name": "MaaRoguelike.CoreChar.name", + "help": "MaaRoguelike.CoreChar.help" } }, - "Copilot": { + "MaaCopilot": { "_info": { - "name": "Copilot._info.name", - "help": "Copilot._info.help" + "name": "MaaCopilot._info.name", + "help": "MaaCopilot._info.help" }, "FileName": { - "name": "Copilot.FileName.name", - "help": "Copilot.FileName.help" + "name": "MaaCopilot.FileName.name", + "help": "MaaCopilot.FileName.help" }, "Formation": { - "name": "Copilot.Formation.name", - "help": "Copilot.Formation.help" + "name": "MaaCopilot.Formation.name", + "help": "MaaCopilot.Formation.help" } } } \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json index 617cec2b0..40ef2a087 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json @@ -98,47 +98,11 @@ "name": "模拟器设置", "help": "" }, - "Serial": { - "name": "模拟器 Serial", - "help": "模拟器默认 Serial:\n- 蓝叠模拟器 127.0.0.1:5555\n- 蓝叠模拟器4 Hyper-v版,填\"bluestacks4-hyperv\"自动连接,多开填\"bluestacks4-hyperv-2\"以此类推\n- 蓝叠模拟器5 Hyper-v版,填\"bluestacks5-hyperv\"自动连接,多开填\"bluestacks5-hyperv-1\"以此类推\n- 夜神模拟器 127.0.0.1:62001\n- 夜神模拟器64位 127.0.0.1:59865\n- MuMu模拟器 127.0.0.1:7555\n- 逍遥模拟器 127.0.0.1:21503\n- 雷电模拟器 emulator-5554 或 127.0.0.1:5555\n- WSA,填\"wsa-0\"使游戏在后台运行,需要使用第三方软件操控或关闭(建议使用scrcpy操控)\n如果你有多个模拟器,它们的 Serial 将不是默认的,可以在 console.bat 中执行 `adb devices` 查询" - }, - "PackageName": { - "name": "游戏服务器", - "help": "模拟器上装有多个游戏客户端时,需要手动选择服务器", - "Official": "官服", - "Bilibili": "Bilibili服" - }, - "Server": { - "name": "服务器", - "help": "会影响掉落和上传", - "CN": "CN", - "US": "US", - "JP": "JP", - "KR": "KR" - }, - "MaaPath": { - "name": "MAA安装路径", - "help": "" - }, "ServerName": { "name": "游戏内服务器(碧蓝航线)", "help": "不显示在界面,仅用于和ALAS接轨" } }, - "Record": { - "_info": { - "name": "掉落记录", - "help": "" - }, - "ReportToPenguin": { - "name": "上传到企鹅物流", - "help": "" - }, - "PenguinID": { - "name": "企鹅物流ID", - "help": "留空即可,第一次上传后会自动生成" - } - }, "Error": { "_info": { "name": "调试设置", @@ -163,7 +127,49 @@ "help": "无任务时关闭游戏,能在收菜期间降低 CPU 占用" } }, - "Fight": { + "MaaEmulator": { + "_info": { + "name": "模拟器设置", + "help": "" + }, + "Serial": { + "name": "模拟器 Serial", + "help": "模拟器默认 Serial:\n- 蓝叠模拟器 127.0.0.1:5555\n- 夜神模拟器 127.0.0.1:62001\n- 夜神模拟器64位 127.0.0.1:59865\n- MuMu模拟器 127.0.0.1:7555\n- 逍遥模拟器 127.0.0.1:21503\n- 雷电模拟器 emulator-5554 或 127.0.0.1:5555\n如果你有多个模拟器,它们的 Serial 将不是默认的,可以在 console.bat 中执行 `adb devices` 查询" + }, + "PackageName": { + "name": "游戏服务器", + "help": "模拟器上装有多个游戏客户端时,需要手动选择服务器", + "Official": "官服", + "Bilibili": "Bilibili服" + }, + "Server": { + "name": "服务器", + "help": "会影响掉落和上传", + "CN": "CN", + "US": "US", + "JP": "JP", + "KR": "KR" + }, + "MaaPath": { + "name": "MAA安装路径", + "help": "" + } + }, + "MaaRecord": { + "_info": { + "name": "掉落记录", + "help": "" + }, + "ReportToPenguin": { + "name": "上传到企鹅物流", + "help": "" + }, + "PenguinID": { + "name": "企鹅物流ID", + "help": "留空即可,第一次上传后会自动生成" + } + }, + "MaaFight": { "_info": { "name": "战斗设置", "help": "" @@ -193,7 +199,7 @@ "help": "在碎石确认界面等待,直到当前的 1 点理智恢复完成后再立刻碎石" } }, - "Recruit": { + "MaaRecruit": { "_info": { "name": "公招设置", "help": "" @@ -227,7 +233,7 @@ "help": "" } }, - "Infrast": { + "MaaInfrast": { "_info": { "name": "基建设置", "help": "" @@ -256,7 +262,7 @@ "help": "" } }, - "Mall": { + "MaaMall": { "_info": { "name": "信用商店", "help": "" @@ -274,7 +280,7 @@ "help": "" } }, - "Roguelike": { + "MaaRoguelike": { "_info": { "name": "肉鸽设置", "help": "" @@ -324,7 +330,7 @@ "help": "仅支持单个干员中文名,不填写则默认选择" } }, - "Copilot": { + "MaaCopilot": { "_info": { "name": "作业设置", "help": "请在有“开始行动”界面的按钮使用本功能\n更多作业下载见https://prts.plus/" diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json b/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json index 1f155e014..7ccf6942a 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json @@ -98,47 +98,11 @@ "name": "模擬器設定", "help": "" }, - "Serial": { - "name": "模擬器 Serial", - "help": "填 \"auto\" 自動檢測模擬器,有多個模擬器正在運行時必須手動填寫 Serial\n模擬器預設 Serial:\n- 藍疊模擬器 127.0.0.1:5555\n- 藍疊模擬器4 Hyper-v版,填\"bluestacks4-hyperv\"自動連接,多開填\"bluestacks4-hyperv-2\"以此類推\n- 藍疊模擬器5 Hyper-v版,填\"bluestacks5-hyperv\"自動連接,多開填\"bluestacks5-hyperv-1\"以此類推\n- 夜神模擬器 127.0.0.1:62001\n- 夜神模擬器64位元 127.0.0.1:59865\n- MuMu模擬器 127.0.0.1:7555\n- 逍遙模擬器 127.0.0.1:21503\n- 雷電模擬器 emulator-5554 或 127.0.0.1:5555\n- WSA,填\"wsa-0\"使遊戲在後臺運行,需要使用第三方軟件操控或關閉\n如果你有多個模擬器,他們的 Serial 將不是預設的,可以在 console.bat 中執行 `adb devices` 查詢" - }, - "PackageName": { - "name": "遊戲伺服器", - "help": "模擬器上裝有多個遊戲客戶端時,需要手動選擇伺服器", - "Official": "Official", - "Bilibili": "Bilibili" - }, - "Server": { - "name": "Emulator.Server.name", - "help": "Emulator.Server.help", - "CN": "CN", - "US": "US", - "JP": "JP", - "KR": "KR" - }, - "MaaPath": { - "name": "Emulator.MaaPath.name", - "help": "Emulator.MaaPath.help" - }, "ServerName": { "name": "Emulator.ServerName.name", "help": "Emulator.ServerName.help" } }, - "Record": { - "_info": { - "name": "Record._info.name", - "help": "Record._info.help" - }, - "ReportToPenguin": { - "name": "Record.ReportToPenguin.name", - "help": "Record.ReportToPenguin.help" - }, - "PenguinID": { - "name": "Record.PenguinID.name", - "help": "Record.PenguinID.help" - } - }, "Error": { "_info": { "name": "Error._info.name", @@ -163,82 +127,124 @@ "help": "無任務時關閉遊戲,能在收菜期間降低 CPU 佔用" } }, - "Fight": { + "MaaEmulator": { "_info": { - "name": "Fight._info.name", - "help": "Fight._info.help" + "name": "MaaEmulator._info.name", + "help": "MaaEmulator._info.help" + }, + "Serial": { + "name": "MaaEmulator.Serial.name", + "help": "MaaEmulator.Serial.help" + }, + "PackageName": { + "name": "MaaEmulator.PackageName.name", + "help": "MaaEmulator.PackageName.help", + "Official": "Official", + "Bilibili": "Bilibili" + }, + "Server": { + "name": "MaaEmulator.Server.name", + "help": "MaaEmulator.Server.help", + "CN": "CN", + "US": "US", + "JP": "JP", + "KR": "KR" + }, + "MaaPath": { + "name": "MaaEmulator.MaaPath.name", + "help": "MaaEmulator.MaaPath.help" + } + }, + "MaaRecord": { + "_info": { + "name": "MaaRecord._info.name", + "help": "MaaRecord._info.help" + }, + "ReportToPenguin": { + "name": "MaaRecord.ReportToPenguin.name", + "help": "MaaRecord.ReportToPenguin.help" + }, + "PenguinID": { + "name": "MaaRecord.PenguinID.name", + "help": "MaaRecord.PenguinID.help" + } + }, + "MaaFight": { + "_info": { + "name": "MaaFight._info.name", + "help": "MaaFight._info.help" }, "Stage": { - "name": "Fight.Stage.name", - "help": "Fight.Stage.help" + "name": "MaaFight.Stage.name", + "help": "MaaFight.Stage.help" }, "Medicine": { - "name": "Fight.Medicine.name", - "help": "Fight.Medicine.help" + "name": "MaaFight.Medicine.name", + "help": "MaaFight.Medicine.help" }, "Stone": { - "name": "Fight.Stone.name", - "help": "Fight.Stone.help" + "name": "MaaFight.Stone.name", + "help": "MaaFight.Stone.help" }, "Times": { - "name": "Fight.Times.name", - "help": "Fight.Times.help" + "name": "MaaFight.Times.name", + "help": "MaaFight.Times.help" }, "Drops": { - "name": "Fight.Drops.name", - "help": "Fight.Drops.help" + "name": "MaaFight.Drops.name", + "help": "MaaFight.Drops.help" }, "DrGrandet": { - "name": "Fight.DrGrandet.name", - "help": "Fight.DrGrandet.help" + "name": "MaaFight.DrGrandet.name", + "help": "MaaFight.DrGrandet.help" } }, - "Recruit": { + "MaaRecruit": { "_info": { - "name": "Recruit._info.name", - "help": "Recruit._info.help" + "name": "MaaRecruit._info.name", + "help": "MaaRecruit._info.help" }, "Refresh": { - "name": "Recruit.Refresh.name", - "help": "Recruit.Refresh.help" + "name": "MaaRecruit.Refresh.name", + "help": "MaaRecruit.Refresh.help" }, "SkipRobot": { - "name": "Recruit.SkipRobot.name", - "help": "Recruit.SkipRobot.help" + "name": "MaaRecruit.SkipRobot.name", + "help": "MaaRecruit.SkipRobot.help" }, "Select3": { - "name": "Recruit.Select3.name", - "help": "Recruit.Select3.help" + "name": "MaaRecruit.Select3.name", + "help": "MaaRecruit.Select3.help" }, "Select4": { - "name": "Recruit.Select4.name", - "help": "Recruit.Select4.help" + "name": "MaaRecruit.Select4.name", + "help": "MaaRecruit.Select4.help" }, "Select5": { - "name": "Recruit.Select5.name", - "help": "Recruit.Select5.help" + "name": "MaaRecruit.Select5.name", + "help": "MaaRecruit.Select5.help" }, "Times": { - "name": "Recruit.Times.name", - "help": "Recruit.Times.help" + "name": "MaaRecruit.Times.name", + "help": "MaaRecruit.Times.help" }, "Expedite": { - "name": "Recruit.Expedite.name", - "help": "Recruit.Expedite.help" + "name": "MaaRecruit.Expedite.name", + "help": "MaaRecruit.Expedite.help" } }, - "Infrast": { + "MaaInfrast": { "_info": { - "name": "Infrast._info.name", - "help": "Infrast._info.help" + "name": "MaaInfrast._info.name", + "help": "MaaInfrast._info.help" }, "Facility": { - "name": "Infrast.Facility.name", - "help": "Infrast.Facility.help" + "name": "MaaInfrast.Facility.name", + "help": "MaaInfrast.Facility.help" }, "Drones": { - "name": "Infrast.Drones.name", - "help": "Infrast.Drones.help", + "name": "MaaInfrast.Drones.name", + "help": "MaaInfrast.Drones.help", "_NotUse": "_NotUse", "Money": "Money", "SyntheticJade": "SyntheticJade", @@ -248,58 +254,58 @@ "Chip": "Chip" }, "Threshold": { - "name": "Infrast.Threshold.name", - "help": "Infrast.Threshold.help" + "name": "MaaInfrast.Threshold.name", + "help": "MaaInfrast.Threshold.help" }, "Replenish": { - "name": "Infrast.Replenish.name", - "help": "Infrast.Replenish.help" + "name": "MaaInfrast.Replenish.name", + "help": "MaaInfrast.Replenish.help" } }, - "Mall": { + "MaaMall": { "_info": { - "name": "Mall._info.name", - "help": "Mall._info.help" + "name": "MaaMall._info.name", + "help": "MaaMall._info.help" }, "Shopping": { - "name": "Mall.Shopping.name", - "help": "Mall.Shopping.help" + "name": "MaaMall.Shopping.name", + "help": "MaaMall.Shopping.help" }, "BuyFirst": { - "name": "Mall.BuyFirst.name", - "help": "Mall.BuyFirst.help" + "name": "MaaMall.BuyFirst.name", + "help": "MaaMall.BuyFirst.help" }, "BlackList": { - "name": "Mall.BlackList.name", - "help": "Mall.BlackList.help" + "name": "MaaMall.BlackList.name", + "help": "MaaMall.BlackList.help" } }, - "Roguelike": { + "MaaRoguelike": { "_info": { - "name": "Roguelike._info.name", - "help": "Roguelike._info.help" + "name": "MaaRoguelike._info.name", + "help": "MaaRoguelike._info.help" }, "Mode": { - "name": "Roguelike.Mode.name", - "help": "Roguelike.Mode.help", + "name": "MaaRoguelike.Mode.name", + "help": "MaaRoguelike.Mode.help", "0": "0", "1": "1" }, "StartsCount": { - "name": "Roguelike.StartsCount.name", - "help": "Roguelike.StartsCount.help" + "name": "MaaRoguelike.StartsCount.name", + "help": "MaaRoguelike.StartsCount.help" }, "InvestmentsCount": { - "name": "Roguelike.InvestmentsCount.name", - "help": "Roguelike.InvestmentsCount.help" + "name": "MaaRoguelike.InvestmentsCount.name", + "help": "MaaRoguelike.InvestmentsCount.help" }, "StopWhenInvestmentFull": { - "name": "Roguelike.StopWhenInvestmentFull.name", - "help": "Roguelike.StopWhenInvestmentFull.help" + "name": "MaaRoguelike.StopWhenInvestmentFull.name", + "help": "MaaRoguelike.StopWhenInvestmentFull.help" }, "Squad": { - "name": "Roguelike.Squad.name", - "help": "Roguelike.Squad.help", + "name": "MaaRoguelike.Squad.name", + "help": "MaaRoguelike.Squad.help", "指挥分队": "指挥分队", "集群分队": "集群分队", "后勤分队": "后勤分队", @@ -312,30 +318,30 @@ "高规格分队": "高规格分队" }, "Roles": { - "name": "Roguelike.Roles.name", - "help": "Roguelike.Roles.help", + "name": "MaaRoguelike.Roles.name", + "help": "MaaRoguelike.Roles.help", "先手必胜": "先手必胜", "稳扎稳打": "稳扎稳打", "取长补短": "取长补短", "随心所欲": "随心所欲" }, "CoreChar": { - "name": "Roguelike.CoreChar.name", - "help": "Roguelike.CoreChar.help" + "name": "MaaRoguelike.CoreChar.name", + "help": "MaaRoguelike.CoreChar.help" } }, - "Copilot": { + "MaaCopilot": { "_info": { - "name": "Copilot._info.name", - "help": "Copilot._info.help" + "name": "MaaCopilot._info.name", + "help": "MaaCopilot._info.help" }, "FileName": { - "name": "Copilot.FileName.name", - "help": "Copilot.FileName.help" + "name": "MaaCopilot.FileName.name", + "help": "MaaCopilot.FileName.help" }, "Formation": { - "name": "Copilot.Formation.name", - "help": "Copilot.Formation.help" + "name": "MaaCopilot.Formation.name", + "help": "MaaCopilot.Formation.help" } } } \ No newline at end of file diff --git a/submodule/AlasMaaBridge/module/handler/handler.py b/submodule/AlasMaaBridge/module/handler/handler.py index 423a41d2b..d145557a9 100644 --- a/submodule/AlasMaaBridge/module/handler/handler.py +++ b/submodule/AlasMaaBridge/module/handler/handler.py @@ -5,7 +5,7 @@ from importlib import import_module from typing import Any from module.base.timer import Timer -from module.config.utils import read_file +from module.config.utils import read_file, deep_get from module.exception import RequestHumanTakeover from module.logger import logger @@ -72,15 +72,27 @@ class AssistantHandler: time.sleep(0.5) def generic_callback(self, m, d): + """ + 从MAA的回调中处理任务结束的信息。 + + 所有其他回调处理函数应遵循同样格式, + 在需要使用的时候加入callback_list, + 可以被随时移除,或在任务结束时自动清空。 + 参数的详细说明见https://github.com/MaaAssistantArknights/MaaAssistantArknights/blob/master/docs/3.2-回调信息协议.md + + Args: + m (Message): 消息类型 + d (dict): 消息详情 + """ if m == self.Message.AllTasksCompleted: self.signal = self.Message.AllTasksCompleted def penguin_id_callback(self, m, d): - if not self.config.Record_PenguinID \ + if not self.config.MaaRecord_PenguinID \ and m == self.Message.SubTaskExtraInfo \ - and d.get('what') == 'PenguinId': - self.config.Record_PenguinID = d["details"]["id"] - self.params["penguin_id"] = self.config.Record_PenguinID + and deep_get(d, keys='what') == 'PenguinId': + self.config.MaaRecord_PenguinID = deep_get(d, keys='details.id') + self.params["penguin_id"] = self.config.MaaRecord_PenguinID self.asst.set_task_params(self.task_id, self.params) self.callback_list.remove(self.penguin_id_callback) @@ -90,34 +102,34 @@ class AssistantHandler: def startup(self): self.maa_start('StartUp', { - "client_type": self.config.Emulator_PackageName, + "client_type": self.config.MaaEmulator_PackageName, "start_game_enabled": True }) self.config.task_delay(server_update=True) def fight(self): args = { - "stage": self.config.Fight_Stage, - "report_to_penguin": self.config.Record_ReportToPenguin, - "server": self.config.Emulator_Server, - "client_type": self.config.Emulator_PackageName, - "DrGrandet": self.config.Fight_DrGrandet, + "stage": self.config.MaaFight_Stage, + "report_to_penguin": self.config.MaaRecord_ReportToPenguin, + "server": self.config.MaaEmulator_Server, + "client_type": self.config.MaaEmulator_PackageName, + "DrGrandet": self.config.MaaFight_DrGrandet, } - if self.config.Fight_Medicine != 0: - args["medicine"] = self.config.Fight_Medicine - if self.config.Fight_Stone != 0: - args["stone"] = self.config.Fight_Stone - if self.config.Fight_Times != 0: - args["times"] = self.config.Fight_Times + if self.config.MaaFight_Medicine != 0: + args["medicine"] = self.config.MaaFight_Medicine + if self.config.MaaFight_Stone != 0: + args["stone"] = self.config.MaaFight_Stone + if self.config.MaaFight_Times != 0: + args["times"] = self.config.MaaFight_Times - if self.config.Fight_Drops: - old = read_file(os.path.join(self.config.Emulator_MaaPath, './resource/item_index.json')) + if self.config.MaaFight_Drops: + old = read_file(os.path.join(self.config.MaaEmulator_MaaPath, './resource/item_index.json')) new = {} for key, value in old.items(): new[value['name']] = key drops = {} - drops_filter = self.split_filter(self.config.Fight_Drops) + drops_filter = self.split_filter(self.config.MaaFight_Drops) for drop in drops_filter: drop = self.split_filter(drop, sep=':') try: @@ -126,9 +138,9 @@ class AssistantHandler: drops[drop[0]] = int(drop[1]) args['drops'] = drops - if self.config.Record_ReportToPenguin and self.config.Record_PenguinID: - args["penguin_id"] = self.config.Record_PenguinID - elif self.config.Record_ReportToPenguin and not self.config.Record_PenguinID: + if self.config.MaaRecord_ReportToPenguin and self.config.MaaRecord_PenguinID: + args["penguin_id"] = self.config.MaaRecord_PenguinID + elif self.config.MaaRecord_ReportToPenguin and not self.config.MaaRecord_PenguinID: self.callback_list.append(self.penguin_id_callback) if self.config.task.command == 'MaaAnnihilation': @@ -145,36 +157,36 @@ class AssistantHandler: def recruit(self): select = [] - if self.config.Recruit_Select3: + if self.config.MaaRecruit_Select3: select.append(3) - if self.config.Recruit_Select4: + if self.config.MaaRecruit_Select4: select.append(4) - if self.config.Recruit_Select5: + if self.config.MaaRecruit_Select5: select.append(5) args = { - "refresh": self.config.Recruit_Refresh, + "refresh": self.config.MaaRecruit_Refresh, "select": select, "confirm": select, - "times": self.config.Recruit_Times, - "expedite": self.config.Recruit_Expedite, - "skip_robot": self.config.Recruit_SkipRobot + "times": self.config.MaaRecruit_Times, + "expedite": self.config.MaaRecruit_Expedite, + "skip_robot": self.config.MaaRecruit_SkipRobot } - if self.config.Record_ReportToPenguin and self.config.Record_PenguinID: - args["penguin_id"] = self.config.Record_PenguinID - elif self.config.Record_ReportToPenguin and not self.config.Record_PenguinID: + if self.config.MaaRecord_ReportToPenguin and self.config.MaaRecord_PenguinID: + args["penguin_id"] = self.config.MaaRecord_PenguinID + elif self.config.MaaRecord_ReportToPenguin and not self.config.MaaRecord_PenguinID: self.callback_list.append(self.penguin_id_callback) self.maa_start('Recruit', args) self.config.task_delay(success=True) def infrast(self): - facility = self.split_filter(self.config.Infrast_Facility) + facility = self.split_filter(self.config.MaaInfrast_Facility) self.maa_start('Infrast', { "facility": facility, - "drones": self.config.Infrast_Drones, - "threshold": self.config.Infrast_Threshold + "drones": self.config.MaaInfrast_Drones, + "threshold": self.config.MaaInfrast_Threshold }) self.config.task_delay(success=True) @@ -185,10 +197,10 @@ class AssistantHandler: self.config.task_delay(server_update=True) def mall(self): - buy_first = self.split_filter(self.config.Mall_BuyFirst) - blacklist = self.split_filter(self.config.Mall_BlackList) + buy_first = self.split_filter(self.config.MaaMall_BuyFirst) + blacklist = self.split_filter(self.config.MaaMall_BlackList) self.maa_start('Mall', { - "shopping": self.config.Mall_Shopping, + "shopping": self.config.MaaMall_Shopping, "buy_first": buy_first, "blacklist": blacklist }) @@ -202,25 +214,29 @@ class AssistantHandler: def roguelike(self): args = { - "mode": self.config.Roguelike_Mode, - "starts_count": self.config.Roguelike_StartsCount, - "investments_count": self.config.Roguelike_InvestmentsCount, - "stop_when_investment_full": self.config.Roguelike_StopWhenInvestmentFull, - "squad": self.config.Roguelike_Squad, - "roles": self.config.Roguelike_Roles + "mode": self.config.MaaRoguelike_Mode, + "starts_count": self.config.MaaRoguelike_StartsCount, + "investments_count": self.config.MaaRoguelike_InvestmentsCount, + "stop_when_investment_full": self.config.MaaRoguelike_StopWhenInvestmentFull, + "squad": self.config.MaaRoguelike_Squad, + "roles": self.config.MaaRoguelike_Roles } - if self.config.Roguelike_CoreChar: - args["core_char"] = self.config.Roguelike_CoreChar + if self.config.MaaRoguelike_CoreChar: + args["core_char"] = self.config.MaaRoguelike_CoreChar self.maa_start('Roguelike', args) self.config.task_delay(success=True) def copilot(self): - path = self.config.Copilot_FileName + path = self.config.MaaCopilot_FileName homework = read_file(path) + stage = deep_get(homework, keys='stage_name') + if not stage: + logger.critical('作业文件不存在或已经损坏') + raise RequestHumanTakeover self.maa_start('Copilot', { - "stage_name": homework['stage_name'], + "stage_name": stage, "filename": path, - "formation": self.config.Copilot_Formation + "formation": self.config.MaaCopilot_Formation }) From 3c467a51b62c18a5fb9baa29471c6c183290ebee Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Wed, 14 Sep 2022 12:02:28 +0800 Subject: [PATCH 12/21] Fix: Configuration missing in MAA --- alas.py | 2 ++ module/config/config.py | 20 +++++++++++--- submodule/AlasMaaBridge/config/template.json | 10 +++++++ .../module/config/argument/args.json | 27 +++++++++++++++++++ .../module/config/argument/task.yaml | 3 +++ 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/alas.py b/alas.py index c5f8211f0..f61061f31 100644 --- a/alas.py +++ b/alas.py @@ -375,8 +375,10 @@ class AzurLaneAutoScript: def wait_until(self, future): """ Wait until a specific time. + Args: future (datetime): + Returns: bool: True if wait finished, False if config changed. """ diff --git a/module/config/config.py b/module/config/config.py index e96fe3bb1..cdfe426cb 100644 --- a/module/config/config.py +++ b/module/config/config.py @@ -46,6 +46,7 @@ def name_to_function(name): """ Args: name (str): + Returns: Function: """ @@ -318,6 +319,7 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher def multi_set(self): """ Set multiple arguments but save once. + Examples: with self.config.multi_set(): self.config.foo1 = 1 @@ -327,10 +329,12 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher def cross_get(self, keys, default=None): """ - Get configs from other tasks + Get configs from other tasks. + Args: keys (str, list[str]): Such as `{task}.Scheduler.Enable` default: + Returns: Any: """ @@ -338,10 +342,12 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher def cross_set(self, keys, value): """ - Set configs to other tasks + Set configs to other tasks. + Args: keys (str, list[str]): Such as `{task}.Scheduler.Enable` value (Any): + Returns: Any: """ @@ -354,6 +360,7 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher Set Scheduler.NextRun Should set at least one arguments. If multiple arguments are set, use the nearest. + Args: success (bool): If True, delay Scheduler.SuccessInterval @@ -415,6 +422,7 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher def opsi_task_delay(self, recon_scan=False, submarine_call=False, ap_limit=False): """ Delay the NextRun of all OpSi tasks. + Args: recon_scan (bool): True to delay all tasks requiring recon scan 27 min. submarine_call (bool): True to delay all tasks requiring submarine call 60 min. @@ -544,7 +552,7 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher @staticmethod def task_stop(message=""): """ - Stop current task + Stop current task. Raises: TaskEnd: @@ -577,7 +585,7 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher def check_task_switch(self, message=""): """ - Stop current task + Stop current task when task switched. Raises: TaskEnd: @@ -605,6 +613,7 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher """ Args: other (AzurLaneConfig, Config): + Returns: AzurLaneConfig """ @@ -674,12 +683,15 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher def temporary(self, **kwargs): """ Cover some settings, and recover later. + Usage: backup = self.config.cover(ENABLE_DAILY_REWARD=False) # do_something() backup.recover() + Args: **kwargs: + Returns: ConfigBackup: """ diff --git a/submodule/AlasMaaBridge/config/template.json b/submodule/AlasMaaBridge/config/template.json index 53ce2b492..a2a7b7e08 100644 --- a/submodule/AlasMaaBridge/config/template.json +++ b/submodule/AlasMaaBridge/config/template.json @@ -9,6 +9,16 @@ "MaaRecord": { "ReportToPenguin": false, "PenguinID": null + }, + "Emulator": { + "ServerName": "disabled" + }, + "Error": { + "SaveError": false, + "OnePushConfig": "provider: null" + }, + "Optimization": { + "WhenTaskQueueEmpty": "stay_there" } }, "MaaStartup": { diff --git a/submodule/AlasMaaBridge/module/config/argument/args.json b/submodule/AlasMaaBridge/module/config/argument/args.json index f5291df16..128416615 100644 --- a/submodule/AlasMaaBridge/module/config/argument/args.json +++ b/submodule/AlasMaaBridge/module/config/argument/args.json @@ -38,6 +38,33 @@ "type": "input", "value": null } + }, + "Emulator": { + "ServerName": { + "type": "input", + "value": "disabled", + "display": "hide" + } + }, + "Error": { + "SaveError": { + "type": "checkbox", + "value": false, + "display": "hide" + }, + "OnePushConfig": { + "type": "input", + "value": "provider: null", + "mode": "yaml", + "display": "hide" + } + }, + "Optimization": { + "WhenTaskQueueEmpty": { + "type": "input", + "value": "stay_there", + "display": "hide" + } } }, "MaaStartup": { diff --git a/submodule/AlasMaaBridge/module/config/argument/task.yaml b/submodule/AlasMaaBridge/module/config/argument/task.yaml index 03be8fe7a..20b1c4817 100644 --- a/submodule/AlasMaaBridge/module/config/argument/task.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/task.yaml @@ -7,6 +7,9 @@ Maa: - MaaEmulator - MaaRecord + - Emulator + - Error + - Optimization MaaStartup: - Scheduler From 27affa179d5df781e3fdf389413eb08f27fc31fd Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Sat, 17 Sep 2022 16:04:36 +0800 Subject: [PATCH 13/21] Opt: Optimized priority of MaaAward --- submodule/AlasMaaBridge/config/template.json | 6 +++--- submodule/AlasMaaBridge/module/config/argument/args.json | 6 +++--- .../AlasMaaBridge/module/config/argument/override.yaml | 7 +++++-- submodule/AlasMaaBridge/module/config/config.py | 5 +++-- submodule/AlasMaaBridge/module/handler/handler.py | 3 +-- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/submodule/AlasMaaBridge/config/template.json b/submodule/AlasMaaBridge/config/template.json index a2a7b7e08..786095d68 100644 --- a/submodule/AlasMaaBridge/config/template.json +++ b/submodule/AlasMaaBridge/config/template.json @@ -90,7 +90,7 @@ "Enable": false, "NextRun": "2020-01-01 00:00:00", "Command": "MaaRecruit", - "SuccessInterval": 540, + "SuccessInterval": 180, "FailureInterval": 120, "ServerUpdate": "04:00" }, @@ -109,7 +109,7 @@ "Enable": false, "NextRun": "2020-01-01 00:00:00", "Command": "MaaInfrast", - "SuccessInterval": 1200, + "SuccessInterval": 720, "FailureInterval": 120, "ServerUpdate": "04:00" }, @@ -152,7 +152,7 @@ "Command": "MaaAward", "SuccessInterval": 60, "FailureInterval": 120, - "ServerUpdate": "04:00" + "ServerUpdate": "04:00, 16:00" } }, "MaaRoguelike": { diff --git a/submodule/AlasMaaBridge/module/config/argument/args.json b/submodule/AlasMaaBridge/module/config/argument/args.json index 128416615..2e82b9fc5 100644 --- a/submodule/AlasMaaBridge/module/config/argument/args.json +++ b/submodule/AlasMaaBridge/module/config/argument/args.json @@ -309,7 +309,7 @@ }, "SuccessInterval": { "type": "input", - "value": 540, + "value": 180, "display": "hide" }, "FailureInterval": { @@ -372,7 +372,7 @@ }, "SuccessInterval": { "type": "input", - "value": 1200, + "value": 720, "display": "hide" }, "FailureInterval": { @@ -522,7 +522,7 @@ }, "ServerUpdate": { "type": "input", - "value": "04:00", + "value": "04:00, 16:00", "display": "hide" } } diff --git a/submodule/AlasMaaBridge/module/config/argument/override.yaml b/submodule/AlasMaaBridge/module/config/argument/override.yaml index 3aeb75d33..416d46d1d 100644 --- a/submodule/AlasMaaBridge/module/config/argument/override.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/override.yaml @@ -35,9 +35,12 @@ MaaFight: MaaRecruit: Scheduler: - SuccessInterval: 540 + SuccessInterval: 180 MaaInfrast: Scheduler: - SuccessInterval: 1200 + SuccessInterval: 720 +MaaAward: + Scheduler: + ServerUpdate: 04:00, 16:00 diff --git a/submodule/AlasMaaBridge/module/config/config.py b/submodule/AlasMaaBridge/module/config/config.py index 16ac5f1e8..4484e5878 100644 --- a/submodule/AlasMaaBridge/module/config/config.py +++ b/submodule/AlasMaaBridge/module/config/config.py @@ -12,9 +12,10 @@ class ArknightsConfig(AzurLaneConfig, ConfigUpdater, GeneratedConfig): SCHEDULER_PRIORITY = """ MaaStartup > MaaRecruit > MaaInfrast - > MaaVisit > MaaMall > MaaAward + > MaaVisit > MaaMall > MaaAnnihilation > MaaMaterial - > MaaFight > MaaRoguelike + > MaaFight > MaaAward + > MaaRoguelike """ def __init__(self, config_name, task=None): diff --git a/submodule/AlasMaaBridge/module/handler/handler.py b/submodule/AlasMaaBridge/module/handler/handler.py index d145557a9..8560e81da 100644 --- a/submodule/AlasMaaBridge/module/handler/handler.py +++ b/submodule/AlasMaaBridge/module/handler/handler.py @@ -53,6 +53,7 @@ class AssistantHandler: def maa_start(self, task_name, params): self.task_id = self.asst.append_task(task_name, params) + self.signal = None self.params = params self.callback_list.append(self.generic_callback) self.callback_timer.reset() @@ -63,8 +64,6 @@ class AssistantHandler: raise RequestHumanTakeover if self.signal == self.Message.AllTasksCompleted: - self.signal = None - self.task_id = None self.callback_list.clear() self.asst.stop() return From c42f526d5d949dfda255230fbd5e0f799320c779 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Sat, 17 Sep 2022 21:37:57 +0800 Subject: [PATCH 14/21] Opt: Interrupt MaaRoguelike when task switched --- .gitignore | 8 ++-- deploy/git.py | 2 - .../AlasMaaBridge/module/handler/handler.py | 42 +++++++++++++++---- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index fff55960c..76bca35cf 100644 --- a/.gitignore +++ b/.gitignore @@ -8,9 +8,6 @@ config/*.yaml config/*.json config/tmp* !config/template.json -submodule/AlasMaaBridge/config/*.json -submodule/AlasMaaBridge/config/tmp* -!submodule/AlasMaaBridge/config/template.json *.pyw dev_tools/debug_tools .idea @@ -22,6 +19,11 @@ config/reloadflag config/reloadalas test.py test/ + +submodule/AlasMaaBridge/config/*.json +submodule/AlasMaaBridge/config/tmp* +!submodule/AlasMaaBridge/config/template.json +map/ debug/ # Created by .ignore support plugin (hsz.mobi) diff --git a/deploy/git.py b/deploy/git.py index 91159f0f9..759e4b085 100644 --- a/deploy/git.py +++ b/deploy/git.py @@ -1,5 +1,3 @@ -import os - from deploy.config import DeployConfig from deploy.logger import logger from deploy.utils import * diff --git a/submodule/AlasMaaBridge/module/handler/handler.py b/submodule/AlasMaaBridge/module/handler/handler.py index 8560e81da..6507da902 100644 --- a/submodule/AlasMaaBridge/module/handler/handler.py +++ b/submodule/AlasMaaBridge/module/handler/handler.py @@ -51,6 +51,16 @@ class AssistantHandler: def split_filter(string, sep='>'): return [f.strip(' \t\r\n') for f in string.split(sep)] + def maa_stop(self): + self.asst.stop() + while 1: + if self.signal in [ + self.Message.AllTasksCompleted, + self.Message.TaskChainCompleted, + self.Message.TaskChainError + ]: + return + def maa_start(self, task_name, params): self.task_id = self.asst.append_task(task_name, params) self.signal = None @@ -63,9 +73,9 @@ class AssistantHandler: logger.critical('MAA no respond, probably stuck') raise RequestHumanTakeover - if self.signal == self.Message.AllTasksCompleted: + if self.signal is not None: + self.maa_stop() self.callback_list.clear() - self.asst.stop() return time.sleep(0.5) @@ -83,21 +93,33 @@ class AssistantHandler: m (Message): 消息类型 d (dict): 消息详情 """ - if m == self.Message.AllTasksCompleted: - self.signal = self.Message.AllTasksCompleted + if m in [ + self.Message.AllTasksCompleted, + self.Message.TaskChainCompleted, + self.Message.TaskChainError + ]: + self.signal = m def penguin_id_callback(self, m, d): if not self.config.MaaRecord_PenguinID \ and m == self.Message.SubTaskExtraInfo \ and deep_get(d, keys='what') == 'PenguinId': self.config.MaaRecord_PenguinID = deep_get(d, keys='details.id') - self.params["penguin_id"] = self.config.MaaRecord_PenguinID - self.asst.set_task_params(self.task_id, self.params) self.callback_list.remove(self.penguin_id_callback) def annihilation_callback(self, m, d): if m == self.Message.SubTaskError: - self.signal = self.Message.AllTasksCompleted + self.signal = m + + def roguelike_callback(self, m, d): + if self.task_switch_timer.reached(): + if self.config.task_switched(): + self.task_switch_timer = None + self.params['starts_count'] = 0 + self.asst.set_task_params(self.task_id, self.params) + self.callback_list.remove(self.roguelike_callback) + else: + self.task_switch_timer.reset() def startup(self): self.maa_start('StartUp', { @@ -223,8 +245,12 @@ class AssistantHandler: if self.config.MaaRoguelike_CoreChar: args["core_char"] = self.config.MaaRoguelike_CoreChar + self.task_switch_timer = Timer(30).start() + self.callback_list.append(self.roguelike_callback) self.maa_start('Roguelike', args) - self.config.task_delay(success=True) + + if self.task_switch_timer is not None: + self.config.Scheduler_Enable = False def copilot(self): path = self.config.MaaCopilot_FileName From a9ba299a0cd9c44706cf8459a40b4f6411f71186 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Sun, 18 Sep 2022 21:38:58 +0800 Subject: [PATCH 15/21] Upd: Link of MaaAssistantArknights in README --- README.md | 1 + README_en.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 950b576bf..aace9aea4 100644 --- a/README.md +++ b/README.md @@ -163,4 +163,5 @@ GUI development, thanks **[@18870](https://github.com/18870)** , say HURRAY. - [ALAuto](https://github.com/Egoistically/ALAuto),EN服的碧蓝航线脚本,已不再维护,Alas 模仿了其架构。 - [ALAuto homg_trans_beta](https://github.com/asd111333/ALAuto/tree/homg_trans_beta),Alas 引入了其中的单应性变换至海图识别模块中。 - [PyWebIO](https://github.com/pywebio/PyWebIO),Alas 使用的 GUI 库。 +- [MaaAssistantArknights](https://github.com/MaaAssistantArknights/MaaAssistantArknights),明日方舟小助手,全日常一键长草,现已加入Alas豪华午餐! diff --git a/README_en.md b/README_en.md index 89f7b5f63..bc296ed77 100644 --- a/README_en.md +++ b/README_en.md @@ -105,4 +105,5 @@ Oh yeah, don't forget to read the [development documentation](https://github.com - [ALAuto](https://github.com/Egoistically/ALAuto), Another Azur Lane bot for EN, not maintaining anymore. Alas imitated its structure. - [ALAuto homg_trans_beta](https://github.com/asd111333/ALAuto/tree/homg_trans_beta), Alas introduced its homography transition into map detection. - [PyWebIO](https://github.com/pywebio/PyWebIO), GUI framework that Alas uses. +- [MaaAssistantArknights](https://github.com/MaaAssistantArknights/MaaAssistantArknights), an Arknights assistant based on image recognition, helps you to complete daily quests efficiently! From 165f6a1c950f6eeaa2aea05dba4ff617ea3c23ed Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Mon, 19 Sep 2022 15:45:25 +0800 Subject: [PATCH 16/21] Upd: Modified location of submodule config --- .gitignore | 5 +--- .../template.json => config/template.maa.json | 20 ++++++++-------- module/config/utils.py | 6 +++-- module/submodule/submodule.py | 1 - module/submodule/utils.py | 24 ++++++++++--------- submodule/AlasMaaBridge/maa.py | 7 +++++- .../module/config/argument/args.json | 23 +++++++++--------- .../module/config/argument/argument.yaml | 3 ++- .../module/config/config_generated.py | 2 +- .../module/config/i18n/zh-CN.json | 2 +- 10 files changed, 50 insertions(+), 43 deletions(-) rename submodule/AlasMaaBridge/config/template.json => config/template.maa.json (90%) diff --git a/.gitignore b/.gitignore index 76bca35cf..2b616d03c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ config/*.yaml !config/deploy.*.yaml config/*.json config/tmp* -!config/template.json +!config/template*.json *.pyw dev_tools/debug_tools .idea @@ -20,9 +20,6 @@ config/reloadalas test.py test/ -submodule/AlasMaaBridge/config/*.json -submodule/AlasMaaBridge/config/tmp* -!submodule/AlasMaaBridge/config/template.json map/ debug/ diff --git a/submodule/AlasMaaBridge/config/template.json b/config/template.maa.json similarity index 90% rename from submodule/AlasMaaBridge/config/template.json rename to config/template.maa.json index 786095d68..fe0484ecd 100644 --- a/submodule/AlasMaaBridge/config/template.json +++ b/config/template.maa.json @@ -24,7 +24,7 @@ "MaaStartup": { "Scheduler": { "Enable": true, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaStartup", "SuccessInterval": 0, "FailureInterval": 0, @@ -34,7 +34,7 @@ "MaaAnnihilation": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaAnnihilation", "SuccessInterval": 480, "FailureInterval": 120, @@ -52,7 +52,7 @@ "MaaMaterial": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaMaterial", "SuccessInterval": 60, "FailureInterval": 120, @@ -70,7 +70,7 @@ "MaaFight": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaFight", "SuccessInterval": 480, "FailureInterval": 120, @@ -88,7 +88,7 @@ "MaaRecruit": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaRecruit", "SuccessInterval": 180, "FailureInterval": 120, @@ -107,7 +107,7 @@ "MaaInfrast": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaInfrast", "SuccessInterval": 720, "FailureInterval": 120, @@ -123,7 +123,7 @@ "MaaVisit": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaVisit", "SuccessInterval": 60, "FailureInterval": 120, @@ -133,7 +133,7 @@ "MaaMall": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaMall", "SuccessInterval": 60, "FailureInterval": 120, @@ -148,7 +148,7 @@ "MaaAward": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaAward", "SuccessInterval": 60, "FailureInterval": 120, @@ -158,7 +158,7 @@ "MaaRoguelike": { "Scheduler": { "Enable": false, - "NextRun": "2020-01-01 00:00:00", + "NextRun": "2020-01-01 04:00:00", "Command": "MaaRoguelike", "SuccessInterval": 60, "FailureInterval": 120, diff --git a/module/config/utils.py b/module/config/utils.py index 9790a44b4..382885d64 100644 --- a/module/config/utils.py +++ b/module/config/utils.py @@ -61,7 +61,7 @@ def filepath_config(filename, mod_name='alas'): if mod_name == 'alas': return os.path.join('./config', f'{filename}.json') else: - return os.path.join(filepath_mod(mod_name), './config', f'{filename}.json') + return os.path.join('./config', f'{filename}.{mod_name}.json') def filepath_code(): @@ -186,7 +186,9 @@ def alas_instance(): out = [] for file in os.listdir('./config'): name, extension = os.path.splitext(file) - if name != 'template' and extension == '.json': + config_name, mod_name = os.path.splitext(name) + mod_name = mod_name[1:] + if name != 'template' and extension == '.json' and mod_name == '': out.append(name) out.extend(mod_instance()) diff --git a/module/submodule/submodule.py b/module/submodule/submodule.py index 67f18cba5..c75e742bc 100644 --- a/module/submodule/submodule.py +++ b/module/submodule/submodule.py @@ -22,6 +22,5 @@ def load_config(config_name): config_lib = importlib.import_module( '.config', 'submodule.' + get_dir_name(mod_name) + '.module.config') - config = config_lib.load_config(config_name, '') return config_lib.load_config(config_name, '') diff --git a/module/submodule/utils.py b/module/submodule/utils.py index ad72189cf..af4306b6f 100644 --- a/module/submodule/utils.py +++ b/module/submodule/utils.py @@ -21,11 +21,12 @@ def filepath_mod(name): def mod_template(): out = [] - for mod_name, dir_name in list_mod(): - for file in os.listdir(os.path.join('./submodule', dir_name, 'config')): - name, extension = os.path.splitext(file) - if name == 'template' and extension == '.json': - out.append(f'{name}-{mod_name}') + for file in os.listdir('./config'): + name, extension = os.path.splitext(file) + config_name, mod_name = os.path.splitext(name) + mod_name = mod_name[1:] + if config_name == 'template' and extension == '.json' and mod_name != '': + out.append(f'{config_name}-{mod_name}') return out @@ -34,12 +35,13 @@ def mod_instance(): global MOD_CONFIG_DICT MOD_CONFIG_DICT.clear() out = [] - for mod_name, dir_name in list_mod(): - for file in os.listdir(os.path.join('./submodule', dir_name, 'config')): - name, extension = os.path.splitext(file) - if name != 'template' and extension == '.json': - out.append(name) - MOD_CONFIG_DICT[name] = mod_name + for file in os.listdir('./config'): + name, extension = os.path.splitext(file) + config_name, mod_name = os.path.splitext(name) + mod_name = mod_name[1:] + if config_name != 'template' and extension == '.json' and mod_name != '': + out.append(config_name) + MOD_CONFIG_DICT[config_name] = mod_name return out diff --git a/submodule/AlasMaaBridge/maa.py b/submodule/AlasMaaBridge/maa.py index eeedabbcb..d0879cf33 100644 --- a/submodule/AlasMaaBridge/maa.py +++ b/submodule/AlasMaaBridge/maa.py @@ -47,7 +47,12 @@ class ArknightsAutoScript(AzurLaneAutoScript): self.config.task_call('MaaStartup', True) self.config.task_stop() - AssistantHandler.load(self.config.MaaEmulator_MaaPath) + logger.info(f'MAA安装路径:{self.config.MaaEmulator_MaaPath}') + try: + AssistantHandler.load(self.config.MaaEmulator_MaaPath) + except ModuleNotFoundError: + logger.critical('找不到MAA,请检查安装路径是否正确') + exit(1) @AssistantHandler.Asst.CallBackType def callback(msg, details, arg): diff --git a/submodule/AlasMaaBridge/module/config/argument/args.json b/submodule/AlasMaaBridge/module/config/argument/args.json index 2e82b9fc5..60c4c03ab 100644 --- a/submodule/AlasMaaBridge/module/config/argument/args.json +++ b/submodule/AlasMaaBridge/module/config/argument/args.json @@ -22,7 +22,8 @@ "US", "JP", "KR" - ] + ], + "display": "hide" }, "MaaPath": { "type": "textarea", @@ -76,7 +77,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -109,7 +110,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -175,7 +176,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -235,7 +236,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -299,7 +300,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -362,7 +363,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -422,7 +423,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -455,7 +456,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -502,7 +503,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { @@ -535,7 +536,7 @@ }, "NextRun": { "type": "datetime", - "value": "2020-01-01 00:00:00", + "value": "2020-01-01 04:00:00", "validate": "datetime" }, "Command": { diff --git a/submodule/AlasMaaBridge/module/config/argument/argument.yaml b/submodule/AlasMaaBridge/module/config/argument/argument.yaml index b62de6dac..ced124031 100644 --- a/submodule/AlasMaaBridge/module/config/argument/argument.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/argument.yaml @@ -6,7 +6,7 @@ Scheduler: Enable: false - NextRun: 2020-01-01 00:00:00 + NextRun: 2020-01-01 04:00:00 Command: Maa SuccessInterval: value: 60 @@ -45,6 +45,7 @@ MaaEmulator: Server: value: CN option: [CN, US, JP, KR] + display: hide MaaPath: value: D:/Program Files/MAA type: textarea diff --git a/submodule/AlasMaaBridge/module/config/config_generated.py b/submodule/AlasMaaBridge/module/config/config_generated.py index 41e310ebd..8952fce09 100644 --- a/submodule/AlasMaaBridge/module/config/config_generated.py +++ b/submodule/AlasMaaBridge/module/config/config_generated.py @@ -11,7 +11,7 @@ class GeneratedConfig: # Group `Scheduler` Scheduler_Enable = False - Scheduler_NextRun = datetime.datetime(2020, 1, 1, 0, 0) + Scheduler_NextRun = datetime.datetime(2020, 1, 1, 4, 0) Scheduler_Command = 'Maa' Scheduler_SuccessInterval = 60 Scheduler_FailureInterval = 120 diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json index 40ef2a087..6eafd5620 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json @@ -144,7 +144,7 @@ }, "Server": { "name": "服务器", - "help": "会影响掉落和上传", + "help": "会影响掉落和上传,由于MAA的外服支持不完全,暂时隐藏选项", "CN": "CN", "US": "US", "JP": "JP", From 6680f6d9ce8290e5e09c9b37c4be6d8032a74d39 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:47:13 +0800 Subject: [PATCH 17/21] Upd: New options of MaaRecruit and MaaInfrast --- config/template.maa.json | 7 +++-- submodule/AlasMaaBridge/maa.py | 6 ----- .../module/config/argument/args.json | 16 ++++++++++-- .../module/config/argument/argument.yaml | 5 +++- .../module/config/argument/override.yaml | 4 --- .../module/config/config_generated.py | 5 +++- .../module/config/i18n/en-US.json | 12 +++++++++ .../module/config/i18n/ja-JP.json | 12 +++++++++ .../module/config/i18n/zh-CN.json | 14 +++++++++- .../module/config/i18n/zh-TW.json | 12 +++++++++ .../AlasMaaBridge/module/handler/handler.py | 26 ++++++++++++++++--- 11 files changed, 99 insertions(+), 20 deletions(-) diff --git a/config/template.maa.json b/config/template.maa.json index fe0484ecd..f305f1a11 100644 --- a/config/template.maa.json +++ b/config/template.maa.json @@ -97,9 +97,10 @@ "MaaRecruit": { "Refresh": true, "SkipRobot": true, - "Select3": true, + "Select3": false, "Select4": true, "Select5": true, + "Level3ShortTime": true, "Times": 4, "Expedite": false } @@ -109,7 +110,7 @@ "Enable": false, "NextRun": "2020-01-01 04:00:00", "Command": "MaaInfrast", - "SuccessInterval": 720, + "SuccessInterval": 60, "FailureInterval": 120, "ServerUpdate": "04:00" }, @@ -117,6 +118,8 @@ "Facility": "Mfg > Trade > Power > Control > Reception > Office > Dorm", "Drones": "Money", "Threshold": 0.3, + "Notstationed": true, + "Trust": true, "Replenish": false } }, diff --git a/submodule/AlasMaaBridge/maa.py b/submodule/AlasMaaBridge/maa.py index d0879cf33..7add07639 100644 --- a/submodule/AlasMaaBridge/maa.py +++ b/submodule/AlasMaaBridge/maa.py @@ -1,9 +1,7 @@ -import os import json from cached_property import cached_property from alas import AzurLaneAutoScript -from deploy.config import DeployConfig from module.exception import RequestHumanTakeover from module.logger import logger @@ -74,10 +72,6 @@ class ArknightsAutoScript(AzurLaneAutoScript): ArknightsAutoScript.callback = callback asst = AssistantHandler.Asst(callback) - if not asst.connect(os.path.abspath(DeployConfig().AdbExecutable), self.config.MaaEmulator_Serial): - logger.critical('Adb connect failed') - raise RequestHumanTakeover - return asst def maa_startup(self): diff --git a/submodule/AlasMaaBridge/module/config/argument/args.json b/submodule/AlasMaaBridge/module/config/argument/args.json index 60c4c03ab..82898cc5c 100644 --- a/submodule/AlasMaaBridge/module/config/argument/args.json +++ b/submodule/AlasMaaBridge/module/config/argument/args.json @@ -335,7 +335,7 @@ }, "Select3": { "type": "checkbox", - "value": true + "value": false }, "Select4": { "type": "checkbox", @@ -345,6 +345,10 @@ "type": "checkbox", "value": true }, + "Level3ShortTime": { + "type": "checkbox", + "value": true + }, "Times": { "type": "input", "value": 4 @@ -373,7 +377,7 @@ }, "SuccessInterval": { "type": "input", - "value": 720, + "value": 60, "display": "hide" }, "FailureInterval": { @@ -409,6 +413,14 @@ "type": "input", "value": 0.3 }, + "Notstationed": { + "type": "checkbox", + "value": true + }, + "Trust": { + "type": "checkbox", + "value": true + }, "Replenish": { "type": "checkbox", "value": false diff --git a/submodule/AlasMaaBridge/module/config/argument/argument.yaml b/submodule/AlasMaaBridge/module/config/argument/argument.yaml index ced124031..65059354c 100644 --- a/submodule/AlasMaaBridge/module/config/argument/argument.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/argument.yaml @@ -68,9 +68,10 @@ MaaFight: MaaRecruit: Refresh: true SkipRobot: true - Select3: true + Select3: false Select4: true Select5: true + Level3ShortTime: True Times: 4 Expedite: false @@ -82,6 +83,8 @@ MaaInfrast: value: Money option: [_NotUse, Money, SyntheticJade, CombatRecord, PureGold, OriginStone, Chip] Threshold: 0.3 + Notstationed: true + Trust: true Replenish: false MaaMall: diff --git a/submodule/AlasMaaBridge/module/config/argument/override.yaml b/submodule/AlasMaaBridge/module/config/argument/override.yaml index 416d46d1d..2101f2701 100644 --- a/submodule/AlasMaaBridge/module/config/argument/override.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/override.yaml @@ -37,10 +37,6 @@ MaaRecruit: Scheduler: SuccessInterval: 180 -MaaInfrast: - Scheduler: - SuccessInterval: 720 - MaaAward: Scheduler: ServerUpdate: 04:00, 16:00 diff --git a/submodule/AlasMaaBridge/module/config/config_generated.py b/submodule/AlasMaaBridge/module/config/config_generated.py index 8952fce09..0278b2308 100644 --- a/submodule/AlasMaaBridge/module/config/config_generated.py +++ b/submodule/AlasMaaBridge/module/config/config_generated.py @@ -48,9 +48,10 @@ class GeneratedConfig: # Group `MaaRecruit` MaaRecruit_Refresh = True MaaRecruit_SkipRobot = True - MaaRecruit_Select3 = True + MaaRecruit_Select3 = False MaaRecruit_Select4 = True MaaRecruit_Select5 = True + MaaRecruit_Level3ShortTime = True MaaRecruit_Times = 4 MaaRecruit_Expedite = False @@ -58,6 +59,8 @@ class GeneratedConfig: MaaInfrast_Facility = 'Mfg > Trade > Power > Control > Reception > Office > Dorm' MaaInfrast_Drones = 'Money' # _NotUse, Money, SyntheticJade, CombatRecord, PureGold, OriginStone, Chip MaaInfrast_Threshold = 0.3 + MaaInfrast_Notstationed = True + MaaInfrast_Trust = True MaaInfrast_Replenish = False # Group `MaaMall` diff --git a/submodule/AlasMaaBridge/module/config/i18n/en-US.json b/submodule/AlasMaaBridge/module/config/i18n/en-US.json index 35e538276..4c45bf3db 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/en-US.json +++ b/submodule/AlasMaaBridge/module/config/i18n/en-US.json @@ -224,6 +224,10 @@ "name": "MaaRecruit.Select5.name", "help": "MaaRecruit.Select5.help" }, + "Level3ShortTime": { + "name": "MaaRecruit.Level3ShortTime.name", + "help": "MaaRecruit.Level3ShortTime.help" + }, "Times": { "name": "MaaRecruit.Times.name", "help": "MaaRecruit.Times.help" @@ -257,6 +261,14 @@ "name": "MaaInfrast.Threshold.name", "help": "MaaInfrast.Threshold.help" }, + "Notstationed": { + "name": "MaaInfrast.Notstationed.name", + "help": "MaaInfrast.Notstationed.help" + }, + "Trust": { + "name": "MaaInfrast.Trust.name", + "help": "MaaInfrast.Trust.help" + }, "Replenish": { "name": "MaaInfrast.Replenish.name", "help": "MaaInfrast.Replenish.help" diff --git a/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json b/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json index 788cd7aca..2b940ac0b 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json +++ b/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json @@ -224,6 +224,10 @@ "name": "MaaRecruit.Select5.name", "help": "MaaRecruit.Select5.help" }, + "Level3ShortTime": { + "name": "MaaRecruit.Level3ShortTime.name", + "help": "MaaRecruit.Level3ShortTime.help" + }, "Times": { "name": "MaaRecruit.Times.name", "help": "MaaRecruit.Times.help" @@ -257,6 +261,14 @@ "name": "MaaInfrast.Threshold.name", "help": "MaaInfrast.Threshold.help" }, + "Notstationed": { + "name": "MaaInfrast.Notstationed.name", + "help": "MaaInfrast.Notstationed.help" + }, + "Trust": { + "name": "MaaInfrast.Trust.name", + "help": "MaaInfrast.Trust.help" + }, "Replenish": { "name": "MaaInfrast.Replenish.name", "help": "MaaInfrast.Replenish.help" diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json index 6eafd5620..76ea5ba1e 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json @@ -209,7 +209,7 @@ "help": "" }, "SkipRobot": { - "name": "手动确认1星", + "name": "手动确认\"支援机械\"", "help": "" }, "Select3": { @@ -224,6 +224,10 @@ "name": "自动确认5星", "help": "" }, + "Level3ShortTime": { + "name": "三星设置7:40而非9:00", + "help": "" + }, "Times": { "name": "最大招募次数", "help": "" @@ -257,6 +261,14 @@ "name": "基建工作心情阈值", "help": "取值范围0 - 1.0" }, + "Notstationed": { + "name": "不将已进驻的干员放入宿舍", + "help": "" + }, + "Trust": { + "name": "宿舍空余位置蹭信赖", + "help": "" + }, "Replenish": { "name": "源石碎片自动补货", "help": "" diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json b/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json index 7ccf6942a..ae9781704 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json @@ -224,6 +224,10 @@ "name": "MaaRecruit.Select5.name", "help": "MaaRecruit.Select5.help" }, + "Level3ShortTime": { + "name": "MaaRecruit.Level3ShortTime.name", + "help": "MaaRecruit.Level3ShortTime.help" + }, "Times": { "name": "MaaRecruit.Times.name", "help": "MaaRecruit.Times.help" @@ -257,6 +261,14 @@ "name": "MaaInfrast.Threshold.name", "help": "MaaInfrast.Threshold.help" }, + "Notstationed": { + "name": "MaaInfrast.Notstationed.name", + "help": "MaaInfrast.Notstationed.help" + }, + "Trust": { + "name": "MaaInfrast.Trust.name", + "help": "MaaInfrast.Trust.help" + }, "Replenish": { "name": "MaaInfrast.Replenish.name", "help": "MaaInfrast.Replenish.help" diff --git a/submodule/AlasMaaBridge/module/handler/handler.py b/submodule/AlasMaaBridge/module/handler/handler.py index 6507da902..1bfe9dddb 100644 --- a/submodule/AlasMaaBridge/module/handler/handler.py +++ b/submodule/AlasMaaBridge/module/handler/handler.py @@ -4,6 +4,7 @@ import time from importlib import import_module from typing import Any +from deploy.config import DeployConfig from module.base.timer import Timer from module.config.utils import read_file, deep_get from module.exception import RequestHumanTakeover @@ -74,6 +75,8 @@ class AssistantHandler: raise RequestHumanTakeover if self.signal is not None: + if self.signal == self.Message.TaskChainError: + raise RequestHumanTakeover self.maa_stop() self.callback_list.clear() return @@ -95,7 +98,6 @@ class AssistantHandler: """ if m in [ self.Message.AllTasksCompleted, - self.Message.TaskChainCompleted, self.Message.TaskChainError ]: self.signal = m @@ -121,7 +123,20 @@ class AssistantHandler: else: self.task_switch_timer.reset() + def connect(self): + adb = os.path.abspath(DeployConfig().AdbExecutable) + serial = self.config.MaaEmulator_Serial + + old_callback_list = self.callback_list + self.callback_list = [] + + if not self.asst.connect(adb, serial): + raise RequestHumanTakeover + + self.callback_list = old_callback_list + def startup(self): + self.connect() self.maa_start('StartUp', { "client_type": self.config.MaaEmulator_PackageName, "start_game_enabled": True @@ -207,9 +222,14 @@ class AssistantHandler: self.maa_start('Infrast', { "facility": facility, "drones": self.config.MaaInfrast_Drones, - "threshold": self.config.MaaInfrast_Threshold + "threshold": self.config.MaaInfrast_Threshold, + "replenish": self.config.MaaInfrast_Replenish, + "dorm_notstationed_enabled": self.config.MaaInfrast_Notstationed, + "drom_trust_enabled": self.config.MaaInfrast_Trust }) - self.config.task_delay(success=True) + # 根据心情阈值计算下次换班时间 + # 心情阈值 * 24 / 0.75 * 60 + self.config.task_delay(minute=self.config.MaaInfrast_Threshold * 1920) def visit(self): self.maa_start('Visit', { From 46fc9bddcf91f0e4ea2a76fed77504805a95041f Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Thu, 22 Sep 2022 11:00:16 +0800 Subject: [PATCH 18/21] Add: Custom infrast of MAA --- config/template.maa.json | 4 ++ .../module/config/argument/args.json | 10 ++++ .../module/config/argument/argument.yaml | 5 ++ .../module/config/argument/task.yaml | 1 + .../module/config/config_generated.py | 4 ++ .../module/config/i18n/en-US.json | 14 +++++ .../module/config/i18n/ja-JP.json | 14 +++++ .../module/config/i18n/zh-CN.json | 14 +++++ .../module/config/i18n/zh-TW.json | 14 +++++ .../AlasMaaBridge/module/handler/handler.py | 52 +++++++++++++++---- 10 files changed, 122 insertions(+), 10 deletions(-) diff --git a/config/template.maa.json b/config/template.maa.json index f305f1a11..e95170b9b 100644 --- a/config/template.maa.json +++ b/config/template.maa.json @@ -121,6 +121,10 @@ "Notstationed": true, "Trust": true, "Replenish": false + }, + "MaaCustomInfrast": { + "Enable": false, + "Filename": null } }, "MaaVisit": { diff --git a/submodule/AlasMaaBridge/module/config/argument/args.json b/submodule/AlasMaaBridge/module/config/argument/args.json index 82898cc5c..c5a62c305 100644 --- a/submodule/AlasMaaBridge/module/config/argument/args.json +++ b/submodule/AlasMaaBridge/module/config/argument/args.json @@ -425,6 +425,16 @@ "type": "checkbox", "value": false } + }, + "MaaCustomInfrast": { + "Enable": { + "type": "checkbox", + "value": false + }, + "Filename": { + "type": "textarea", + "value": null + } } }, "MaaVisit": { diff --git a/submodule/AlasMaaBridge/module/config/argument/argument.yaml b/submodule/AlasMaaBridge/module/config/argument/argument.yaml index 65059354c..25b64c2ec 100644 --- a/submodule/AlasMaaBridge/module/config/argument/argument.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/argument.yaml @@ -86,6 +86,11 @@ MaaInfrast: Notstationed: true Trust: true Replenish: false +MaaCustomInfrast: + Enable: false + Filename: + value: null + type: textarea MaaMall: Shopping: true diff --git a/submodule/AlasMaaBridge/module/config/argument/task.yaml b/submodule/AlasMaaBridge/module/config/argument/task.yaml index 20b1c4817..3d2a472a5 100644 --- a/submodule/AlasMaaBridge/module/config/argument/task.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/task.yaml @@ -33,6 +33,7 @@ MaaRecruit: MaaInfrast: - Scheduler - MaaInfrast + - MaaCustomInfrast MaaVisit: - Scheduler diff --git a/submodule/AlasMaaBridge/module/config/config_generated.py b/submodule/AlasMaaBridge/module/config/config_generated.py index 0278b2308..4eff2576d 100644 --- a/submodule/AlasMaaBridge/module/config/config_generated.py +++ b/submodule/AlasMaaBridge/module/config/config_generated.py @@ -63,6 +63,10 @@ class GeneratedConfig: MaaInfrast_Trust = True MaaInfrast_Replenish = False + # Group `MaaCustomInfrast` + MaaCustomInfrast_Enable = False + MaaCustomInfrast_Filename = None + # Group `MaaMall` MaaMall_Shopping = True MaaMall_BuyFirst = '招聘许可 > 龙门币' diff --git a/submodule/AlasMaaBridge/module/config/i18n/en-US.json b/submodule/AlasMaaBridge/module/config/i18n/en-US.json index 4c45bf3db..d64231664 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/en-US.json +++ b/submodule/AlasMaaBridge/module/config/i18n/en-US.json @@ -274,6 +274,20 @@ "help": "MaaInfrast.Replenish.help" } }, + "MaaCustomInfrast": { + "_info": { + "name": "MaaCustomInfrast._info.name", + "help": "MaaCustomInfrast._info.help" + }, + "Enable": { + "name": "MaaCustomInfrast.Enable.name", + "help": "MaaCustomInfrast.Enable.help" + }, + "Filename": { + "name": "MaaCustomInfrast.Filename.name", + "help": "MaaCustomInfrast.Filename.help" + } + }, "MaaMall": { "_info": { "name": "MaaMall._info.name", diff --git a/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json b/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json index 2b940ac0b..9a2656b21 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json +++ b/submodule/AlasMaaBridge/module/config/i18n/ja-JP.json @@ -274,6 +274,20 @@ "help": "MaaInfrast.Replenish.help" } }, + "MaaCustomInfrast": { + "_info": { + "name": "MaaCustomInfrast._info.name", + "help": "MaaCustomInfrast._info.help" + }, + "Enable": { + "name": "MaaCustomInfrast.Enable.name", + "help": "MaaCustomInfrast.Enable.help" + }, + "Filename": { + "name": "MaaCustomInfrast.Filename.name", + "help": "MaaCustomInfrast.Filename.help" + } + }, "MaaMall": { "_info": { "name": "MaaMall._info.name", diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json index 76ea5ba1e..e7eb66bd9 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json @@ -274,6 +274,20 @@ "help": "" } }, + "MaaCustomInfrast": { + "_info": { + "name": "自定义基建设置", + "help": "" + }, + "Enable": { + "name": "使用自定义基建配置", + "help": "" + }, + "Filename": { + "name": "自定义配置路径", + "help": "" + } + }, "MaaMall": { "_info": { "name": "信用商店", diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json b/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json index ae9781704..35294d729 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-TW.json @@ -274,6 +274,20 @@ "help": "MaaInfrast.Replenish.help" } }, + "MaaCustomInfrast": { + "_info": { + "name": "MaaCustomInfrast._info.name", + "help": "MaaCustomInfrast._info.help" + }, + "Enable": { + "name": "MaaCustomInfrast.Enable.name", + "help": "MaaCustomInfrast.Enable.help" + }, + "Filename": { + "name": "MaaCustomInfrast.Filename.name", + "help": "MaaCustomInfrast.Filename.help" + } + }, "MaaMall": { "_info": { "name": "MaaMall._info.name", diff --git a/submodule/AlasMaaBridge/module/handler/handler.py b/submodule/AlasMaaBridge/module/handler/handler.py index 1bfe9dddb..bddea788c 100644 --- a/submodule/AlasMaaBridge/module/handler/handler.py +++ b/submodule/AlasMaaBridge/module/handler/handler.py @@ -1,6 +1,7 @@ import os import sys import time +import datetime from importlib import import_module from typing import Any @@ -209,6 +210,9 @@ class AssistantHandler: "skip_robot": self.config.MaaRecruit_SkipRobot } + if self.config.MaaRecruit_Level3ShortTime: + args['recruitment_time'] = {'3': 460} + if self.config.MaaRecord_ReportToPenguin and self.config.MaaRecord_PenguinID: args["penguin_id"] = self.config.MaaRecord_PenguinID elif self.config.MaaRecord_ReportToPenguin and not self.config.MaaRecord_PenguinID: @@ -218,18 +222,47 @@ class AssistantHandler: self.config.task_delay(success=True) def infrast(self): - facility = self.split_filter(self.config.MaaInfrast_Facility) - self.maa_start('Infrast', { - "facility": facility, + args = { + "facility": self.split_filter(self.config.MaaInfrast_Facility), "drones": self.config.MaaInfrast_Drones, "threshold": self.config.MaaInfrast_Threshold, "replenish": self.config.MaaInfrast_Replenish, "dorm_notstationed_enabled": self.config.MaaInfrast_Notstationed, "drom_trust_enabled": self.config.MaaInfrast_Trust - }) - # 根据心情阈值计算下次换班时间 - # 心情阈值 * 24 / 0.75 * 60 - self.config.task_delay(minute=self.config.MaaInfrast_Threshold * 1920) + } + + if self.config.MaaCustomInfrast_Enable: + args['mode'] = 10000 + args['filename'] = self.config.MaaCustomInfrast_Filename + plans = deep_get(read_file(self.config.MaaCustomInfrast_Filename), keys='plans') + for i in range(len(plans)): + periods = deep_get(plans[i], keys='period') + if periods is None: + logger.critical('无法找到配置文件中的排班周期,请检查文件是否有效') + raise RequestHumanTakeover + for period in periods: + start_time = datetime.datetime.combine( + datetime.date.today(), + datetime.datetime.strptime(period[0], '%H:%M').time() + ) + end_time = datetime.datetime.combine( + datetime.date.today(), + datetime.datetime.strptime(period[1], '%H:%M').time() + ) + now_time = datetime.datetime.now() + if start_time <= now_time < end_time: + args['plan_index'] = i + break + if 'plan_index' in args: + break + + self.maa_start('Infrast', args) + if self.config.MaaCustomInfrast_Enable: + self.config.task_delay(target=end_time + datetime.timedelta(minutes=1)) + else: + # 根据心情阈值计算下次换班时间 + # 心情阈值 * 24 / 0.75 * 60 + self.config.task_delay(minute=self.config.MaaInfrast_Threshold * 1920) def visit(self): self.maa_start('Visit', { @@ -273,8 +306,7 @@ class AssistantHandler: self.config.Scheduler_Enable = False def copilot(self): - path = self.config.MaaCopilot_FileName - homework = read_file(path) + homework = read_file(self.config.MaaCopilot_FileName) stage = deep_get(homework, keys='stage_name') if not stage: logger.critical('作业文件不存在或已经损坏') @@ -282,6 +314,6 @@ class AssistantHandler: self.maa_start('Copilot', { "stage_name": stage, - "filename": path, + "filename": self.config.MaaCopilot_FileName, "formation": self.config.MaaCopilot_Formation }) From 500227517cb685b58f3e9f546768ee078227abd3 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Mon, 3 Oct 2022 20:01:00 +0800 Subject: [PATCH 19/21] Fix: Unable to confirm 3 stars without choose tags --- .gitignore | 3 --- submodule/AlasMaaBridge/module/handler/handler.py | 13 +++++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 2b616d03c..3491d1dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -20,9 +20,6 @@ config/reloadalas test.py test/ -map/ -debug/ - # Created by .ignore support plugin (hsz.mobi) ### JetBrains template diff --git a/submodule/AlasMaaBridge/module/handler/handler.py b/submodule/AlasMaaBridge/module/handler/handler.py index bddea788c..540d8020d 100644 --- a/submodule/AlasMaaBridge/module/handler/handler.py +++ b/submodule/AlasMaaBridge/module/handler/handler.py @@ -193,18 +193,18 @@ class AssistantHandler: self.config.task_delay(success=True) def recruit(self): - select = [] + confirm = [] if self.config.MaaRecruit_Select3: - select.append(3) + confirm.append(3) if self.config.MaaRecruit_Select4: - select.append(4) + confirm.append(4) if self.config.MaaRecruit_Select5: - select.append(5) + confirm.append(5) args = { "refresh": self.config.MaaRecruit_Refresh, - "select": select, - "confirm": select, + "select": [4, 5, 6], + "confirm": confirm, "times": self.config.MaaRecruit_Times, "expedite": self.config.MaaRecruit_Expedite, "skip_robot": self.config.MaaRecruit_SkipRobot @@ -231,6 +231,7 @@ class AssistantHandler: "drom_trust_enabled": self.config.MaaInfrast_Trust } + end_time = datetime.datetime.now() + datetime.timedelta(minutes=30) if self.config.MaaCustomInfrast_Enable: args['mode'] = 10000 args['filename'] = self.config.MaaCustomInfrast_Filename From ff86ce3aa9679548c92412a889cb0396c8324ae3 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Tue, 4 Oct 2022 13:31:41 +0800 Subject: [PATCH 20/21] Add: Mystery code support of MAA copilot --- config/template.maa.json | 2 +- submodule/AlasMaaBridge/maa.py | 4 +++- .../module/config/argument/args.json | 5 +++-- .../module/config/argument/argument.yaml | 2 +- .../module/config/argument/override.yaml | 1 + .../module/config/config_generated.py | 2 +- .../module/config/i18n/zh-CN.json | 4 ++-- .../AlasMaaBridge/module/handler/handler.py | 22 +++++++++++++++++-- 8 files changed, 32 insertions(+), 10 deletions(-) diff --git a/config/template.maa.json b/config/template.maa.json index e95170b9b..e95d17c2d 100644 --- a/config/template.maa.json +++ b/config/template.maa.json @@ -97,7 +97,7 @@ "MaaRecruit": { "Refresh": true, "SkipRobot": true, - "Select3": false, + "Select3": true, "Select4": true, "Select5": true, "Level3ShortTime": true, diff --git a/submodule/AlasMaaBridge/maa.py b/submodule/AlasMaaBridge/maa.py index 7add07639..18d6dd052 100644 --- a/submodule/AlasMaaBridge/maa.py +++ b/submodule/AlasMaaBridge/maa.py @@ -112,4 +112,6 @@ def loop(config_name): def maa_copilot(config_name): script = ArknightsAutoScript(config_name) script.config.bind('MaaCopilot') - AssistantHandler(config=script.config, asst=script.asst).copilot() + handler = AssistantHandler(config=script.config, asst=script.asst) + handler.connect() + handler.copilot() diff --git a/submodule/AlasMaaBridge/module/config/argument/args.json b/submodule/AlasMaaBridge/module/config/argument/args.json index c5a62c305..436124b36 100644 --- a/submodule/AlasMaaBridge/module/config/argument/args.json +++ b/submodule/AlasMaaBridge/module/config/argument/args.json @@ -288,7 +288,8 @@ }, "DrGrandet": { "type": "checkbox", - "value": false + "value": false, + "display": "hide" } } }, @@ -335,7 +336,7 @@ }, "Select3": { "type": "checkbox", - "value": false + "value": true }, "Select4": { "type": "checkbox", diff --git a/submodule/AlasMaaBridge/module/config/argument/argument.yaml b/submodule/AlasMaaBridge/module/config/argument/argument.yaml index 25b64c2ec..24dbb6803 100644 --- a/submodule/AlasMaaBridge/module/config/argument/argument.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/argument.yaml @@ -68,7 +68,7 @@ MaaFight: MaaRecruit: Refresh: true SkipRobot: true - Select3: false + Select3: true Select4: true Select5: true Level3ShortTime: True diff --git a/submodule/AlasMaaBridge/module/config/argument/override.yaml b/submodule/AlasMaaBridge/module/config/argument/override.yaml index 2101f2701..fa8c499cd 100644 --- a/submodule/AlasMaaBridge/module/config/argument/override.yaml +++ b/submodule/AlasMaaBridge/module/config/argument/override.yaml @@ -32,6 +32,7 @@ MaaFight: Stone: 0 Times: 0 Drops: null + DrGrandet: false MaaRecruit: Scheduler: diff --git a/submodule/AlasMaaBridge/module/config/config_generated.py b/submodule/AlasMaaBridge/module/config/config_generated.py index 4eff2576d..097af1d8c 100644 --- a/submodule/AlasMaaBridge/module/config/config_generated.py +++ b/submodule/AlasMaaBridge/module/config/config_generated.py @@ -48,7 +48,7 @@ class GeneratedConfig: # Group `MaaRecruit` MaaRecruit_Refresh = True MaaRecruit_SkipRobot = True - MaaRecruit_Select3 = False + MaaRecruit_Select3 = True MaaRecruit_Select4 = True MaaRecruit_Select5 = True MaaRecruit_Level3ShortTime = True diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json index e7eb66bd9..7856fb1ff 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json @@ -359,10 +359,10 @@ "MaaCopilot": { "_info": { "name": "作业设置", - "help": "请在有“开始行动”界面的按钮使用本功能\n更多作业下载见https://prts.plus/" + "help": "请在有“开始行动”按钮的界面使用本功能\n使用好友助战可以关闭“自动编队”,手动选择干员后开始\n悖论模拟需要关闭“自动编队”,并选好技能后处于“开始模拟”按钮的界面再开始\n神秘代码获取见https://prts.plus/,更多作业下载可以加MAA作业群" }, "FileName": { - "name": "作业路径", + "name": "作业路径/神秘代码", "help": "" }, "Formation": { diff --git a/submodule/AlasMaaBridge/module/handler/handler.py b/submodule/AlasMaaBridge/module/handler/handler.py index 540d8020d..3cc1c5019 100644 --- a/submodule/AlasMaaBridge/module/handler/handler.py +++ b/submodule/AlasMaaBridge/module/handler/handler.py @@ -1,6 +1,8 @@ import os import sys +import json import time +import requests import datetime from importlib import import_module from typing import Any @@ -307,7 +309,23 @@ class AssistantHandler: self.config.Scheduler_Enable = False def copilot(self): - homework = read_file(self.config.MaaCopilot_FileName) + filename = self.config.MaaCopilot_FileName + if filename.startswith('maa://'): + logger.info('正在从神秘代码中下载作业') + r = requests.get(f"https://api.prts.plus/copilot/get/{filename.strip('maa://')}", timeout=30) + if r.status_code != 200: + logger.critical('作业文件下载失败,请检查神秘代码或网络状况') + raise RequestHumanTakeover + logger.info('作业下载完毕') + + r.encoding = 'utf-8' + buf = json.loads(r.text)['data']['content'].encode('utf-8') + filename = os.path.join(self.config.MaaEmulator_MaaPath, './resource/_temp_copilot.json') + filename = filename.replace('\\', '/').replace('./', '/').replace('//', '/') + with open(filename, 'wb') as f: + f.write(buf) + + homework = read_file(filename) stage = deep_get(homework, keys='stage_name') if not stage: logger.critical('作业文件不存在或已经损坏') @@ -315,6 +333,6 @@ class AssistantHandler: self.maa_start('Copilot', { "stage_name": stage, - "filename": self.config.MaaCopilot_FileName, + "filename": filename, "formation": self.config.MaaCopilot_Formation }) From b7812b48f095a3248ed186dc9b8fcda924471399 Mon Sep 17 00:00:00 2001 From: SarContDeli <48789988+SaiCateDoan@users.noreply.github.com> Date: Wed, 5 Oct 2022 19:41:03 +0800 Subject: [PATCH 21/21] Fix: Unable to restart alas after updated --- module/webui/process_manager.py | 2 +- submodule/AlasMaaBridge/module/config/i18n/zh-CN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/webui/process_manager.py b/module/webui/process_manager.py index 8e032c97f..c0f124aee 100644 --- a/module/webui/process_manager.py +++ b/module/webui/process_manager.py @@ -204,7 +204,7 @@ class ProcessManager: for process in _instances: logger.info(f"Starting [{process.config_name}]") - process.start(func="Alas", ev=ev) + process.start(func=get_config_mod(process.config_name), ev=ev) try: os.remove("./config/reloadalas") diff --git a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json index 7856fb1ff..c5da19a9e 100644 --- a/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json +++ b/submodule/AlasMaaBridge/module/config/i18n/zh-CN.json @@ -152,7 +152,7 @@ }, "MaaPath": { "name": "MAA安装路径", - "help": "" + "help": "警告:由于MAA本身不支持多开,如果想要使用多开功能需要手动复制MAA,否则会导致严重错误" } }, "MaaRecord": {