feat(core):初步完成定时执行功能开发
This commit is contained in:
@@ -29,7 +29,7 @@ __version__ = "4.2.0"
|
||||
__author__ = "DLmaster361 <DLmaster_361@163.com>"
|
||||
__license__ = "GPL-3.0 license"
|
||||
|
||||
from .config import AppConfig, QueueConfig, MaaConfig
|
||||
from .core import AppConfig, QueueConfig, MaaConfig, Task, TaskManager, MainTimer
|
||||
from .models import MaaManager
|
||||
from .services import Notification, CryptoHandler, SystemHandler
|
||||
from .ui import AUTO_MAA
|
||||
@@ -39,6 +39,9 @@ __all__ = [
|
||||
"AppConfig",
|
||||
"QueueConfig",
|
||||
"MaaConfig",
|
||||
"Task",
|
||||
"TaskManager",
|
||||
"MainTimer",
|
||||
"MaaManager",
|
||||
"Notification",
|
||||
"CryptoHandler",
|
||||
|
||||
BIN
app/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
app/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/config.cpython-312.pyc
Normal file
BIN
app/__pycache__/config.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/task_manager.cpython-312.pyc
Normal file
BIN
app/__pycache__/task_manager.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/__pycache__/timer.cpython-312.pyc
Normal file
BIN
app/__pycache__/timer.cpython-312.pyc
Normal file
Binary file not shown.
45
app/core/__init__.py
Normal file
45
app/core/__init__.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# <AUTO_MAA:A MAA Multi Account Management and Automation Tool>
|
||||
# Copyright © <2024> <DLmaster361>
|
||||
|
||||
# This file is part of AUTO_MAA.
|
||||
|
||||
# AUTO_MAA is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
# AUTO_MAA is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
# the GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# DLmaster_361@163.com
|
||||
|
||||
"""
|
||||
AUTO_MAA
|
||||
AUTO_MAA核心组件包
|
||||
v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
__version__ = "4.2.0"
|
||||
__author__ = "DLmaster361 <DLmaster_361@163.com>"
|
||||
__license__ = "GPL-3.0 license"
|
||||
|
||||
from .config import AppConfig, QueueConfig, MaaConfig
|
||||
from .main_info_bar import MainInfoBar
|
||||
from .task_manager import Task, TaskManager
|
||||
from .timer import MainTimer
|
||||
|
||||
__all__ = [
|
||||
"AppConfig",
|
||||
"QueueConfig",
|
||||
"MaaConfig",
|
||||
"MainInfoBar",
|
||||
"Task",
|
||||
"TaskManager",
|
||||
"MainTimer",
|
||||
]
|
||||
BIN
app/core/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
app/core/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/core/__pycache__/config.cpython-312.pyc
Normal file
BIN
app/core/__pycache__/config.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/core/__pycache__/main_info_bar.cpython-312.pyc
Normal file
BIN
app/core/__pycache__/main_info_bar.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/core/__pycache__/task_manager.cpython-312.pyc
Normal file
BIN
app/core/__pycache__/task_manager.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/core/__pycache__/timer.cpython-312.pyc
Normal file
BIN
app/core/__pycache__/timer.cpython-312.pyc
Normal file
Binary file not shown.
@@ -25,9 +25,9 @@ v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
import sqlite3
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, Union
|
||||
@@ -37,11 +37,9 @@ from qfluentwidgets import (
|
||||
qconfig,
|
||||
OptionsConfigItem,
|
||||
RangeConfigItem,
|
||||
OptionsValidator,
|
||||
FolderValidator,
|
||||
BoolValidator,
|
||||
RangeValidator,
|
||||
EnumSerializer,
|
||||
)
|
||||
|
||||
|
||||
@@ -52,13 +50,17 @@ class AppConfig:
|
||||
self.app_path = Path(sys.argv[0]).resolve().parent # 获取软件根目录
|
||||
self.app_path_sys = str(Path(sys.argv[0]).resolve()) # 获取软件自身的路径
|
||||
|
||||
self.log_path = self.app_path / "debug/AUTO_MAA.log"
|
||||
self.database_path = self.app_path / "data/data.db"
|
||||
self.config_path = self.app_path / "config/config.json"
|
||||
self.history_path = self.app_path / "config/history.json"
|
||||
self.key_path = self.app_path / "data/key"
|
||||
self.gameid_path = self.app_path / "data/gameid.txt"
|
||||
self.version_path = self.app_path / "resources/version.json"
|
||||
|
||||
self.PASSWORD = ""
|
||||
self.running_list = []
|
||||
self.if_silence_needed = 0
|
||||
self.if_database_opened = False
|
||||
|
||||
# 检查文件完整性
|
||||
@@ -70,6 +72,7 @@ class AppConfig:
|
||||
# 检查目录
|
||||
(self.app_path / "config").mkdir(parents=True, exist_ok=True)
|
||||
(self.app_path / "data").mkdir(parents=True, exist_ok=True)
|
||||
(self.app_path / "debug").mkdir(parents=True, exist_ok=True)
|
||||
# (self.app_path / "data/MAAconfig/simple").mkdir(parents=True, exist_ok=True)
|
||||
# (self.app_path / "data/MAAconfig/beta").mkdir(parents=True, exist_ok=True)
|
||||
# (self.app_path / "data/MAAconfig/Default").mkdir(parents=True, exist_ok=True)
|
||||
@@ -90,18 +93,47 @@ class AppConfig:
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
self.init_logger()
|
||||
self.init_config()
|
||||
# self.check_database()
|
||||
logger.info("程序配置管理模块初始化完成")
|
||||
|
||||
def init_logger(self) -> None:
|
||||
"""初始化日志记录器"""
|
||||
|
||||
# logger.remove(0)
|
||||
|
||||
# logger.add(
|
||||
# sink=sys.stdout,
|
||||
# level="DEBUG",
|
||||
# format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <level>{message}</level>",
|
||||
# enqueue=True,
|
||||
# backtrace=True,
|
||||
# diagnose=True,
|
||||
# )
|
||||
logger.add(
|
||||
sink=self.log_path,
|
||||
level="DEBUG",
|
||||
format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <level>{message}</level>",
|
||||
enqueue=True,
|
||||
backtrace=True,
|
||||
diagnose=True,
|
||||
rotation="1 week",
|
||||
retention="1 month",
|
||||
compression="zip",
|
||||
)
|
||||
|
||||
logger.info("日志记录器初始化完成")
|
||||
|
||||
def init_config(self) -> None:
|
||||
"""初始化配置类"""
|
||||
|
||||
self.global_config = GlobalConfig()
|
||||
qconfig.load(self.config_path, self.global_config)
|
||||
|
||||
self.queue_config = QueueConfig()
|
||||
self.maa_config = MaaConfig()
|
||||
|
||||
logger.info("配置类初始化完成")
|
||||
|
||||
def init_database(self, mode: str) -> None:
|
||||
"""初始化用户数据库"""
|
||||
|
||||
@@ -113,6 +145,8 @@ class AppConfig:
|
||||
self.cur.execute("INSERT INTO version VALUES(?)", ("v1.3",))
|
||||
self.db.commit()
|
||||
|
||||
logger.info("用户数据库初始化完成")
|
||||
|
||||
def check_database(self) -> None:
|
||||
"""检查用户数据库文件并处理数据库版本更新"""
|
||||
|
||||
@@ -196,10 +230,9 @@ class AppConfig:
|
||||
"""打开数据库"""
|
||||
|
||||
self.close_database()
|
||||
if mode == "Maa":
|
||||
self.db = sqlite3.connect(
|
||||
self.app_path / f"config/{mode}Config/{index}/user_date.db"
|
||||
)
|
||||
self.db = sqlite3.connect(
|
||||
self.app_path / f"config/{mode}Config/{index}/user_data.db"
|
||||
)
|
||||
self.cur = self.db.cursor()
|
||||
self.if_database_opened = True
|
||||
|
||||
@@ -211,6 +244,28 @@ class AppConfig:
|
||||
self.db.close()
|
||||
self.if_database_opened = False
|
||||
|
||||
def save_history(self, key: str, content: dict) -> None:
|
||||
"""保存历史记录"""
|
||||
|
||||
history = {}
|
||||
if self.history_path.exists():
|
||||
with self.history_path.open(mode="r", encoding="utf-8") as f:
|
||||
history = json.load(f)
|
||||
history[key] = content
|
||||
with self.history_path.open(mode="w", encoding="utf-8") as f:
|
||||
json.dump(history, f, indent=4)
|
||||
|
||||
def get_history(self, key: str) -> dict:
|
||||
"""获取历史记录"""
|
||||
|
||||
history = {}
|
||||
if self.history_path.exists():
|
||||
with self.history_path.open(mode="r", encoding="utf-8") as f:
|
||||
history = json.load(f)
|
||||
return history.get(
|
||||
key, {"Time": "0000-00-00 00:00", "History": "暂无历史运行记录"}
|
||||
)
|
||||
|
||||
def clear_maa_config(self) -> None:
|
||||
"""清空MAA配置"""
|
||||
|
||||
92
app/core/main_info_bar.py
Normal file
92
app/core/main_info_bar.py
Normal file
@@ -0,0 +1,92 @@
|
||||
# <AUTO_MAA:A MAA Multi Account Management and Automation Tool>
|
||||
# Copyright © <2024> <DLmaster361>
|
||||
|
||||
# This file is part of AUTO_MAA.
|
||||
|
||||
# AUTO_MAA is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
# AUTO_MAA is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
# the GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# DLmaster_361@163.com
|
||||
|
||||
"""
|
||||
AUTO_MAA
|
||||
AUTO_MAA信息通知栏
|
||||
v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtCore import Qt
|
||||
from qfluentwidgets import (
|
||||
InfoBar,
|
||||
InfoBarPosition,
|
||||
)
|
||||
|
||||
|
||||
class _MainInfoBar:
|
||||
"""信息通知栏"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
|
||||
self.parent = parent
|
||||
|
||||
def push_info_bar(self, mode: str, title: str, content: str, time: int):
|
||||
"""推送到信息通知栏"""
|
||||
|
||||
if self.parent is None:
|
||||
logger.error("信息通知栏未设置父窗口")
|
||||
return None
|
||||
|
||||
if mode == "success":
|
||||
InfoBar.success(
|
||||
title=title,
|
||||
content=content,
|
||||
orient=Qt.Horizontal,
|
||||
isClosable=True,
|
||||
position=InfoBarPosition.TOP_RIGHT,
|
||||
duration=time,
|
||||
parent=self.parent,
|
||||
)
|
||||
elif mode == "warning":
|
||||
InfoBar.warning(
|
||||
title=title,
|
||||
content=content,
|
||||
orient=Qt.Horizontal,
|
||||
isClosable=True,
|
||||
position=InfoBarPosition.TOP_RIGHT,
|
||||
duration=time,
|
||||
parent=self.parent,
|
||||
)
|
||||
elif mode == "error":
|
||||
InfoBar.error(
|
||||
title=title,
|
||||
content=content,
|
||||
orient=Qt.Horizontal,
|
||||
isClosable=True,
|
||||
position=InfoBarPosition.TOP_RIGHT,
|
||||
duration=time,
|
||||
parent=self.parent,
|
||||
)
|
||||
elif mode == "info":
|
||||
InfoBar.info(
|
||||
title=title,
|
||||
content=content,
|
||||
orient=Qt.Horizontal,
|
||||
isClosable=True,
|
||||
position=InfoBarPosition.TOP_RIGHT,
|
||||
duration=time,
|
||||
parent=self.parent,
|
||||
)
|
||||
|
||||
|
||||
MainInfoBar = _MainInfoBar()
|
||||
222
app/core/task_manager.py
Normal file
222
app/core/task_manager.py
Normal file
@@ -0,0 +1,222 @@
|
||||
# <AUTO_MAA:A MAA Multi Account Management and Automation Tool>
|
||||
# Copyright © <2024> <DLmaster361>
|
||||
|
||||
# This file is part of AUTO_MAA.
|
||||
|
||||
# AUTO_MAA is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
# AUTO_MAA is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
# the GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# DLmaster_361@163.com
|
||||
|
||||
"""
|
||||
AUTO_MAA
|
||||
AUTO_MAA业务调度器
|
||||
v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import QApplication
|
||||
from PySide6 import QtCore
|
||||
import json
|
||||
from typing import Dict, Union, List
|
||||
|
||||
from .config import AppConfig
|
||||
from .main_info_bar import MainInfoBar
|
||||
from app.models import MaaManager
|
||||
from app.services import Notification
|
||||
|
||||
|
||||
class Task(QtCore.QThread):
|
||||
"""业务线程"""
|
||||
|
||||
push_info_bar = QtCore.Signal(str, str, str, int)
|
||||
update_user_info = QtCore.Signal(list, list, list, list, list, list)
|
||||
create_task_list = QtCore.Signal(list)
|
||||
create_user_list = QtCore.Signal(list)
|
||||
update_task_list = QtCore.Signal(list)
|
||||
update_user_list = QtCore.Signal(list)
|
||||
update_log_text = QtCore.Signal(str)
|
||||
accomplish = QtCore.Signal(list)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
notify: Notification,
|
||||
name: str,
|
||||
info: Dict[str, Dict[str, Union[str, int, bool]]],
|
||||
):
|
||||
super(Task, self).__init__()
|
||||
|
||||
self.config = config
|
||||
self.notify = notify
|
||||
self.name = name
|
||||
self.info = info
|
||||
|
||||
self.logs = []
|
||||
|
||||
def run(self):
|
||||
|
||||
self.member_dict = self.search_member()
|
||||
self.task_list = [
|
||||
[value, "等待"]
|
||||
for _, value in self.info["Queue"].items()
|
||||
if value != "禁用"
|
||||
]
|
||||
|
||||
self.create_task_list.emit(self.task_list)
|
||||
|
||||
for i in range(len(self.task_list)):
|
||||
|
||||
if self.isInterruptionRequested():
|
||||
break
|
||||
|
||||
self.task_list[i][1] = "运行"
|
||||
self.update_task_list.emit(self.task_list)
|
||||
|
||||
if self.task_list[i][0] not in self.config.running_list:
|
||||
|
||||
self.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], 5000)
|
||||
|
||||
if self.member_dict[self.task_list[i][0]][0] == "Maa":
|
||||
|
||||
self.task = MaaManager(
|
||||
self.config,
|
||||
self.notify,
|
||||
"自动代理",
|
||||
self.member_dict[self.task_list[i][0]][1],
|
||||
)
|
||||
|
||||
self.task.push_info_bar.connect(self.push_info_bar.emit)
|
||||
self.task.create_user_list.connect(self.create_user_list.emit)
|
||||
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(self.update_user_info.emit)
|
||||
self.task.accomplish.connect(
|
||||
lambda log: self.save_log(self.task_list[i][0], log)
|
||||
)
|
||||
|
||||
self.task.run()
|
||||
|
||||
self.config.running_list.remove(self.task_list[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], 5000)
|
||||
|
||||
else:
|
||||
|
||||
self.task_list[i][1] = "跳过"
|
||||
logger.info(f"跳过任务:{self.task_list[i][0]}")
|
||||
self.push_info_bar.emit("info", "跳过任务", self.task_list[i][0], 5000)
|
||||
|
||||
self.accomplish.emit(self.logs)
|
||||
|
||||
def search_member(self) -> dict:
|
||||
"""搜索所有脚本实例并固定相关配置信息"""
|
||||
|
||||
member_dict = {}
|
||||
|
||||
if (self.config.app_path / "config/MaaConfig").exists():
|
||||
for subdir in (self.config.app_path / "config/MaaConfig").iterdir():
|
||||
if subdir.is_dir():
|
||||
|
||||
member_dict[subdir.name] = ["Maa", subdir]
|
||||
|
||||
return member_dict
|
||||
|
||||
def save_log(self, name: str, log: dict):
|
||||
"""保存保存任务结果"""
|
||||
|
||||
self.logs.append([name, log])
|
||||
|
||||
|
||||
class TaskManager(QtCore.QObject):
|
||||
"""业务调度器"""
|
||||
|
||||
create_gui = QtCore.Signal(Task)
|
||||
push_info_bar = QtCore.Signal(str, str, str, int)
|
||||
|
||||
def __init__(self, config: AppConfig, notify: Notification):
|
||||
super(TaskManager, self).__init__()
|
||||
|
||||
self.config = config
|
||||
self.notify = notify
|
||||
|
||||
self.task_list: Dict[str, Task] = {}
|
||||
|
||||
def add_task(
|
||||
self, mode: str, name: str, info: Dict[str, Dict[str, Union[str, int, bool]]]
|
||||
):
|
||||
"""添加任务"""
|
||||
|
||||
if (
|
||||
mode == "运行队列"
|
||||
and name not in self.config.running_list
|
||||
and name not in self.task_list
|
||||
):
|
||||
|
||||
logger.info(f"任务开始:{name}")
|
||||
MainInfoBar.push_info_bar("info", "任务开始", name, 5000)
|
||||
|
||||
self.config.running_list.append(name)
|
||||
self.task_list[name] = Task(self.config, self.notify, name, info)
|
||||
self.task_list[name].push_info_bar.connect(MainInfoBar.push_info_bar)
|
||||
self.task_list[name].accomplish.connect(
|
||||
lambda logs: self.remove_task(name, logs)
|
||||
)
|
||||
self.create_gui.emit(self.task_list[name])
|
||||
self.task_list[name].start()
|
||||
|
||||
def stop_task(self, name: str):
|
||||
"""中止任务"""
|
||||
|
||||
logger.info(f"中止任务:{name}")
|
||||
MainInfoBar.push_info_bar("info", "中止任务", name, 5000)
|
||||
|
||||
if name == "ALL":
|
||||
|
||||
for name in self.task_list:
|
||||
|
||||
self.task_list[name].task.requestInterruption()
|
||||
self.task_list[name].requestInterruption()
|
||||
self.task_list[name].quit()
|
||||
self.task_list[name].wait()
|
||||
|
||||
elif name in self.task_list:
|
||||
|
||||
self.task_list[name].task.requestInterruption()
|
||||
self.task_list[name].requestInterruption()
|
||||
self.task_list[name].quit()
|
||||
self.task_list[name].wait()
|
||||
|
||||
def remove_task(self, name: str, logs: str):
|
||||
"""移除任务标记"""
|
||||
|
||||
logger.info(f"任务结束:{name}")
|
||||
MainInfoBar.push_info_bar("info", "任务结束", name, 5000)
|
||||
|
||||
if len(logs) > 0:
|
||||
time = logs[0][1]["Time"]
|
||||
history = ""
|
||||
for log in logs:
|
||||
self.config.save_history(log[0], log[1])
|
||||
history += (
|
||||
f"任务名称:{log[0]},{log[1]["History"].replace("\n","\n ")}\n"
|
||||
)
|
||||
self.config.save_history(name, {"Time": time, "History": history})
|
||||
|
||||
self.task_list.pop(name)
|
||||
self.config.running_list.remove(name)
|
||||
119
app/core/timer.py
Normal file
119
app/core/timer.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# <AUTO_MAA:A MAA Multi Account Management and Automation Tool>
|
||||
# Copyright © <2024> <DLmaster361>
|
||||
|
||||
# This file is part of AUTO_MAA.
|
||||
|
||||
# AUTO_MAA is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
# AUTO_MAA is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
# the GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# DLmaster_361@163.com
|
||||
|
||||
"""
|
||||
AUTO_MAA
|
||||
AUTO_MAA主业务定时器
|
||||
v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import QWidget
|
||||
from PySide6 import QtCore
|
||||
import json
|
||||
import datetime
|
||||
|
||||
from .config import AppConfig
|
||||
from .task_manager import TaskManager
|
||||
from app.services import SystemHandler
|
||||
|
||||
|
||||
class MainTimer(QWidget):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
system: SystemHandler,
|
||||
task_manager: TaskManager,
|
||||
parent=None,
|
||||
):
|
||||
super().__init__(parent)
|
||||
|
||||
self.config = config
|
||||
self.system = system
|
||||
self.task_manager = task_manager
|
||||
|
||||
self.Timer = QtCore.QTimer()
|
||||
self.Timer.timeout.connect(self.timed_start)
|
||||
self.Timer.timeout.connect(self.set_silence)
|
||||
self.Timer.start(1000)
|
||||
|
||||
def timed_start(self):
|
||||
"""定时启动代理任务"""
|
||||
|
||||
# 获取定时列表
|
||||
queue_list = self.search_queue()
|
||||
|
||||
for i in queue_list:
|
||||
|
||||
name, info = i
|
||||
|
||||
if not info["QueueSet"]["Enabled"]:
|
||||
continue
|
||||
|
||||
history = self.config.get_history(name)
|
||||
|
||||
time_set = [
|
||||
info["Time"][f"TimeSet_{_}"]
|
||||
for _ in range(10)
|
||||
if info["Time"][f"TimeEnabled_{_}"]
|
||||
]
|
||||
# 按时间调起代理任务
|
||||
curtime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
if (
|
||||
curtime[11:16] in time_set
|
||||
and curtime != history["Time"][:16]
|
||||
and name not in self.config.running_list
|
||||
):
|
||||
|
||||
logger.info(f"按时间调起任务:{name}")
|
||||
self.task_manager.add_task("运行队列", name, info)
|
||||
|
||||
def set_silence(self):
|
||||
"""设置静默模式"""
|
||||
# # 临时
|
||||
# windows = self.system.get_window_info()
|
||||
# if any(emulator_path in _ for _ in windows):
|
||||
# try:
|
||||
# pyautogui.hotkey(*boss_key)
|
||||
# except pyautogui.FailSafeException as e:
|
||||
# 执行日志记录,暂时缺省
|
||||
logger.debug(self.config.running_list)
|
||||
|
||||
def set_last_time(self):
|
||||
"""设置上次运行时间"""
|
||||
|
||||
pass
|
||||
|
||||
def search_queue(self) -> list:
|
||||
"""搜索所有调度队列实例"""
|
||||
|
||||
queue_list = []
|
||||
|
||||
if (self.config.app_path / "config/QueueConfig").exists():
|
||||
for json_file in (self.config.app_path / "config/QueueConfig").glob(
|
||||
"*.json"
|
||||
):
|
||||
with json_file.open("r", encoding="utf-8") as f:
|
||||
info = json.load(f)
|
||||
queue_list.append([json_file.stem, info])
|
||||
|
||||
return queue_list
|
||||
@@ -24,75 +24,76 @@ MAA功能组件
|
||||
v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6 import QtCore
|
||||
import json
|
||||
import sqlite3
|
||||
import datetime
|
||||
import os
|
||||
import subprocess
|
||||
import shutil
|
||||
import time
|
||||
from pathlib import Path
|
||||
from qfluentwidgets import (
|
||||
QConfig,
|
||||
ConfigItem,
|
||||
qconfig,
|
||||
OptionsConfigItem,
|
||||
RangeConfigItem,
|
||||
OptionsValidator,
|
||||
BoolValidator,
|
||||
RangeValidator,
|
||||
EnumSerializer,
|
||||
FolderValidator,
|
||||
)
|
||||
from typing import List, Dict, Union
|
||||
|
||||
from app import AppConfig
|
||||
from app.core import AppConfig
|
||||
from app.services import Notification
|
||||
|
||||
|
||||
class MaaManager(QtCore.QThread):
|
||||
class MaaManager(QtCore.QObject):
|
||||
"""MAA控制器"""
|
||||
|
||||
question = QtCore.Signal()
|
||||
push_notification = QtCore.Signal(str, str, str, int)
|
||||
send_mail = QtCore.Signal(str, str)
|
||||
update_gui = QtCore.Signal(str, str, str, str, str)
|
||||
question = QtCore.Signal(str, str)
|
||||
question_response = QtCore.Signal(int)
|
||||
update_user_info = QtCore.Signal(list, list, list, list, list, list)
|
||||
set_silence = QtCore.Signal(str, str, list)
|
||||
accomplish = QtCore.Signal()
|
||||
push_info_bar = QtCore.Signal(str, str, str, int)
|
||||
create_user_list = QtCore.Signal(list)
|
||||
update_user_list = QtCore.Signal(list)
|
||||
update_log_text = QtCore.Signal(str)
|
||||
accomplish = QtCore.Signal(dict)
|
||||
get_json = QtCore.Signal(list)
|
||||
|
||||
def __init__(self, config: AppConfig):
|
||||
isInterruptionRequested = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: AppConfig,
|
||||
notify: Notification,
|
||||
mode: str,
|
||||
config_path: Path,
|
||||
):
|
||||
super(MaaManager, self).__init__()
|
||||
|
||||
self.config = config
|
||||
self.mode = None
|
||||
self.data = None
|
||||
self.notify = notify
|
||||
self.mode = mode
|
||||
self.config_path = config_path
|
||||
|
||||
with (self.config_path / "config.json").open("r", encoding="utf-8") as f:
|
||||
self.set = json.load(f)
|
||||
|
||||
db = sqlite3.connect(self.config_path / "user_data.db")
|
||||
cur = db.cursor()
|
||||
cur.execute("SELECT * FROM adminx WHERE True")
|
||||
self.data = cur.fetchall()
|
||||
self.data = [list(row) for row in self.data]
|
||||
cur.close()
|
||||
db.close()
|
||||
|
||||
self.get_json_path = [0, 0, 0]
|
||||
|
||||
def configure(self):
|
||||
"""提取配置信息"""
|
||||
|
||||
self.maa_root_path = Path(self.config.content["Default"]["MaaSet.path"])
|
||||
self.set_path = self.maa_root_path / "config/gui.json"
|
||||
self.log_path = self.maa_root_path / "debug/gui.log"
|
||||
self.maa_path = self.maa_root_path / "MAA.exe"
|
||||
self.json_path = self.config.app_path / "data/MAAconfig"
|
||||
self.routine = self.config.content["Default"]["TimeLimit.routine"]
|
||||
self.annihilation = self.config.content["Default"]["TimeLimit.annihilation"]
|
||||
self.num = self.config.content["Default"]["TimesLimit.run"]
|
||||
self.maa_root_path = Path(self.set["MaaSet"]["Path"])
|
||||
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.boss_key = [
|
||||
_.strip().lower()
|
||||
for _ in self.config.content["Default"]["SelfSet.BossKey"].split("+")
|
||||
for _ in self.config.global_config.get(
|
||||
self.config.global_config.function_BossKey
|
||||
).split("+")
|
||||
]
|
||||
self.if_send_mail = bool(
|
||||
self.config.content["Default"]["SelfSet.IfSendMail"] == "True"
|
||||
)
|
||||
self.if_send_error_only = bool(
|
||||
self.config.content["Default"]["SelfSet.IfSendMail.OnlyError"] == "True"
|
||||
)
|
||||
self.if_silence = bool(
|
||||
self.config.content["Default"]["SelfSet.IfSilence"] == "True"
|
||||
)
|
||||
|
||||
def run(self):
|
||||
"""主进程,运行MAA代理进程"""
|
||||
@@ -101,86 +102,86 @@ class MaaManager(QtCore.QThread):
|
||||
begin_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
self.configure()
|
||||
# 检查MAA路径是否可用
|
||||
if not self.maa_exe_path.exists() or not self.maa_set_path.exists():
|
||||
|
||||
logger.error("未正确配置MAA路径,MAA代理进程中止")
|
||||
self.push_info_bar.emit(
|
||||
"error", "启动MAA代理进程失败", "您还未正确配置MAA路径!", -1
|
||||
)
|
||||
return None
|
||||
|
||||
# 整理用户数据,筛选需代理的用户
|
||||
self.data = sorted(self.data, key=lambda x: (-len(x[15]), x[16]))
|
||||
wait_index = []
|
||||
over_index = []
|
||||
error_index = []
|
||||
all_index = [
|
||||
_
|
||||
for _ in range(len(self.data))
|
||||
if (self.data[_][3] != 0 and self.data[_][4] == "y")
|
||||
user_list: List[List[str, str, int]] = [
|
||||
[_[0], "等待", index]
|
||||
for index, _ in enumerate(self.data)
|
||||
if (_[3] != 0 and _[4] == "y")
|
||||
]
|
||||
self.create_user_list.emit(user_list)
|
||||
|
||||
# 日常代理模式
|
||||
if self.mode == "日常代理":
|
||||
# 自动代理模式
|
||||
if self.mode == "自动代理":
|
||||
|
||||
# 执行情况预处理
|
||||
for _ in all_index:
|
||||
if self.data[_][5] != curdate:
|
||||
self.data[_][5] = curdate
|
||||
self.data[_][14] = 0
|
||||
self.data[_][0] += f"_第{str(self.data[_][14] + 1)}次代理"
|
||||
for _ in user_list:
|
||||
if self.data[_[2]][5] != curdate:
|
||||
self.data[_[2]][5] = curdate
|
||||
self.data[_[2]][14] = 0
|
||||
_[0] += f" - 第{self.data[_[2]][14] + 1}次代理"
|
||||
|
||||
# 开始代理
|
||||
for index in all_index:
|
||||
for user in user_list:
|
||||
|
||||
if self.isInterruptionRequested():
|
||||
if self.isInterruptionRequested:
|
||||
break
|
||||
|
||||
user[1] = "运行"
|
||||
self.update_user_list.emit(user_list)
|
||||
|
||||
# 初始化代理情况记录和模式替换记录
|
||||
run_book = [False for _ in range(2)]
|
||||
mode_book = ["日常代理_剿灭", "日常代理_日常"]
|
||||
mode_book = ["自动代理_剿灭", "自动代理_日常"]
|
||||
|
||||
# 简洁模式用户默认开启日常代理
|
||||
if self.data[index][15] == "simple":
|
||||
self.data[index][9] = "y"
|
||||
# 简洁模式用户默认开启日常选项
|
||||
if self.data[user[2]][15] == "simple":
|
||||
self.data[user[2]][9] = "y"
|
||||
|
||||
# 尝试次数循环
|
||||
for i in range(self.num):
|
||||
for i in range(self.set["RunSet"]["RunTimesLimit"]):
|
||||
|
||||
if self.isInterruptionRequested():
|
||||
if self.isInterruptionRequested:
|
||||
break
|
||||
|
||||
# 剿灭-日常模式循环
|
||||
for j in range(2):
|
||||
|
||||
if self.isInterruptionRequested():
|
||||
if self.isInterruptionRequested:
|
||||
break
|
||||
|
||||
if self.data[index][10 - j] == "n":
|
||||
if self.data[user[2]][10 - j] == "n":
|
||||
run_book[j] = True
|
||||
continue
|
||||
if run_book[j]:
|
||||
continue
|
||||
|
||||
# 配置MAA
|
||||
self.set_maa(mode_book[j], index)
|
||||
self.set_maa(mode_book[j], user[2])
|
||||
# 记录当前时间
|
||||
start_time = datetime.datetime.now()
|
||||
# 创建MAA任务
|
||||
maa = subprocess.Popen(
|
||||
[self.maa_path],
|
||||
[self.maa_exe_path],
|
||||
shell=True,
|
||||
creationflags=subprocess.CREATE_NO_WINDOW,
|
||||
)
|
||||
# 启动静默进程
|
||||
if self.if_silence:
|
||||
self.set_silence.emit(
|
||||
"启用", self.get_emulator_path(), self.boss_key
|
||||
)
|
||||
# 添加静默进程数量标记
|
||||
self.config.if_silence_needed += 1
|
||||
# 记录是否超时的标记
|
||||
self.if_time_out = False
|
||||
# 更新运行信息
|
||||
wait_index = [
|
||||
_
|
||||
for _ in all_index
|
||||
if (not _ in over_index + error_index + [index])
|
||||
]
|
||||
|
||||
# 监测MAA运行状态
|
||||
while not self.isInterruptionRequested():
|
||||
while not self.isInterruptionRequested:
|
||||
|
||||
# 获取MAA日志
|
||||
logs = self.get_maa_log(start_time)
|
||||
@@ -200,11 +201,17 @@ class MaaManager(QtCore.QThread):
|
||||
if (
|
||||
j == 0
|
||||
and now_time - latest_time
|
||||
> datetime.timedelta(minutes=self.annihilation)
|
||||
> datetime.timedelta(
|
||||
minutes=self.set["RunSet"][
|
||||
"AnnihilationTimeLimit"
|
||||
]
|
||||
)
|
||||
) or (
|
||||
j == 1
|
||||
and now_time - latest_time
|
||||
> datetime.timedelta(minutes=self.routine)
|
||||
> datetime.timedelta(
|
||||
minutes=self.set["RunSet"]["RoutineTimeLimit"]
|
||||
)
|
||||
):
|
||||
self.if_time_out = True
|
||||
|
||||
@@ -213,38 +220,21 @@ class MaaManager(QtCore.QThread):
|
||||
|
||||
# 更新MAA日志
|
||||
if len(logs) > 100:
|
||||
self.update_gui.emit(
|
||||
f"{self.data[index][0]}_第{i + 1}次_{mode_book[j][5:7]}",
|
||||
"\n".join([self.data[_][0] for _ in wait_index]),
|
||||
"\n".join([self.data[_][0] for _ in over_index]),
|
||||
"\n".join([self.data[_][0] for _ in error_index]),
|
||||
"".join(logs[-100:]),
|
||||
)
|
||||
self.update_log_text.emit("".join(logs[-100:]))
|
||||
else:
|
||||
self.update_gui.emit(
|
||||
f"{self.data[index][0]}_第{i + 1}次_{mode_book[j][5:7]}",
|
||||
"\n".join([self.data[_][0] for _ in wait_index]),
|
||||
"\n".join([self.data[_][0] for _ in over_index]),
|
||||
"\n".join([self.data[_][0] for _ in error_index]),
|
||||
"".join(logs),
|
||||
)
|
||||
self.update_log_text.emit("".join(logs))
|
||||
|
||||
# 判断MAA程序运行状态
|
||||
result = self.if_maa_success(log, mode_book[j])
|
||||
if result == "Success!":
|
||||
run_book[j] = True
|
||||
self.update_gui.emit(
|
||||
f"{self.data[index][0]}_第{i + 1}次_{mode_book[j][5:7]}",
|
||||
"\n".join([self.data[_][0] for _ in wait_index]),
|
||||
"\n".join([self.data[_][0] for _ in over_index]),
|
||||
"\n".join([self.data[_][0] for _ in error_index]),
|
||||
"检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s",
|
||||
self.update_log_text.emit(
|
||||
"检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s"
|
||||
)
|
||||
# 关闭静默进程
|
||||
if self.if_silence:
|
||||
self.set_silence.emit("禁用", "", [])
|
||||
# 移除静默进程数量标记
|
||||
self.config.if_silence_needed -= 1
|
||||
for _ in range(10):
|
||||
if self.isInterruptionRequested():
|
||||
if self.isInterruptionRequested:
|
||||
break
|
||||
time.sleep(1)
|
||||
break
|
||||
@@ -254,13 +244,7 @@ class MaaManager(QtCore.QThread):
|
||||
else:
|
||||
# 打印中止信息
|
||||
# 此时,log变量内存储的就是出现异常的日志信息,可以保存或发送用于问题排查
|
||||
self.update_gui.emit(
|
||||
f"{self.data[index][0]}_第{i + 1}次_{mode_book[j][5:7]}",
|
||||
"\n".join([self.data[_][0] for _ in wait_index]),
|
||||
"\n".join([self.data[_][0] for _ in over_index]),
|
||||
"\n".join([self.data[_][0] for _ in error_index]),
|
||||
result,
|
||||
)
|
||||
self.update_log_text.emit(result)
|
||||
# 无命令行中止MAA与其子程序
|
||||
killprocess = subprocess.Popen(
|
||||
f"taskkill /F /T /PID {maa.pid}",
|
||||
@@ -268,39 +252,40 @@ class MaaManager(QtCore.QThread):
|
||||
creationflags=subprocess.CREATE_NO_WINDOW,
|
||||
)
|
||||
killprocess.wait()
|
||||
# 关闭静默进程
|
||||
if self.if_silence:
|
||||
self.set_silence.emit("禁用", "", [])
|
||||
# 移除静默进程数量标记
|
||||
self.config.if_silence_needed -= 1
|
||||
# 推送异常通知
|
||||
self.push_notification.emit(
|
||||
"用户日常代理出现异常!",
|
||||
f"用户 {self.data[index][0].replace("_", " 今天的")}的{mode_book[j][5:7]}部分出现一次异常",
|
||||
f"{self.data[index][0].replace("_", " ")}的{mode_book[j][5:7]}出现异常",
|
||||
self.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():
|
||||
if self.isInterruptionRequested:
|
||||
break
|
||||
time.sleep(1)
|
||||
break
|
||||
|
||||
# 成功完成代理的用户修改相关参数
|
||||
if run_book[0] and run_book[1]:
|
||||
if self.data[index][14] == 0 and self.data[index][3] != -1:
|
||||
self.data[index][3] -= 1
|
||||
self.data[index][14] += 1
|
||||
over_index.append(index)
|
||||
self.push_notification.emit(
|
||||
"成功完成一个日常代理任务!",
|
||||
f"已完成用户 {self.data[index][0].replace("_", " 今天的")}任务",
|
||||
f"已完成 {self.data[index][0].replace("_", " 的")}",
|
||||
if self.data[user[2]][14] == 0 and self.data[user[2]][3] != -1:
|
||||
self.data[user[2]][3] -= 1
|
||||
self.data[user[2]][14] += 1
|
||||
user[1] = "完成"
|
||||
self.notify.push_notification(
|
||||
"成功完成一个自动代理任务!",
|
||||
f"已完成用户 {user[0].replace("_", " 今天的")}任务",
|
||||
f"已完成 {user[0].replace("_", " 的")}",
|
||||
3,
|
||||
)
|
||||
break
|
||||
|
||||
# 录入代理失败的用户
|
||||
if not (run_book[0] and run_book[1]):
|
||||
error_index.append(index)
|
||||
user[1] = "异常"
|
||||
|
||||
self.update_user_list.emit(user_list)
|
||||
|
||||
# 人工排查模式
|
||||
elif self.mode == "人工排查":
|
||||
@@ -308,47 +293,44 @@ class MaaManager(QtCore.QThread):
|
||||
# 标记是否需要启动模拟器
|
||||
if_strat_app = True
|
||||
# 标识排查模式
|
||||
for _ in all_index:
|
||||
self.data[_][0] += "_排查模式"
|
||||
for _ in user_list:
|
||||
_[0] += "_排查模式"
|
||||
|
||||
# 开始排查
|
||||
for index in all_index:
|
||||
for user in user_list:
|
||||
|
||||
if self.isInterruptionRequested():
|
||||
if self.isInterruptionRequested:
|
||||
break
|
||||
|
||||
if self.data[index][15] == "beta":
|
||||
user[1] = "运行"
|
||||
self.update_user_list.emit(user_list)
|
||||
|
||||
if self.data[user[2]][15] == "beta":
|
||||
if_strat_app = True
|
||||
|
||||
run_book = [False for _ in range(2)]
|
||||
|
||||
# 启动重试循环
|
||||
while not self.isInterruptionRequested():
|
||||
while not self.isInterruptionRequested:
|
||||
|
||||
# 配置MAA
|
||||
if if_strat_app:
|
||||
self.set_maa("人工排查_启动模拟器", index)
|
||||
self.set_maa("人工排查_启动模拟器", user[2])
|
||||
if_strat_app = False
|
||||
else:
|
||||
self.set_maa("人工排查_仅切换账号", index)
|
||||
self.set_maa("人工排查_仅切换账号", user[2])
|
||||
|
||||
# 记录当前时间
|
||||
start_time = datetime.datetime.now()
|
||||
# 创建MAA任务
|
||||
maa = subprocess.Popen(
|
||||
[self.maa_path],
|
||||
[self.maa_exe_path],
|
||||
shell=True,
|
||||
creationflags=subprocess.CREATE_NO_WINDOW,
|
||||
)
|
||||
# 更新运行信息
|
||||
wait_index = [
|
||||
_
|
||||
for _ in all_index
|
||||
if (not _ in over_index + error_index + [index])
|
||||
]
|
||||
|
||||
# 监测MAA运行状态
|
||||
while not self.isInterruptionRequested():
|
||||
while not self.isInterruptionRequested:
|
||||
|
||||
# 获取MAA日志
|
||||
logs = self.get_maa_log(start_time)
|
||||
@@ -357,45 +339,21 @@ class MaaManager(QtCore.QThread):
|
||||
|
||||
# 更新MAA日志
|
||||
if len(logs) > 100:
|
||||
self.update_gui.emit(
|
||||
self.data[index][0],
|
||||
"\n".join([self.data[_][0] for _ in wait_index]),
|
||||
"\n".join([self.data[_][0] for _ in over_index]),
|
||||
"\n".join([self.data[_][0] for _ in error_index]),
|
||||
"".join(logs[-100:]),
|
||||
)
|
||||
self.update_log_text.emit("".join(logs[-100:]))
|
||||
else:
|
||||
self.update_gui.emit(
|
||||
self.data[index][0],
|
||||
"\n".join([self.data[_][0] for _ in wait_index]),
|
||||
"\n".join([self.data[_][0] for _ in over_index]),
|
||||
"\n".join([self.data[_][0] for _ in error_index]),
|
||||
"".join(logs),
|
||||
)
|
||||
self.update_log_text.emit("".join(logs))
|
||||
|
||||
# 判断MAA程序运行状态
|
||||
result = self.if_maa_success(log, "人工排查")
|
||||
if result == "Success!":
|
||||
run_book[0] = True
|
||||
self.update_gui.emit(
|
||||
self.data[index][0],
|
||||
"\n".join([self.data[_][0] for _ in wait_index]),
|
||||
"\n".join([self.data[_][0] for _ in over_index]),
|
||||
"\n".join([self.data[_][0] for _ in error_index]),
|
||||
"检测到MAA进程成功登录PRTS",
|
||||
)
|
||||
self.update_log_text.emit("检测到MAA进程成功登录PRTS")
|
||||
break
|
||||
elif result == "Wait":
|
||||
# 检测时间间隔
|
||||
time.sleep(1)
|
||||
else:
|
||||
self.update_gui.emit(
|
||||
self.data[index][0],
|
||||
"\n".join([self.data[_][0] for _ in wait_index]),
|
||||
"\n".join([self.data[_][0] for _ in over_index]),
|
||||
"\n".join([self.data[_][0] for _ in error_index]),
|
||||
result,
|
||||
)
|
||||
self.update_log_text.emit(result)
|
||||
# 无命令行中止MAA与其子程序
|
||||
killprocess = subprocess.Popen(
|
||||
f"taskkill /F /T /PID {maa.pid}",
|
||||
@@ -405,7 +363,7 @@ class MaaManager(QtCore.QThread):
|
||||
killprocess.wait()
|
||||
if_strat_app = True
|
||||
for _ in range(10):
|
||||
if self.isInterruptionRequested():
|
||||
if self.isInterruptionRequested:
|
||||
break
|
||||
time.sleep(1)
|
||||
break
|
||||
@@ -414,7 +372,7 @@ class MaaManager(QtCore.QThread):
|
||||
if run_book[0]:
|
||||
break
|
||||
# 登录失败,询问是否结束循环
|
||||
elif not self.isInterruptionRequested():
|
||||
elif not self.isInterruptionRequested:
|
||||
self.question_title = "操作提示"
|
||||
self.question_info = "MAA未能正确登录到PRTS,是否重试?"
|
||||
self.question_choice = "wait"
|
||||
@@ -425,7 +383,7 @@ class MaaManager(QtCore.QThread):
|
||||
break
|
||||
|
||||
# 登录成功,录入人工排查情况
|
||||
if run_book[0] and not self.isInterruptionRequested():
|
||||
if run_book[0] and not self.isInterruptionRequested:
|
||||
self.question_title = "操作提示"
|
||||
self.question_info = "请检查用户代理情况,如无异常请按下确认键。"
|
||||
self.question_choice = "wait"
|
||||
@@ -437,15 +395,19 @@ class MaaManager(QtCore.QThread):
|
||||
|
||||
# 结果录入用户备注栏
|
||||
if run_book[0] and run_book[1]:
|
||||
if "未通过人工排查" in self.data[index][13]:
|
||||
self.data[index][13] = self.data[index][13].replace(
|
||||
if "未通过人工排查" in self.data[user[2]][13]:
|
||||
self.data[user[2]][13] = self.data[user[2]][13].replace(
|
||||
"未通过人工排查|", ""
|
||||
)
|
||||
over_index.append(index)
|
||||
user[1] = "完成"
|
||||
elif not (run_book[0] and run_book[1]):
|
||||
if not "未通过人工排查" in self.data[index][13]:
|
||||
self.data[index][13] = f"未通过人工排查|{self.data[index][13]}"
|
||||
error_index.append(index)
|
||||
if not "未通过人工排查" in self.data[user[2]][13]:
|
||||
self.data[user[2]][
|
||||
13
|
||||
] = f"未通过人工排查|{self.data[user[2]][13]}"
|
||||
user[1] = "异常"
|
||||
|
||||
self.update_user_list.emit(user_list)
|
||||
|
||||
# 设置MAA模式
|
||||
elif "设置MAA" in self.mode:
|
||||
@@ -454,7 +416,7 @@ class MaaManager(QtCore.QThread):
|
||||
self.set_maa(self.mode, "")
|
||||
# 创建MAA任务
|
||||
maa = subprocess.Popen(
|
||||
[self.maa_path],
|
||||
[self.maa_exe_path],
|
||||
shell=True,
|
||||
creationflags=subprocess.CREATE_NO_WINDOW,
|
||||
)
|
||||
@@ -462,7 +424,7 @@ class MaaManager(QtCore.QThread):
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
# 监测MAA运行状态
|
||||
while not self.isInterruptionRequested():
|
||||
while not self.isInterruptionRequested:
|
||||
|
||||
# 获取MAA日志
|
||||
logs = self.get_maa_log(start_time)
|
||||
@@ -483,13 +445,13 @@ class MaaManager(QtCore.QThread):
|
||||
elif "用户" in self.mode:
|
||||
self.get_json.emit(self.get_json_path)
|
||||
|
||||
self.accomplish.emit()
|
||||
end_log = ""
|
||||
|
||||
# 导出结果
|
||||
if self.mode in ["日常代理", "人工排查"]:
|
||||
if self.mode in ["自动代理", "人工排查"]:
|
||||
|
||||
# 关闭可能未正常退出的MAA进程
|
||||
if self.isInterruptionRequested():
|
||||
if self.isInterruptionRequested:
|
||||
killprocess = subprocess.Popen(
|
||||
f"taskkill /F /T /PID {maa.pid}",
|
||||
shell=True,
|
||||
@@ -498,14 +460,18 @@ class MaaManager(QtCore.QThread):
|
||||
killprocess.wait()
|
||||
|
||||
# 更新用户数据
|
||||
modes = [self.data[_][15] for _ in all_index]
|
||||
uids = [self.data[_][16] for _ in all_index]
|
||||
days = [self.data[_][3] for _ in all_index]
|
||||
lasts = [self.data[_][5] for _ in all_index]
|
||||
notes = [self.data[_][13] for _ in all_index]
|
||||
numbs = [self.data[_][14] for _ in all_index]
|
||||
modes = [self.data[_[2]][15] for _ in user_list]
|
||||
uids = [self.data[_[2]][16] for _ in user_list]
|
||||
days = [self.data[_[2]][3] for _ in user_list]
|
||||
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)
|
||||
|
||||
error_index = [_[2] for _ in user_list if _[1] == "异常"]
|
||||
over_index = [_[2] for _ in user_list if _[1] == "完成"]
|
||||
wait_index = [_[2] for _ in user_list if _[1] == "等待"]
|
||||
|
||||
# 保存运行日志
|
||||
end_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
end_log = (
|
||||
@@ -518,46 +484,45 @@ class MaaManager(QtCore.QThread):
|
||||
f"{self.mode[2:4]}未成功的用户:\n"
|
||||
f"{"\n".join([self.data[_][0] for _ in error_index])}\n"
|
||||
)
|
||||
wait_index = [_ for _ in all_index if (not _ in over_index + error_index)]
|
||||
if len(wait_index) != 0:
|
||||
end_log += (
|
||||
f"\n未开始{self.mode[2:4]}的用户:\n"
|
||||
f"{"\n".join([self.data[_][0] for _ in wait_index])}\n"
|
||||
)
|
||||
|
||||
(self.config.app_path / "log.txt").write_text(
|
||||
end_log,
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
# 恢复GUI运行面板
|
||||
self.update_gui.emit("", "", "", "", end_log)
|
||||
|
||||
# 推送代理结果通知
|
||||
self.push_notification.emit(
|
||||
self.notify.push_notification(
|
||||
f"{self.mode[2:4]}任务已完成!",
|
||||
f"已完成用户数:{len(over_index)},未完成用户数:{len(error_index) + len(wait_index)}",
|
||||
f"已完成用户数:{len(over_index)},未完成用户数:{len(error_index) + len(wait_index)}",
|
||||
10,
|
||||
)
|
||||
if self.if_send_mail and (
|
||||
not self.if_send_error_only
|
||||
or (self.if_send_error_only and len(error_index) + len(wait_index) != 0)
|
||||
if not self.config.global_config.get(
|
||||
self.config.global_config.notify_IfSendErrorOnly
|
||||
) or (
|
||||
self.config.global_config.get(
|
||||
self.config.global_config.notify_IfSendErrorOnly
|
||||
)
|
||||
and len(error_index) + len(wait_index) != 0
|
||||
):
|
||||
self.send_mail.emit(
|
||||
self.notify.send_mail(
|
||||
f"{self.mode[:4]}任务报告",
|
||||
f"{end_log}\n\nAUTO_MAA 敬上\n\n我们根据您在 AUTO_MAA 中的设置发送了这封电子邮件,本邮件无需回复\n",
|
||||
)
|
||||
|
||||
if not self.isInterruptionRequested():
|
||||
self.accomplish.emit()
|
||||
self.accomplish.emit({"Time": begin_time, "History": end_log})
|
||||
|
||||
def requestInterruption(self) -> None:
|
||||
|
||||
logger.info("申请中止本次任务")
|
||||
self.isInterruptionRequested = True
|
||||
|
||||
def get_maa_log(self, start_time):
|
||||
"""获取MAA日志"""
|
||||
|
||||
logs = []
|
||||
if_log_start = False
|
||||
with self.log_path.open(mode="r", encoding="utf-8") as f:
|
||||
with self.maa_log_path.open(mode="r", encoding="utf-8") as f:
|
||||
for entry in f:
|
||||
if not if_log_start:
|
||||
try:
|
||||
@@ -576,8 +541,8 @@ class MaaManager(QtCore.QThread):
|
||||
def if_maa_success(self, log, mode):
|
||||
"""判断MAA程序运行状态"""
|
||||
|
||||
if "日常代理" in mode:
|
||||
if mode == "日常代理_日常" and "任务出错: Fight" in log:
|
||||
if "自动代理" in mode:
|
||||
if mode == "自动代理_日常" and "任务出错: Fight" in log:
|
||||
return "检测到MAA未能实际执行任务\n正在中止相关程序\n请等待10s"
|
||||
if "任务出错: StartUp" in log:
|
||||
return "检测到MAA未能正确登录PRTS\n正在中止相关程序\n请等待10s"
|
||||
@@ -591,7 +556,7 @@ class MaaManager(QtCore.QThread):
|
||||
return "检测到MAA进程异常\n正在中止相关程序\n请等待10s"
|
||||
elif self.if_time_out:
|
||||
return "检测到MAA进程超时\n正在中止相关程序\n请等待10s"
|
||||
elif self.isInterruptionRequested():
|
||||
elif self.isInterruptionRequested:
|
||||
return "您中止了本次任务\n正在中止相关程序\n请等待"
|
||||
else:
|
||||
return "Wait"
|
||||
@@ -605,7 +570,7 @@ class MaaManager(QtCore.QThread):
|
||||
or ("MaaAssistantArknights GUI exited" in log)
|
||||
):
|
||||
return "检测到MAA进程异常\n正在中止相关程序\n请等待10s"
|
||||
elif self.isInterruptionRequested():
|
||||
elif self.isInterruptionRequested:
|
||||
return "您中止了本次任务\n正在中止相关程序\n请等待"
|
||||
else:
|
||||
return "Wait"
|
||||
@@ -623,49 +588,49 @@ class MaaManager(QtCore.QThread):
|
||||
if mode == "设置MAA_用户":
|
||||
set_book = ["simple", "beta"]
|
||||
if (
|
||||
self.json_path
|
||||
self.config_path
|
||||
/ f"{set_book[self.get_json_path[0]]}/{self.get_json_path[1]}/{self.get_json_path[2]}/gui.json"
|
||||
).exists():
|
||||
shutil.copy(
|
||||
self.json_path
|
||||
self.config_path
|
||||
/ f"{set_book[self.get_json_path[0]]}/{self.get_json_path[1]}/{self.get_json_path[2]}/gui.json",
|
||||
self.set_path,
|
||||
self.maa_set_path,
|
||||
)
|
||||
else:
|
||||
shutil.copy(
|
||||
self.json_path / "Default/gui.json",
|
||||
self.set_path,
|
||||
self.config_path / "Default/gui.json",
|
||||
self.maa_set_path,
|
||||
)
|
||||
elif (mode == "设置MAA_全局") or (
|
||||
("日常代理" in mode or "人工排查" in mode)
|
||||
("自动代理" in mode or "人工排查" in mode)
|
||||
and self.data[index][15] == "simple"
|
||||
):
|
||||
shutil.copy(
|
||||
self.json_path / "Default/gui.json",
|
||||
self.set_path,
|
||||
self.config_path / "Default/gui.json",
|
||||
self.maa_set_path,
|
||||
)
|
||||
elif "日常代理" in mode and self.data[index][15] == "beta":
|
||||
if mode == "日常代理_剿灭":
|
||||
elif "自动代理" in mode and self.data[index][15] == "beta":
|
||||
if mode == "自动代理_剿灭":
|
||||
shutil.copy(
|
||||
self.json_path
|
||||
self.config_path
|
||||
/ f"beta/{self.data[index][16]}/annihilation/gui.json",
|
||||
self.set_path,
|
||||
self.maa_set_path,
|
||||
)
|
||||
elif mode == "日常代理_日常":
|
||||
elif mode == "自动代理_日常":
|
||||
shutil.copy(
|
||||
self.json_path / f"beta/{self.data[index][16]}/routine/gui.json",
|
||||
self.set_path,
|
||||
self.config_path / f"beta/{self.data[index][16]}/routine/gui.json",
|
||||
self.maa_set_path,
|
||||
)
|
||||
elif "人工排查" in mode and self.data[index][15] == "beta":
|
||||
shutil.copy(
|
||||
self.json_path / f"beta/{self.data[index][16]}/routine/gui.json",
|
||||
self.set_path,
|
||||
self.config_path / f"beta/{self.data[index][16]}/routine/gui.json",
|
||||
self.maa_set_path,
|
||||
)
|
||||
with self.set_path.open(mode="r", encoding="utf-8") as f:
|
||||
with self.maa_set_path.open(mode="r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
# 日常代理配置
|
||||
if "日常代理" in mode:
|
||||
# 自动代理配置
|
||||
if "自动代理" in mode:
|
||||
|
||||
data["Current"] = "Default" # 切换配置
|
||||
for i in range(1, 9):
|
||||
@@ -678,7 +643,7 @@ class MaaManager(QtCore.QThread):
|
||||
"Start.OpenEmulatorAfterLaunch"
|
||||
] = "True" # 启动MAA后自动开启模拟器
|
||||
|
||||
if self.if_silence:
|
||||
if self.config.if_silence_needed > 0:
|
||||
data["Global"]["Start.MinimizeDirectly"] = "True" # 启动MAA后直接最小化
|
||||
data["Global"]["GUI.UseTray"] = "True" # 显示托盘图标
|
||||
data["Global"]["GUI.MinimizeToTray"] = "True" # 最小化时隐藏至托盘
|
||||
@@ -869,7 +834,7 @@ class MaaManager(QtCore.QThread):
|
||||
] = "False" # 自定义基建配置文件只读
|
||||
data["Configurations"]["Default"][
|
||||
"Infrast.CustomInfrastFile"
|
||||
] = f"{self.json_path}/simple/{self.data[index][16]}/infrastructure/infrastructure.json" # 自定义基建配置文件地址
|
||||
] = f"{self.config_path}/simple/{self.data[index][16]}/infrastructure/infrastructure.json" # 自定义基建配置文件地址
|
||||
|
||||
# 人工排查配置
|
||||
elif "人工排查" in mode:
|
||||
@@ -955,7 +920,7 @@ class MaaManager(QtCore.QThread):
|
||||
"Start.OpenEmulatorAfterLaunch"
|
||||
] = "False" # 启动MAA后自动开启模拟器
|
||||
|
||||
if self.if_silence:
|
||||
if self.config.if_silence_needed > 0:
|
||||
data["Global"][
|
||||
"Start.MinimizeDirectly"
|
||||
] = "False" # 启动MAA后直接最小化
|
||||
@@ -997,7 +962,7 @@ class MaaManager(QtCore.QThread):
|
||||
] = "False" # 生息演算
|
||||
|
||||
# 覆写配置文件
|
||||
with self.set_path.open(mode="w", encoding="utf-8") as f:
|
||||
with self.maa_set_path.open(mode="w", encoding="utf-8") as f:
|
||||
json.dump(data, f, indent=4)
|
||||
|
||||
return True
|
||||
@@ -1006,7 +971,7 @@ class MaaManager(QtCore.QThread):
|
||||
"""获取模拟器路径"""
|
||||
|
||||
# 读取配置文件
|
||||
with self.set_path.open(mode="r", encoding="utf-8") as f:
|
||||
with self.maa_set_path.open(mode="r", encoding="utf-8") as f:
|
||||
set = json.load(f)
|
||||
# 获取模拟器路径
|
||||
return Path(set["Configurations"]["Default"]["Start.EmulatorPath"])
|
||||
|
||||
BIN
app/models/__pycache__/MAA.cpython-312.pyc
Normal file
BIN
app/models/__pycache__/MAA.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/models/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
app/models/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/services/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
app/services/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/services/__pycache__/notification.cpython-312.pyc
Normal file
BIN
app/services/__pycache__/notification.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/services/__pycache__/security.cpython-312.pyc
Normal file
BIN
app/services/__pycache__/security.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/services/__pycache__/system.cpython-312.pyc
Normal file
BIN
app/services/__pycache__/system.cpython-312.pyc
Normal file
Binary file not shown.
@@ -32,7 +32,7 @@ from email.header import Header
|
||||
from email.utils import formataddr
|
||||
import os
|
||||
|
||||
from app import AppConfig
|
||||
from app.core import AppConfig
|
||||
|
||||
|
||||
class Notification:
|
||||
|
||||
@@ -34,7 +34,7 @@ from Crypto.PublicKey import RSA
|
||||
from Crypto.Cipher import PKCS1_OAEP
|
||||
from Crypto.Util.Padding import pad, unpad
|
||||
|
||||
from app import AppConfig
|
||||
from app.core import AppConfig
|
||||
|
||||
|
||||
class CryptoHandler:
|
||||
|
||||
@@ -31,7 +31,7 @@ import win32process
|
||||
import winreg
|
||||
import psutil
|
||||
|
||||
from app import AppConfig
|
||||
from app.core import AppConfig
|
||||
|
||||
|
||||
class SystemHandler:
|
||||
|
||||
BIN
app/ui/__pycache__/Widget.cpython-312.pyc
Normal file
BIN
app/ui/__pycache__/Widget.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/ui/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
app/ui/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/ui/__pycache__/dispatch_center.cpython-312.pyc
Normal file
BIN
app/ui/__pycache__/dispatch_center.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/ui/__pycache__/main_window.cpython-312.pyc
Normal file
BIN
app/ui/__pycache__/main_window.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/ui/__pycache__/member_manager.cpython-312.pyc
Normal file
BIN
app/ui/__pycache__/member_manager.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/ui/__pycache__/queue_manager.cpython-312.pyc
Normal file
BIN
app/ui/__pycache__/queue_manager.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/ui/__pycache__/setting.cpython-312.pyc
Normal file
BIN
app/ui/__pycache__/setting.cpython-312.pyc
Normal file
Binary file not shown.
359
app/ui/dispatch_center.py
Normal file
359
app/ui/dispatch_center.py
Normal file
@@ -0,0 +1,359 @@
|
||||
# <AUTO_MAA:A MAA Multi Account Management and Automation Tool>
|
||||
# Copyright © <2024> <DLmaster361>
|
||||
|
||||
# This file is part of AUTO_MAA.
|
||||
|
||||
# AUTO_MAA is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
# AUTO_MAA is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
# the GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# DLmaster_361@163.com
|
||||
|
||||
"""
|
||||
AUTO_MAA
|
||||
AUTO_MAA调度中枢界面
|
||||
v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (
|
||||
QWidget,
|
||||
QVBoxLayout,
|
||||
QStackedWidget,
|
||||
QHBoxLayout,
|
||||
)
|
||||
from qfluentwidgets import (
|
||||
CardWidget,
|
||||
IconWidget,
|
||||
BodyLabel,
|
||||
qconfig,
|
||||
Pivot,
|
||||
ScrollArea,
|
||||
FluentIcon,
|
||||
MessageBox,
|
||||
HeaderCardWidget,
|
||||
CommandBar,
|
||||
FluentIcon,
|
||||
TextBrowser,
|
||||
ComboBox,
|
||||
setTheme,
|
||||
Theme,
|
||||
SubtitleLabel,
|
||||
PushButton,
|
||||
ElevatedCardWidget,
|
||||
)
|
||||
from PySide6.QtUiTools import QUiLoader
|
||||
from PySide6 import QtCore
|
||||
from typing import List, Dict
|
||||
import json
|
||||
import shutil
|
||||
|
||||
uiLoader = QUiLoader()
|
||||
|
||||
from app.core import AppConfig, TaskManager, Task, MainInfoBar
|
||||
from app.services import Notification
|
||||
|
||||
|
||||
class DispatchCenter(QWidget):
|
||||
|
||||
def __init__(self, config: AppConfig, task_manager: TaskManager, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setObjectName("调度中枢")
|
||||
self.config = config
|
||||
self.task_manager = task_manager
|
||||
|
||||
self.pivot = Pivot(self)
|
||||
self.stackedWidget = QStackedWidget(self)
|
||||
self.Layout = QVBoxLayout(self)
|
||||
|
||||
self.script_list: Dict[str, DispatchBox] = {}
|
||||
|
||||
dispatch_box = DispatchBox(self.config, "主调度台", self)
|
||||
self.script_list["主调度台"] = dispatch_box
|
||||
self.stackedWidget.addWidget(self.script_list["主调度台"])
|
||||
self.pivot.addItem(
|
||||
routeKey="主调度台",
|
||||
text="主调度台",
|
||||
onClick=self.update_top_bar,
|
||||
icon=FluentIcon.CAFE,
|
||||
)
|
||||
self.update_top_bar()
|
||||
|
||||
self.Layout.addWidget(self.pivot, 0, QtCore.Qt.AlignHCenter)
|
||||
self.Layout.addWidget(self.stackedWidget)
|
||||
self.Layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.pivot.currentItemChanged.connect(
|
||||
lambda index: self.stackedWidget.setCurrentWidget(self.script_list[index])
|
||||
)
|
||||
|
||||
def add_board(self, task: Task) -> None:
|
||||
"""添加一个调度台界面"""
|
||||
|
||||
dispatch_box = DispatchBox(self.config, task.name, self)
|
||||
|
||||
dispatch_box.top_bar.button.clicked.connect(
|
||||
lambda: self.task_manager.stop_task(task.name)
|
||||
)
|
||||
|
||||
task.create_task_list.connect(dispatch_box.info.task.create_task)
|
||||
task.create_user_list.connect(dispatch_box.info.user.create_user)
|
||||
task.update_task_list.connect(dispatch_box.info.task.update_task)
|
||||
task.update_user_list.connect(dispatch_box.info.user.update_user)
|
||||
task.update_log_text.connect(dispatch_box.info.log_text.text.setText)
|
||||
task.accomplish.connect(lambda: self.del_board(f"调度台_{task.name}"))
|
||||
|
||||
self.script_list[f"调度台_{task.name}"] = dispatch_box
|
||||
|
||||
self.stackedWidget.addWidget(self.script_list[f"调度台_{task.name}"])
|
||||
|
||||
self.pivot.addItem(routeKey=f"调度台_{task.name}", text=f"调度台 {task.name}")
|
||||
|
||||
def del_board(self, name: str) -> None:
|
||||
"""删除指定子界面"""
|
||||
|
||||
self.pivot.setCurrentItem("主调度台")
|
||||
self.stackedWidget.removeWidget(self.script_list[name])
|
||||
self.script_list[name].deleteLater()
|
||||
self.pivot.removeWidget(name)
|
||||
|
||||
def update_top_bar(self):
|
||||
"""更新顶栏"""
|
||||
|
||||
list = []
|
||||
|
||||
if (self.config.app_path / "config/QueueConfig").exists():
|
||||
for json_file in (self.config.app_path / "config/QueueConfig").glob(
|
||||
"*.json"
|
||||
):
|
||||
list.append(f"队列 - {json_file.stem}")
|
||||
|
||||
if (self.config.app_path / "config/MaaConfig").exists():
|
||||
for subdir in (self.config.app_path / "config/MaaConfig").iterdir():
|
||||
if subdir.is_dir():
|
||||
list.append(f"实例 - Maa - {subdir.name}")
|
||||
|
||||
self.script_list["主调度台"].top_bar.object.clear()
|
||||
self.script_list["主调度台"].top_bar.object.addItems(list)
|
||||
|
||||
|
||||
class DispatchBox(QWidget):
|
||||
|
||||
def __init__(self, config: AppConfig, name: str, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setObjectName(name)
|
||||
|
||||
self.config = config
|
||||
|
||||
layout = QVBoxLayout()
|
||||
|
||||
scrollArea = ScrollArea()
|
||||
scrollArea.setWidgetResizable(True)
|
||||
|
||||
content_widget = QWidget()
|
||||
content_layout = QVBoxLayout(content_widget)
|
||||
|
||||
self.top_bar = self.DispatchTopBar(self, name)
|
||||
self.info = self.DispatchInfoCard(self)
|
||||
|
||||
content_layout.addWidget(self.top_bar)
|
||||
content_layout.addWidget(self.info)
|
||||
|
||||
scrollArea.setWidget(content_widget)
|
||||
|
||||
layout.addWidget(scrollArea)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
class DispatchTopBar(CardWidget):
|
||||
|
||||
def __init__(self, parent=None, name: str = None):
|
||||
super().__init__(parent)
|
||||
|
||||
Layout = QHBoxLayout(self)
|
||||
|
||||
if name == "主调度台":
|
||||
|
||||
self.object = ComboBox()
|
||||
self.object.setCurrentIndex(-1)
|
||||
self.object.setPlaceholderText("请选择调度对象")
|
||||
self.mode = ComboBox()
|
||||
self.mode.addItems(["自动代理", "人工排查"])
|
||||
self.mode.setCurrentIndex(-1)
|
||||
self.mode.setPlaceholderText("请选择调度模式")
|
||||
|
||||
self.button = PushButton("开始任务")
|
||||
|
||||
Layout.addWidget(self.object)
|
||||
Layout.addWidget(self.mode)
|
||||
Layout.addStretch(1)
|
||||
Layout.addWidget(self.button)
|
||||
|
||||
else:
|
||||
|
||||
self.Lable = SubtitleLabel(name, self)
|
||||
self.button = PushButton("中止任务")
|
||||
|
||||
Layout.addWidget(self.Lable)
|
||||
Layout.addStretch(1)
|
||||
Layout.addWidget(self.button)
|
||||
|
||||
class DispatchInfoCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setTitle("调度信息")
|
||||
|
||||
self.task = self.TaskInfoCard(self)
|
||||
self.user = self.UserInfoCard(self)
|
||||
self.log_text = self.LogCard(self)
|
||||
|
||||
self.viewLayout.addWidget(self.task)
|
||||
self.viewLayout.addWidget(self.user)
|
||||
self.viewLayout.addWidget(self.log_text)
|
||||
|
||||
self.viewLayout.setStretch(0, 1)
|
||||
self.viewLayout.setStretch(1, 1)
|
||||
self.viewLayout.setStretch(2, 5)
|
||||
|
||||
def update_board(self, task_list: list, user_list: list, log: str):
|
||||
"""更新调度信息"""
|
||||
|
||||
self.task.update_task(task_list)
|
||||
self.user.update_user(user_list)
|
||||
self.log_text.text.setText(log)
|
||||
|
||||
class TaskInfoCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setTitle("任务队列")
|
||||
|
||||
self.Layout = QVBoxLayout()
|
||||
self.viewLayout.addLayout(self.Layout)
|
||||
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
||||
|
||||
self.task_cards: List[ItemCard] = []
|
||||
|
||||
def create_task(self, task_list: list):
|
||||
"""创建任务队列"""
|
||||
|
||||
while self.Layout.count() > 0:
|
||||
item = self.Layout.takeAt(0)
|
||||
if item.spacerItem():
|
||||
self.Layout.removeItem(item.spacerItem())
|
||||
elif item.widget():
|
||||
item.widget().deleteLater()
|
||||
|
||||
self.task_cards = []
|
||||
|
||||
for task in task_list:
|
||||
|
||||
self.task_cards.append(ItemCard(task))
|
||||
self.Layout.addWidget(self.task_cards[-1])
|
||||
|
||||
self.Layout.addStretch(1)
|
||||
|
||||
def update_task(self, task_list: list):
|
||||
"""更新任务队列"""
|
||||
|
||||
for i in range(len(task_list)):
|
||||
|
||||
self.task_cards[i].update_status(task_list[i][1])
|
||||
|
||||
class UserInfoCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setTitle("用户队列")
|
||||
|
||||
self.Layout = QVBoxLayout()
|
||||
self.viewLayout.addLayout(self.Layout)
|
||||
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
||||
|
||||
self.user_cards: List[ItemCard] = []
|
||||
|
||||
def create_user(self, user_list: list):
|
||||
"""创建用户队列"""
|
||||
|
||||
while self.Layout.count() > 0:
|
||||
item = self.Layout.takeAt(0)
|
||||
if item.spacerItem():
|
||||
self.Layout.removeItem(item.spacerItem())
|
||||
elif item.widget():
|
||||
item.widget().deleteLater()
|
||||
|
||||
self.user_cards = []
|
||||
|
||||
for user in user_list:
|
||||
|
||||
self.user_cards.append(ItemCard(user))
|
||||
self.Layout.addWidget(self.user_cards[-1])
|
||||
|
||||
self.Layout.addStretch(1)
|
||||
|
||||
def update_user(self, user_list: list):
|
||||
"""更新用户队列"""
|
||||
|
||||
for i in range(len(user_list)):
|
||||
|
||||
self.user_cards[i].Label.setText(user_list[i][0])
|
||||
self.user_cards[i].update_status(user_list[i][1])
|
||||
|
||||
class LogCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setTitle("日志")
|
||||
|
||||
self.text = TextBrowser()
|
||||
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
||||
self.viewLayout.addWidget(self.text)
|
||||
|
||||
|
||||
class ItemCard(CardWidget):
|
||||
|
||||
def __init__(self, task_item: list, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.Layout = QHBoxLayout(self)
|
||||
|
||||
self.Label = BodyLabel(task_item[0], self)
|
||||
self.icon = IconWidget(FluentIcon.MORE, self)
|
||||
self.icon.setFixedSize(16, 16)
|
||||
self.update_status(task_item[1])
|
||||
|
||||
self.Layout.addWidget(self.icon)
|
||||
self.Layout.addWidget(self.Label)
|
||||
self.Layout.addStretch(1)
|
||||
|
||||
def update_status(self, status: str):
|
||||
|
||||
if status == "完成":
|
||||
self.icon.setIcon(FluentIcon.ACCEPT)
|
||||
self.Label.setTextColor("#0eb840", "#0eb840")
|
||||
elif status == "等待":
|
||||
self.icon.setIcon(FluentIcon.MORE)
|
||||
self.Label.setTextColor("#7397ab", "#7397ab")
|
||||
elif status == "运行":
|
||||
self.icon.setIcon(FluentIcon.PLAY)
|
||||
self.Label.setTextColor("#2e4e7e", "#2e4e7e")
|
||||
elif status == "跳过":
|
||||
self.icon.setIcon(FluentIcon.REMOVE)
|
||||
self.Label.setTextColor("#606060", "#d2d2d2")
|
||||
elif status == "异常":
|
||||
self.icon.setIcon(FluentIcon.CLOSE)
|
||||
self.Label.setTextColor("#ff2121", "#ff2121")
|
||||
169
app/ui/else.py
169
app/ui/else.py
@@ -75,7 +75,7 @@ class Main(QWidget):
|
||||
|
||||
# self.run_now: PushButton = self.ui.findChild(PushButton, "pushButton_runnow")
|
||||
# self.run_now.setIcon(FluentIcon.PLAY)
|
||||
# self.run_now.clicked.connect(lambda: self.maa_starter("日常代理"))
|
||||
# self.run_now.clicked.connect(lambda: self.maa_starter("自动代理"))
|
||||
|
||||
# self.check_start: PushButton = self.ui.findChild(
|
||||
# PushButton, "pushButton_checkstart"
|
||||
@@ -182,7 +182,7 @@ class Main(QWidget):
|
||||
self.MaaManager.update_user_info.connect(self.change_user_info)
|
||||
self.MaaManager.push_notification.connect(self.notify.push_notification)
|
||||
self.MaaManager.send_mail.connect(self.notify.send_mail)
|
||||
self.MaaManager.accomplish.connect(lambda: self.maa_ender("日常代理_结束"))
|
||||
self.MaaManager.accomplish.connect(lambda: self.maa_ender("自动代理_结束"))
|
||||
self.MaaManager.get_json.connect(self.get_maa_config)
|
||||
self.MaaManager.set_silence.connect(self.switch_silence)
|
||||
|
||||
@@ -199,7 +199,7 @@ class Main(QWidget):
|
||||
|
||||
# 启动后直接开始代理
|
||||
if self.config.content["Default"]["SelfSet.IfProxyDirectly"] == "True":
|
||||
self.maa_starter("日常代理")
|
||||
self.maa_starter("自动代理")
|
||||
|
||||
|
||||
|
||||
@@ -275,39 +275,7 @@ class Main(QWidget):
|
||||
# self.start_time[i][1].setTime(time)
|
||||
# self.if_update_config = True
|
||||
|
||||
def update_board(self, run_text, wait_text, over_text, error_text, log_text):
|
||||
"""写入数据至GUI执行界面的调度台面板"""
|
||||
|
||||
self.run_text.setPlainText(run_text)
|
||||
self.wait_text.setPlainText(wait_text)
|
||||
self.over_text.setPlainText(over_text)
|
||||
self.error_text.setPlainText(error_text)
|
||||
self.log_text.setPlainText(log_text)
|
||||
self.log_text.verticalScrollBar().setValue(
|
||||
self.log_text.verticalScrollBar().maximum()
|
||||
)
|
||||
|
||||
def change_user_info(self, modes, uids, days, lasts, notes, numbs):
|
||||
"""将代理完成后发生改动的用户信息同步至本地数据库"""
|
||||
|
||||
for index in range(len(uids)):
|
||||
self.config.cur.execute(
|
||||
"UPDATE adminx SET day = ? WHERE mode = ? AND uid = ?",
|
||||
(days[index], modes[index], uids[index]),
|
||||
)
|
||||
self.config.cur.execute(
|
||||
"UPDATE adminx SET last = ? WHERE mode = ? AND uid = ?",
|
||||
(lasts[index], modes[index], uids[index]),
|
||||
)
|
||||
self.config.cur.execute(
|
||||
"UPDATE adminx SET notes = ? WHERE mode = ? AND uid = ?",
|
||||
(notes[index], modes[index], uids[index]),
|
||||
)
|
||||
self.config.cur.execute(
|
||||
"UPDATE adminx SET numb = ? WHERE mode = ? AND uid = ?",
|
||||
(numbs[index], modes[index], uids[index]),
|
||||
)
|
||||
self.config.db.commit()
|
||||
|
||||
# 同步用户信息更改至GUI
|
||||
self.update_user_info("normal")
|
||||
@@ -431,115 +399,7 @@ class Main(QWidget):
|
||||
self.user_list_simple.setStyleSheet("QTableWidget::item {}")
|
||||
self.user_list_beta.setStyleSheet("QTableWidget::item {}")
|
||||
|
||||
def read(self, operation):
|
||||
"""弹出对话框组件进行读入"""
|
||||
|
||||
class InputMessageBox(MessageBoxBase):
|
||||
"""输入对话框"""
|
||||
|
||||
def __init__(self, parent, title: str, content: str, mode: str):
|
||||
super().__init__(parent)
|
||||
self.title = SubtitleLabel(title)
|
||||
|
||||
if mode == "明文":
|
||||
self.input = LineEdit()
|
||||
elif mode == "密码":
|
||||
self.input = PasswordLineEdit()
|
||||
|
||||
self.input.setPlaceholderText(content)
|
||||
self.input.setClearButtonEnabled(True)
|
||||
|
||||
# 将组件添加到布局中
|
||||
self.viewLayout.addWidget(self.title)
|
||||
self.viewLayout.addWidget(self.input)
|
||||
|
||||
# 读入PASSWORD
|
||||
if operation == "key":
|
||||
|
||||
choice = InputMessageBox(self.ui, "请输入管理密钥", "管理密钥", "密码")
|
||||
if choice.exec() and choice.input.text() != "":
|
||||
self.PASSWORD = choice.input.text()
|
||||
self.update_user_info("normal")
|
||||
|
||||
elif operation == "oldkey":
|
||||
|
||||
choice = InputMessageBox(
|
||||
self.ui, "请输入旧的管理密钥", "旧管理密钥", "密码"
|
||||
)
|
||||
if choice.exec() and choice.input.text() != "":
|
||||
self.PASSWORD = choice.input.text()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
elif operation == "newkey":
|
||||
|
||||
choice = InputMessageBox(
|
||||
self.ui, "请输入新的管理密钥", "新管理密钥", "密码"
|
||||
)
|
||||
if choice.exec() and choice.input.text() != "":
|
||||
return choice.input.text()
|
||||
else:
|
||||
return None
|
||||
|
||||
elif operation == "setkey":
|
||||
|
||||
choice = InputMessageBox(
|
||||
self.ui,
|
||||
"未检测到管理密钥,请设置您的管理密钥",
|
||||
"管理密钥",
|
||||
"密码",
|
||||
)
|
||||
if choice.exec() and choice.input.text() != "":
|
||||
self.PASSWORD = choice.input.text()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
# 读入选择
|
||||
elif operation == "question_runner":
|
||||
choice = MessageBox(
|
||||
self.MaaManager.question_title,
|
||||
self.MaaManager.question_info,
|
||||
None,
|
||||
)
|
||||
if choice.exec():
|
||||
self.MaaManager.question_choice = "Yes"
|
||||
else:
|
||||
self.MaaManager.question_choice = "No"
|
||||
|
||||
# 读入MAA文件目录
|
||||
elif operation == "file_path_maa":
|
||||
file_path = QFileDialog.getExistingDirectory(self.ui, "选择MAA文件夹")
|
||||
if file_path:
|
||||
self.maa_path.setText(file_path)
|
||||
|
||||
# 读入自定义基建文件目录
|
||||
elif operation == "file_path_infrastructure":
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self.ui, "选择自定义基建文件", "", "JSON 文件 (*.json)"
|
||||
)
|
||||
return file_path
|
||||
|
||||
def timed_start(self):
|
||||
"""定时启动代理任务"""
|
||||
|
||||
# 获取定时列表
|
||||
time_set = [
|
||||
self.config.content["Default"][f"TimeSet.run{_ + 1}"]
|
||||
for _ in range(10)
|
||||
if self.config.content["Default"][f"TimeSet.set{_ + 1}"] == "True"
|
||||
]
|
||||
# 按时间调起代理任务
|
||||
curtime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
if (
|
||||
curtime[11:16] in time_set
|
||||
and curtime != self.last_time
|
||||
and not self.MaaManager.isRunning()
|
||||
):
|
||||
self.last_time = curtime
|
||||
self.maa_starter("日常代理")
|
||||
|
||||
|
||||
def switch_silence(self, mode, emulator_path, boss_key):
|
||||
"""切换静默模式"""
|
||||
|
||||
@@ -557,16 +417,7 @@ class Main(QWidget):
|
||||
self.Timer.timeout.connect(self.set_system)
|
||||
self.Timer.timeout.connect(self.timed_start)
|
||||
|
||||
def set_silence(self, emulator_path, boss_key):
|
||||
"""设置静默模式"""
|
||||
|
||||
windows = self.get_window_info()
|
||||
if any(emulator_path in _ for _ in windows):
|
||||
try:
|
||||
pyautogui.hotkey(*boss_key)
|
||||
except pyautogui.FailSafeException as e:
|
||||
# 执行日志记录,暂时缺省
|
||||
pass
|
||||
|
||||
|
||||
def maa_starter(self, mode):
|
||||
"""启动MaaManager线程运行任务"""
|
||||
@@ -620,14 +471,14 @@ class Main(QWidget):
|
||||
|
||||
self.update_user_info("read_only")
|
||||
|
||||
if mode == "日常代理_开始":
|
||||
if mode == "自动代理_开始":
|
||||
self.MaaManager.accomplish.connect(
|
||||
lambda: self.maa_ender("日常代理_结束")
|
||||
lambda: self.maa_ender("自动代理_结束")
|
||||
)
|
||||
self.check_start.setEnabled(False)
|
||||
self.run_now.clicked.disconnect()
|
||||
self.run_now.setText("结束运行")
|
||||
self.run_now.clicked.connect(lambda: self.maa_ender("日常代理_结束"))
|
||||
self.run_now.clicked.connect(lambda: self.maa_ender("自动代理_结束"))
|
||||
|
||||
elif mode == "人工排查_开始":
|
||||
self.MaaManager.accomplish.connect(
|
||||
@@ -660,12 +511,12 @@ class Main(QWidget):
|
||||
|
||||
self.update_user_info("editable")
|
||||
|
||||
if mode == "日常代理_结束":
|
||||
if mode == "自动代理_结束":
|
||||
|
||||
self.check_start.setEnabled(True)
|
||||
self.run_now.clicked.disconnect()
|
||||
self.run_now.setText("立即执行")
|
||||
self.run_now.clicked.connect(lambda: self.maa_starter("日常代理"))
|
||||
self.run_now.clicked.connect(lambda: self.maa_starter("自动代理"))
|
||||
|
||||
elif mode == "人工排查_结束":
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (
|
||||
QApplication,
|
||||
QSystemTrayIcon,
|
||||
@@ -41,18 +42,17 @@ from qfluentwidgets import (
|
||||
Theme,
|
||||
MSFluentWindow,
|
||||
NavigationItemPosition,
|
||||
qconfig,
|
||||
)
|
||||
from PySide6.QtUiTools import QUiLoader
|
||||
from PySide6.QtGui import QIcon, QCloseEvent
|
||||
from PySide6 import QtCore
|
||||
|
||||
uiLoader = QUiLoader()
|
||||
|
||||
from app import AppConfig
|
||||
from app.core import AppConfig, TaskManager, MainTimer, MainInfoBar
|
||||
from app.services import Notification, CryptoHandler, SystemHandler
|
||||
from .setting import Setting
|
||||
from .member_manager import MemberManager
|
||||
from .queue_manager import QueueManager
|
||||
from .dispatch_center import DispatchCenter
|
||||
|
||||
|
||||
class AUTO_MAA(MSFluentWindow):
|
||||
@@ -81,10 +81,16 @@ class AUTO_MAA(MSFluentWindow):
|
||||
self.splashScreen = SplashScreen(self.windowIcon(), self)
|
||||
self.show_ui("显示主窗口", if_quick=True)
|
||||
|
||||
MainInfoBar.parent = self
|
||||
|
||||
self.task_manager = TaskManager(self.config, self.notify)
|
||||
self.main_timer = MainTimer(self.config, self.system, self.task_manager, self)
|
||||
|
||||
# 创建主窗口
|
||||
self.setting = Setting(self.config, self.notify, self.crypto, self.system, self)
|
||||
self.member_manager = MemberManager(self.config, self.notify, self.crypto, self)
|
||||
self.queue_manager = QueueManager(self.config, self.notify, self)
|
||||
self.dispatch_center = DispatchCenter(self.config, self.task_manager, self)
|
||||
|
||||
self.addSubInterface(
|
||||
self.setting,
|
||||
@@ -107,9 +113,31 @@ class AUTO_MAA(MSFluentWindow):
|
||||
FluentIcon.BOOK_SHELF,
|
||||
NavigationItemPosition.TOP,
|
||||
)
|
||||
self.addSubInterface(
|
||||
self.dispatch_center,
|
||||
FluentIcon.IOT,
|
||||
"调度中心",
|
||||
FluentIcon.IOT,
|
||||
NavigationItemPosition.TOP,
|
||||
)
|
||||
self.stackedWidget.currentChanged.connect(
|
||||
lambda index: (self.member_manager.refresh() if index == 1 else None)
|
||||
)
|
||||
self.stackedWidget.currentChanged.connect(
|
||||
lambda index: self.queue_manager.refresh() if index == 2 else None
|
||||
)
|
||||
self.stackedWidget.currentChanged.connect(
|
||||
lambda index: (
|
||||
self.dispatch_center.pivot.setCurrentItem("主调度台")
|
||||
if index == 3
|
||||
else None
|
||||
)
|
||||
)
|
||||
self.stackedWidget.currentChanged.connect(
|
||||
lambda index: (
|
||||
self.dispatch_center.update_top_bar() if index == 3 else None
|
||||
)
|
||||
)
|
||||
|
||||
# 创建系统托盘及其菜单
|
||||
self.tray = QSystemTrayIcon(
|
||||
@@ -134,8 +162,8 @@ class AUTO_MAA(MSFluentWindow):
|
||||
# [
|
||||
# Action(
|
||||
# FluentIcon.PLAY,
|
||||
# "运行日常代理",
|
||||
# triggered=lambda: self.start_task("日常代理"),
|
||||
# "运行自动代理",
|
||||
# triggered=lambda: self.start_task("自动代理"),
|
||||
# ),
|
||||
# Action(
|
||||
# FluentIcon.PLAY,
|
||||
@@ -156,6 +184,7 @@ class AUTO_MAA(MSFluentWindow):
|
||||
self.tray.setContextMenu(self.tray_menu)
|
||||
self.tray.activated.connect(self.on_tray_activated)
|
||||
|
||||
self.task_manager.create_gui.connect(self.dispatch_center.add_board)
|
||||
self.setting.ui.card_IfShowTray.checkedChanged.connect(
|
||||
lambda: self.show_ui("配置托盘")
|
||||
)
|
||||
@@ -166,22 +195,17 @@ class AUTO_MAA(MSFluentWindow):
|
||||
def start_up_task(self) -> None:
|
||||
"""启动时任务"""
|
||||
|
||||
# 加载配置
|
||||
qconfig.load(self.config.config_path, self.config.global_config)
|
||||
|
||||
# 检查密码
|
||||
self.setting.check_PASSWORD()
|
||||
|
||||
# 检查更新
|
||||
if self.config.global_config.get(self.config.global_config.update_IfAutoUpdate):
|
||||
result = self.setting.check_update()
|
||||
result = self.setting.get_update_info()
|
||||
if result == "已是最新版本~":
|
||||
InfoBar.success(
|
||||
title="更新检查",
|
||||
content=result,
|
||||
orient=QtCore.Qt.Horizontal,
|
||||
isClosable=True,
|
||||
position=InfoBarPosition.TOP_RIGHT,
|
||||
duration=3000,
|
||||
parent=self,
|
||||
)
|
||||
MainInfoBar.push_info_bar("success", "更新检查", result, 3000)
|
||||
else:
|
||||
info = InfoBar.info(
|
||||
title="更新检查",
|
||||
@@ -193,9 +217,7 @@ class AUTO_MAA(MSFluentWindow):
|
||||
parent=self,
|
||||
)
|
||||
Up = PushButton("更新")
|
||||
Up.clicked.connect(
|
||||
lambda: self.setting.check_version(if_question=False)
|
||||
)
|
||||
Up.clicked.connect(lambda: self.setting.get_update(if_question=False))
|
||||
Up.clicked.connect(info.close)
|
||||
info.addWidget(Up)
|
||||
info.show()
|
||||
@@ -234,7 +256,7 @@ class AUTO_MAA(MSFluentWindow):
|
||||
# """中止当前任务"""
|
||||
# if self.main.MaaManager.isRunning():
|
||||
# if (
|
||||
# self.main.MaaManager.mode == "日常代理"
|
||||
# self.main.MaaManager.mode == "自动代理"
|
||||
# or self.main.MaaManager.mode == "人工排查"
|
||||
# ):
|
||||
# self.main.maa_ender(f"{self.main.MaaManager.mode}_结束")
|
||||
|
||||
@@ -24,7 +24,7 @@ AUTO_MAA脚本管理界面
|
||||
v4.2
|
||||
作者:DLmaster_361
|
||||
"""
|
||||
|
||||
from loguru import logger
|
||||
from PySide6.QtWidgets import (
|
||||
QWidget,
|
||||
QFileDialog,
|
||||
@@ -49,17 +49,15 @@ from qfluentwidgets import (
|
||||
ExpandGroupSettingCard,
|
||||
PushSettingCard,
|
||||
)
|
||||
from PySide6.QtUiTools import QUiLoader
|
||||
from PySide6 import QtCore
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import datetime
|
||||
import json
|
||||
import shutil
|
||||
|
||||
uiLoader = QUiLoader()
|
||||
|
||||
from app import AppConfig, MaaConfig
|
||||
from app.core import AppConfig, MaaConfig, MainInfoBar
|
||||
from app.services import Notification, CryptoHandler
|
||||
from .Widget import (
|
||||
InputMessageBox,
|
||||
@@ -315,6 +313,15 @@ class MemberManager(QWidget):
|
||||
with json_file.open("w", encoding="utf-8") as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=4)
|
||||
|
||||
def refresh(self):
|
||||
"""刷新脚本实例界面"""
|
||||
|
||||
if len(self.member_manager.search_member()) == 0:
|
||||
index = 0
|
||||
else:
|
||||
index = int(self.member_manager.pivot.currentRouteKey()[3:])
|
||||
self.member_manager.switch_SettingBox(index)
|
||||
|
||||
|
||||
class MemberSettingBox(QWidget):
|
||||
|
||||
@@ -444,7 +451,7 @@ class MaaSettingBox(QWidget):
|
||||
content_widget = QWidget()
|
||||
content_layout = QVBoxLayout(content_widget)
|
||||
|
||||
self.app_setting = self.AppSettingCard(self, self.config.maa_config)
|
||||
self.app_setting = self.AppSettingCard(self, self.config, uid)
|
||||
self.user_setting = self.UserSettingCard(
|
||||
self, self.objectName(), self.config, self.crypto
|
||||
)
|
||||
@@ -461,12 +468,13 @@ class MaaSettingBox(QWidget):
|
||||
|
||||
class AppSettingCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, parent=None, maa_config: MaaConfig = None):
|
||||
def __init__(self, parent=None, config: AppConfig = None, uid: int = None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setTitle("MAA实例")
|
||||
|
||||
self.maa_config = maa_config
|
||||
self.config = config
|
||||
self.uid = uid
|
||||
|
||||
Layout = QVBoxLayout()
|
||||
|
||||
@@ -475,13 +483,13 @@ class MaaSettingBox(QWidget):
|
||||
FluentIcon.EDIT,
|
||||
"实例名称",
|
||||
"用于标识MAA实例的名称",
|
||||
self.maa_config.MaaSet_Name,
|
||||
self.config.maa_config.MaaSet_Name,
|
||||
)
|
||||
self.card_Path = PushSettingCard(
|
||||
"选择文件夹",
|
||||
FluentIcon.FOLDER,
|
||||
"MAA目录",
|
||||
self.maa_config.get(self.maa_config.MaaSet_Path),
|
||||
self.config.maa_config.get(self.config.maa_config.MaaSet_Path),
|
||||
)
|
||||
self.card_Set = PushSettingCard(
|
||||
"设置",
|
||||
@@ -489,9 +497,14 @@ class MaaSettingBox(QWidget):
|
||||
"MAA全局配置",
|
||||
"简洁模式下MAA将继承全局配置",
|
||||
)
|
||||
self.RunSet = self.RunSetSettingCard(self, self.maa_config)
|
||||
self.RunSet = self.RunSetSettingCard(self, self.config.maa_config)
|
||||
|
||||
self.card_Path.clicked.connect(self.PathClicked)
|
||||
self.config.maa_config.MaaSet_Path.valueChanged.connect(
|
||||
lambda: self.card_Path.setContent(
|
||||
self.config.maa_config.get(self.config.maa_config.MaaSet_Path)
|
||||
)
|
||||
)
|
||||
|
||||
Layout.addWidget(self.card_Name)
|
||||
Layout.addWidget(self.card_Path)
|
||||
@@ -503,9 +516,35 @@ class MaaSettingBox(QWidget):
|
||||
def PathClicked(self):
|
||||
|
||||
folder = QFileDialog.getExistingDirectory(self, "选择MAA目录", "./")
|
||||
if not folder or self.maa_config.get(self.maa_config.MaaSet_Path) == folder:
|
||||
return
|
||||
self.maa_config.set(self.maa_config.MaaSet_Path, folder)
|
||||
if (
|
||||
not folder
|
||||
or self.config.maa_config.get(self.config.maa_config.MaaSet_Path)
|
||||
== folder
|
||||
):
|
||||
logger.warning("选择MAA目录时未选择文件夹或未更改文件夹")
|
||||
MainInfoBar.push_info_bar(
|
||||
"warning", "警告", "未选择文件夹或未更改文件夹", 5000
|
||||
)
|
||||
return None
|
||||
elif (
|
||||
not (Path(folder) / "config/gui.json").exists()
|
||||
or not (Path(folder) / "MAA.exe").exists()
|
||||
):
|
||||
logger.warning("选择MAA目录时未找到MAA程序或配置文件")
|
||||
MainInfoBar.push_info_bar(
|
||||
"warning", "警告", "未找到MAA程序或配置文件", 5000
|
||||
)
|
||||
return None
|
||||
|
||||
(self.config.app_path / f"config/MaaConfig/脚本_{self.uid}/Default").mkdir(
|
||||
parents=True, exist_ok=True
|
||||
)
|
||||
shutil.copy(
|
||||
Path(folder) / "config/gui.json",
|
||||
self.config.app_path
|
||||
/ f"config/MaaConfig/脚本_{self.uid}/Default/gui.json",
|
||||
)
|
||||
self.config.maa_config.set(self.config.maa_config.MaaSet_Path, folder)
|
||||
self.card_Path.setContent(folder)
|
||||
|
||||
class RunSetSettingCard(ExpandGroupSettingCard):
|
||||
@@ -534,7 +573,7 @@ class MaaSettingBox(QWidget):
|
||||
self.RoutineTimeLimit = SpinBoxSettingCard(
|
||||
(1, 1024),
|
||||
FluentIcon.PAGE_RIGHT,
|
||||
"日常代理超时限制",
|
||||
"自动代理超时限制",
|
||||
"MAA日志无变化时间超过该阈值视为超时,单位为分钟",
|
||||
self.maa_config.RunSet_RoutineTimeLimit,
|
||||
)
|
||||
|
||||
@@ -39,6 +39,7 @@ from qfluentwidgets import (
|
||||
FluentIcon,
|
||||
MessageBox,
|
||||
HeaderCardWidget,
|
||||
TextBrowser,
|
||||
CommandBar,
|
||||
setTheme,
|
||||
Theme,
|
||||
@@ -52,7 +53,7 @@ import shutil
|
||||
|
||||
uiLoader = QUiLoader()
|
||||
|
||||
from app import AppConfig, QueueConfig
|
||||
from app.core import AppConfig, QueueConfig
|
||||
from app.services import Notification
|
||||
from .Widget import (
|
||||
LineEditSettingCard,
|
||||
@@ -143,9 +144,9 @@ class QueueManager(QWidget):
|
||||
if choice.exec():
|
||||
|
||||
queue_list = self.queue_manager.search_queue()
|
||||
move_list = [_ for _ in queue_list if int(_[0][3:]) > int(name[3:])]
|
||||
move_list = [_ for _ in queue_list if int(_[0][5:]) > int(name[5:])]
|
||||
|
||||
index = max(int(name[3:]) - 1, 1)
|
||||
index = max(int(name[5:]) - 1, 1)
|
||||
|
||||
self.queue_manager.clear_SettingBox()
|
||||
|
||||
@@ -249,7 +250,7 @@ class QueueSettingBox(QWidget):
|
||||
self.Layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.pivot.currentItemChanged.connect(
|
||||
lambda index: self.switch_SettingBox(int(index[5:]), if_chang_pivot=False)
|
||||
lambda index: self.switch_SettingBox(int(index[5:]), if_change_pivot=False)
|
||||
)
|
||||
|
||||
self.show_SettingBox(1)
|
||||
@@ -271,7 +272,7 @@ class QueueSettingBox(QWidget):
|
||||
|
||||
self.switch_SettingBox(index)
|
||||
|
||||
def switch_SettingBox(self, index: int, if_chang_pivot: bool = True) -> None:
|
||||
def switch_SettingBox(self, index: int, if_change_pivot: bool = True) -> None:
|
||||
"""切换到指定的子界面"""
|
||||
|
||||
queue_list = self.search_queue()
|
||||
@@ -288,7 +289,7 @@ class QueueSettingBox(QWidget):
|
||||
self.config.queue_config,
|
||||
)
|
||||
|
||||
if if_chang_pivot:
|
||||
if if_change_pivot:
|
||||
self.pivot.setCurrentItem(self.script_list[index - 1].objectName())
|
||||
self.stackedWidget.setCurrentWidget(self.script_list[index - 1])
|
||||
|
||||
@@ -355,10 +356,12 @@ class QueueMemberSettingBox(QWidget):
|
||||
self.queue_set = self.QueueSetSettingCard(self, self.config.queue_config)
|
||||
self.time = self.TimeSettingCard(self, self.config.queue_config)
|
||||
self.task = self.TaskSettingCard(self, self.config)
|
||||
self.history = self.HistoryCard(self, self.config, f"调度队列_{uid}")
|
||||
|
||||
content_layout.addWidget(self.queue_set)
|
||||
content_layout.addWidget(self.time)
|
||||
content_layout.addWidget(self.task)
|
||||
content_layout.addWidget(self.history)
|
||||
content_layout.addStretch(1)
|
||||
|
||||
scrollArea.setWidget(content_widget)
|
||||
@@ -498,36 +501,6 @@ class QueueMemberSettingBox(QWidget):
|
||||
|
||||
self.viewLayout.addLayout(Layout)
|
||||
|
||||
class QueueSetSettingCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, parent=None, queue_config: QueueConfig = None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setTitle("队列设置")
|
||||
|
||||
self.queue_config = queue_config
|
||||
|
||||
Layout = QVBoxLayout()
|
||||
|
||||
self.card_Name = LineEditSettingCard(
|
||||
"请输入调度队列名称",
|
||||
FluentIcon.EDIT,
|
||||
"调度队列名称",
|
||||
"用于标识调度队列的名称",
|
||||
self.queue_config.queueSet_Name,
|
||||
)
|
||||
self.card_Enable = SwitchSettingCard(
|
||||
FluentIcon.HOME,
|
||||
"状态",
|
||||
"调度队列状态",
|
||||
self.queue_config.queueSet_Enabled,
|
||||
)
|
||||
|
||||
Layout.addWidget(self.card_Name)
|
||||
Layout.addWidget(self.card_Enable)
|
||||
|
||||
self.viewLayout.addLayout(Layout)
|
||||
|
||||
class TaskSettingCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, parent=None, config: AppConfig = None):
|
||||
@@ -656,3 +629,18 @@ class QueueMemberSettingBox(QWidget):
|
||||
member_list_text.append(subdir.name)
|
||||
|
||||
return [member_list_name, member_list_text]
|
||||
|
||||
class HistoryCard(HeaderCardWidget):
|
||||
|
||||
def __init__(self, parent=None, config: AppConfig = None, name: str = None):
|
||||
super().__init__(parent)
|
||||
self.setTitle("历史运行记录")
|
||||
|
||||
self.config = config
|
||||
|
||||
self.text = TextBrowser()
|
||||
self.text.setMinimumHeight(300)
|
||||
history = self.config.get_history(name)
|
||||
self.text.setPlainText(history["History"])
|
||||
|
||||
self.viewLayout.addWidget(self.text)
|
||||
|
||||
@@ -36,9 +36,8 @@ from qfluentwidgets import (
|
||||
setTheme,
|
||||
Theme,
|
||||
MessageBox,
|
||||
Dialog,
|
||||
HeaderCardWidget,
|
||||
InfoBar,
|
||||
InfoBarPosition,
|
||||
SwitchSettingCard,
|
||||
ExpandGroupSettingCard,
|
||||
PushSettingCard,
|
||||
@@ -52,7 +51,7 @@ import requests
|
||||
|
||||
uiLoader = QUiLoader()
|
||||
|
||||
from app import AppConfig
|
||||
from app.core import AppConfig, MainInfoBar
|
||||
from app.services import Notification, CryptoHandler, SystemHandler
|
||||
from app.utils import Updater, version_text
|
||||
from .Widget import InputMessageBox, LineEditSettingCard
|
||||
@@ -98,7 +97,7 @@ class Setting(QWidget):
|
||||
self.function.card_IfAllowSleep.checkedChanged.connect(self.system.set_Sleep)
|
||||
self.start.card_IfSelfStart.checkedChanged.connect(self.system.set_SelfStart)
|
||||
self.security.card_changePASSWORD.clicked.connect(self.change_PASSWORD)
|
||||
self.updater.card_CheckUpdate.clicked.connect(self.check_version)
|
||||
self.updater.card_CheckUpdate.clicked.connect(self.get_update)
|
||||
self.other.card_Tips.clicked.connect(self.show_tips)
|
||||
|
||||
content_layout.addWidget(self.function)
|
||||
@@ -258,7 +257,7 @@ class Setting(QWidget):
|
||||
if choice.exec():
|
||||
break
|
||||
|
||||
def check_update(self) -> str:
|
||||
def get_update_info(self) -> str:
|
||||
"""检查主程序版本更新,返回更新信息"""
|
||||
|
||||
# 从本地版本信息文件获取当前版本信息
|
||||
@@ -294,7 +293,7 @@ class Setting(QWidget):
|
||||
else:
|
||||
return "已是最新版本~"
|
||||
|
||||
def check_version(self, if_question: bool = True) -> None:
|
||||
def get_update(self, if_question: bool = True) -> None:
|
||||
"""检查版本更新,调起文件下载进程"""
|
||||
|
||||
# 从本地版本信息文件获取当前版本信息
|
||||
@@ -387,15 +386,7 @@ class Setting(QWidget):
|
||||
|
||||
# 无版本更新
|
||||
else:
|
||||
InfoBar.success(
|
||||
title="更新检查",
|
||||
content="已是最新版本~",
|
||||
orient=QtCore.Qt.Horizontal,
|
||||
isClosable=True,
|
||||
position=InfoBarPosition.TOP_RIGHT,
|
||||
duration=3000,
|
||||
parent=self,
|
||||
)
|
||||
MainInfoBar.push_info_bar("success", "更新检查", "已是最新版本~", 3000)
|
||||
|
||||
def update_main(self):
|
||||
"""更新主程序"""
|
||||
@@ -411,7 +402,7 @@ class Setting(QWidget):
|
||||
def show_tips(self):
|
||||
"""显示小贴士"""
|
||||
|
||||
choice = MessageBox("小贴士", "这里什么都没有~", self)
|
||||
choice = Dialog("小贴士", "这里什么都没有~", self)
|
||||
choice.cancelButton.hide()
|
||||
choice.buttonLayout.insertStretch(1)
|
||||
if choice.exec():
|
||||
|
||||
BIN
app/utils/__pycache__/Updater.cpython-312.pyc
Normal file
BIN
app/utils/__pycache__/Updater.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/utils/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
app/utils/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
app/utils/__pycache__/version.cpython-312.pyc
Normal file
BIN
app/utils/__pycache__/version.cpython-312.pyc
Normal file
Binary file not shown.
Reference in New Issue
Block a user