From 292e7f51e012436309a90516b5219453c8a3e6d1 Mon Sep 17 00:00:00 2001 From: DLmaster Date: Fri, 14 Feb 2025 16:27:18 +0800 Subject: [PATCH] =?UTF-8?q?chore(core):=20=E5=8D=87=E7=BA=A7=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E7=9B=91=E7=9C=8B=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/__init__.py | 8 +- app/core/task_manager.py | 13 +- app/core/timer.py | 8 +- app/models/MAA.py | 320 ++++++++++++++++++-------------------- app/ui/dispatch_center.py | 10 +- app/ui/main_window.py | 12 +- app/ui/member_manager.py | 6 +- resources/version.json | 2 +- 8 files changed, 184 insertions(+), 195 deletions(-) diff --git a/app/core/__init__.py b/app/core/__init__.py index 8990b48..3b8b5a3 100644 --- a/app/core/__init__.py +++ b/app/core/__init__.py @@ -31,8 +31,8 @@ __license__ = "GPL-3.0 license" from .config import AppConfig, QueueConfig, MaaConfig, Config from .main_info_bar import MainInfoBar -from .task_manager import Task, Task_manager -from .timer import Main_timer +from .task_manager import Task, TaskManager +from .timer import MainTimer __all__ = [ "AppConfig", @@ -41,6 +41,6 @@ __all__ = [ "MaaConfig", "MainInfoBar", "Task", - "Task_manager", - "Main_timer", + "TaskManager", + "MainTimer", ] diff --git a/app/core/task_manager.py b/app/core/task_manager.py index c2217e7..afe43fa 100644 --- a/app/core/task_manager.py +++ b/app/core/task_manager.py @@ -147,7 +147,7 @@ class Task(QThread): ) ) self.task.accomplish.connect( - lambda log: self.save_log(self.task_dict[i][0], log) + lambda log: self.task_accomplish(self.task_dict[i][0], log) ) self.task.run() @@ -173,13 +173,14 @@ class Task(QThread): return member_dict - def save_log(self, name: str, log: dict): + def task_accomplish(self, name: str, log: dict): """保存保存任务结果""" self.logs.append([name, log]) + self.task.deleteLater() -class TaskManager(QObject): +class _TaskManager(QObject): """业务调度器""" create_gui = Signal(Task) @@ -187,7 +188,7 @@ class TaskManager(QObject): push_info_bar = Signal(str, str, str, int) def __init__(self): - super(TaskManager, self).__init__() + super(_TaskManager, self).__init__() self.task_dict: Dict[str, Task] = {} @@ -252,6 +253,8 @@ class TaskManager(QObject): logger.info(f"任务结束:{name}") MainInfoBar.push_info_bar("info", "任务结束", name, 3000) + self.task_dict[name].deleteLater() + if len(logs) > 0: time = logs[0][1]["Time"] history = "" @@ -290,4 +293,4 @@ class TaskManager(QObject): self.task_dict[name].question_response.emit(bool(choice.exec_())) -Task_manager = TaskManager() +TaskManager = _TaskManager() diff --git a/app/core/timer.py b/app/core/timer.py index 6664a4b..97357b2 100644 --- a/app/core/timer.py +++ b/app/core/timer.py @@ -33,11 +33,11 @@ from datetime import datetime import pyautogui from .config import Config -from .task_manager import Task_manager +from .task_manager import TaskManager from app.services import System -class MainTimer(QWidget): +class _MainTimer(QWidget): def __init__( self, @@ -81,7 +81,7 @@ class MainTimer(QWidget): ): logger.info(f"定时任务:{name}") - Task_manager.add_task("自动代理_新调度台", name, info) + TaskManager.add_task("自动代理_新调度台", name, info) def set_silence(self): """设置静默模式""" @@ -125,4 +125,4 @@ class MainTimer(QWidget): return queue_list -Main_timer = MainTimer() +MainTimer = _MainTimer() diff --git a/app/models/MAA.py b/app/models/MAA.py index a663e8a..1631899 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -26,7 +26,7 @@ v4.2 """ from loguru import logger -from PySide6.QtCore import QObject, Signal, QEventLoop +from PySide6.QtCore import QObject, Signal, QEventLoop, QFileSystemWatcher, QTimer import json import sqlite3 from datetime import datetime, timedelta @@ -50,6 +50,7 @@ class MaaManager(QObject): create_user_list = Signal(list) update_user_list = Signal(list) update_log_text = Signal(str) + interrupt = Signal() accomplish = Signal(dict) isInterruptionRequested = False @@ -65,6 +66,12 @@ class MaaManager(QObject): self.mode = mode self.config_path = config_path self.user_config_path = user_config_path + self.log_monitor = QFileSystemWatcher() + self.log_monitor_timer = QTimer() + self.log_monitor_timer.timeout.connect(self.refresh_maa_log) + self.monitor_loop = QEventLoop() + + self.interrupt.connect(self.quit_monitor) with (self.config_path / "config.json").open("r", encoding="utf-8") as f: self.set = json.load(f) @@ -139,7 +146,6 @@ class MaaManager(QObject): # 开始代理 for user in self.user_list: - logger.info(f"{self.name} | 开始代理用户: {user[0]}") if self.isInterruptionRequested: break @@ -155,6 +161,8 @@ class MaaManager(QObject): self.update_user_list.emit(self.user_list) continue + logger.info(f"{self.name} | 开始代理用户: {user[0]}") + # 初始化代理情况记录和模式替换记录 run_book = [False for _ in range(2)] mode_book = ["自动代理_剿灭", "自动代理_日常"] @@ -170,18 +178,16 @@ class MaaManager(QObject): # 尝试次数循环 for i in range(self.set["RunSet"]["RunTimesLimit"]): - logger.info( - f"{self.name} | 用户: {user[0]} - 尝试次数: {i + 1}/{self.set["RunSet"]["RunTimesLimit"]}" - ) if self.isInterruptionRequested: break + logger.info( + f"{self.name} | 用户: {user[0]} - 尝试次数: {i + 1}/{self.set["RunSet"]["RunTimesLimit"]}" + ) + # 剿灭-日常模式循环 for j in range(2): - logger.info( - f"{self.name} | 用户: {user[0]} - 模式: {mode_book[j]}" - ) if self.isInterruptionRequested: break @@ -192,6 +198,10 @@ class MaaManager(QObject): if run_book[j]: continue + logger.info( + f"{self.name} | 用户: {user[0]} - 模式: {mode_book[j]}" + ) + if self.data[user[2]][15] == "beta": self.if_open_emulator = True @@ -234,95 +244,45 @@ class MaaManager(QObject): set["Configurations"]["Default"]["Start.EmulatorPath"] ) Config.silence_list.append(self.emulator_path) - # 记录是否超时的标记 - self.if_time_out = False # 监测MAA运行状态 - while not self.isInterruptionRequested: + self.start_monitor(start_time, mode_book[j]) - # 获取MAA日志 - logs = self.get_maa_log(start_time) - - # 判断是否超时 - if len(logs) > 0: - latest_time = datetime.now() - for _ in range(-1, 0 - len(logs) - 1, -1): - try: - latest_time = datetime.strptime( - logs[_][1:20], "%Y-%m-%d %H:%M:%S" - ) - break - except ValueError: - pass - now_time = datetime.now() - if ( - j == 0 - and now_time - latest_time - > timedelta( - minutes=self.set["RunSet"][ - "AnnihilationTimeLimit" - ] - ) - ) or ( - j == 1 - and now_time - latest_time - > timedelta( - minutes=self.set["RunSet"]["RoutineTimeLimit"] - ) - ): - self.if_time_out = True - - # 合并日志 - log = "".join(logs) - - # 更新MAA日志 - if len(logs) > 100: - self.update_log_text.emit("".join(logs[-100:])) - else: - self.update_log_text.emit("".join(logs)) - - # 判断MAA程序运行状态 - result = self.if_maa_success(log, mode_book[j]) - if result == "Success!": - logger.info( - f"{self.name} | 用户: {user[0]} - MAA进程完成代理任务" - ) - run_book[j] = True - self.update_log_text.emit( - "检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s" - ) - for _ in range(10): - if self.isInterruptionRequested: - break - time.sleep(1) - break - elif result == "Wait": - # 检测时间间隔 + if self.maa_result == "Success!": + logger.info( + f"{self.name} | 用户: {user[0]} - MAA进程完成代理任务" + ) + run_book[j] = True + self.update_log_text.emit( + "检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s" + ) + for _ in range(10): + if self.isInterruptionRequested: + break + time.sleep(1) + else: + logger.error( + f"{self.name} | 用户: {user[0]} - 代理任务异常: {self.maa_result}" + ) + # 打印中止信息 + # 此时,log变量内存储的就是出现异常的日志信息,可以保存或发送用于问题排查 + self.update_log_text.emit( + f"{self.maa_result}\n正在中止相关程序\n请等待10s" + ) + # 无命令行中止MAA与其子程序 + System.kill_process(self.maa_exe_path) + self.if_open_emulator = True + # 推送异常通知 + Notify.push_notification( + "用户自动代理出现异常!", + f"用户 {user[0].replace("_", " 今天的")}的{mode_book[j][5:7]}部分出现一次异常", + f"{user[0].replace("_", " ")}的{mode_book[j][5:7]}出现异常", + 1, + ) + for _ in range(10): + if self.isInterruptionRequested: + break time.sleep(1) - else: - logger.error( - f"{self.name} | 用户: {user[0]} - 代理任务异常: {result}" - ) - # 打印中止信息 - # 此时,log变量内存储的就是出现异常的日志信息,可以保存或发送用于问题排查 - self.update_log_text.emit( - f"{result}\n正在中止相关程序\n请等待10s" - ) - # 无命令行中止MAA与其子程序 - System.kill_process(self.maa_exe_path) - self.if_open_emulator = True - # 推送异常通知 - Notify.push_notification( - "用户自动代理出现异常!", - f"用户 {user[0].replace("_", " 今天的")}的{mode_book[j][5:7]}部分出现一次异常", - f"{user[0].replace("_", " ")}的{mode_book[j][5:7]}出现异常", - 1, - ) - for _ in range(10): - if self.isInterruptionRequested: - break - time.sleep(1) - break # 移除静默进程标记 Config.silence_list.remove(self.emulator_path) @@ -358,11 +318,12 @@ class MaaManager(QObject): # 开始排查 for user in self.user_list: - logger.info(f"{self.name} | 开始排查用户: {user[0]}") if self.isInterruptionRequested: break + logger.info(f"{self.name} | 开始排查用户: {user[0]}") + user[1] = "运行" self.update_user_list.emit(self.user_list) @@ -387,46 +348,28 @@ class MaaManager(QObject): ) # 监测MAA运行状态 - while not self.isInterruptionRequested: + self.start_monitor(start_time, "人工排查") - # 获取MAA日志 - logs = self.get_maa_log(start_time) - # 合并日志 - log = "".join(logs) - - # 更新MAA日志 - if len(logs) > 100: - self.update_log_text.emit("".join(logs[-100:])) - else: - self.update_log_text.emit("".join(logs)) - - # 判断MAA程序运行状态 - result = self.if_maa_success(log, "人工排查") - if result == "Success!": - logger.info( - f"{self.name} | 用户: {user[0]} - MAA进程成功登录PRTS" - ) - run_book[0] = True - self.update_log_text.emit("检测到MAA进程成功登录PRTS") - break - elif result == "Wait": - # 检测时间间隔 + if self.maa_result == "Success!": + logger.info( + f"{self.name} | 用户: {user[0]} - MAA进程成功登录PRTS" + ) + run_book[0] = True + self.update_log_text.emit("检测到MAA进程成功登录PRTS") + else: + logger.error( + f"{self.name} | 用户: {user[0]} - MAA未能正确登录到PRTS: {self.maa_result}" + ) + self.update_log_text.emit( + f"{self.maa_result}\n正在中止相关程序\n请等待10s" + ) + # 无命令行中止MAA与其子程序 + System.kill_process(self.maa_exe_path) + self.if_open_emulator = True + for _ in range(10): + if self.isInterruptionRequested: + break time.sleep(1) - else: - logger.error( - f"{self.name} | 用户: {user[0]} - MAA未能正确登录到PRTS: {result}" - ) - self.update_log_text.emit( - f"{result}\n正在中止相关程序\n请等待10s" - ) - # 无命令行中止MAA与其子程序 - System.kill_process(self.maa_exe_path) - self.if_open_emulator = True - for _ in range(10): - if self.isInterruptionRequested: - break - time.sleep(1) - break # 登录成功,结束循环 if run_book[0]: @@ -480,20 +423,7 @@ class MaaManager(QObject): start_time = datetime.now() # 监测MAA运行状态 - while not self.isInterruptionRequested: - - # 获取MAA日志 - logs = self.get_maa_log(start_time) - # 合并日志 - log = "".join(logs) - - # 判断MAA程序运行状态 - result = self.if_maa_success(log, "设置MAA") - if result == "Success!": - break - elif result == "Wait": - # 检测时间间隔 - time.sleep(1) + self.start_monitor(start_time, "设置MAA") if "全局" in self.mode: (self.config_path / "Default").mkdir(parents=True, exist_ok=True) @@ -569,10 +499,17 @@ class MaaManager(QObject): Notify.CompanyWebHookBotPush(title, f"{end_log}AUTO_MAA 敬上") self.agree_bilibili(False) + self.log_monitor.deleteLater() + self.log_monitor_timer.deleteLater() self.accomplish.emit({"Time": begin_time, "History": end_log}) def requestInterruption(self) -> None: logger.info(f"{self.name} | 收到任务中止申请") + + if len(self.log_monitor.files()) != 0: + self.interrupt.emit() + + self.maa_result = "您中止了本次任务" self.isInterruptionRequested = True def push_question(self, title: str, message: str) -> bool: @@ -587,9 +524,16 @@ class MaaManager(QObject): def _capture_response(self, response: bool) -> None: self.response = response - def get_maa_log(self, start_time): - """获取MAA日志""" + def refresh_maa_log(self) -> None: + """刷新MAA日志""" + with self.maa_log_path.open(mode="r", encoding="utf-8") as f: + pass + + def check_maa_log(self, start_time: datetime, mode: str) -> None: + """检查MAA日志以判断MAA程序运行状态""" + + # 获取日志 logs = [] if_log_start = False with self.maa_log_path.open(mode="r", encoding="utf-8") as f: @@ -604,50 +548,92 @@ class MaaManager(QObject): pass else: logs.append(entry) - return logs + log = "".join(logs) - def if_maa_success(self, log, mode) -> str: - """判断MAA程序运行状态""" + # 更新MAA日志 + if len(logs) > 100: + self.update_log_text.emit("".join(logs[-100:])) + else: + self.update_log_text.emit("".join(logs)) if "自动代理" in mode: + + # 获取最近一条日志的时间 + latest_time = start_time + for _ in logs[::-1]: + try: + latest_time = datetime.strptime(_[1:20], "%Y-%m-%d %H:%M:%S") + break + except ValueError: + pass + + time_book = { + "自动代理_剿灭": "AnnihilationTimeLimit", + "自动代理_日常": "RoutineTimeLimit", + } + if mode == "自动代理_日常" and "任务出错: Fight" in log: - return "检测到MAA未能实际执行任务" + self.maa_result = "检测到MAA未能实际执行任务" if "任务出错: StartUp" in log: - return "检测到MAA未能正确登录PRTS" + self.maa_result = "检测到MAA未能正确登录PRTS" elif "任务已全部完成!" in log: - return "Success!" + self.maa_result = "Success!" elif ( ("请「检查连接设置」或「尝试重启模拟器与 ADB」或「重启电脑」" in log) or ("已停止" in log) or ("MaaAssistantArknights GUI exited" in log) ): - return "检测到MAA进程异常" - elif self.if_time_out: - return "检测到MAA进程超时" - elif self.isInterruptionRequested: - return "您中止了本次任务" + self.maa_result = "检测到MAA进程异常" + elif datetime.now() - latest_time > timedelta( + minutes=self.set["RunSet"][time_book[mode]] + ): + self.maa_result = "检测到MAA进程超时" else: - return "Wait" + self.maa_result = "Wait" elif mode == "人工排查": if "完成任务: StartUp" in log: - return "Success!" + self.maa_result = "Success!" elif ( ("请「检查连接设置」或「尝试重启模拟器与 ADB」或「重启电脑」" in log) or ("已停止" in log) or ("MaaAssistantArknights GUI exited" in log) ): - return "检测到MAA进程异常" - elif self.isInterruptionRequested: - return "您中止了本次任务" + self.maa_result = "检测到MAA进程异常" else: - return "Wait" + self.maa_result = "Wait" elif mode == "设置MAA": if "MaaAssistantArknights GUI exited" in log: - return "Success!" + self.maa_result = "Success!" else: - return "Wait" + self.maa_result = "Wait" + + if self.maa_result != "Wait": + + self.quit_monitor() + + def start_monitor(self, start_time: datetime, mode: str) -> None: + """开始监视MAA日志""" + + logger.info(f"{self.name} | 开始监视MAA日志") + self.log_monitor.addPath(str(self.maa_log_path)) + self.log_monitor.fileChanged.connect( + lambda: self.check_maa_log(start_time, mode) + ) + self.log_monitor_timer.start(1000) + self.monitor_loop.exec() + + def quit_monitor(self) -> None: + """退出MAA日志监视进程""" + + if len(self.log_monitor.files()) != 0: + + logger.info(f"{self.name} | 退出MAA日志监视") + self.log_monitor.removePath(str(self.maa_log_path)) + self.log_monitor.fileChanged.disconnect() + self.log_monitor_timer.stop() + self.monitor_loop.quit() def set_maa(self, mode, index): """配置MAA运行参数""" diff --git a/app/ui/dispatch_center.py b/app/ui/dispatch_center.py index af073e0..e1dc839 100644 --- a/app/ui/dispatch_center.py +++ b/app/ui/dispatch_center.py @@ -52,7 +52,7 @@ from typing import List, Dict import json -from app.core import Config, Task_manager, Task, MainInfoBar +from app.core import Config, TaskManager, Task, MainInfoBar class DispatchCenter(QWidget): @@ -92,7 +92,7 @@ class DispatchCenter(QWidget): dispatch_box = DispatchBox(task.name, self) dispatch_box.top_bar.button.clicked.connect( - lambda: Task_manager.stop_task(task.name) + lambda: TaskManager.stop_task(task.name) ) task.create_task_list.connect(dispatch_box.info.task.create_task) @@ -128,7 +128,7 @@ class DispatchCenter(QWidget): self.script_list["主调度台"].top_bar.button.clicked.disconnect() self.script_list["主调度台"].top_bar.button.setText("中止任务") self.script_list["主调度台"].top_bar.button.clicked.connect( - lambda: Task_manager.stop_task(task.name) + lambda: TaskManager.stop_task(task.name) ) task.create_task_list.connect( self.script_list["主调度台"].info.task.create_task @@ -276,7 +276,7 @@ class DispatchBox(QWidget): info = json.load(f) logger.info(f"用户添加任务:{name}") - Task_manager.add_task(f"{self.mode.currentText()}_主调度台", name, info) + TaskManager.add_task(f"{self.mode.currentText()}_主调度台", name, info) elif self.object.currentText().split(" - ")[0] == "实例": @@ -285,7 +285,7 @@ class DispatchBox(QWidget): info = {"Queue": {"Member_1": name}} logger.info(f"用户添加任务:{name}") - Task_manager.add_task( + TaskManager.add_task( f"{self.mode.currentText()}_主调度台", "自定义队列", info ) diff --git a/app/ui/main_window.py b/app/ui/main_window.py index 3893002..21cf592 100644 --- a/app/ui/main_window.py +++ b/app/ui/main_window.py @@ -44,7 +44,7 @@ from qfluentwidgets import ( from PySide6.QtGui import QIcon, QCloseEvent from PySide6.QtCore import Qt -from app.core import Config, Task_manager, Main_timer, MainInfoBar +from app.core import Config, TaskManager, MainTimer, MainInfoBar from app.services import Notify, Crypto, System from .setting import Setting from .member_manager import MemberManager @@ -166,8 +166,8 @@ class AUTO_MAA(MSFluentWindow): self.tray.setContextMenu(self.tray_menu) self.tray.activated.connect(self.on_tray_activated) - Task_manager.create_gui.connect(self.dispatch_center.add_board) - Task_manager.connect_gui.connect(self.dispatch_center.connect_main_board) + TaskManager.create_gui.connect(self.dispatch_center.add_board) + TaskManager.connect_gui.connect(self.dispatch_center.connect_main_board) self.setting.ui.card_IfShowTray.checkedChanged.connect( lambda: self.show_ui("配置托盘") ) @@ -327,9 +327,9 @@ class AUTO_MAA(MSFluentWindow): self.show_ui("隐藏到托盘", if_quick=True) # 清理各功能线程 - Main_timer.Timer.stop() - Main_timer.Timer.deleteLater() - Task_manager.stop_task("ALL") + MainTimer.Timer.stop() + MainTimer.Timer.deleteLater() + TaskManager.stop_task("ALL") # 关闭数据库连接 Config.close_database() diff --git a/app/ui/member_manager.py b/app/ui/member_manager.py index 55d2090..9f149d7 100644 --- a/app/ui/member_manager.py +++ b/app/ui/member_manager.py @@ -57,7 +57,7 @@ from datetime import datetime, timedelta import json import shutil -from app.core import Config, MainInfoBar, Task_manager +from app.core import Config, MainInfoBar, TaskManager from app.services import Crypto from .Widget import ( LineEditMessageBox, @@ -523,7 +523,7 @@ class MaaSettingBox(QWidget): ) ) self.card_Set.clicked.connect( - lambda: Task_manager.add_task("设置MAA_全局", self.name, None) + lambda: TaskManager.add_task("设置MAA_全局", self.name, None) ) Layout.addWidget(self.card_Name) @@ -749,7 +749,7 @@ class MaaSettingBox(QWidget): ): set_book = ["routine", "annihilation"] - Task_manager.add_task( + TaskManager.add_task( "设置MAA_用户", self.name, { diff --git a/resources/version.json b/resources/version.json index 9a761c0..978c640 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,7 +1,7 @@ { "main_version": "4.2.3.1", "updater_version": "1.1.1.3", - "announcement": "\n## 新增功能\n- 添加`简洁用户列表下相邻两个任务间的切换方式`可选项\n## 修复BUG\n- 修复静默代理标记移除异常情况\n## 程序优化\n- 优化MAA关闭方法\n- 添加高级代理文件校验过程", + "announcement": "\n## 新增功能\n- 添加`简洁用户列表下相邻两个任务间的切换方式`可选项\n## 修复BUG\n- 修复静默代理标记移除异常情况\n## 程序优化\n- 优化MAA关闭方法\n- 添加高级代理文件校验过程\n- 升级日志监看方法", "proxy_list": [ "", "https://gitproxy.click/",