feat(core):初步完成定时执行功能开发
This commit is contained in:
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.
411
app/core/config.py
Normal file
411
app/core/config.py
Normal file
@@ -0,0 +1,411 @@
|
||||
# <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
|
||||
import sqlite3
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, Union
|
||||
from qfluentwidgets import (
|
||||
QConfig,
|
||||
ConfigItem,
|
||||
qconfig,
|
||||
OptionsConfigItem,
|
||||
RangeConfigItem,
|
||||
FolderValidator,
|
||||
BoolValidator,
|
||||
RangeValidator,
|
||||
)
|
||||
|
||||
|
||||
class AppConfig:
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
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
|
||||
|
||||
# 检查文件完整性
|
||||
self.initialize()
|
||||
|
||||
def initialize(self) -> None:
|
||||
"""初始化程序的配置文件"""
|
||||
|
||||
# 检查目录
|
||||
(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)
|
||||
|
||||
# 生成版本信息文件
|
||||
if not self.version_path.exists():
|
||||
version = {
|
||||
"main_version": "0.0.0.0",
|
||||
"updater_version": "0.0.0.0",
|
||||
}
|
||||
with self.version_path.open(mode="w", encoding="utf-8") as f:
|
||||
json.dump(version, f, indent=4)
|
||||
|
||||
# 生成预设gameid替换方案文件
|
||||
if not self.gameid_path.exists():
|
||||
self.gameid_path.write_text(
|
||||
"龙门币:CE-6\n技能:CA-5\n红票:AP-5\n经验:LS-6\n剿灭模式:Annihilation",
|
||||
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()
|
||||
self.queue_config = QueueConfig()
|
||||
self.maa_config = MaaConfig()
|
||||
|
||||
logger.info("配置类初始化完成")
|
||||
|
||||
def init_database(self, mode: str) -> None:
|
||||
"""初始化用户数据库"""
|
||||
|
||||
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)"
|
||||
)
|
||||
self.cur.execute("CREATE TABLE version(v text)")
|
||||
self.cur.execute("INSERT INTO version VALUES(?)", ("v1.3",))
|
||||
self.db.commit()
|
||||
|
||||
logger.info("用户数据库初始化完成")
|
||||
|
||||
def check_database(self) -> None:
|
||||
"""检查用户数据库文件并处理数据库版本更新"""
|
||||
|
||||
# 生成用户数据库
|
||||
if not self.database_path.exists():
|
||||
db = sqlite3.connect(self.database_path)
|
||||
cur = db.cursor()
|
||||
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)"
|
||||
)
|
||||
cur.execute("CREATE TABLE version(v text)")
|
||||
cur.execute("INSERT INTO version VALUES(?)", ("v1.3",))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
|
||||
# 数据库版本更新
|
||||
db = sqlite3.connect(self.database_path)
|
||||
cur = db.cursor()
|
||||
cur.execute("SELECT * FROM version WHERE True")
|
||||
version = cur.fetchall()
|
||||
# v1.0-->v1.1
|
||||
if version[0][0] == "v1.0":
|
||||
cur.execute("SELECT * FROM adminx WHERE True")
|
||||
data = cur.fetchall()
|
||||
cur.execute("DROP TABLE IF EXISTS 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,routines text,annihilation text,infrastructure text,password byte,notes text,numb int,mode text,uid int)"
|
||||
)
|
||||
for i in range(len(data)):
|
||||
cur.execute(
|
||||
"INSERT INTO adminx VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||
(
|
||||
data[i][0], # 0 0 0
|
||||
data[i][1], # 1 1 -
|
||||
"Official", # 2 2 -
|
||||
data[i][2], # 3 3 1
|
||||
data[i][3], # 4 4 2
|
||||
data[i][4], # 5 5 3
|
||||
data[i][5], # 6 6 -
|
||||
data[i][6], # 7 7 -
|
||||
data[i][7], # 8 8 -
|
||||
"y", # 9 - 4
|
||||
data[i][8], # 10 9 5
|
||||
data[i][9], # 11 10 -
|
||||
data[i][10], # 12 11 6
|
||||
data[i][11], # 13 12 7
|
||||
data[i][12], # 14 - -
|
||||
"simple", # 15 - -
|
||||
data[i][13], # 16 - -
|
||||
),
|
||||
)
|
||||
cur.execute("DELETE FROM version WHERE v = ?", ("v1.0",))
|
||||
cur.execute("INSERT INTO version VALUES(?)", ("v1.1",))
|
||||
db.commit()
|
||||
# v1.1-->v1.2
|
||||
if version[0][0] == "v1.1":
|
||||
cur.execute("SELECT * FROM adminx WHERE True")
|
||||
data = cur.fetchall()
|
||||
for i in range(len(data)):
|
||||
cur.execute(
|
||||
"UPDATE adminx SET infrastructure = 'n' WHERE mode = ? AND uid = ?",
|
||||
(
|
||||
data[i][15],
|
||||
data[i][16],
|
||||
),
|
||||
)
|
||||
cur.execute("DELETE FROM version WHERE v = ?", ("v1.1",))
|
||||
cur.execute("INSERT INTO version VALUES(?)", ("v1.2",))
|
||||
db.commit()
|
||||
# v1.2-->v1.3
|
||||
if version[0][0] == "v1.2":
|
||||
cur.execute("ALTER TABLE adminx RENAME COLUMN routines TO routine")
|
||||
cur.execute("DELETE FROM version WHERE v = ?", ("v1.2",))
|
||||
cur.execute("INSERT INTO version VALUES(?)", ("v1.3",))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
|
||||
def open_database(self, mode: str, index: str = None) -> None:
|
||||
"""打开数据库"""
|
||||
|
||||
self.close_database()
|
||||
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
|
||||
|
||||
def close_database(self) -> None:
|
||||
"""关闭数据库"""
|
||||
|
||||
if self.if_database_opened:
|
||||
self.cur.close()
|
||||
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配置"""
|
||||
|
||||
self.maa_config.set(self.maa_config.MaaSet_Name, "")
|
||||
self.maa_config.set(self.maa_config.MaaSet_Path, ".")
|
||||
self.maa_config.set(self.maa_config.RunSet_AnnihilationTimeLimit, 40)
|
||||
self.maa_config.set(self.maa_config.RunSet_RoutineTimeLimit, 10)
|
||||
self.maa_config.set(self.maa_config.RunSet_RunTimesLimit, 3)
|
||||
self.maa_config.set(self.maa_config.MaaSet_Name, "")
|
||||
self.maa_config.set(self.maa_config.MaaSet_Name, "")
|
||||
self.maa_config.set(self.maa_config.MaaSet_Name, "")
|
||||
|
||||
def clear_queue_config(self) -> None:
|
||||
"""清空队列配置"""
|
||||
|
||||
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.time_TimeEnabled_0, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_0, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_1, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_1, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_2, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_2, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_3, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_3, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_4, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_4, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_5, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_5, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_6, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_6, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_7, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_7, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_8, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_8, "00:00")
|
||||
self.queue_config.set(self.queue_config.time_TimeEnabled_9, False)
|
||||
self.queue_config.set(self.queue_config.time_TimeSet_9, "00:00")
|
||||
|
||||
self.queue_config.set(self.queue_config.queue_Member_1, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_2, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_3, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_4, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_5, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_6, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_7, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_8, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_9, "禁用")
|
||||
self.queue_config.set(self.queue_config.queue_Member_10, "禁用")
|
||||
|
||||
|
||||
class GlobalConfig(QConfig):
|
||||
"""全局配置"""
|
||||
|
||||
function_IfAllowSleep = ConfigItem(
|
||||
"Function", "IfAllowSleep", False, BoolValidator()
|
||||
)
|
||||
function_IfSilence = ConfigItem("Function", "IfSilence", False, BoolValidator())
|
||||
function_BossKey = ConfigItem("Function", "BossKey", "")
|
||||
|
||||
start_IfSelfStart = ConfigItem("Start", "IfSelfStart", False, BoolValidator())
|
||||
start_IfRunDirectly = ConfigItem("Start", "IfRunDirectly", False, BoolValidator())
|
||||
|
||||
ui_IfShowTray = ConfigItem("UI", "IfShowTray", False, BoolValidator())
|
||||
ui_IfToTray = ConfigItem("UI", "IfToTray", False, BoolValidator())
|
||||
ui_size = ConfigItem("UI", "size", "1200x700")
|
||||
ui_location = ConfigItem("UI", "location", "100x100")
|
||||
ui_maximized = ConfigItem("UI", "maximized", False, BoolValidator())
|
||||
ui_MainIndex = RangeConfigItem("UI", "MainIndex", 0, RangeValidator(0, 3))
|
||||
|
||||
notify_IfPushPlyer = ConfigItem("Notify", "IfPushPlyer", False, BoolValidator())
|
||||
notify_IfSendMail = ConfigItem("Notify", "IfSendMail", False, BoolValidator())
|
||||
notify_IfSendErrorOnly = ConfigItem(
|
||||
"Notify", "IfSendErrorOnly", False, BoolValidator()
|
||||
)
|
||||
notify_MailAddress = ConfigItem("Notify", "MailAddress", "")
|
||||
|
||||
update_IfAutoUpdate = ConfigItem("Update", "IfAutoUpdate", False, BoolValidator())
|
||||
|
||||
|
||||
class QueueConfig(QConfig):
|
||||
"""队列配置"""
|
||||
|
||||
queueSet_Name = ConfigItem("QueueSet", "Name", "")
|
||||
queueSet_Enabled = ConfigItem("QueueSet", "Enabled", False, BoolValidator())
|
||||
|
||||
time_TimeEnabled_0 = ConfigItem("Time", "TimeEnabled_0", False, BoolValidator())
|
||||
time_TimeSet_0 = ConfigItem("Time", "TimeSet_0", "00:00")
|
||||
|
||||
time_TimeEnabled_1 = ConfigItem("Time", "TimeEnabled_1", False, BoolValidator())
|
||||
time_TimeSet_1 = ConfigItem("Time", "TimeSet_1", "00:00")
|
||||
|
||||
time_TimeEnabled_2 = ConfigItem("Time", "TimeEnabled_2", False, BoolValidator())
|
||||
time_TimeSet_2 = ConfigItem("Time", "TimeSet_2", "00:00")
|
||||
|
||||
time_TimeEnabled_3 = ConfigItem("Time", "TimeEnabled_3", False, BoolValidator())
|
||||
time_TimeSet_3 = ConfigItem("Time", "TimeSet_3", "00:00")
|
||||
|
||||
time_TimeEnabled_4 = ConfigItem("Time", "TimeEnabled_4", False, BoolValidator())
|
||||
time_TimeSet_4 = ConfigItem("Time", "TimeSet_4", "00:00")
|
||||
|
||||
time_TimeEnabled_5 = ConfigItem("Time", "TimeEnabled_5", False, BoolValidator())
|
||||
time_TimeSet_5 = ConfigItem("Time", "TimeSet_5", "00:00")
|
||||
|
||||
time_TimeEnabled_6 = ConfigItem("Time", "TimeEnabled_6", False, BoolValidator())
|
||||
time_TimeSet_6 = ConfigItem("Time", "TimeSet_6", "00:00")
|
||||
|
||||
time_TimeEnabled_7 = ConfigItem("Time", "TimeEnabled_7", False, BoolValidator())
|
||||
time_TimeSet_7 = ConfigItem("Time", "TimeSet_7", "00:00")
|
||||
|
||||
time_TimeEnabled_8 = ConfigItem("Time", "TimeEnabled_8", False, BoolValidator())
|
||||
time_TimeSet_8 = ConfigItem("Time", "TimeSet_8", "00:00")
|
||||
|
||||
time_TimeEnabled_9 = ConfigItem("Time", "TimeEnabled_9", False, BoolValidator())
|
||||
time_TimeSet_9 = ConfigItem("Time", "TimeSet_9", "00:00")
|
||||
|
||||
queue_Member_1 = OptionsConfigItem("Queue", "Member_1", "禁用")
|
||||
queue_Member_2 = OptionsConfigItem("Queue", "Member_2", "禁用")
|
||||
queue_Member_3 = OptionsConfigItem("Queue", "Member_3", "禁用")
|
||||
queue_Member_4 = OptionsConfigItem("Queue", "Member_4", "禁用")
|
||||
queue_Member_5 = OptionsConfigItem("Queue", "Member_5", "禁用")
|
||||
queue_Member_6 = OptionsConfigItem("Queue", "Member_6", "禁用")
|
||||
queue_Member_7 = OptionsConfigItem("Queue", "Member_7", "禁用")
|
||||
queue_Member_8 = OptionsConfigItem("Queue", "Member_8", "禁用")
|
||||
queue_Member_9 = OptionsConfigItem("Queue", "Member_9", "禁用")
|
||||
queue_Member_10 = OptionsConfigItem("Queue", "Member_10", "禁用")
|
||||
|
||||
|
||||
class MaaConfig(QConfig):
|
||||
"""MAA配置"""
|
||||
|
||||
MaaSet_Name = ConfigItem("MaaSet", "Name", "")
|
||||
MaaSet_Path = ConfigItem("MaaSet", "Path", ".", FolderValidator())
|
||||
|
||||
RunSet_AnnihilationTimeLimit = RangeConfigItem(
|
||||
"RunSet", "AnnihilationTimeLimit", 40, RangeValidator(1, 1024)
|
||||
)
|
||||
RunSet_RoutineTimeLimit = RangeConfigItem(
|
||||
"RunSet", "RoutineTimeLimit", 10, RangeValidator(1, 1024)
|
||||
)
|
||||
RunSet_RunTimesLimit = RangeConfigItem(
|
||||
"RunSet", "RunTimesLimit", 3, RangeValidator(1, 1024)
|
||||
)
|
||||
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
|
||||
Reference in New Issue
Block a user