From 3307793a3d4475776334e5bca3f7b87e1a89fca0 Mon Sep 17 00:00:00 2001 From: AoXuan Date: Thu, 6 Feb 2025 15:55:55 +0800 Subject: [PATCH 01/13] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E5=AE=8C=E6=88=90=E5=90=8E=E8=87=AA=E5=8A=A8=E5=85=B3?= =?UTF-8?q?=E6=9C=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 2 ++ app/models/MAA.py | 8 ++++++++ app/ui/setting.py | 13 +++++++++++++ 3 files changed, 23 insertions(+) diff --git a/app/core/config.py b/app/core/config.py index 1496a6e..b9d1a1d 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -542,6 +542,8 @@ class GlobalConfig(QConfig): function_IfSilence = ConfigItem("Function", "IfSilence", False, BoolValidator()) function_BossKey = ConfigItem("Function", "BossKey", "") + function_AutoShutdown = ConfigItem("Function", "AutoShutdown", False, BoolValidator()) + start_IfSelfStart = ConfigItem("Start", "IfSelfStart", False, BoolValidator()) start_IfRunDirectly = ConfigItem("Start", "IfRunDirectly", False, BoolValidator()) diff --git a/app/models/MAA.py b/app/models/MAA.py index 27b8fcb..92e7ba1 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -24,6 +24,7 @@ MAA功能组件 v4.2 作者:DLmaster_361 """ +import sys from loguru import logger from PySide6.QtCore import QObject, Signal, QEventLoop @@ -538,6 +539,13 @@ class MaaManager(QObject): f"{self.mode[:4]}任务报告", f"{end_log}AUTO_MAA 敬上", ) + if Config.global_config.function_AutoShutdown: + logger.info("任务完成,系统将在 60 秒后自动关机...") + if sys.platform.startswith("win"): + subprocess.run("shutdown /s /t 60", shell=True) # Windows + else: + # 看到 Issues 里有兼容 Linux 的计划,加上 Linux 的 + subprocess.run("shutdown -h +1", shell=True) # Linux/macOS self.accomplish.emit({"Time": begin_time, "History": end_log}) diff --git a/app/ui/setting.py b/app/ui/setting.py index 60d44b4..0f13450 100644 --- a/app/ui/setting.py +++ b/app/ui/setting.py @@ -399,11 +399,20 @@ class FunctionSettingCard(HeaderCardWidget): content="仅阻止电脑自动休眠,不会影响屏幕是否熄灭", configItem=Config.global_config.function_IfAllowSleep, ) + + self.card_AutoShutdown = SwitchSettingCard( + icon=FluentIcon.POWER_BUTTON, + title="运行完成后自动关机", + content="启用后,任务完成后将自动关机", + configItem=Config.global_config.function_AutoShutdown, + ) + self.card_IfSilence = self.SilenceSettingCard(self) Layout = QVBoxLayout() Layout.addWidget(self.card_IfAllowSleep) Layout.addWidget(self.card_IfSilence) + Layout.addWidget(self.card_AutoShutdown) self.viewLayout.addLayout(Layout) class SilenceSettingCard(ExpandGroupSettingCard): @@ -753,3 +762,7 @@ def version_text(version_numb: list) -> str: f"v{'.'.join(str(_) for _ in version_numb[0:3])}-beta.{version_numb[3]}" ) return version + +def toggle_auto_shutdown(self, checked: bool) -> None: + """启用或禁用自动关机""" + Config.global_config.function_AutoShutdown = checked From 7f5478b0986b80ddb331a11d1f2f7791fb610a3d Mon Sep 17 00:00:00 2001 From: DLmaster Date: Thu, 6 Feb 2025 23:33:00 +0800 Subject: [PATCH 02/13] =?UTF-8?q?feat(core):=20=E6=B7=BB=E5=8A=A0=E8=B0=83?= =?UTF-8?q?=E5=BA=A6=E9=98=9F=E5=88=97=E5=AE=8C=E6=88=90=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=90=8E=E8=A1=8C=E4=B8=BA=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 9 ++++-- app/core/main_info_bar.py | 14 ++++----- app/core/task_manager.py | 15 +++++++-- app/models/MAA.py | 7 ----- app/services/system.py | 66 +++++++++++++++++++++++++++++++++++++-- app/ui/dispatch_center.py | 2 +- app/ui/main_window.py | 10 ++---- app/ui/member_manager.py | 30 +++++------------- app/ui/queue_manager.py | 17 +++++++++- app/ui/setting.py | 31 ++++++------------ resources/version.json | 4 +-- 11 files changed, 127 insertions(+), 78 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index b9d1a1d..6f05a49 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -499,6 +499,7 @@ class AppConfig: self.queue_config.set(self.queue_config.queueSet_Name, "") self.queue_config.set(self.queue_config.queueSet_Enabled, False) + self.queue_config.set(self.queue_config.queueSet_AfterAccomplish, "None") self.queue_config.set(self.queue_config.time_TimeEnabled_0, False) self.queue_config.set(self.queue_config.time_TimeSet_0, "00:00") @@ -542,8 +543,6 @@ class GlobalConfig(QConfig): function_IfSilence = ConfigItem("Function", "IfSilence", False, BoolValidator()) function_BossKey = ConfigItem("Function", "BossKey", "") - function_AutoShutdown = ConfigItem("Function", "AutoShutdown", False, BoolValidator()) - start_IfSelfStart = ConfigItem("Start", "IfSelfStart", False, BoolValidator()) start_IfRunDirectly = ConfigItem("Start", "IfRunDirectly", False, BoolValidator()) @@ -581,6 +580,12 @@ class QueueConfig(QConfig): queueSet_Name = ConfigItem("QueueSet", "Name", "") queueSet_Enabled = ConfigItem("QueueSet", "Enabled", False, BoolValidator()) + queueSet_AfterAccomplish = OptionsConfigItem( + "QueueSet", + "AfterAccomplish", + "None", + OptionsValidator(["None", "KillSelf", "Sleep", "Hibernate", "Shutdown"]), + ) time_TimeEnabled_0 = ConfigItem("Time", "TimeEnabled_0", False, BoolValidator()) time_TimeSet_0 = ConfigItem("Time", "TimeSet_0", "00:00") diff --git a/app/core/main_info_bar.py b/app/core/main_info_bar.py index 349df7e..c83f1ca 100644 --- a/app/core/main_info_bar.py +++ b/app/core/main_info_bar.py @@ -36,14 +36,14 @@ from qfluentwidgets import ( class _MainInfoBar: """信息通知栏""" - def __init__(self, parent=None): + def __init__(self, main_window=None): - self.parent = parent + self.main_window = main_window def push_info_bar(self, mode: str, title: str, content: str, time: int): """推送到信息通知栏""" - if self.parent is None: + if self.main_window is None: logger.error("信息通知栏未设置父窗口") return None @@ -55,7 +55,7 @@ class _MainInfoBar: isClosable=True, position=InfoBarPosition.TOP_RIGHT, duration=time, - parent=self.parent, + parent=self.main_window, ) elif mode == "warning": InfoBar.warning( @@ -65,7 +65,7 @@ class _MainInfoBar: isClosable=True, position=InfoBarPosition.TOP_RIGHT, duration=time, - parent=self.parent, + parent=self.main_window, ) elif mode == "error": InfoBar.error( @@ -75,7 +75,7 @@ class _MainInfoBar: isClosable=True, position=InfoBarPosition.TOP_RIGHT, duration=time, - parent=self.parent, + parent=self.main_window, ) elif mode == "info": InfoBar.info( @@ -85,7 +85,7 @@ class _MainInfoBar: isClosable=True, position=InfoBarPosition.TOP_RIGHT, duration=time, - parent=self.parent, + parent=self.main_window, ) diff --git a/app/core/task_manager.py b/app/core/task_manager.py index 70ae791..28d9fcc 100644 --- a/app/core/task_manager.py +++ b/app/core/task_manager.py @@ -28,6 +28,7 @@ v4.2 from loguru import logger from PySide6.QtCore import QThread, QObject, Signal from qfluentwidgets import Dialog +import json from pathlib import Path from datetime import datetime from typing import Dict, Union @@ -35,6 +36,7 @@ from typing import Dict, Union from .config import Config from .main_info_bar import MainInfoBar from app.models import MaaManager +from app.services import System class Task(QThread): @@ -214,7 +216,7 @@ class TaskManager(QObject): self.task_list[name].push_info_bar.connect(MainInfoBar.push_info_bar) self.task_list[name].update_user_info.connect(Config.change_user_info) self.task_list[name].accomplish.connect( - lambda logs: self.remove_task(name, logs) + lambda logs: self.remove_task(mode, name, logs) ) if "新调度台" in mode: @@ -247,8 +249,8 @@ class TaskManager(QObject): self.task_list[name].quit() self.task_list[name].wait() - def remove_task(self, name: str, logs: str): - """移除任务标记""" + def remove_task(self, mode: str, name: str, logs: str): + """任务结束后的处理""" logger.info(f"任务结束:{name}") MainInfoBar.push_info_bar("info", "任务结束", name, 3000) @@ -274,6 +276,13 @@ class TaskManager(QObject): self.task_list.pop(name) Config.running_list.remove(name) + if "调度队列" in name and "人工排查" not in mode: + with (Config.app_path / f"config/QueueConfig/{name}.json").open( + "r", encoding="utf-8" + ) as f: + info = json.load(f) + System.set_power(info["QueueSet"]["AfterAccomplish"]) + def push_dialog(self, name: str, title: str, content: str): """推送对话框""" diff --git a/app/models/MAA.py b/app/models/MAA.py index 92e7ba1..9536b79 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -539,13 +539,6 @@ class MaaManager(QObject): f"{self.mode[:4]}任务报告", f"{end_log}AUTO_MAA 敬上", ) - if Config.global_config.function_AutoShutdown: - logger.info("任务完成,系统将在 60 秒后自动关机...") - if sys.platform.startswith("win"): - subprocess.run("shutdown /s /t 60", shell=True) # Windows - else: - # 看到 Issues 里有兼容 Linux 的计划,加上 Linux 的 - subprocess.run("shutdown -h +1", shell=True) # Linux/macOS self.accomplish.emit({"Time": begin_time, "History": end_log}) diff --git a/app/services/system.py b/app/services/system.py index 8099229..b2939d2 100644 --- a/app/services/system.py +++ b/app/services/system.py @@ -25,21 +25,27 @@ v4.2 作者:DLmaster_361 """ +from loguru import logger +from PySide6.QtWidgets import QWidget +import sys import ctypes import win32gui import win32process import winreg import psutil +import subprocess from app.core import Config -class SystemHandler: +class _SystemHandler: ES_CONTINUOUS = 0x80000000 ES_SYSTEM_REQUIRED = 0x00000001 - def __init__(self): + def __init__(self, main_window: QWidget = None): + + self.main_window = main_window self.set_Sleep() self.set_SelfStart() @@ -84,6 +90,60 @@ class SystemHandler: winreg.DeleteValue(key, "AUTO_MAA") winreg.CloseKey(key) + def set_power(self, mode): + + if sys.platform.startswith("win"): + + if mode == "None": + + logger.info("不执行系统电源操作") + + elif mode == "Shutdown": + + logger.info("执行关机操作") + subprocess.run(["shutdown", "/s", "/t", "0"]) + + elif mode == "Hibernate": + + logger.info("执行休眠操作") + subprocess.run(["shutdown", "/h"]) + + elif mode == "Sleep": + + logger.info("执行睡眠操作") + subprocess.run( + ["rundll32.exe", "powrprof.dll,SetSuspendState", "0,1,0"] + ) + + elif mode == "KillSelf": + + self.main_window.close() + + elif sys.platform.startswith("linux"): + + if mode == "None": + + logger.info("不执行系统电源操作") + + elif mode == "Shutdown": + + logger.info("执行关机操作") + subprocess.run(["shutdown", "-h", "now"]) + + elif mode == "Hibernate": + + logger.info("执行休眠操作") + subprocess.run(["systemctl", "hibernate"]) + + elif mode == "Sleep": + + logger.info("执行睡眠操作") + subprocess.run(["systemctl", "suspend"]) + + elif mode == "KillSelf": + + self.main_window.close() + def is_startup(self): """判断程序是否已经开机自启""" @@ -117,4 +177,4 @@ class SystemHandler: return window_info -System = SystemHandler() +System = _SystemHandler() diff --git a/app/ui/dispatch_center.py b/app/ui/dispatch_center.py index d8161e9..af073e0 100644 --- a/app/ui/dispatch_center.py +++ b/app/ui/dispatch_center.py @@ -286,7 +286,7 @@ class DispatchBox(QWidget): logger.info(f"用户添加任务:{name}") Task_manager.add_task( - f"{self.mode.currentText()}_主调度台", "用户自定义队列", info + f"{self.mode.currentText()}_主调度台", "自定义队列", info ) class DispatchInfoCard(HeaderCardWidget): diff --git a/app/ui/main_window.py b/app/ui/main_window.py index e5de864..efb49f7 100644 --- a/app/ui/main_window.py +++ b/app/ui/main_window.py @@ -68,7 +68,8 @@ class AUTO_MAA(MSFluentWindow): self.splashScreen = SplashScreen(self.windowIcon(), self) self.show_ui("显示主窗口", if_quick=True) - MainInfoBar.parent = self + MainInfoBar.main_window = self.window() + System.main_window = self.window() # 创建主窗口 self.setting = Setting(self) @@ -161,7 +162,7 @@ class AUTO_MAA(MSFluentWindow): # 退出主程序菜单项 self.tray_menu.addAction( - Action(FluentIcon.POWER_BUTTON, "退出主程序", triggered=self.kill_main) + Action(FluentIcon.POWER_BUTTON, "退出主程序", triggered=self.window().close) ) # 设置托盘菜单 @@ -264,11 +265,6 @@ class AUTO_MAA(MSFluentWindow): # 3, # ) - def kill_main(self) -> None: - """退出主程序""" - self.close() - QApplication.quit() - def show_ui(self, mode: str, if_quick: bool = False) -> None: """配置窗口状态""" diff --git a/app/ui/member_manager.py b/app/ui/member_manager.py index ed60c90..a90201e 100644 --- a/app/ui/member_manager.py +++ b/app/ui/member_manager.py @@ -124,7 +124,7 @@ class MemberManager(QWidget): """添加一个脚本实例""" choice = InputMessageBox( - self, + self.window(), "选择一个脚本类型并添加相应脚本实例", "选择脚本类型", "选择", @@ -170,7 +170,7 @@ class MemberManager(QWidget): choice = MessageBox( "确认", f"确定要删除 {name} 实例吗?", - self, + self.window(), ) if choice.exec(): @@ -296,7 +296,7 @@ class MemberManager(QWidget): if Config.PASSWORD == "": choice = InputMessageBox( - self, + self.window(), "请输入管理密钥", "管理密钥", "密码", @@ -691,7 +691,7 @@ class MaaSettingBox(QWidget): set_list = ["自定义基建"] choice = SetMessageBox( - self.parent().parent().parent().parent().parent().parent().parent(), + self.window(), "用户选项配置", ["选择要配置的用户", "选择要配置的选项"], [user_list, set_list], @@ -731,7 +731,7 @@ class MaaSettingBox(QWidget): set_list = ["MAA日常配置", "MAA剿灭配置"] choice = SetMessageBox( - self.parent().parent().parent().parent().parent().parent().parent(), + self.window(), "用户选项配置", ["选择要配置的用户", "选择要配置的选项"], [user_list, set_list], @@ -1273,15 +1273,7 @@ class MaaSettingBox(QWidget): choice = MessageBox( "确认", f"确定要删除用户 {data[0][0]} 吗?", - self.parent() - .parent() - .parent() - .parent() - .parent() - .parent() - .parent() - .parent() - .parent(), + self.window(), ) # 删除用户 @@ -1570,15 +1562,7 @@ class MaaSettingBox(QWidget): choice = MessageBox( "确认", f"确定要将用户 {data[0][0]} 转为{mode_list[1 - mode]}配置模式吗?", - self.parent() - .parent() - .parent() - .parent() - .parent() - .parent() - .parent() - .parent() - .parent(), + self.window(), ) # 切换用户 diff --git a/app/ui/queue_manager.py b/app/ui/queue_manager.py index 8ae4f5b..4004220 100644 --- a/app/ui/queue_manager.py +++ b/app/ui/queue_manager.py @@ -43,6 +43,7 @@ from qfluentwidgets import ( TextBrowser, CommandBar, SwitchSettingCard, + ComboBoxSettingCard, ) from PySide6.QtCore import Qt from typing import List @@ -138,7 +139,7 @@ class QueueManager(QWidget): choice = MessageBox( "确认", f"确定要删除 {name} 吗?", - self, + self.window(), ) if choice.exec(): @@ -412,9 +413,23 @@ class QueueMemberSettingBox(QWidget): "调度队列状态", Config.queue_config.queueSet_Enabled, ) + self.card_AfterAccomplish = ComboBoxSettingCard( + configItem=Config.queue_config.queueSet_AfterAccomplish, + icon=FluentIcon.POWER_BUTTON, + title="调度队列结束后", + content="选择调度队列结束后的操作", + texts=[ + "无动作", + "退出AUTO_MAA", + "睡眠(win系统需禁用休眠)", + "休眠", + "关机", + ], + ) Layout.addWidget(self.card_Name) Layout.addWidget(self.card_Enable) + Layout.addWidget(self.card_AfterAccomplish) self.viewLayout.addLayout(Layout) diff --git a/app/ui/setting.py b/app/ui/setting.py index 0f13450..dcfdd87 100644 --- a/app/ui/setting.py +++ b/app/ui/setting.py @@ -111,7 +111,7 @@ class Setting(QWidget): while True: choice = InputMessageBox( - self.parent().parent().parent(), + self.window(), "未检测到管理密钥,请设置您的管理密钥", "管理密钥", "密码", @@ -123,7 +123,7 @@ class Setting(QWidget): choice = MessageBox( "警告", "您没有设置管理密钥,无法使用本软件,请先设置管理密钥", - self.parent().parent().parent(), + self.window(), ) choice.cancelButton.hide() choice.buttonLayout.insertStretch(1) @@ -138,7 +138,7 @@ class Setting(QWidget): while if_change: choice = InputMessageBox( - self, + self.window(), "请输入旧的管理密钥", "旧管理密钥", "密码", @@ -153,7 +153,7 @@ class Setting(QWidget): while True: choice = InputMessageBox( - self, + self.window(), "请输入新的管理密钥", "新管理密钥", "密码", @@ -173,14 +173,14 @@ class Setting(QWidget): choice = MessageBox( "确认", "您没有输入新的管理密钥,是否取消修改管理密钥?", - self, + self.window(), ) if choice.exec(): if_change = False break else: - choice = MessageBox("错误", "管理密钥错误", self) + choice = MessageBox("错误", "管理密钥错误", self.window()) choice.cancelButton.hide() choice.buttonLayout.insertStretch(1) if choice.exec(): @@ -189,7 +189,7 @@ class Setting(QWidget): choice = MessageBox( "确认", "您没有输入管理密钥,是否取消修改管理密钥?", - self, + self.window(), ) if choice.exec(): break @@ -261,7 +261,7 @@ class Setting(QWidget): choice = MessageBox( "错误", f"获取版本信息时出错:\n{err}", - self, + self.window(), ) choice.cancelButton.hide() choice.buttonLayout.insertStretch(1) @@ -297,7 +297,7 @@ class Setting(QWidget): choice = MessageBox( "版本更新", f"发现新版本:\n{main_version_info}{updater_version_info} 更新说明:\n{version_remote['announcement'].replace("\n# ","\n !").replace("\n## ","\n - ").replace("\n- ","\n · ")}\n\n是否开始更新?\n\n 注意:主程序更新时AUTO_MAA将自动关闭", - self, + self.window(), ) if not choice.exec(): return None @@ -399,20 +399,11 @@ class FunctionSettingCard(HeaderCardWidget): content="仅阻止电脑自动休眠,不会影响屏幕是否熄灭", configItem=Config.global_config.function_IfAllowSleep, ) - - self.card_AutoShutdown = SwitchSettingCard( - icon=FluentIcon.POWER_BUTTON, - title="运行完成后自动关机", - content="启用后,任务完成后将自动关机", - configItem=Config.global_config.function_AutoShutdown, - ) - self.card_IfSilence = self.SilenceSettingCard(self) Layout = QVBoxLayout() Layout.addWidget(self.card_IfAllowSleep) Layout.addWidget(self.card_IfSilence) - Layout.addWidget(self.card_AutoShutdown) self.viewLayout.addLayout(Layout) class SilenceSettingCard(ExpandGroupSettingCard): @@ -762,7 +753,3 @@ def version_text(version_numb: list) -> str: f"v{'.'.join(str(_) for _ in version_numb[0:3])}-beta.{version_numb[3]}" ) return version - -def toggle_auto_shutdown(self, checked: bool) -> None: - """启用或禁用自动关机""" - Config.global_config.function_AutoShutdown = checked diff --git a/resources/version.json b/resources/version.json index a957e16..1f5706b 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,7 +1,7 @@ { - "main_version": "4.2.2.2", + "main_version": "4.2.2.3", "updater_version": "1.1.1.3", - "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n## 程序优化\n- 无", + "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n## 程序优化\n- 优化弹窗逻辑", "proxy_list": [ "", "https://gitproxy.click/", From a93a60d125823d1bace5cc197ee8d70ce13bc2cf Mon Sep 17 00:00:00 2001 From: DLmaster Date: Fri, 7 Feb 2025 15:37:07 +0800 Subject: [PATCH 03/13] =?UTF-8?q?chore(core):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=9D=99=E9=BB=98=E5=88=A4=E5=AE=9A=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/timer.py | 41 +++++++++++++++++++++++------------------ app/models/MAA.py | 27 ++++++++------------------- resources/version.json | 4 ++-- 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/app/core/timer.py b/app/core/timer.py index bcf5909..6664a4b 100644 --- a/app/core/timer.py +++ b/app/core/timer.py @@ -86,25 +86,30 @@ class MainTimer(QWidget): def set_silence(self): """设置静默模式""" - windows = System.get_window_info() - if any( - str(emulator_path) in window - for window in windows - for emulator_path in Config.silence_list + if ( + Config.global_config.get(Config.global_config.function_IfSilence) + and Config.global_config.get(Config.global_config.function_BossKey) != "" ): - try: - pyautogui.hotkey( - *[ - _.strip().lower() - for _ in Config.global_config.get( - Config.global_config.function_BossKey - ).split("+") - ] - ) - except pyautogui.FailSafeException as e: - if not self.if_FailSafeException: - logger.warning(f"FailSafeException: {e}") - self.if_FailSafeException = True + + windows = System.get_window_info() + if any( + str(emulator_path) in window + for window in windows + for emulator_path in Config.silence_list + ): + try: + pyautogui.hotkey( + *[ + _.strip().lower() + for _ in Config.global_config.get( + Config.global_config.function_BossKey + ).split("+") + ] + ) + except pyautogui.FailSafeException as e: + if not self.if_FailSafeException: + logger.warning(f"FailSafeException: {e}") + self.if_FailSafeException = True def search_queue(self) -> list: """搜索所有调度队列实例""" diff --git a/app/models/MAA.py b/app/models/MAA.py index 9536b79..77815ba 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -188,17 +188,12 @@ class MaaManager(QObject): creationflags=subprocess.CREATE_NO_WINDOW, ) # 添加静默进程标记 - if Config.global_config.get( - Config.global_config.function_IfSilence - ): - with self.maa_set_path.open( - mode="r", encoding="utf-8" - ) as f: - set = json.load(f) - self.emulator_path = Path( - set["Configurations"]["Default"]["Start.EmulatorPath"] - ) - Config.silence_list.append(self.emulator_path) + with self.maa_set_path.open(mode="r", encoding="utf-8") as f: + set = json.load(f) + self.emulator_path = Path( + set["Configurations"]["Default"]["Start.EmulatorPath"] + ) + Config.silence_list.append(self.emulator_path) # 记录是否超时的标记 self.if_time_out = False @@ -254,10 +249,7 @@ class MaaManager(QObject): "检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s" ) # 移除静默进程标记 - if Config.global_config.get( - Config.global_config.function_IfSilence - ): - Config.silence_list.remove(self.emulator_path) + Config.silence_list.remove(self.emulator_path) for _ in range(10): if self.isInterruptionRequested: break @@ -278,10 +270,7 @@ class MaaManager(QObject): ) killprocess.wait() # 移除静默进程标记 - if Config.global_config.get( - Config.global_config.function_IfSilence - ): - Config.silence_list.remove(self.emulator_path) + Config.silence_list.remove(self.emulator_path) # 推送异常通知 Notify.push_notification( "用户自动代理出现异常!", diff --git a/resources/version.json b/resources/version.json index 1f5706b..f8fe05c 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,7 +1,7 @@ { - "main_version": "4.2.2.3", + "main_version": "4.2.2.4", "updater_version": "1.1.1.3", - "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n## 程序优化\n- 优化弹窗逻辑", + "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑", "proxy_list": [ "", "https://gitproxy.click/", From c3e710b5cf18b55a81351a5d48b11b84c8efc29c Mon Sep 17 00:00:00 2001 From: DLmaster Date: Fri, 7 Feb 2025 15:53:37 +0800 Subject: [PATCH 04/13] =?UTF-8?q?chore(gui):=20=E8=B0=83=E6=95=B4MAA?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=9B=AE=E5=BD=95=E6=97=B6=E6=89=93=E5=BC=80?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E5=B7=B2=E9=85=8D=E7=BD=AE=E7=9A=84=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/ui/member_manager.py | 6 +++++- resources/version.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/ui/member_manager.py b/app/ui/member_manager.py index a90201e..60d4740 100644 --- a/app/ui/member_manager.py +++ b/app/ui/member_manager.py @@ -535,7 +535,11 @@ class MaaSettingBox(QWidget): def PathClicked(self): - folder = QFileDialog.getExistingDirectory(self, "选择MAA目录", "./") + folder = QFileDialog.getExistingDirectory( + self, + "选择MAA目录", + Config.maa_config.get(Config.maa_config.MaaSet_Path), + ) if ( not folder or Config.maa_config.get(Config.maa_config.MaaSet_Path) == folder diff --git a/resources/version.json b/resources/version.json index f8fe05c..8667198 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,7 +1,7 @@ { "main_version": "4.2.2.4", "updater_version": "1.1.1.3", - "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑", + "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置", "proxy_list": [ "", "https://gitproxy.click/", From 748fa7a004ab772c8e70bd5cc6de4fd26b2eacef Mon Sep 17 00:00:00 2001 From: DLmaster Date: Fri, 7 Feb 2025 18:27:01 +0800 Subject: [PATCH 05/13] =?UTF-8?q?fix(gui):=20=E4=BF=AE=E5=A4=8D=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E8=AE=B0=E5=BF=86=E5=8A=9F=E8=83=BD=E5=A4=B1=E6=95=88?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 2 ++ app/core/task_manager.py | 2 -- app/ui/main_window.py | 16 ++++++++-------- resources/version.json | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index 6f05a49..833d11c 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -127,6 +127,8 @@ class AppConfig: self.queue_config = QueueConfig() self.maa_config = MaaConfig() + qconfig.load(self.config_path, self.global_config) + config_list = self.search_config() for config in config_list: if config[0] == "Maa": diff --git a/app/core/task_manager.py b/app/core/task_manager.py index 28d9fcc..85e97f8 100644 --- a/app/core/task_manager.py +++ b/app/core/task_manager.py @@ -67,8 +67,6 @@ class Task(QThread): self.logs = [] - self.question_response.connect(lambda: print("response")) - def run(self): if "设置MAA" in self.mode: diff --git a/app/ui/main_window.py b/app/ui/main_window.py index efb49f7..28e99e9 100644 --- a/app/ui/main_window.py +++ b/app/ui/main_window.py @@ -223,7 +223,7 @@ class AUTO_MAA(MSFluentWindow): else: self.titleBar.minBtn.clicked.disconnect() - self.titleBar.minBtn.clicked.connect(self.showMinimized) + self.titleBar.minBtn.clicked.connect(self.window().showMinimized) def on_tray_activated(self, reason): """双击返回主界面""" @@ -285,11 +285,11 @@ class AUTO_MAA(MSFluentWindow): ), ) ) - self.setGeometry(location[0], location[1], size[0], size[1]) - self.show() + self.window().setGeometry(location[0], location[1], size[0], size[1]) + self.window().show() if not if_quick: if Config.global_config.get(Config.global_config.ui_maximized): - self.showMaximized() + self.window().showMaximized() self.set_min_method() self.show_ui("配置托盘") @@ -303,7 +303,7 @@ class AUTO_MAA(MSFluentWindow): elif mode == "隐藏到托盘": # 保存窗口相关属性 - if not self.isMaximized(): + if not self.window().isMaximized(): Config.global_config.set( Config.global_config.ui_size, @@ -314,14 +314,14 @@ class AUTO_MAA(MSFluentWindow): f"{self.geometry().x()}x{self.geometry().y()}", ) Config.global_config.set( - Config.global_config.ui_maximized, self.isMaximized() + Config.global_config.ui_maximized, self.window().isMaximized() ) Config.global_config.save() # 隐藏主窗口 if not if_quick: - self.hide() + self.window().hide() self.tray.show() def closeEvent(self, event: QCloseEvent): @@ -338,6 +338,6 @@ class AUTO_MAA(MSFluentWindow): Config.close_database() logger.info("AUTO_MAA主程序关闭") - logger.info("===================================") + logger.info("----------------END----------------") event.accept() diff --git a/resources/version.json b/resources/version.json index 8667198..6432c87 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,7 +1,7 @@ { "main_version": "4.2.2.4", "updater_version": "1.1.1.3", - "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置", + "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n- 修复窗口记忆功能失效问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置", "proxy_list": [ "", "https://gitproxy.click/", From 4ff632ed2aefb170fcb0da4ce25db222366289b6 Mon Sep 17 00:00:00 2001 From: heziziziscool Date: Fri, 7 Feb 2025 18:50:32 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=AD=97=E6=AE=B5`today=5Fstauts`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增用户字段`today_status`(位于user_db),用于记录用户的代理是否代理成功,便于后续的衍生项目与二次开发。 --- app/core/config.py | 41 +++++++++++++++++++++++++++++++++++++--- app/core/task_manager.py | 5 +++-- app/models/MAA.py | 7 +++++-- app/ui/member_manager.py | 5 ++++- 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index 833d11c..f3339a5 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -145,7 +145,7 @@ class AppConfig: if mode == "Maa": self.cur.execute( - "CREATE TABLE adminx(admin text,id text,server text,day int,status text,last date,game text,game_1 text,game_2 text,routine text,annihilation text,infrastructure text,password byte,notes text,numb int,mode text,uid int)" + "CREATE TABLE adminx(admin text,id text,server text,day int,status text,last date,game text,game_1 text,game_2 text,routine text,annihilation text,infrastructure text,password byte,notes text,numb int,mode text,uid int,today_status text)" ) self.cur.execute("CREATE TABLE version(v text)") self.cur.execute("INSERT INTO version VALUES(?)", ("v1.4",)) @@ -161,7 +161,7 @@ class AppConfig: db = sqlite3.connect(self.database_path) cur = db.cursor() cur.execute("CREATE TABLE version(v text)") - cur.execute("INSERT INTO version VALUES(?)", ("v1.4",)) + cur.execute("INSERT INTO version VALUES(?)", ("v1.5",)) db.commit() cur.close() db.close() @@ -172,7 +172,7 @@ class AppConfig: cur.execute("SELECT * FROM version WHERE True") version = cur.fetchall() - if version[0][0] != "v1.4": + if version[0][0] != "v1.5": logger.info("数据文件版本更新开始") if_streaming = False # v1.0-->v1.1 @@ -387,10 +387,40 @@ class AppConfig: ) as f: json.dump(queue_config, f, ensure_ascii=False, indent=4) (self.app_path / "config/gui.json").unlink() + + if version[0][0] == "v1.4" or if_streaming: + logger.info("数据文件版本更新:v1.4-->v1.5") + if_streaming = True + # 检查adminx表是否存在 + cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='adminx'") + if not cur.fetchone(): + self.create_adminx_table(cur) + else: + # 获取现有数据 + cur.execute("SELECT * FROM adminx") + data = cur.fetchall() + # 重建表以包含新字段 + cur.execute("DROP TABLE IF EXISTS adminx") + self.create_adminx_table(cur) + # 恢复数据 + for row in data: + cur.execute( + "INSERT INTO adminx VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", + row + ("n",) # 添加today_status默认值为'n' + ) + cur.execute("DELETE FROM version WHERE v = ?", ("v1.4",)) + cur.execute("INSERT INTO version VALUES(?)", ("v1.5",)) + db.commit() cur.close() db.close() logger.info("数据文件版本更新完成") + def create_adminx_table(self, cur): + """创建adminx表""" + cur.execute( + "CREATE TABLE adminx(admin text,id text,server text,day int,status text,last date,game text,game_1 text,game_2 text,routine text,annihilation text,infrastructure text,password byte,notes text,numb int,mode text,uid int,today_status text)" + ) + def search_config(self) -> list: """搜索所有子配置文件""" @@ -434,6 +464,7 @@ class AppConfig: lasts: list, notes: list, numbs: list, + today_status: list, ) -> None: """将代理完成后发生改动的用户信息同步至本地数据库""" @@ -457,6 +488,10 @@ class AppConfig: "UPDATE adminx SET numb = ? WHERE mode = ? AND uid = ?", (numbs[index], modes[index], uids[index]), ) + cur.execute( # 添加today_status的更新 + "UPDATE adminx SET today_status = ? WHERE mode = ? AND uid = ?", + (today_status[index], modes[index], uids[index]), + ) db.commit() cur.close() db.close() diff --git a/app/core/task_manager.py b/app/core/task_manager.py index 85e97f8..142fe1d 100644 --- a/app/core/task_manager.py +++ b/app/core/task_manager.py @@ -45,7 +45,7 @@ class Task(QThread): push_info_bar = Signal(str, str, str, int) question = Signal(str, str) question_response = Signal(bool) - update_user_info = Signal(Path, list, list, list, list, list, list) + update_user_info = Signal(Path, list, list, list, list, list, list, list) create_task_list = Signal(list) create_user_list = Signal(list) update_task_list = Signal(list) @@ -137,7 +137,7 @@ class Task(QThread): self.task.update_user_list.connect(self.update_user_list.emit) self.task.update_log_text.connect(self.update_log_text.emit) self.task.update_user_info.connect( - lambda modes, uids, days, lasts, notes, numbs: self.update_user_info.emit( + lambda modes, uids, days, lasts, notes, numbs, today_status: self.update_user_info.emit( self.member_dict[self.task_list[i][0]][1], modes, uids, @@ -145,6 +145,7 @@ class Task(QThread): lasts, notes, numbs, + today_status ) ) self.task.accomplish.connect( diff --git a/app/models/MAA.py b/app/models/MAA.py index 77815ba..6726c06 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -46,7 +46,7 @@ class MaaManager(QObject): question = Signal(str, str) question_response = Signal(bool) - update_user_info = Signal(list, list, list, list, list, list) + update_user_info = Signal(list, list, list, list, list, list, list) push_info_bar = Signal(str, str, str, int) create_user_list = Signal(list) update_user_list = Signal(list) @@ -272,6 +272,7 @@ class MaaManager(QObject): # 移除静默进程标记 Config.silence_list.remove(self.emulator_path) # 推送异常通知 + self.data[user[2]][17] = 'n' Notify.push_notification( "用户自动代理出现异常!", f"用户 {user[0].replace("_", " 今天的")}的{mode_book[j][5:7]}部分出现一次异常", @@ -300,6 +301,7 @@ class MaaManager(QObject): # 录入代理失败的用户 if not (run_book[0] and run_book[1]): + self.data[user[2]][17] = 'n' user[1] = "异常" self.update_user_list.emit(user_list) @@ -479,7 +481,8 @@ class MaaManager(QObject): lasts = [self.data[_[2]][5] for _ in user_list] notes = [self.data[_[2]][13] for _ in user_list] numbs = [self.data[_[2]][14] for _ in user_list] - self.update_user_info.emit(modes, uids, days, lasts, notes, numbs) + today_status = [self.data[_[2]][17] for _ in user_list] + self.update_user_info.emit(modes, uids, days, lasts, notes, numbs, today_status) error_index = [_[2] for _ in user_list if _[1] == "异常"] over_index = [_[2] for _ in user_list if _[1] == "完成"] diff --git a/app/ui/member_manager.py b/app/ui/member_manager.py index 60d4740..1be99e7 100644 --- a/app/ui/member_manager.py +++ b/app/ui/member_manager.py @@ -789,6 +789,7 @@ class MaaSettingBox(QWidget): "numb", "mode", "uid", + "today_status", ] self.userlist_simple_index = [ 0, @@ -808,6 +809,7 @@ class MaaSettingBox(QWidget): "-", "-", "-", + "-" ] self.userlist_beta_index = [ 0, @@ -827,6 +829,7 @@ class MaaSettingBox(QWidget): "-", "-", "-", + "-", ] self.pivot = Pivot(self) @@ -1225,7 +1228,7 @@ class MaaSettingBox(QWidget): elif "高级用户列表" in self.pivot.currentRouteKey(): set_book = ["beta", self.user_list_beta.rowCount()] Config.cur.execute( - "INSERT INTO adminx VALUES('新用户','手机号码(官服)/B站ID(B服)','Official',-1,'y','2000-01-01','1-7','-','-','n','n','n',?,'无',0,?,?)", + "INSERT INTO adminx VALUES('新用户','手机号码(官服)/B站ID(B服)','Official',-1,'y','2000-01-01','1-7','-','-','n','n','n',?,'无',0,?,?,'n')", ( Crypto.encryptx("未设置"), set_book[0], From 6c2f19a8849c186df2fa2683c6da26bfda5070fd Mon Sep 17 00:00:00 2001 From: DLmaster Date: Fri, 7 Feb 2025 19:56:41 +0800 Subject: [PATCH 07/13] =?UTF-8?q?Revert=20"=E6=96=B0=E5=A2=9E=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=AD=97=E6=AE=B5`today=5Fstauts`"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4ff632ed2aefb170fcb0da4ce25db222366289b6. --- app/core/config.py | 41 +++------------------------------------- app/core/task_manager.py | 5 ++--- app/models/MAA.py | 7 ++----- app/ui/member_manager.py | 5 +---- 4 files changed, 8 insertions(+), 50 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index f3339a5..833d11c 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -145,7 +145,7 @@ class AppConfig: if mode == "Maa": self.cur.execute( - "CREATE TABLE adminx(admin text,id text,server text,day int,status text,last date,game text,game_1 text,game_2 text,routine text,annihilation text,infrastructure text,password byte,notes text,numb int,mode text,uid int,today_status text)" + "CREATE TABLE adminx(admin text,id text,server text,day int,status text,last date,game text,game_1 text,game_2 text,routine text,annihilation text,infrastructure text,password byte,notes text,numb int,mode text,uid int)" ) self.cur.execute("CREATE TABLE version(v text)") self.cur.execute("INSERT INTO version VALUES(?)", ("v1.4",)) @@ -161,7 +161,7 @@ class AppConfig: db = sqlite3.connect(self.database_path) cur = db.cursor() cur.execute("CREATE TABLE version(v text)") - cur.execute("INSERT INTO version VALUES(?)", ("v1.5",)) + cur.execute("INSERT INTO version VALUES(?)", ("v1.4",)) db.commit() cur.close() db.close() @@ -172,7 +172,7 @@ class AppConfig: cur.execute("SELECT * FROM version WHERE True") version = cur.fetchall() - if version[0][0] != "v1.5": + if version[0][0] != "v1.4": logger.info("数据文件版本更新开始") if_streaming = False # v1.0-->v1.1 @@ -387,40 +387,10 @@ class AppConfig: ) as f: json.dump(queue_config, f, ensure_ascii=False, indent=4) (self.app_path / "config/gui.json").unlink() - - if version[0][0] == "v1.4" or if_streaming: - logger.info("数据文件版本更新:v1.4-->v1.5") - if_streaming = True - # 检查adminx表是否存在 - cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='adminx'") - if not cur.fetchone(): - self.create_adminx_table(cur) - else: - # 获取现有数据 - cur.execute("SELECT * FROM adminx") - data = cur.fetchall() - # 重建表以包含新字段 - cur.execute("DROP TABLE IF EXISTS adminx") - self.create_adminx_table(cur) - # 恢复数据 - for row in data: - cur.execute( - "INSERT INTO adminx VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", - row + ("n",) # 添加today_status默认值为'n' - ) - cur.execute("DELETE FROM version WHERE v = ?", ("v1.4",)) - cur.execute("INSERT INTO version VALUES(?)", ("v1.5",)) - db.commit() cur.close() db.close() logger.info("数据文件版本更新完成") - def create_adminx_table(self, cur): - """创建adminx表""" - cur.execute( - "CREATE TABLE adminx(admin text,id text,server text,day int,status text,last date,game text,game_1 text,game_2 text,routine text,annihilation text,infrastructure text,password byte,notes text,numb int,mode text,uid int,today_status text)" - ) - def search_config(self) -> list: """搜索所有子配置文件""" @@ -464,7 +434,6 @@ class AppConfig: lasts: list, notes: list, numbs: list, - today_status: list, ) -> None: """将代理完成后发生改动的用户信息同步至本地数据库""" @@ -488,10 +457,6 @@ class AppConfig: "UPDATE adminx SET numb = ? WHERE mode = ? AND uid = ?", (numbs[index], modes[index], uids[index]), ) - cur.execute( # 添加today_status的更新 - "UPDATE adminx SET today_status = ? WHERE mode = ? AND uid = ?", - (today_status[index], modes[index], uids[index]), - ) db.commit() cur.close() db.close() diff --git a/app/core/task_manager.py b/app/core/task_manager.py index 142fe1d..85e97f8 100644 --- a/app/core/task_manager.py +++ b/app/core/task_manager.py @@ -45,7 +45,7 @@ class Task(QThread): push_info_bar = Signal(str, str, str, int) question = Signal(str, str) question_response = Signal(bool) - update_user_info = Signal(Path, list, list, list, list, list, list, list) + update_user_info = Signal(Path, list, list, list, list, list, list) create_task_list = Signal(list) create_user_list = Signal(list) update_task_list = Signal(list) @@ -137,7 +137,7 @@ class Task(QThread): self.task.update_user_list.connect(self.update_user_list.emit) self.task.update_log_text.connect(self.update_log_text.emit) self.task.update_user_info.connect( - lambda modes, uids, days, lasts, notes, numbs, today_status: self.update_user_info.emit( + lambda modes, uids, days, lasts, notes, numbs: self.update_user_info.emit( self.member_dict[self.task_list[i][0]][1], modes, uids, @@ -145,7 +145,6 @@ class Task(QThread): lasts, notes, numbs, - today_status ) ) self.task.accomplish.connect( diff --git a/app/models/MAA.py b/app/models/MAA.py index 6726c06..77815ba 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -46,7 +46,7 @@ class MaaManager(QObject): question = Signal(str, str) question_response = Signal(bool) - update_user_info = Signal(list, list, list, list, list, list, list) + update_user_info = Signal(list, list, list, list, list, list) push_info_bar = Signal(str, str, str, int) create_user_list = Signal(list) update_user_list = Signal(list) @@ -272,7 +272,6 @@ class MaaManager(QObject): # 移除静默进程标记 Config.silence_list.remove(self.emulator_path) # 推送异常通知 - self.data[user[2]][17] = 'n' Notify.push_notification( "用户自动代理出现异常!", f"用户 {user[0].replace("_", " 今天的")}的{mode_book[j][5:7]}部分出现一次异常", @@ -301,7 +300,6 @@ class MaaManager(QObject): # 录入代理失败的用户 if not (run_book[0] and run_book[1]): - self.data[user[2]][17] = 'n' user[1] = "异常" self.update_user_list.emit(user_list) @@ -481,8 +479,7 @@ class MaaManager(QObject): lasts = [self.data[_[2]][5] for _ in user_list] notes = [self.data[_[2]][13] for _ in user_list] numbs = [self.data[_[2]][14] for _ in user_list] - today_status = [self.data[_[2]][17] for _ in user_list] - self.update_user_info.emit(modes, uids, days, lasts, notes, numbs, today_status) + self.update_user_info.emit(modes, uids, days, lasts, notes, numbs) error_index = [_[2] for _ in user_list if _[1] == "异常"] over_index = [_[2] for _ in user_list if _[1] == "完成"] diff --git a/app/ui/member_manager.py b/app/ui/member_manager.py index 1be99e7..60d4740 100644 --- a/app/ui/member_manager.py +++ b/app/ui/member_manager.py @@ -789,7 +789,6 @@ class MaaSettingBox(QWidget): "numb", "mode", "uid", - "today_status", ] self.userlist_simple_index = [ 0, @@ -809,7 +808,6 @@ class MaaSettingBox(QWidget): "-", "-", "-", - "-" ] self.userlist_beta_index = [ 0, @@ -829,7 +827,6 @@ class MaaSettingBox(QWidget): "-", "-", "-", - "-", ] self.pivot = Pivot(self) @@ -1228,7 +1225,7 @@ class MaaSettingBox(QWidget): elif "高级用户列表" in self.pivot.currentRouteKey(): set_book = ["beta", self.user_list_beta.rowCount()] Config.cur.execute( - "INSERT INTO adminx VALUES('新用户','手机号码(官服)/B站ID(B服)','Official',-1,'y','2000-01-01','1-7','-','-','n','n','n',?,'无',0,?,?,'n')", + "INSERT INTO adminx VALUES('新用户','手机号码(官服)/B站ID(B服)','Official',-1,'y','2000-01-01','1-7','-','-','n','n','n',?,'无',0,?,?)", ( Crypto.encryptx("未设置"), set_book[0], From 5c24eb7d56fb203a9ad62c56a699fb6aa77f5860 Mon Sep 17 00:00:00 2001 From: DLmaster Date: Fri, 7 Feb 2025 20:15:12 +0800 Subject: [PATCH 08/13] =?UTF-8?q?docs:=20=E6=94=B9=E7=94=A8=E8=85=BE?= =?UTF-8?q?=E8=AE=AF=E6=96=87=E6=A1=A3=E5=B1=95=E7=A4=BA=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 129 ++---------------------------------------------------- 1 file changed, 3 insertions(+), 126 deletions(-) diff --git a/README.md b/README.md index 2c5c299..b19e238 100644 --- a/README.md +++ b/README.md @@ -58,132 +58,9 @@ MAA多账号管理与自动化软件 # 使用方法 -## 安装软件 +本项目已改用腾讯文档展示使用方法 -``` -本软件是MAA的外部工具,需要安装MAA后才能使用。 -``` - -### 下载MAA - -- 什么是MAA? [官网](https://maa.plus/)/[GitHub](https://github.com/MaaAssistantArknights/MaaAssistantArknights) -- MAA下载地址 [GitHub下载](https://github.com/MaaAssistantArknights/MaaAssistantArknights/releases) - -### 安装MAA - -- 将MAA压缩包解压至任意普通文件夹即可。 -- 若为首次安装MAA,请双击`MAA.exe`启动MAA程序以生成MAA配置文件。 - -### 下载AUTO_MAA [![](https://img.shields.io/github/downloads/DLmaster361/AUTO_MAA/total?color=66ccff)](https://github.com/DLmaster361/AUTO_MAA/releases) - -- GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/releases) - -### 安装AUTO_MAA - -- 将AUTO_MAA压缩包解压至任意普通文件夹即可。 - -## 配置AUTO_MAA - -### 启动AUTO_MAA - -- 双击`AUTO_MAA.exe`以启动软件。 - -``` -注意: - - 首次启动时会要求设置管理密钥。 - - 管理密钥是解密用户密码的唯一凭证,与用户数据库绑定。 - 密钥丢失或data/key/目录下任一文件损坏都将导致解密无法正常进行。 - - 本项目采用自主开发的混合加密模式,项目组也无法找回您的管理密钥或修复data/key/目录下的文件。 - 如果不幸的事发生,建议您删除data/key目录与config目录后重新录入信息。 -``` - -### 配置信息 - -#### 设置脚本实例 - -1. 单击`+`并选择`MAA`以添加MAA脚本实例。 -2. 在`MAA目录`选项卡中通过`选择文件夹`打开MAA软件目录以绑定MAA。 -3. 在`MAA全局配置`选项卡中通过`设置`进行MAA全局设置。在打开的MAA界面完成`性能设置`、`游戏设置`、`连接设置`、`启动设置`、`界面设置`、`软件更新`等基本配置以及代理任务的详细配置。 -4. 完成基本配置后,关闭MAA页面,AUTO_MAA会自动保存您的配置。 - -- 注意:在MAA的设置过程中,若MAA要求`立刻重启应用更改`,请选择`稍后`。否则,MAA重启后的一切更改都不会被程序记录。 - -- 特别的,在设置MAA过程中,您需要确保自己: - - 在`切换配置`选项卡中选择了`Default`项。 - - 取消勾选`开机自启动MAA`。 - - 配置自己模拟器所在的位置并根据实际情况填写`等待模拟器启动时间`(建议预留10s以防意外)。 - - 如果是模拟器多开用户,还需要填写`附加命令`,具体填写值参见多开模拟器对应快捷方式路径(如`-v 1`)。 - -![MAA配置](https://github.com/DLmaster361/AUTO_MAA/blob/main/resources/images/README/MAA配置.png "MAA配置") - - -#### 设置用户配置 - -每一个脚本实例都有独立的用户数据库,您可以直接在`用户列表`选项卡配置用户相关信息,页面简介如下: -- `新建用户`、`删除用户`:新建一个用户到当前用户配置列表、删除当前所选第一行所对应的用户。 -- `向上移动`、`向下移动`:移动用户位置,用户位置即代理顺序。 -- `模式转换`:将当前所选第一行所对应的用户转为高级/简洁配置模式。 -- `用户选项配置`:选择用户与对应配置项目,执行对应配置流程。 - - `自定义基建`:选择自定义基建配置文件。 - - `日常`、`剿灭`:打开MAA界面进行设置,设置方法与MAA全局配置相同。 -- `显示密码`:输入管理密钥以显示用户密码,仅当管理密钥正确时能够修改`密码栏目`。 -- `简洁用户配置列表`:仅支持核心代理选项的设置,其它设置选项沿用MAA的全局设置,部分代理核心功能选项由程序托管。 -- `高级用户配置列表`:支持几乎所有代理选项的设置,通过`用户选项配置`进行MAA自定义,仅部分代理核心功能选项由程序托管。 -- `用户配置列表栏目`详解如下: - - `用户名`:展示在执行界面的用户名,用于区分不同用户。 - - `账号ID`:MAA进行账号切换所需的凭据,官服用户请输入手机号码、B服请输入B站ID。 - - `服务器`:当前支持官服、B服。 - - `代理天数`:剩余需要进行代理的天数,输入`任意负数`可设置为无限代理天数,当剩余天数为0时不再代理或排查。 - - `状态`:用户的状态,禁用时将不再对其进行代理或排查。 - - `执行情况`:当日执行情况,不可编辑。 - - `关卡`、`备选关卡-1`、`备选关卡-2`:关卡号。 - - `日常`:单独设定是否进行自动代理的日常部分,可进一步配置MAA的具体代理任务,该配置与全局MAA配置相互独立。 - - `剿灭`:单独设定是否进行自动代理的剿灭部分,高级配置模式下可进一步配置MAA的具体代理任务,该配置与全局MAA配置相互独立。 - - `自定义基建`:是否启用自定义基建功能,需要进一步配置自定义基建文件,该配置与其他用户相互独立。 - - `密码`:仅用于登记用户的密码,可留空。 - - `备注`:用于备注用户信息。 - -- 特别的: - - 对于`简洁用户配置列表的关卡、备选关卡-1、备选关卡-2栏目`您可以自定义关卡号替换方案。 - - 程序会读取`data/gameid.txt`中的数据,依据此进行关卡号的替换,便于常用关卡的使用。 - - `gameid.txt`会在程序首次运行时生成,其中将预置一些常用资源本的替换方案。 - -![gameid](https://github.com/DLmaster361/AUTO_MAA/blob/main/resources/images/README/gameid.png "gameid") - -#### 设置调度队列 - -- 单个调度队列可包含至多10个定时与至多10个任务实例。 -- 调度队列状态为关闭时,将不会定时启动该调度队列,但仍能在主调度台直接运行该调度队列。 -- 同一调度队列内任务实例被依次挨个调起运行,非同一调度队列内的不同任务实例可被同时调起。 -- 同一时间内,任何脚本实例或调度队列都不会被重复调起,若某一任务运行时发现同一任务已在运行,将自动跳过。 - -#### 设置AUTO_MAA - -- 详见软件中对应选项卡的注解。 - -## 运行代理任务 - -### 直接运行 - -- 在`调度中心`的`主调度台`选择对应任务与`自动代理`模式,单击`开始任务`即可开始代理。 - -### 定时运行 - -- 将调度队列状态设为开启,并在`定时`选项卡设置定时启动时间。 -- 保持软件开启,软件会在设定的时间自动运行。 - -## 人工排查代理结果 - -### 直接开始人工排查 - -- 在`调度中心`的`主调度台`选择对应任务与`人工排查`模式,单击`开始任务`即可开始人工排查。 -- 软件将调起MAA,依次登录各用户的账号。 -- 完成PRTS登录后,请人工检查代理情况,可以手动完成未代理的任务。 -- 在对话框中单击对应账号的代理情况。 -- 结束人工排查后,相应排查情况将被写入用户管理页的`备注栏目`。 +- [《AUTO_MAA用户指南》](https://docs.qq.com/aio/DQ2NwUHRiWGtMWHBy) --- @@ -213,7 +90,7 @@ MAA多账号管理与自动化软件 欢迎加入AUTO_MAA项目组,欢迎反馈bug -- QQ群:[957750551](https://qm.qq.com/q/bd9fISNoME) +- QQ交流群:[957750551](https://qm.qq.com/q/bd9fISNoME) --- From d13fbb063d15395cd33cedf082e44a7d414782e5 Mon Sep 17 00:00:00 2001 From: DLmaster Date: Sat, 8 Feb 2025 12:05:28 +0800 Subject: [PATCH 09/13] =?UTF-8?q?feat(core):=20=E5=88=9D=E6=AD=A5=E5=AE=8C?= =?UTF-8?q?=E6=88=90`=E6=89=98=E7=AE=A1bilibili=E6=B8=B8=E6=88=8F=E9=9A=90?= =?UTF-8?q?=E7=A7=81=E6=94=BF=E7=AD=96`=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 3 ++ app/core/task_manager.py | 86 ++++++++++++++++++++-------------------- app/models/MAA.py | 39 +++++++++++++++++- app/ui/setting.py | 39 ++++++++++++++++-- resources/version.json | 4 +- 5 files changed, 121 insertions(+), 50 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index 833d11c..68244f2 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -544,6 +544,9 @@ class GlobalConfig(QConfig): ) function_IfSilence = ConfigItem("Function", "IfSilence", False, BoolValidator()) function_BossKey = ConfigItem("Function", "BossKey", "") + function_IfAgreeBilibili = ConfigItem( + "Function", "IfAgreeBilibili", False, BoolValidator() + ) start_IfSelfStart = ConfigItem("Start", "IfSelfStart", False, BoolValidator()) start_IfRunDirectly = ConfigItem("Start", "IfRunDirectly", False, BoolValidator()) diff --git a/app/core/task_manager.py b/app/core/task_manager.py index 85e97f8..aae284d 100644 --- a/app/core/task_manager.py +++ b/app/core/task_manager.py @@ -92,41 +92,41 @@ class Task(QThread): else: self.member_dict = self.search_member() - self.task_list = [ + self.task_dict = [ [value, "等待"] for _, value in self.info["Queue"].items() if value != "禁用" ] - self.create_task_list.emit(self.task_list) + self.create_task_list.emit(self.task_dict) - for i in range(len(self.task_list)): + for i in range(len(self.task_dict)): if self.isInterruptionRequested(): break - self.task_list[i][1] = "运行" - self.update_task_list.emit(self.task_list) + self.task_dict[i][1] = "运行" + self.update_task_list.emit(self.task_dict) - if self.task_list[i][0] in Config.running_list: + if self.task_dict[i][0] in Config.running_list: - self.task_list[i][1] = "跳过" - self.update_task_list.emit(self.task_list) - logger.info(f"跳过任务:{self.task_list[i][0]}") + self.task_dict[i][1] = "跳过" + self.update_task_list.emit(self.task_dict) + logger.info(f"跳过任务:{self.task_dict[i][0]}") self.push_info_bar.emit( - "info", "跳过任务", self.task_list[i][0], 3000 + "info", "跳过任务", self.task_dict[i][0], 3000 ) continue - Config.running_list.append(self.task_list[i][0]) - logger.info(f"任务开始:{self.task_list[i][0]}") - self.push_info_bar.emit("info", "任务开始", self.task_list[i][0], 3000) + Config.running_list.append(self.task_dict[i][0]) + logger.info(f"任务开始:{self.task_dict[i][0]}") + self.push_info_bar.emit("info", "任务开始", self.task_dict[i][0], 3000) - if self.member_dict[self.task_list[i][0]][0] == "Maa": + if self.member_dict[self.task_dict[i][0]][0] == "Maa": self.task = MaaManager( self.mode[0:4], - self.member_dict[self.task_list[i][0]][1], + self.member_dict[self.task_dict[i][0]][1], ) self.task.question.connect(self.question.emit) @@ -138,7 +138,7 @@ class Task(QThread): self.task.update_log_text.connect(self.update_log_text.emit) self.task.update_user_info.connect( lambda modes, uids, days, lasts, notes, numbs: self.update_user_info.emit( - self.member_dict[self.task_list[i][0]][1], + self.member_dict[self.task_dict[i][0]][1], modes, uids, days, @@ -148,16 +148,16 @@ class Task(QThread): ) ) self.task.accomplish.connect( - lambda log: self.save_log(self.task_list[i][0], log) + lambda log: self.save_log(self.task_dict[i][0], log) ) self.task.run() - Config.running_list.remove(self.task_list[i][0]) + Config.running_list.remove(self.task_dict[i][0]) - self.task_list[i][1] = "完成" - logger.info(f"任务完成:{self.task_list[i][0]}") - self.push_info_bar.emit("info", "任务完成", self.task_list[i][0], 3000) + self.task_dict[i][1] = "完成" + logger.info(f"任务完成:{self.task_dict[i][0]}") + self.push_info_bar.emit("info", "任务完成", self.task_dict[i][0], 3000) self.accomplish.emit(self.logs) @@ -190,14 +190,14 @@ class TaskManager(QObject): def __init__(self): super(TaskManager, self).__init__() - self.task_list: Dict[str, Task] = {} + self.task_dict: Dict[str, Task] = {} def add_task( self, mode: str, name: str, info: Dict[str, Dict[str, Union[str, int, bool]]] ): """添加任务""" - if name in Config.running_list or name in self.task_list: + if name in Config.running_list or name in self.task_dict: logger.warning(f"任务已存在:{name}") MainInfoBar.push_info_bar("warning", "任务已存在", name, 5000) @@ -207,23 +207,23 @@ class TaskManager(QObject): MainInfoBar.push_info_bar("info", "任务开始", name, 3000) Config.running_list.append(name) - self.task_list[name] = Task(mode, name, info) - self.task_list[name].question.connect( + self.task_dict[name] = Task(mode, name, info) + self.task_dict[name].question.connect( lambda title, content: self.push_dialog(name, title, content) ) - self.task_list[name].push_info_bar.connect(MainInfoBar.push_info_bar) - self.task_list[name].update_user_info.connect(Config.change_user_info) - self.task_list[name].accomplish.connect( + self.task_dict[name].push_info_bar.connect(MainInfoBar.push_info_bar) + self.task_dict[name].update_user_info.connect(Config.change_user_info) + self.task_dict[name].accomplish.connect( lambda logs: self.remove_task(mode, name, logs) ) if "新调度台" in mode: - self.create_gui.emit(self.task_list[name]) + self.create_gui.emit(self.task_dict[name]) elif "主调度台" in mode: - self.connect_gui.emit(self.task_list[name]) + self.connect_gui.emit(self.task_dict[name]) - self.task_list[name].start() + self.task_dict[name].start() def stop_task(self, name: str): """中止任务""" @@ -233,19 +233,19 @@ class TaskManager(QObject): if name == "ALL": - for name in self.task_list: + for name in self.task_dict: - self.task_list[name].task.requestInterruption() - self.task_list[name].requestInterruption() - self.task_list[name].quit() - self.task_list[name].wait() + self.task_dict[name].task.requestInterruption() + self.task_dict[name].requestInterruption() + self.task_dict[name].quit() + self.task_dict[name].wait() - elif name in self.task_list: + elif name in self.task_dict: - self.task_list[name].task.requestInterruption() - self.task_list[name].requestInterruption() - self.task_list[name].quit() - self.task_list[name].wait() + self.task_dict[name].task.requestInterruption() + self.task_dict[name].requestInterruption() + self.task_dict[name].quit() + self.task_dict[name].wait() def remove_task(self, mode: str, name: str, logs: str): """任务结束后的处理""" @@ -271,7 +271,7 @@ class TaskManager(QObject): }, ) - self.task_list.pop(name) + self.task_dict.pop(name) Config.running_list.remove(name) if "调度队列" in name and "人工排查" not in mode: @@ -288,7 +288,7 @@ class TaskManager(QObject): choice.yesButton.setText("是") choice.cancelButton.setText("否") - self.task_list[name].question_response.emit(bool(choice.exec_())) + self.task_dict[name].question_response.emit(bool(choice.exec_())) Task_manager = TaskManager() diff --git a/app/models/MAA.py b/app/models/MAA.py index 77815ba..bdb7b24 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -24,7 +24,6 @@ MAA功能组件 v4.2 作者:DLmaster_361 """ -import sys from loguru import logger from PySide6.QtCore import QObject, Signal, QEventLoop @@ -90,6 +89,7 @@ class MaaManager(QObject): self.maa_set_path = self.maa_root_path / "config/gui.json" self.maa_log_path = self.maa_root_path / "debug/gui.log" self.maa_exe_path = self.maa_root_path / "MAA.exe" + self.maa_tasks_path = self.maa_root_path / "resource/tasks.json" def run(self): """主进程,运行MAA代理进程""" @@ -529,6 +529,7 @@ class MaaManager(QObject): f"{end_log}AUTO_MAA 敬上", ) + self.agree_bilibili(False) self.accomplish.emit({"Time": begin_time, "History": end_log}) def requestInterruption(self) -> None: @@ -650,6 +651,14 @@ class MaaManager(QObject): with self.maa_set_path.open(mode="r", encoding="utf-8") as f: data = json.load(f) + if (self.data[index][15] == "simple" and self.data[index][2] == "Bilibili") or ( + self.data[index][15] == "beta" + and data["Configurations"]["Default"]["Start.ClientType"] == "Bilibili" + ): + self.agree_bilibili(True) + else: + self.agree_bilibili(False) + # 自动代理配置 if "自动代理" in mode: @@ -1011,6 +1020,34 @@ class MaaManager(QObject): return True + def agree_bilibili(self, if_agree): + """向MAA写入Bilibili协议相关任务""" + + with self.maa_tasks_path.open(mode="r", encoding="utf-8") as f: + data = json.load(f) + + if if_agree and Config.global_config.get( + Config.global_config.function_IfAgreeBilibili + ): + data["BilibiliAgreement_AUTO"] = { + "algorithm": "OcrDetect", + "action": "ClickSelf", + "text": ["同意"], + "maxTimes": 5, + "Doc": "关闭B服用户协议", + "next": ["StartUpThemes#next"], + } + if "BilibiliAgreement_AUTO" not in data["StartUpThemes"]["next"]: + data["StartUpThemes"]["next"].insert(0, "BilibiliAgreement_AUTO") + else: + if "BilibiliAgreement_AUTO" in data: + data.pop("BilibiliAgreement_AUTO") + if "BilibiliAgreement_AUTO" in data["StartUpThemes"]["next"]: + data["StartUpThemes"]["next"].remove("BilibiliAgreement_AUTO") + + with self.maa_tasks_path.open(mode="w", encoding="utf-8") as f: + json.dump(data, f, ensure_ascii=False, indent=4) + def get_emulator_path(self): """获取模拟器路径""" diff --git a/app/ui/setting.py b/app/ui/setting.py index dcfdd87..e78b9e1 100644 --- a/app/ui/setting.py +++ b/app/ui/setting.py @@ -83,6 +83,7 @@ class Setting(QWidget): self.other = OtherSettingCard(self) self.function.card_IfAllowSleep.checkedChanged.connect(System.set_Sleep) + self.function.card_IfAgreeBilibili.checkedChanged.connect(self.agree_bilibili) self.start.card_IfSelfStart.checkedChanged.connect(System.set_SelfStart) self.security.card_changePASSWORD.clicked.connect(self.change_PASSWORD) self.updater.card_CheckUpdate.clicked.connect(self.get_update) @@ -102,6 +103,31 @@ class Setting(QWidget): self.setLayout(layout) + def agree_bilibili(self) -> None: + """授权bilibili游戏隐私政策""" + + if not Config.global_config.get(Config.global_config.function_IfAgreeBilibili): + logger.info("取消授权bilibili游戏隐私政策") + MainInfoBar.push_info_bar( + "info", "操作成功", "已取消授权bilibili游戏隐私政策", 3000 + ) + return None + + choice = MessageBox( + "授权声明", + "开启“托管bilibili游戏隐私政策”功能,即代表您已完整阅读并同意《哔哩哔哩弹幕网用户使用协议》、《哔哩哔哩隐私政策》和《哔哩哔哩游戏中心用户协议》,并授权AUTO_MAA在其认定需要时以其认定合适的方法替您处理相关弹窗\n\n是否同意授权?", + self.window(), + ) + if choice.exec(): + logger.success("确认授权bilibili游戏隐私政策") + MainInfoBar.push_info_bar( + "success", "操作成功", "已确认授权bilibili游戏隐私政策", 3000 + ) + else: + Config.global_config.set( + Config.global_config.function_IfAgreeBilibili, False + ) + def check_PASSWORD(self) -> None: """检查并配置管理密钥""" @@ -127,8 +153,7 @@ class Setting(QWidget): ) choice.cancelButton.hide() choice.buttonLayout.insertStretch(1) - if choice.exec(): - pass + choice.exec() def change_PASSWORD(self) -> None: """修改管理密钥""" @@ -183,8 +208,7 @@ class Setting(QWidget): choice = MessageBox("错误", "管理密钥错误", self.window()) choice.cancelButton.hide() choice.buttonLayout.insertStretch(1) - if choice.exec(): - pass + choice.exec() else: choice = MessageBox( "确认", @@ -400,10 +424,17 @@ class FunctionSettingCard(HeaderCardWidget): configItem=Config.global_config.function_IfAllowSleep, ) self.card_IfSilence = self.SilenceSettingCard(self) + self.card_IfAgreeBilibili = SwitchSettingCard( + icon=FluentIcon.PAGE_RIGHT, + title="托管bilibili游戏隐私政策", + content="授权AUTO_MAA同意bilibili游戏隐私政策", + configItem=Config.global_config.function_IfAgreeBilibili, + ) Layout = QVBoxLayout() Layout.addWidget(self.card_IfAllowSleep) Layout.addWidget(self.card_IfSilence) + Layout.addWidget(self.card_IfAgreeBilibili) self.viewLayout.addLayout(Layout) class SilenceSettingCard(ExpandGroupSettingCard): diff --git a/resources/version.json b/resources/version.json index 6432c87..91658ff 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,7 +1,7 @@ { - "main_version": "4.2.2.4", + "main_version": "4.2.2.5", "updater_version": "1.1.1.3", - "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n- 修复窗口记忆功能失效问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置", + "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n- 初步完成`托管bilibili游戏隐私政策`功能\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n- 修复窗口记忆功能失效问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置", "proxy_list": [ "", "https://gitproxy.click/", From 0c123e9389a2852e4241f28f9f540e7eea6b17a3 Mon Sep 17 00:00:00 2001 From: DLmaster Date: Sat, 8 Feb 2025 12:25:48 +0800 Subject: [PATCH 10/13] =?UTF-8?q?feat(services):=20=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E6=B7=BB=E5=8A=A0=E8=84=9A=E6=9C=AC=E5=AE=9E?= =?UTF-8?q?=E4=BE=8B=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/task_manager.py | 7 +++---- app/models/MAA.py | 19 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/app/core/task_manager.py b/app/core/task_manager.py index aae284d..c2217e7 100644 --- a/app/core/task_manager.py +++ b/app/core/task_manager.py @@ -54,10 +54,7 @@ class Task(QThread): accomplish = Signal(list) def __init__( - self, - mode: str, - name: str, - info: Dict[str, Dict[str, Union[str, int, bool]]], + self, mode: str, name: str, info: Dict[str, Dict[str, Union[str, int, bool]]] ): super(Task, self).__init__() @@ -67,6 +64,8 @@ class Task(QThread): self.logs = [] + self.question_response.connect(lambda: print("response")) + def run(self): if "设置MAA" in self.mode: diff --git a/app/models/MAA.py b/app/models/MAA.py index bdb7b24..48ecb3b 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -503,9 +503,14 @@ class MaaManager(QObject): f"{"\n".join([self.data[_][0] for _ in wait_index])}\n" ) + title = ( + f"{self.set["MaaSet"]["Name"]}的{self.mode[:4]}任务报告" + if self.set["MaaSet"]["Name"] != "" + else f"{self.mode[:4]}任务报告" + ) # 推送代理结果通知 Notify.push_notification( - f"{self.mode[2:4]}任务已完成!", + title.replace("报告", "已完成!"), f"已完成用户数:{len(over_index)},未完成用户数:{len(error_index) + len(wait_index)}", f"已完成用户数:{len(over_index)},未完成用户数:{len(error_index) + len(wait_index)}", 10, @@ -517,17 +522,11 @@ class MaaManager(QObject): and len(error_index) + len(wait_index) != 0 ): Notify.send_mail( - f"{self.mode[:4]}任务报告", + title, f"{end_log}\n\nAUTO_MAA 敬上\n\n我们根据您在 AUTO_MAA 中的设置发送了这封电子邮件,本邮件无需回复\n", ) - Notify.ServerChanPush( - f"{self.mode[:4]}任务报告", - f"{end_log}\n\nAUTO_MAA 敬上", - ) - Notify.CompanyWebHookBotPush( - f"{self.mode[:4]}任务报告", - f"{end_log}AUTO_MAA 敬上", - ) + Notify.ServerChanPush(title, f"{end_log}\n\nAUTO_MAA 敬上") + Notify.CompanyWebHookBotPush(title, f"{end_log}AUTO_MAA 敬上") self.agree_bilibili(False) self.accomplish.emit({"Time": begin_time, "History": end_log}) From de262ee6bd75e6a203d793220ec430950546dce1 Mon Sep 17 00:00:00 2001 From: DLmaster Date: Sat, 8 Feb 2025 16:58:11 +0800 Subject: [PATCH 11/13] =?UTF-8?q?fix(models):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=AE=BE=E7=BD=AEMAA=E6=97=B6=E5=BC=82=E5=B8=B8=E8=B0=83?= =?UTF-8?q?=E7=94=A8B=E6=9C=8D=E4=BB=BB=E5=8A=A1=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/MAA.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/models/MAA.py b/app/models/MAA.py index 48ecb3b..02f5509 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -650,9 +650,12 @@ class MaaManager(QObject): with self.maa_set_path.open(mode="r", encoding="utf-8") as f: data = json.load(f) - if (self.data[index][15] == "simple" and self.data[index][2] == "Bilibili") or ( - self.data[index][15] == "beta" - and data["Configurations"]["Default"]["Start.ClientType"] == "Bilibili" + if "设置MAA" not in mode and ( + (self.data[index][15] == "simple" and self.data[index][2] == "Bilibili") + or ( + self.data[index][15] == "beta" + and data["Configurations"]["Default"]["Start.ClientType"] == "Bilibili" + ) ): self.agree_bilibili(True) else: From f07cd2b44ac782126b7c7f8b8c0fbdd0f8169df5 Mon Sep 17 00:00:00 2001 From: DLmaster Date: Sun, 9 Feb 2025 21:36:33 +0800 Subject: [PATCH 12/13] =?UTF-8?q?feat(core):=20=E9=82=AE=E7=AE=B1=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E5=8A=9F=E8=83=BD=E8=B0=83=E6=95=B4=EF=BC=8C=E6=94=B9?= =?UTF-8?q?=E7=94=B1=E7=94=A8=E6=88=B7=E6=8F=90=E4=BE=9B=E5=8F=91=E4=BF=A1?= =?UTF-8?q?=E9=82=AE=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/core/config.py | 5 +- app/services/notification.py | 144 ++++++++++++++++++++++------------- app/services/security.py | 41 ++++++++-- app/ui/Widget.py | 59 +++++++++++--- app/ui/member_manager.py | 33 ++++---- app/ui/setting.py | 44 ++++++++--- resources/version.json | 4 +- 7 files changed, 229 insertions(+), 101 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index 68244f2..f0bee3f 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -562,7 +562,10 @@ class GlobalConfig(QConfig): notify_IfSendErrorOnly = ConfigItem( "Notify", "IfSendErrorOnly", False, BoolValidator() ) - notify_MailAddress = ConfigItem("Notify", "MailAddress", "") + notify_SMTPServerAddress = ConfigItem("Notify", "SMTPServerAddress", "") + notify_AuthorizationCode = ConfigItem("Notify", "AuthorizationCode", "") + notify_FromAddress = ConfigItem("Notify", "FromAddress", "") + notify_ToAddress = ConfigItem("Notify", "ToAddress", "") notify_IfServerChan = ConfigItem("Notify", "IfServerChan", False, BoolValidator()) notify_ServerChanKey = ConfigItem("Notify", "ServerChanKey", "") notify_ServerChanChannel = ConfigItem("Notify", "ServerChanChannel", "") diff --git a/app/services/notification.py b/app/services/notification.py index c566cdd..7f373bf 100644 --- a/app/services/notification.py +++ b/app/services/notification.py @@ -34,7 +34,8 @@ from email.utils import formataddr from serverchan_sdk import sc_send -from app.core import Config +from app.core import Config, MainInfoBar +from app.services.security import Crypto class Notification: @@ -57,73 +58,97 @@ class Notification: return True def send_mail(self, title, content): - """使用官方专用邮箱推送邮件通知""" - - # 声明:此邮箱为AUTO_MAA项目组资产,未经授权不得私自使用 - # 注意:此声明注释只有使用者更换发信邮箱时才能删除,本条规则优先级高于GPLv3 + """推送邮件通知""" if Config.global_config.get(Config.global_config.notify_IfSendMail): - # 第三方 SMTP 服务配置 - mail_host = "smtp.163.com" # 设置服务器 - mail_sender = "AUTO_MAA_server@163.com" # 用户名 - mail_key = "SYrq87nDLD4RNB5T" # 授权码 24/11/15 - - # 定义邮件正文 - message = MIMEText(content, "plain", "utf-8") - message["From"] = formataddr( - ( - Header("AUTO_MAA通知服务", "utf-8").encode(), - "AUTO_MAA_server@163.com", - ) - ) # 发件人显示的名字 - message["To"] = formataddr( - ( - Header("AUTO_MAA用户", "utf-8").encode(), - Config.global_config.get(Config.global_config.notify_MailAddress), - ) - ) # 收件人显示的名字 - message["Subject"] = Header(title, "utf-8") - try: - smtpObj = smtplib.SMTP_SSL(mail_host, 465) # 465为SMTP_SSL默认端口 - smtpObj.login(mail_sender, mail_key) + # 定义邮件正文 + message = MIMEText(content, "plain", "utf-8") + message["From"] = formataddr( + ( + Header("AUTO_MAA通知服务", "utf-8").encode(), + "AUTO_MAA_server@163.com", + ) + ) # 发件人显示的名字 + message["To"] = formataddr( + ( + Header("AUTO_MAA用户", "utf-8").encode(), + Config.global_config.get(Config.global_config.notify_ToAddress), + ) + ) # 收件人显示的名字 + message["Subject"] = Header(title, "utf-8") + + smtpObj = smtplib.SMTP_SSL( + Config.global_config.get( + Config.global_config.notify_SMTPServerAddress + ), + 465, + ) + smtpObj.login( + Config.global_config.get(Config.global_config.notify_FromAddress), + Crypto.win_decryptor( + Config.global_config.get( + Config.global_config.notify_AuthorizationCode + ) + ), + ) smtpObj.sendmail( - mail_sender, - Config.global_config.get(Config.global_config.notify_MailAddress), + Config.global_config.get(Config.global_config.notify_FromAddress), + Config.global_config.get(Config.global_config.notify_ToAddress), message.as_string(), ) - return True - except smtplib.SMTPException as e: - return f"发送邮件时出错:\n{e}" - finally: smtpObj.quit() + logger.success("邮件发送成功") + except Exception as e: + logger.error(f"发送邮件时出错:\n{e}") + MainInfoBar.push_info_bar("error", "发送邮件时出错", f"{e}", -1) def ServerChanPush(self, title, content): """使用Server酱推送通知""" if Config.global_config.get(Config.global_config.notify_IfServerChan): - send_key = Config.global_config.get(Config.global_config.notify_ServerChanKey) + send_key = Config.global_config.get( + Config.global_config.notify_ServerChanKey + ) option = {} - is_valid = lambda s: s == "" or (s == '|'.join(s.split('|')) and (s.count('|') == 0 or all(s.split('|')))) + is_valid = lambda s: s == "" or ( + s == "|".join(s.split("|")) and (s.count("|") == 0 or all(s.split("|"))) + ) """ is_valid => True, 如果启用的话需要正确设置Tag和Channel。 允许空的Tag和Channel即不启用,但不允许例如a||b,|a|b,a|b|,|||| """ - send_tag = Config.global_config.get(Config.global_config.notify_ServerChanTag) - send_channel = Config.global_config.get(Config.global_config.notify_ServerChanChannel) + send_tag = Config.global_config.get( + Config.global_config.notify_ServerChanTag + ) + send_channel = Config.global_config.get( + Config.global_config.notify_ServerChanChannel + ) if is_valid(send_tag): - option['tags'] = send_tag + option["tags"] = send_tag else: - option['tags'] = '' - logger.warning('请正确设置Auto_MAA中ServerChan的Tag。') + option["tags"] = "" + logger.warning("请正确设置Auto_MAA中ServerChan的Tag。") + MainInfoBar.push_info_bar( + "warning", + "Server酱通知推送异常", + "请正确设置Auto_MAA中ServerChan的Tag。", + -1, + ) if is_valid(send_channel): - option['channel'] = send_channel + option["channel"] = send_channel else: - option['channel'] = '' - logger.warning('请正确设置Auto_MAA中ServerChan的Channel。') + option["channel"] = "" + logger.warning("请正确设置Auto_MAA中ServerChan的Channel。") + MainInfoBar.push_info_bar( + "warning", + "Server酱通知推送异常", + "请正确设置Auto_MAA中ServerChan的Channel。", + -1, + ) response = sc_send(send_key, title, content, option) if response["code"] == 0: @@ -132,21 +157,24 @@ class Notification: else: logger.info("Server酱推送通知失败") logger.error(response) + MainInfoBar.push_info_bar( + "error", + "Server酱通知推送失败", + f'使用Server酱推送通知时出错:\n{response["data"]['error']}', + -1, + ) return f'使用Server酱推送通知时出错:\n{response["data"]['error']}' def CompanyWebHookBotPush(self, title, content): """使用企业微信群机器人推送通知""" if Config.global_config.get(Config.global_config.notify_IfCompanyWebHookBot): - content = f'{title}\n{content}' - data = { - "msgtype": "text", - "text": { - "content": content - } - } + content = f"{title}\n{content}" + data = {"msgtype": "text", "text": {"content": content}} response = requests.post( - url=Config.global_config.get(Config.global_config.notify_CompanyWebHookBotUrl), - json=data + url=Config.global_config.get( + Config.global_config.notify_CompanyWebHookBotUrl + ), + json=data, ) if response.json()["errcode"] == 0: logger.info("企业微信群机器人推送通知成功") @@ -154,7 +182,15 @@ class Notification: else: logger.info("企业微信群机器人推送通知失败") logger.error(response.json()) - return f'使用企业微信群机器人推送通知时出错:\n{response.json()["errmsg"]}' + MainInfoBar.push_info_bar( + "error", + "企业微信群机器人通知推送失败", + f'使用企业微信群机器人推送通知时出错:\n{response.json()["errmsg"]}', + -1, + ) + return ( + f'使用企业微信群机器人推送通知时出错:\n{response.json()["errmsg"]}' + ) Notify = Notification() diff --git a/app/services/security.py b/app/services/security.py index 719c124..ed7c50e 100644 --- a/app/services/security.py +++ b/app/services/security.py @@ -30,6 +30,8 @@ import sqlite3 import hashlib import random import secrets +import base64 +import win32crypt from pathlib import Path from Crypto.Cipher import AES from Crypto.PublicKey import RSA @@ -83,8 +85,8 @@ class CryptoHandler: private_key_local = AES_key.encrypt(pad(private_key.exportKey(), 32)) (Config.app_path / "data/key/private_key.bin").write_bytes(private_key_local) - def encryptx(self, note: str) -> bytes: - """加密数据""" + def AUTO_encryptor(self, note: str) -> bytes: + """使用AUTO_MAA的算法加密数据""" # 读取RSA公钥 public_key_local = RSA.import_key( @@ -95,8 +97,8 @@ class CryptoHandler: encrypted = cipher.encrypt(note.encode("utf-8")) return encrypted - def decryptx(self, note: bytes, PASSWORD: str) -> str: - """解密数据""" + def AUTO_decryptor(self, note: bytes, PASSWORD: str) -> str: + """使用AUTO_MAA的算法解密数据""" # 读入RSA私钥密文、盐与校验哈希值 private_key_local = ( @@ -150,7 +152,9 @@ class CryptoHandler: # 使用旧管理密钥解密 user_data["Password"] = [] for i in range(len(data)): - user_data["Password"].append(self.decryptx(data[i][12], PASSWORD_old)) + user_data["Password"].append( + self.AUTO_decryptor(data[i][12], PASSWORD_old) + ) cur.close() db.close() @@ -169,7 +173,7 @@ class CryptoHandler: cur.execute( "UPDATE adminx SET password = ? WHERE mode = ? AND uid = ?", ( - self.encryptx(user_data["Password"][i]), + self.AUTO_encryptor(user_data["Password"][i]), data[i][15], data[i][16], ), @@ -181,6 +185,27 @@ class CryptoHandler: cur.close() db.close() + def win_encryptor( + self, note: str, description: str = None, entropy: bytes = None + ) -> str: + """使用Windows DPAPI加密数据""" + + encrypted = win32crypt.CryptProtectData( + note.encode("utf-8"), description, entropy, None, None, 0 + ) + return base64.b64encode(encrypted).decode("utf-8") + + def win_decryptor(self, note: str, entropy: bytes = None) -> str: + """使用Windows DPAPI解密数据""" + + if note == "": + return "" + + decrypted = win32crypt.CryptUnprotectData( + base64.b64decode(note), entropy, None, None, 0 + ) + return decrypted[1].decode("utf-8") + def search_member(self) -> List[Dict[str, Union[Path, list]]]: """搜索所有脚本实例及其用户数据库路径""" @@ -197,7 +222,9 @@ class CryptoHandler: def check_PASSWORD(self, PASSWORD: str) -> bool: """验证管理密钥""" - return bool(self.decryptx(self.encryptx(""), PASSWORD) != "管理密钥错误") + return bool( + self.AUTO_decryptor(self.AUTO_encryptor(""), PASSWORD) != "管理密钥错误" + ) Crypto = CryptoHandler() diff --git a/app/ui/Widget.py b/app/ui/Widget.py index 1ec5a8f..6ac1d6b 100644 --- a/app/ui/Widget.py +++ b/app/ui/Widget.py @@ -44,14 +44,15 @@ from qfluentwidgets import ( TimeEdit, OptionsConfigItem, ) - from typing import Union, List +from app.services import Crypto -class InputMessageBox(MessageBoxBase): + +class LineEditMessageBox(MessageBoxBase): """输入对话框""" - def __init__(self, parent, title: str, content: str, mode: str, list: list = None): + def __init__(self, parent, title: str, content: str, mode: str): super().__init__(parent) self.title = SubtitleLabel(title) @@ -60,10 +61,6 @@ class InputMessageBox(MessageBoxBase): self.input.setClearButtonEnabled(True) elif mode == "密码": self.input = PasswordLineEdit() - elif mode == "选择": - self.input = ComboBox() - self.input.addItems(list) - self.input.setCurrentIndex(-1) self.input.setPlaceholderText(content) @@ -72,8 +69,8 @@ class InputMessageBox(MessageBoxBase): self.viewLayout.addWidget(self.input) -class SetMessageBox(MessageBoxBase): - """输入对话框""" +class ComboBoxMessageBox(MessageBoxBase): + """选择对话框""" def __init__(self, parent, title: str, content: List[str], list: List[List[str]]): super().__init__(parent) @@ -98,7 +95,7 @@ class SetMessageBox(MessageBoxBase): class LineEditSettingCard(SettingCard): - """Setting card with switch button""" + """Setting card with LineEdit""" textChanged = Signal(str) @@ -138,7 +135,49 @@ class LineEditSettingCard(SettingCard): self.LineEdit.setText(content) +class PasswordLineEditSettingCard(SettingCard): + """Setting card with PasswordLineEdit""" + + textChanged = Signal(str) + + def __init__( + self, + text, + icon: Union[str, QIcon, FluentIconBase], + title, + content=None, + configItem: ConfigItem = None, + parent=None, + ): + + super().__init__(icon, title, content, parent) + self.configItem = configItem + self.LineEdit = PasswordLineEdit(self) + self.LineEdit.setMinimumWidth(250) + self.LineEdit.setPlaceholderText(text) + + if configItem: + self.setValue(qconfig.get(configItem)) + configItem.valueChanged.connect(self.setValue) + + self.hBoxLayout.addWidget(self.LineEdit, 0, Qt.AlignRight) + self.hBoxLayout.addSpacing(16) + + self.LineEdit.textChanged.connect(self.__textChanged) + + def __textChanged(self, content: str): + self.setValue(Crypto.win_encryptor(content)) + self.textChanged.emit(content) + + def setValue(self, content: str): + if self.configItem: + qconfig.set(self.configItem, content) + + self.LineEdit.setText(Crypto.win_decryptor(content)) + + class SpinBoxSettingCard(SettingCard): + """Setting card with SpinBox""" textChanged = Signal(int) diff --git a/app/ui/member_manager.py b/app/ui/member_manager.py index 60d4740..ec7bfe6 100644 --- a/app/ui/member_manager.py +++ b/app/ui/member_manager.py @@ -59,10 +59,10 @@ import shutil from app.core import Config, MainInfoBar, Task_manager from app.services import Crypto from .Widget import ( - InputMessageBox, + LineEditMessageBox, LineEditSettingCard, SpinBoxSettingCard, - SetMessageBox, + ComboBoxMessageBox, ) @@ -123,16 +123,15 @@ class MemberManager(QWidget): def add_setting_box(self): """添加一个脚本实例""" - choice = InputMessageBox( + choice = ComboBoxMessageBox( self.window(), - "选择一个脚本类型并添加相应脚本实例", - "选择脚本类型", - "选择", - ["MAA"], + "选择一个脚本类型以添加相应脚本实例", + ["选择脚本类型"], + [["MAA"]], ) - if choice.exec() and choice.input.currentIndex() != -1: + if choice.exec() and choice.input[0].currentIndex() != -1: - if choice.input.currentText() == "MAA": + if choice.input[0].currentText() == "MAA": index = len(self.member_manager.search_member()) + 1 @@ -295,7 +294,7 @@ class MemberManager(QWidget): def show_password(self): if Config.PASSWORD == "": - choice = InputMessageBox( + choice = LineEditMessageBox( self.window(), "请输入管理密钥", "管理密钥", @@ -694,7 +693,7 @@ class MaaSettingBox(QWidget): user_list = [_[0] for _ in data if _[15] == "simple"] set_list = ["自定义基建"] - choice = SetMessageBox( + choice = ComboBoxMessageBox( self.window(), "用户选项配置", ["选择要配置的用户", "选择要配置的选项"], @@ -734,7 +733,7 @@ class MaaSettingBox(QWidget): user_list = [_[0] for _ in data if _[15] == "beta"] set_list = ["MAA日常配置", "MAA剿灭配置"] - choice = SetMessageBox( + choice = ComboBoxMessageBox( self.window(), "用户选项配置", ["选择要配置的用户", "选择要配置的选项"], @@ -989,7 +988,7 @@ class MaaSettingBox(QWidget): item = QTableWidgetItem("******") item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) else: - result = Crypto.decryptx(value, Config.PASSWORD) + result = Crypto.AUTO_decryptor(value, Config.PASSWORD) item = QTableWidgetItem(result) if result == "管理密钥错误": item.setFlags( @@ -1056,7 +1055,7 @@ class MaaSettingBox(QWidget): item = QTableWidgetItem("******") item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) else: - result = Crypto.decryptx(value, Config.PASSWORD) + result = Crypto.AUTO_decryptor(value, Config.PASSWORD) item = QTableWidgetItem(result) if result == "管理密钥错误": item.setFlags( @@ -1127,7 +1126,7 @@ class MaaSettingBox(QWidget): games[game_in.strip()] = game_out.strip() text = games.get(text, text) if item.column() == 11: # 密码 - text = Crypto.encryptx(text) + text = Crypto.AUTO_encryptor(text) # 保存至本地数据库 if text != "": @@ -1145,7 +1144,7 @@ class MaaSettingBox(QWidget): self.update_user_info("normal") return None if item.column() == 6: # 密码 - text = Crypto.encryptx(text) + text = Crypto.AUTO_encryptor(text) # 保存至本地数据库 if text != "": @@ -1227,7 +1226,7 @@ class MaaSettingBox(QWidget): Config.cur.execute( "INSERT INTO adminx VALUES('新用户','手机号码(官服)/B站ID(B服)','Official',-1,'y','2000-01-01','1-7','-','-','n','n','n',?,'无',0,?,?)", ( - Crypto.encryptx("未设置"), + Crypto.AUTO_encryptor("未设置"), set_book[0], set_book[1], ), diff --git a/app/ui/setting.py b/app/ui/setting.py index e78b9e1..3c4c91f 100644 --- a/app/ui/setting.py +++ b/app/ui/setting.py @@ -53,7 +53,7 @@ import requests from app.core import Config, MainInfoBar from app.services import Crypto, System from app.utils import Updater -from .Widget import InputMessageBox, LineEditSettingCard +from .Widget import LineEditMessageBox, LineEditSettingCard, PasswordLineEditSettingCard class Setting(QWidget): @@ -136,7 +136,7 @@ class Setting(QWidget): while True: - choice = InputMessageBox( + choice = LineEditMessageBox( self.window(), "未检测到管理密钥,请设置您的管理密钥", "管理密钥", @@ -162,7 +162,7 @@ class Setting(QWidget): while if_change: - choice = InputMessageBox( + choice = LineEditMessageBox( self.window(), "请输入旧的管理密钥", "旧管理密钥", @@ -177,7 +177,7 @@ class Setting(QWidget): # 获取新的管理密钥 while True: - choice = InputMessageBox( + choice = LineEditMessageBox( self.window(), "请输入新的管理密钥", "新管理密钥", @@ -557,7 +557,7 @@ class NotifySettingCard(HeaderCardWidget): super().__init__( FluentIcon.SETTING, "推送邮件通知", - "通过AUTO_MAA官方通知服务邮箱推送任务结果", + "通过电子邮箱推送任务结果", parent, ) @@ -567,18 +567,42 @@ class NotifySettingCard(HeaderCardWidget): content="是否启用邮件通知功能", configItem=Config.global_config.notify_IfSendMail, ) - self.card_MailAddress = LineEditSettingCard( - text="请输入邮箱地址", + self.card_SMTPServerAddress = LineEditSettingCard( + text="请输入SMTP服务器地址", icon=FluentIcon.PAGE_RIGHT, - title="邮箱地址", + title="SMTP服务器地址", + content="发信邮箱的SMTP服务器地址", + configItem=Config.global_config.notify_SMTPServerAddress, + ) + self.card_FromAddress = LineEditSettingCard( + text="请输入发信邮箱地址", + icon=FluentIcon.PAGE_RIGHT, + title="发信邮箱地址", + content="发送通知的邮箱地址", + configItem=Config.global_config.notify_FromAddress, + ) + self.card_AuthorizationCode = PasswordLineEditSettingCard( + text="请输入发信邮箱授权码", + icon=FluentIcon.PAGE_RIGHT, + title="发信邮箱授权码", + content="发送通知的邮箱授权码", + configItem=Config.global_config.notify_AuthorizationCode, + ) + self.card_ToAddress = LineEditSettingCard( + text="请输入收信邮箱地址", + icon=FluentIcon.PAGE_RIGHT, + title="收信邮箱地址", content="接收通知的邮箱地址", - configItem=Config.global_config.notify_MailAddress, + configItem=Config.global_config.notify_ToAddress, ) widget = QWidget() Layout = QVBoxLayout(widget) Layout.addWidget(self.card_IfSendMail) - Layout.addWidget(self.card_MailAddress) + Layout.addWidget(self.card_SMTPServerAddress) + Layout.addWidget(self.card_FromAddress) + Layout.addWidget(self.card_AuthorizationCode) + Layout.addWidget(self.card_ToAddress) self.viewLayout.setContentsMargins(0, 0, 0, 0) self.viewLayout.setSpacing(0) self.addGroupWidget(widget) diff --git a/resources/version.json b/resources/version.json index 91658ff..9603433 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,7 +1,7 @@ { - "main_version": "4.2.2.5", + "main_version": "4.2.3.0", "updater_version": "1.1.1.3", - "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n- 初步完成`托管bilibili游戏隐私政策`功能\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n- 修复窗口记忆功能失效问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置", + "announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n- 初步完成`托管bilibili游戏隐私政策`功能\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n- 修复窗口记忆功能失效问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置\n- 邮箱推送功能调整,改由用户提供发信邮箱", "proxy_list": [ "", "https://gitproxy.click/", From 90d3dad8c8de45351e3d4ec24f35fe546db928fd Mon Sep 17 00:00:00 2001 From: DLmaster Date: Mon, 10 Feb 2025 11:29:27 +0800 Subject: [PATCH 13/13] =?UTF-8?q?fix(services):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=82=AE=E7=AE=B1=E5=8F=91=E4=BF=A1=E4=BA=BA=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/notification.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/notification.py b/app/services/notification.py index 7f373bf..4f21411 100644 --- a/app/services/notification.py +++ b/app/services/notification.py @@ -68,7 +68,9 @@ class Notification: message["From"] = formataddr( ( Header("AUTO_MAA通知服务", "utf-8").encode(), - "AUTO_MAA_server@163.com", + Config.global_config.get( + Config.global_config.notify_FromAddress + ), ) ) # 发件人显示的名字 message["To"] = formataddr(