From 63cb1aaa7406277e55b96a7c056f910daedabf07 Mon Sep 17 00:00:00 2001 From: DLmaster361 Date: Tue, 15 Apr 2025 22:15:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=87=AA=E5=8A=A8=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 2 +- app/models/MAA.py | 226 ++++++++++++++++------------- app/ui/setting.py | 14 +- app/utils/downloader.py | 11 +- resources/docs/MAA_config_info.txt | 4 +- resources/version.json | 11 +- 6 files changed, 151 insertions(+), 117 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index 57e8394..92fa29c 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -599,7 +599,7 @@ class MaaUserConfig(QConfig): class AppConfig(GlobalConfig): - VERSION = "4.3.3.1" + VERSION = "4.3.4.1" gameid_refreshed = Signal() PASSWORD_refreshed = Signal() diff --git a/app/models/MAA.py b/app/models/MAA.py index 9c8ad57..a5324aa 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -186,7 +186,7 @@ class MaaManager(QObject): logger.info(f"{self.name} | 开始代理用户: {user[0]}") - # 初始化代理情况记录和模式替换记录 + # 初始化代理情况记录和模式替换表 run_book = {"Annihilation": False, "Routine": False} mode_book = { "Annihilation": "自动代理_剿灭", @@ -196,92 +196,80 @@ class MaaManager(QObject): # 简洁模式用户默认开启日常选项 if user_data["Info"]["Mode"] == "简洁": user_data["Info"]["Routine"] = True + # 详细模式用户首次代理需打开模拟器 elif user_data["Info"]["Mode"] == "详细": - check_book = { - "Annihilation": True, - "Routine": True, - } + self.if_open_emulator = True user_logs_list = [] user_start_time = datetime.now() - # 尝试次数循环 - for i in range(self.set["RunSet"]["RunTimesLimit"]): + # 剿灭-日常模式循环 + for mode in ["Annihilation", "Routine"]: if self.isInterruptionRequested: break - logger.info( - f"{self.name} | 用户: {user[0]} - 尝试次数: {i + 1}/{self.set["RunSet"]["RunTimesLimit"]}" + # 剿灭模式;满足条件跳过剿灭 + if ( + mode == "Annihilation" + and self.set["RunSet"]["AnnihilationWeeklyLimit"] + and datetime.strptime( + user_data["Data"]["LastAnnihilationDate"], "%Y-%m-%d" + ).isocalendar()[:2] + == datetime.strptime(curdate, "%Y-%m-%d").isocalendar()[:2] + ): + logger.info( + f"{self.name} | 用户: {user_data["Info"]["Name"]} - 本周剿灭模式已达上限,跳过执行剿灭任务" + ) + run_book[mode] = True + continue + else: + self.weekly_annihilation_limit_reached = False + + if not user_data["Info"][mode]: + run_book[mode] = True + continue + + if user_data["Info"]["Mode"] == "详细": + + if not ( + self.data[user[2]]["Path"] / f"{mode}/gui.json" + ).exists(): + logger.error( + f"{self.name} | 用户: {user[0]} - 未找到{mode_book[mode][5:7]}配置文件" + ) + self.push_info_bar.emit( + "error", + "启动MAA代理进程失败", + f"未找到{user[0]}的{mode_book[mode][5:7]}配置文件!", + -1, + ) + run_book[mode] = False + continue + + # 更新当前模式到界面 + self.update_user_list.emit( + [ + ( + [f"{_[0]} - {mode_book[mode][5:7]}", _[1], _[2]] + if _[2] == user[2] + else _ + ) + for _ in self.user_list + ] ) - # 剿灭-日常模式循环 - for mode in ["Annihilation", "Routine"]: + # 尝试次数循环 + for i in range(self.set["RunSet"]["RunTimesLimit"]): if self.isInterruptionRequested: break - # 剿灭模式;满足条件跳过剿灭 - if ( - mode == "Annihilation" - and self.set["RunSet"]["AnnihilationWeeklyLimit"] - and datetime.strptime( - user_data["Data"]["LastAnnihilationDate"], "%Y-%m-%d" - ).isocalendar()[:2] - == datetime.strptime(curdate, "%Y-%m-%d").isocalendar()[:2] - ): - logger.info( - f"{self.name} | 用户: {user_data["Info"]["Name"]} - 本周剿灭模式已达上限,跳过执行剿灭任务" - ) - run_book[mode] = True - continue - else: - self.weekly_annihilation_limit_reached = False - - if not user_data["Info"][mode]: - run_book[mode] = True - continue if run_book[mode]: - continue + break logger.info( - f"{self.name} | 用户: {user[0]} - 模式: {mode_book[mode]}" - ) - - if user_data["Info"]["Mode"] == "详细": - - self.if_open_emulator = True - - if ( - check_book[mode] - and not ( - self.data[user[2]]["Path"] / f"{mode}/gui.json" - ).exists() - ): - logger.error( - f"{self.name} | 用户: {user[0]} - 未找到{mode_book[mode][5:7]}配置文件" - ) - self.push_info_bar.emit( - "error", - "启动MAA代理进程失败", - f"未找到{user[0]}的{mode_book[mode][5:7]}配置文件!", - -1, - ) - check_book[mode] = False - continue - elif not check_book[mode]: - continue - - # 更新当前模式到界面 - self.update_user_list.emit( - [ - ( - [f"{_[0]} - {mode_book[mode][5:7]}", _[1], _[2]] - if _[2] == user[2] - else _ - ) - for _ in self.user_list - ] + f"{self.name} | 用户: {user[0]} - 模式: {mode_book[mode]} - 尝试次数: {i + 1}/{self.set["RunSet"]["RunTimesLimit"]}" ) # 配置MAA @@ -293,24 +281,50 @@ class MaaManager(QObject): self.emulator_path = Path( set["Configurations"]["Default"]["Start.EmulatorPath"] ) + self.emulator_arguments = set["Configurations"]["Default"][ + "Start.EmulatorAddCommand" + ].split() self.ADB_path = Path( set["Configurations"]["Default"]["Connect.AdbPath"] ) + self.ADB_address = set["Configurations"]["Default"][ + "Connect.Address" + ] self.if_kill_emulator = bool( set["Configurations"]["Default"]["MainFunction.PostActions"] == "12" ) + self.if_open_emulator_process = bool( + set["Configurations"]["Default"][ + "Start.OpenEmulatorAfterLaunch" + ] + == "True" + ) # 添加静默进程标记 Config.silence_list.append(self.emulator_path) # 增强任务:任务开始前强杀ADB if "ADB" in self.set["RunSet"]["EnhanceTask"]: System.kill_process(self.ADB_path) + else: + try: + subprocess.run( + [self.ADB_path, "disconnect", self.ADB_address], + creationflags=subprocess.CREATE_NO_WINDOW, + ) + except subprocess.CalledProcessError as e: + # 忽略错误,因为可能本来就没有连接 + logger.warning(f"{self.name} | 释放ADB时出现异常:{e}") + + if self.if_open_emulator_process: + self.emulator_process = subprocess.Popen( + [self.emulator_path, *self.emulator_arguments], + creationflags=subprocess.CREATE_NO_WINDOW, + ) # 创建MAA任务 maa = subprocess.Popen( [self.maa_exe_path], - shell=True, creationflags=subprocess.CREATE_NO_WINDOW, ) # 监测MAA运行状态 @@ -339,8 +353,13 @@ class MaaManager(QObject): ) # 无命令行中止MAA与其子程序 System.kill_process(self.maa_exe_path) + if "Emulator" in self.set["RunSet"]["EnhanceTask"]: System.kill_process(self.emulator_path) + else: + self.emulator_process.terminate() + self.emulator_process.wait() + self.if_open_emulator = True # 推送异常通知 Notify.push_plyer( @@ -357,14 +376,25 @@ class MaaManager(QObject): # 移除静默进程标记 Config.silence_list.remove(self.emulator_path) - # 增强任务:任务结束后强杀ADB和模拟器 + # 增强任务:任务结束后强杀ADB和模拟器或释放进程 if "ADB" in self.set["RunSet"]["EnhanceTask"]: System.kill_process(self.ADB_path) - if ( - self.if_kill_emulator - and "Emulator" in self.set["RunSet"]["EnhanceTask"] - ): - System.kill_process(self.emulator_path) + else: + try: + subprocess.run( + [self.ADB_path, "disconnect", self.ADB_address], + creationflags=subprocess.CREATE_NO_WINDOW, + ) + except subprocess.CalledProcessError as e: + # 忽略错误,因为可能本来就没有连接 + logger.warning(f"{self.name} | 释放ADB时出现异常:{e}") + if self.if_kill_emulator: + if "Emulator" in self.set["RunSet"]["EnhanceTask"]: + System.kill_process(self.emulator_path) + else: + self.emulator_process.terminate() + self.emulator_process.wait() + self.if_open_emulator = True # 记录剿灭情况 if ( @@ -392,23 +422,6 @@ class MaaManager(QObject): {"user_name": user_data["Info"]["Name"]}, ) - # 成功完成代理的用户修改相关参数 - if run_book["Annihilation"] and run_book["Routine"]: - if ( - user_data["Data"]["ProxyTimes"] == 0 - and user_data["Info"]["RemainedDay"] != -1 - ): - user_data["Info"]["RemainedDay"] -= 1 - user_data["Data"]["ProxyTimes"] += 1 - user[1] = "完成" - Notify.push_plyer( - "成功完成一个自动代理任务!", - f"已完成用户 {user[0].replace("_", " 今天的")}任务", - f"已完成 {user[0].replace("_", " 的")}", - 3, - ) - break - if Config.get(Config.notify_IfSendStatistic): statistics = Config.merge_maa_logs("指定项", user_logs_list) @@ -428,8 +441,23 @@ class MaaManager(QObject): "统计信息", f"用户 {user[0]} 的自动代理统计报告", statistics ) - # 录入代理失败的用户 - if not (run_book["Annihilation"] and run_book["Routine"]): + if run_book["Annihilation"] and run_book["Routine"]: + # 成功完成代理的用户修改相关参数 + if ( + user_data["Data"]["ProxyTimes"] == 0 + and user_data["Info"]["RemainedDay"] != -1 + ): + user_data["Info"]["RemainedDay"] -= 1 + user_data["Data"]["ProxyTimes"] += 1 + user[1] = "完成" + Notify.push_plyer( + "成功完成一个自动代理任务!", + f"已完成用户 {user[0].replace("_", " 今天的")}任务", + f"已完成 {user[0].replace("_", " 的")}", + 3, + ) + else: + # 录入代理失败的用户 user[1] = "异常" self.update_user_list.emit(self.user_list) @@ -475,7 +503,6 @@ class MaaManager(QObject): # 创建MAA任务 maa = subprocess.Popen( [self.maa_exe_path], - shell=True, creationflags=subprocess.CREATE_NO_WINDOW, ) @@ -545,7 +572,6 @@ class MaaManager(QObject): # 创建MAA任务 maa = subprocess.Popen( [self.maa_exe_path], - shell=True, creationflags=subprocess.CREATE_NO_WINDOW, ) # 记录当前时间 @@ -1273,11 +1299,7 @@ class MaaManager(QObject): ] = "False" # 生息演算 # 启动模拟器仅生效一次 - if ( - "设置MAA" not in mode - and self.if_open_emulator - and self.set["RunSet"]["TaskTransitionMethod"] != "ExitEmulator" - ): + if "设置MAA" not in mode and self.if_open_emulator: self.if_open_emulator = False # 覆写配置文件 diff --git a/app/ui/setting.py b/app/ui/setting.py index 5b6ba60..92c3220 100644 --- a/app/ui/setting.py +++ b/app/ui/setting.py @@ -51,6 +51,7 @@ import shutil import requests import subprocess from datetime import datetime +from packaging import version from pathlib import Path from typing import Dict, List, Union @@ -337,7 +338,9 @@ class Setting(QWidget): ) # 有版本更新 - if remote_version > current_version: + if version.parse(version_text(remote_version)) > version.parse( + version_text(current_version) + ): version_info_json: Dict[str, Dict[str, str]] = json.loads( re.sub( @@ -354,9 +357,11 @@ class Setting(QWidget): all_version_info = {} for v_i in [ info - for version, info in version_info_json.items() - if list(map(int, version.split("."))) > current_version + for ver, info in version_info_json.items() + if version.parse(version_text(list(map(int, ver.split("."))))) + > version.parse(version_text(current_version)) ]: + for key, value in v_i.items(): if key in update_version_info: update_version_info[key] += value.copy() @@ -401,8 +406,7 @@ class Setting(QWidget): return None subprocess.Popen( - str(Config.app_path / "AUTO_Updater.active.exe"), - shell=True, + [Config.app_path / "AUTO_Updater.active.exe"], creationflags=subprocess.CREATE_NO_WINDOW, ) self.window().close() diff --git a/app/utils/downloader.py b/app/utils/downloader.py index 7cde9a9..a0864ed 100644 --- a/app/utils/downloader.py +++ b/app/utils/downloader.py @@ -33,6 +33,7 @@ import subprocess import time import win32crypt import base64 +from packaging import version from functools import partial from pathlib import Path @@ -529,14 +530,12 @@ class DownloadManager(QDialog): # 主程序更新完成后打开对应程序 if not self.isInterruptionRequested and self.name == "AUTO_MAA": subprocess.Popen( - str(self.app_path / "AUTO_MAA.exe"), - shell=True, + [self.app_path / "AUTO_MAA.exe"], creationflags=subprocess.CREATE_NO_WINDOW, ) elif not self.isInterruptionRequested and self.name == "MAA": subprocess.Popen( - str(self.app_path / "MAA.exe"), - shell=True, + [self.app_path / "MAA.exe"], creationflags=subprocess.CREATE_NO_WINDOW, ) @@ -720,7 +719,9 @@ if __name__ == "__main__": (app_path / "changes.json").unlink() # 启动更新线程 - if remote_version > current_version: + if version.parse(version_text(remote_version)) > version.parse( + version_text(current_version) + ): app = AUTO_MAA_Downloader( app_path, "AUTO_MAA", diff --git a/resources/docs/MAA_config_info.txt b/resources/docs/MAA_config_info.txt index 1510c73..a7cf7fb 100644 --- a/resources/docs/MAA_config_info.txt +++ b/resources/docs/MAA_config_info.txt @@ -38,6 +38,8 @@ #设置 "Start.ClientType": "Bilibili"、 "Official" #服务器 G"Timer.Timer1": "False" #时间设置1 +"Connect.AdbPath" #ADB路径 +"Connect.Address": "127.0.0.1:16448" #连接地址 G"VersionUpdate.ScheduledUpdateCheck": "True" #定时检查更新 G"VersionUpdate.AutoDownloadUpdatePackage": "True" #自动下载更新包 G"VersionUpdate.AutoInstallUpdatePackage": "True" #自动安装更新包 @@ -47,4 +49,4 @@ G"Start.MinimizeDirectly": "True" #启动MAA后直接最小化 G"GUI.UseTray": "True" #显示托盘图标 G"GUI.MinimizeToTray": "False" #最小化时隐藏至托盘 "Start.EmulatorPath" #模拟器路径 -"Connect.AdbPath" #ADB路径 \ No newline at end of file +"Start.EmulatorAddCommand": "-v 2" #附加命令 \ No newline at end of file diff --git a/resources/version.json b/resources/version.json index 6efddc7..0752ac1 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,11 +1,16 @@ { - "main_version": "4.3.3.1", + "main_version": "4.3.4.1", "updater_version": "1.0.0.0", "announcement": "\n## 新增功能\n- 屏蔽MuMu模拟器开屏广告功能上线\n- 更新器支持多线程下载\n- 添加强制关闭ADB与模拟器等增强任务项\n## 修复BUG\n- 修复统计信息HTML模板公招匹配错误\n- 修复密码显示按钮动画异常\n- 修复`检测到MAA未能实际执行任务`报错被异常屏蔽\n- 修复MAA超时判定异常失效\n## 程序优化\n- 关机等电源操作添加100s倒计时\n- 人工排查弹窗方法优化\n- 人工排查时自动屏蔽静默操作\n- 公告样式优化", "version_info": { - "4.3.3.1": { + "4.3.4.1": { + "新增功能": [ + "开始任务前自动释放ADB端口" + ], "程序优化": [ - "request 添加超时限制" + "request 添加超时限制", + "用户任务运行流程改进", + "自动代理中模拟器改由AUTO_MAA控制" ] }, "4.3.3.0": {