Compare commits

...

22 Commits

Author SHA1 Message Date
DLmaster
c99707ecb4 Merge branch 'dev' 2025-02-17 18:09:42 +08:00
DLmaster
2b8e648fe6 Merge branch 'DLMS_dev' into dev 2025-02-17 18:08:45 +08:00
DLmaster
fcf61fd39a feat(core): 接入镜像源 2025-02-17 18:06:05 +08:00
DLmaster
8e3026f91e ci(build): 激活测试流程 2025-02-17 14:27:06 +08:00
DLmaster
8e00676faf ci(build): 测试服务器上传功能 2025-02-17 14:20:23 +08:00
DLmaster
ae293c4c20 Merge pull request #28 from ClozyA:dev
ci(build): 增加预发布版本服务器上传
2025-02-17 13:28:53 +08:00
df4a5f3318 ci(build): 增加预发布版本服务器上传 2025-02-17 12:02:03 +08:00
DLmaster
1da96c4d1d fix(ui): 矫正老板键文案 2025-02-17 11:06:07 +08:00
DLmaster
144c7f5db7 feat(modles): 配置MAA前关闭可能未正常退出的MAA进程 2025-02-16 18:44:46 +08:00
DLmaster
b3a3ccfea3 feat(core): 恢复启动后直接运行主任务功能以及相关托盘菜单 2025-02-16 14:56:25 +08:00
DLmaster
c3212f0ca1 Merge branch 'DLMS_dev' into dev 2025-02-15 17:32:47 +08:00
DLmaster
a946999782 fix: 修正版本号 2025-02-15 17:32:33 +08:00
DLmaster
284c41feb7 fix(ui): 适配深色模式 2025-02-15 17:28:54 +08:00
DLmaster
ddf905cb13 docs: 文档站试运行 2025-02-15 15:55:25 +08:00
DLmaster
d5082d18ef fix: 更正版本描述 2025-02-14 23:21:38 +08:00
DLmaster
af51831062 Merge branch 'DLMS_dev' into dev 2025-02-14 16:51:04 +08:00
DLmaster
fe4707df84 feat(ui): 优化主调度台默认选项 2025-02-14 16:50:45 +08:00
DLmaster
292e7f51e0 chore(core): 升级日志监看方法 2025-02-14 16:27:18 +08:00
DLmaster
8936b1c41d fix(core): 修复部分异常;添加高级代理文件校验过程 2025-02-13 13:03:44 +08:00
DLmaster
d45da439bd chore(models): 优化MAA关闭方法 2025-02-12 22:15:17 +08:00
DLmaster
7dc057e30f feat(models): 简洁用户列表下相邻两个任务间的切换方式 2025-02-12 22:06:04 +08:00
DLmaster
eb2f9d2cea fix(models): 修复静默代理标记移除异常情况 2025-02-11 13:47:12 +08:00
17 changed files with 576 additions and 345 deletions

View File

@@ -150,4 +150,13 @@ jobs:
gh release delete "$TAGNAME" --yes
gh release create "$TAGNAME" --target "main" --title "$NAME" --notes "$NOTES" artifacts/*
env:
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
- name: Setup SSH Key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts
- name: Upload Release to Server
run: |
scp -r artifacts/* ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }}:/home/user/files/AUTO_MAA/

View File

@@ -150,4 +150,13 @@ jobs:
gh release delete "$TAGNAME" --yes
gh release create "$TAGNAME" --target "main" --title "$NAME" --notes "$NOTES" --prerelease artifacts/*
env:
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
- name: Setup SSH Key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts
- name: Upload Release to Server
run: |
scp -r artifacts/* ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }}:/home/user/files/AUTO_MAA/

View File

@@ -58,9 +58,9 @@ MAA多账号管理与自动化软件
# 使用方法
本项目已改用腾讯文档展示使用方法
访问AUTO_MAA官方文档站以获取使用指南和项目相关信息
- [AUTO_MAA用户指南》](https://docs.qq.com/aio/DQ2NwUHRiWGtMWHBy)
- [AUTO_MAA官方文档站](https://clozya.github.io/AUTOMAA_docs)
---
@@ -82,6 +82,8 @@ MAA多账号管理与自动化软件
![Alt](https://repobeats.axiom.co/api/embed/6c2f834141eff1ac297db70d12bd11c6236a58a5.svg "Repobeats analytics image")
感谢 @ClozyA 为本项目提供的下载服务器
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=DLmaster361/AUTO_MAA&type=Date)](https://star-history.com/#DLmaster361/AUTO_MAA&Date)

View File

@@ -29,7 +29,7 @@ __version__ = "4.2.0"
__author__ = "DLmaster361 <DLmaster_361@163.com>"
__license__ = "GPL-3.0 license"
from .core import AppConfig, QueueConfig, MaaConfig, Task, Task_manager, Main_timer
from .core import AppConfig, QueueConfig, MaaConfig, Task, TaskManager, MainTimer
from .models import MaaManager
from .services import Notify, Crypto, System
from .ui import AUTO_MAA
@@ -40,8 +40,8 @@ __all__ = [
"QueueConfig",
"MaaConfig",
"Task",
"Task_manager",
"Main_timer",
"TaskManager",
"MainTimer",
"MaaManager",
"Notify",
"Crypto",

View File

@@ -31,8 +31,8 @@ __license__ = "GPL-3.0 license"
from .config import AppConfig, QueueConfig, MaaConfig, Config
from .main_info_bar import MainInfoBar
from .task_manager import Task, Task_manager
from .timer import Main_timer
from .task_manager import Task, TaskManager
from .timer import MainTimer
__all__ = [
"AppConfig",
@@ -41,6 +41,6 @@ __all__ = [
"MaaConfig",
"MainInfoBar",
"Task",
"Task_manager",
"Main_timer",
"TaskManager",
"MainTimer",
]

View File

@@ -488,6 +488,7 @@ class AppConfig:
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_TaskTransitionMethod, "ExitEmulator")
self.maa_config.set(self.maa_config.RunSet_ProxyTimesLimit, 0)
self.maa_config.set(self.maa_config.RunSet_AnnihilationTimeLimit, 40)
self.maa_config.set(self.maa_config.RunSet_RoutineTimeLimit, 10)
@@ -643,6 +644,12 @@ class MaaConfig(QConfig):
MaaSet_Name = ConfigItem("MaaSet", "Name", "")
MaaSet_Path = ConfigItem("MaaSet", "Path", ".", FolderValidator())
RunSet_TaskTransitionMethod = OptionsConfigItem(
"RunSet",
"TaskTransitionMethod",
"ExitEmulator",
OptionsValidator(["NoAction", "ExitGame", "ExitEmulator"]),
)
RunSet_ProxyTimesLimit = RangeConfigItem(
"RunSet", "ProxyTimesLimit", 0, RangeValidator(0, 1024)
)

View File

@@ -147,7 +147,7 @@ class Task(QThread):
)
)
self.task.accomplish.connect(
lambda log: self.save_log(self.task_dict[i][0], log)
lambda log: self.task_accomplish(self.task_dict[i][0], log)
)
self.task.run()
@@ -173,13 +173,14 @@ class Task(QThread):
return member_dict
def save_log(self, name: str, log: dict):
def task_accomplish(self, name: str, log: dict):
"""保存保存任务结果"""
self.logs.append([name, log])
self.task.deleteLater()
class TaskManager(QObject):
class _TaskManager(QObject):
"""业务调度器"""
create_gui = Signal(Task)
@@ -187,7 +188,7 @@ class TaskManager(QObject):
push_info_bar = Signal(str, str, str, int)
def __init__(self):
super(TaskManager, self).__init__()
super(_TaskManager, self).__init__()
self.task_dict: Dict[str, Task] = {}
@@ -252,6 +253,8 @@ class TaskManager(QObject):
logger.info(f"任务结束:{name}")
MainInfoBar.push_info_bar("info", "任务结束", name, 3000)
self.task_dict[name].deleteLater()
if len(logs) > 0:
time = logs[0][1]["Time"]
history = ""
@@ -290,4 +293,4 @@ class TaskManager(QObject):
self.task_dict[name].question_response.emit(bool(choice.exec_()))
Task_manager = TaskManager()
TaskManager = _TaskManager()

View File

@@ -33,11 +33,11 @@ from datetime import datetime
import pyautogui
from .config import Config
from .task_manager import Task_manager
from .task_manager import TaskManager
from app.services import System
class MainTimer(QWidget):
class _MainTimer(QWidget):
def __init__(
self,
@@ -81,7 +81,7 @@ class MainTimer(QWidget):
):
logger.info(f"定时任务:{name}")
Task_manager.add_task("自动代理_新调度台", name, info)
TaskManager.add_task("自动代理_新调度台", name, info)
def set_silence(self):
"""设置静默模式"""
@@ -125,4 +125,4 @@ class MainTimer(QWidget):
return queue_list
Main_timer = MainTimer()
MainTimer = _MainTimer()

View File

@@ -26,7 +26,7 @@ v4.2
"""
from loguru import logger
from PySide6.QtCore import QObject, Signal, QEventLoop
from PySide6.QtCore import QObject, Signal, QEventLoop, QFileSystemWatcher, QTimer
import json
import sqlite3
from datetime import datetime, timedelta
@@ -37,7 +37,7 @@ from pathlib import Path
from typing import List
from app.core import Config
from app.services import Notify
from app.services import Notify, System
class MaaManager(QObject):
@@ -50,6 +50,7 @@ class MaaManager(QObject):
create_user_list = Signal(list)
update_user_list = Signal(list)
update_log_text = Signal(str)
interrupt = Signal()
accomplish = Signal(dict)
isInterruptionRequested = False
@@ -65,6 +66,12 @@ class MaaManager(QObject):
self.mode = mode
self.config_path = config_path
self.user_config_path = user_config_path
self.log_monitor = QFileSystemWatcher()
self.log_monitor_timer = QTimer()
self.log_monitor_timer.timeout.connect(self.refresh_maa_log)
self.monitor_loop = QEventLoop()
self.interrupt.connect(self.quit_monitor)
with (self.config_path / "config.json").open("r", encoding="utf-8") as f:
self.set = json.load(f)
@@ -85,6 +92,7 @@ class MaaManager(QObject):
def configure(self):
"""提取配置信息"""
self.name = self.set["MaaSet"]["Name"]
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"
@@ -117,25 +125,27 @@ class MaaManager(QObject):
if "设置MAA" not in self.mode:
self.data = sorted(self.data, key=lambda x: (-len(x[15]), x[16]))
user_list: List[List[str, str, int]] = [
self.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)
self.create_user_list.emit(self.user_list)
# 自动代理模式
if self.mode == "自动代理":
# 标记是否需要重启模拟器
self.if_open_emulator = True
# 执行情况预处理
for _ in user_list:
for _ in self.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 user in user_list:
for user in self.user_list:
if self.isInterruptionRequested:
break
@@ -145,12 +155,14 @@ class MaaManager(QObject):
or self.data[user[2]][14] < self.set["RunSet"]["ProxyTimesLimit"]
):
user[1] = "运行"
self.update_user_list.emit(user_list)
self.update_user_list.emit(self.user_list)
else:
user[1] = "跳过"
self.update_user_list.emit(user_list)
self.update_user_list.emit(self.user_list)
continue
logger.info(f"{self.name} | 开始代理用户: {user[0]}")
# 初始化代理情况记录和模式替换记录
run_book = [False for _ in range(2)]
mode_book = ["自动代理_剿灭", "自动代理_日常"]
@@ -158,6 +170,11 @@ class MaaManager(QObject):
# 简洁模式用户默认开启日常选项
if self.data[user[2]][15] == "simple":
self.data[user[2]][9] = "y"
elif self.data[user[2]][15] == "beta":
check_book = [
[True, "annihilation", "剿灭"],
[True, "routine", "日常"],
]
# 尝试次数循环
for i in range(self.set["RunSet"]["RunTimesLimit"]):
@@ -165,6 +182,10 @@ class MaaManager(QObject):
if self.isInterruptionRequested:
break
logger.info(
f"{self.name} | 用户: {user[0]} - 尝试次数: {i + 1}/{self.set["RunSet"]["RunTimesLimit"]}"
)
# 剿灭-日常模式循环
for j in range(2):
@@ -177,6 +198,35 @@ class MaaManager(QObject):
if run_book[j]:
continue
logger.info(
f"{self.name} | 用户: {user[0]} - 模式: {mode_book[j]}"
)
if self.data[user[2]][15] == "beta":
self.if_open_emulator = True
if (
check_book[j][0]
and not (
self.config_path
/ f"beta/{self.data[user[2]][16]}/{check_book[j][1]}/gui.json"
).exists()
):
logger.error(
f"{self.name} | 用户: {user[0]} - 未找到{check_book[j][2]}配置文件"
)
self.push_info_bar.emit(
"error",
"启动MAA代理进程失败",
f"未找到{user[0]}{check_book[j][2]}配置文件!",
-1,
)
check_book[j][0] = False
continue
elif not check_book[j][0]:
continue
# 配置MAA
self.set_maa(mode_book[j], user[2])
# 记录当前时间
@@ -194,95 +244,48 @@ class MaaManager(QObject):
set["Configurations"]["Default"]["Start.EmulatorPath"]
)
Config.silence_list.append(self.emulator_path)
# 记录是否超时的标记
self.if_time_out = False
# 监测MAA运行状态
while not self.isInterruptionRequested:
self.start_monitor(start_time, mode_book[j])
# 获取MAA日志
logs = self.get_maa_log(start_time)
# 判断是否超时
if len(logs) > 0:
latest_time = datetime.now()
for _ in range(-1, 0 - len(logs) - 1, -1):
try:
latest_time = datetime.strptime(
logs[_][1:20], "%Y-%m-%d %H:%M:%S"
)
break
except ValueError:
pass
now_time = datetime.now()
if (
j == 0
and now_time - latest_time
> timedelta(
minutes=self.set["RunSet"][
"AnnihilationTimeLimit"
]
)
) or (
j == 1
and now_time - latest_time
> timedelta(
minutes=self.set["RunSet"]["RoutineTimeLimit"]
)
):
self.if_time_out = True
# 合并日志
log = "".join(logs)
# 更新MAA日志
if len(logs) > 100:
self.update_log_text.emit("".join(logs[-100:]))
else:
self.update_log_text.emit("".join(logs))
# 判断MAA程序运行状态
result = self.if_maa_success(log, mode_book[j])
if result == "Success!":
run_book[j] = True
self.update_log_text.emit(
"检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s"
)
# 移除静默进程标记
Config.silence_list.remove(self.emulator_path)
for _ in range(10):
if self.isInterruptionRequested:
break
time.sleep(1)
break
elif result == "Wait":
# 检测时间间隔
if self.maa_result == "Success!":
logger.info(
f"{self.name} | 用户: {user[0]} - MAA进程完成代理任务"
)
run_book[j] = True
self.update_log_text.emit(
"检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s"
)
for _ in range(10):
if self.isInterruptionRequested:
break
time.sleep(1)
else:
# 打印中止信息
# 此时log变量内存储的就是出现异常的日志信息可以保存或发送用于问题排查
self.update_log_text.emit(result)
# 无命令行中止MAA与其子程序
killprocess = subprocess.Popen(
f"taskkill /F /T /PID {maa.pid}",
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
killprocess.wait()
# 移除静默进程标记
Config.silence_list.remove(self.emulator_path)
# 推送异常通知
Notify.push_notification(
"用户自动代理出现异常",
f"用户 {user[0].replace("_", " 今天的")}{mode_book[j][5:7]}部分出现一次异常",
f"{user[0].replace("_", " ")}{mode_book[j][5:7]}出现异常",
1,
)
for _ in range(10):
if self.isInterruptionRequested:
break
time.sleep(1)
break
else:
logger.error(
f"{self.name} | 用户: {user[0]} - 代理任务异常: {self.maa_result}"
)
# 打印中止信息
# 此时log变量内存储的就是出现异常的日志信息可以保存或发送用于问题排查
self.update_log_text.emit(
f"{self.maa_result}\n正在中止相关程序\n请等待10s"
)
# 无命令行中止MAA与其子程序
System.kill_process(self.maa_exe_path)
self.if_open_emulator = True
# 推送异常通知
Notify.push_notification(
"用户自动代理出现异常!",
f"用户 {user[0].replace("_", " 今天的")}{mode_book[j][5:7]}部分出现一次异常",
f"{user[0].replace("_", " ")}{mode_book[j][5:7]}出现异常",
1,
)
for _ in range(10):
if self.isInterruptionRequested:
break
time.sleep(1)
# 移除静默进程标记
Config.silence_list.remove(self.emulator_path)
# 成功完成代理的用户修改相关参数
if run_book[0] and run_book[1]:
@@ -302,28 +305,30 @@ class MaaManager(QObject):
if not (run_book[0] and run_book[1]):
user[1] = "异常"
self.update_user_list.emit(user_list)
self.update_user_list.emit(self.user_list)
# 人工排查模式
elif self.mode == "人工排查":
# 标记是否需要启动模拟器
if_strat_app = True
self.if_open_emulator = True
# 标识排查模式
for _ in user_list:
for _ in self.user_list:
_[0] += "_排查模式"
# 开始排查
for user in user_list:
for user in self.user_list:
if self.isInterruptionRequested:
break
logger.info(f"{self.name} | 开始排查用户: {user[0]}")
user[1] = "运行"
self.update_user_list.emit(user_list)
self.update_user_list.emit(self.user_list)
if self.data[user[2]][15] == "beta":
if_strat_app = True
self.if_open_emulator = True
run_book = [False for _ in range(2)]
@@ -331,11 +336,7 @@ class MaaManager(QObject):
while not self.isInterruptionRequested:
# 配置MAA
if if_strat_app:
self.set_maa("人工排查_启动模拟器", user[2])
if_strat_app = False
else:
self.set_maa("人工排查_仅切换账号", user[2])
self.set_maa("人工排查", user[2])
# 记录当前时间
start_time = datetime.now()
@@ -347,43 +348,28 @@ class MaaManager(QObject):
)
# 监测MAA运行状态
while not self.isInterruptionRequested:
self.start_monitor(start_time, "人工排查")
# 获取MAA日志
logs = self.get_maa_log(start_time)
# 合并日志
log = "".join(logs)
# 更新MAA日志
if len(logs) > 100:
self.update_log_text.emit("".join(logs[-100:]))
else:
self.update_log_text.emit("".join(logs))
# 判断MAA程序运行状态
result = self.if_maa_success(log, "人工排查")
if result == "Success!":
run_book[0] = True
self.update_log_text.emit("检测到MAA进程成功登录PRTS")
break
elif result == "Wait":
# 检测时间间隔
if self.maa_result == "Success!":
logger.info(
f"{self.name} | 用户: {user[0]} - MAA进程成功登录PRTS"
)
run_book[0] = True
self.update_log_text.emit("检测到MAA进程成功登录PRTS")
else:
logger.error(
f"{self.name} | 用户: {user[0]} - MAA未能正确登录到PRTS: {self.maa_result}"
)
self.update_log_text.emit(
f"{self.maa_result}\n正在中止相关程序\n请等待10s"
)
# 无命令行中止MAA与其子程序
System.kill_process(self.maa_exe_path)
self.if_open_emulator = True
for _ in range(10):
if self.isInterruptionRequested:
break
time.sleep(1)
else:
self.update_log_text.emit(result)
# 无命令行中止MAA与其子程序
killprocess = subprocess.Popen(
f"taskkill /F /T /PID {maa.pid}",
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
killprocess.wait()
if_strat_app = True
for _ in range(10):
if self.isInterruptionRequested:
break
time.sleep(1)
break
# 登录成功,结束循环
if run_book[0]:
@@ -406,19 +392,21 @@ class MaaManager(QObject):
# 结果录入用户备注栏
if run_book[0] and run_book[1]:
logger.info(f"{self.name} | 用户 {user[0]} 通过人工排查")
if "未通过人工排查" in self.data[user[2]][13]:
self.data[user[2]][13] = self.data[user[2]][13].replace(
"未通过人工排查|", ""
)
user[1] = "完成"
elif not (run_book[0] and run_book[1]):
else:
logger.info(f"{self.name} | 用户 {user[0]} 未通过人工排查")
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)
self.update_user_list.emit(self.user_list)
# 设置MAA模式
elif "设置MAA" in self.mode:
@@ -435,20 +423,7 @@ class MaaManager(QObject):
start_time = datetime.now()
# 监测MAA运行状态
while not self.isInterruptionRequested:
# 获取MAA日志
logs = self.get_maa_log(start_time)
# 合并日志
log = "".join(logs)
# 判断MAA程序运行状态
result = self.if_maa_success(log, "设置MAA")
if result == "Success!":
break
elif result == "Wait":
# 检测时间间隔
time.sleep(1)
self.start_monitor(start_time, "设置MAA")
if "全局" in self.mode:
(self.config_path / "Default").mkdir(parents=True, exist_ok=True)
@@ -465,25 +440,20 @@ class MaaManager(QObject):
# 关闭可能未正常退出的MAA进程
if self.isInterruptionRequested:
killprocess = subprocess.Popen(
f"taskkill /F /T /PID {maa.pid}",
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
killprocess.wait()
System.kill_process(self.maa_exe_path)
# 更新用户数据
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]
modes = [self.data[_[2]][15] for _ in self.user_list]
uids = [self.data[_[2]][16] for _ in self.user_list]
days = [self.data[_[2]][3] for _ in self.user_list]
lasts = [self.data[_[2]][5] for _ in self.user_list]
notes = [self.data[_[2]][13] for _ in self.user_list]
numbs = [self.data[_[2]][14] for _ in self.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] == "等待"]
error_index = [_[2] for _ in self.user_list if _[1] == "异常"]
over_index = [_[2] for _ in self.user_list if _[1] == "完成"]
wait_index = [_[2] for _ in self.user_list if _[1] == "等待"]
# 保存运行日志
end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@@ -529,11 +499,17 @@ class MaaManager(QObject):
Notify.CompanyWebHookBotPush(title, f"{end_log}AUTO_MAA 敬上")
self.agree_bilibili(False)
self.log_monitor.deleteLater()
self.log_monitor_timer.deleteLater()
self.accomplish.emit({"Time": begin_time, "History": end_log})
def requestInterruption(self) -> None:
logger.info(f"{self.name} | 收到任务中止申请")
logger.info("申请中止本次任务")
if len(self.log_monitor.files()) != 0:
self.interrupt.emit()
self.maa_result = "您中止了本次任务"
self.isInterruptionRequested = True
def push_question(self, title: str, message: str) -> bool:
@@ -548,9 +524,16 @@ class MaaManager(QObject):
def _capture_response(self, response: bool) -> None:
self.response = response
def get_maa_log(self, start_time):
"""获取MAA日志"""
def refresh_maa_log(self) -> None:
"""刷新MAA日志"""
with self.maa_log_path.open(mode="r", encoding="utf-8") as f:
pass
def check_maa_log(self, start_time: datetime, mode: str) -> None:
"""检查MAA日志以判断MAA程序运行状态"""
# 获取日志
logs = []
if_log_start = False
with self.maa_log_path.open(mode="r", encoding="utf-8") as f:
@@ -565,53 +548,99 @@ class MaaManager(QObject):
pass
else:
logs.append(entry)
return logs
log = "".join(logs)
def if_maa_success(self, log, mode):
"""判断MAA程序运行状态"""
# 更新MAA日志
if len(logs) > 100:
self.update_log_text.emit("".join(logs[-100:]))
else:
self.update_log_text.emit("".join(logs))
if "自动代理" in mode:
# 获取最近一条日志的时间
latest_time = start_time
for _ in logs[::-1]:
try:
latest_time = datetime.strptime(_[1:20], "%Y-%m-%d %H:%M:%S")
break
except ValueError:
pass
time_book = {
"自动代理_剿灭": "AnnihilationTimeLimit",
"自动代理_日常": "RoutineTimeLimit",
}
if mode == "自动代理_日常" and "任务出错: Fight" in log:
return "检测到MAA未能实际执行任务\n正在中止相关程序\n请等待10s"
self.maa_result = "检测到MAA未能实际执行任务"
if "任务出错: StartUp" in log:
return "检测到MAA未能正确登录PRTS\n正在中止相关程序\n请等待10s"
self.maa_result = "检测到MAA未能正确登录PRTS"
elif "任务已全部完成!" in log:
return "Success!"
self.maa_result = "Success!"
elif (
("请「检查连接设置」或「尝试重启模拟器与 ADB」或「重启电脑」" in log)
or ("已停止" in log)
or ("MaaAssistantArknights GUI exited" in log)
):
return "检测到MAA进程异常\n正在中止相关程序\n请等待10s"
elif self.if_time_out:
return "检测到MAA进程超时\n正在中止相关程序\n请等待10s"
elif self.isInterruptionRequested:
return "您中止了本次任务\n正在中止相关程序\n请等待"
self.maa_result = "检测到MAA进程异常"
elif datetime.now() - latest_time > timedelta(
minutes=self.set["RunSet"][time_book[mode]]
):
self.maa_result = "检测到MAA进程超时"
else:
return "Wait"
self.maa_result = "Wait"
elif mode == "人工排查":
if "完成任务: StartUp" in log:
return "Success!"
self.maa_result = "Success!"
elif (
("请「检查连接设置」或「尝试重启模拟器与 ADB」或「重启电脑」" in log)
or ("已停止" in log)
or ("MaaAssistantArknights GUI exited" in log)
):
return "检测到MAA进程异常\n正在中止相关程序\n请等待10s"
elif self.isInterruptionRequested:
return "您中止了本次任务\n正在中止相关程序\n请等待"
self.maa_result = "检测到MAA进程异常"
else:
return "Wait"
self.maa_result = "Wait"
elif mode == "设置MAA":
if "MaaAssistantArknights GUI exited" in log:
return "Success!"
self.maa_result = "Success!"
else:
return "Wait"
self.maa_result = "Wait"
if self.maa_result != "Wait":
self.quit_monitor()
def start_monitor(self, start_time: datetime, mode: str) -> None:
"""开始监视MAA日志"""
logger.info(f"{self.name} | 开始监视MAA日志")
self.log_monitor.addPath(str(self.maa_log_path))
self.log_monitor.fileChanged.connect(
lambda: self.check_maa_log(start_time, mode)
)
self.log_monitor_timer.start(1000)
self.monitor_loop.exec()
def quit_monitor(self) -> None:
"""退出MAA日志监视进程"""
if len(self.log_monitor.files()) != 0:
logger.info(f"{self.name} | 退出MAA日志监视")
self.log_monitor.removePath(str(self.maa_log_path))
self.log_monitor.fileChanged.disconnect()
self.log_monitor_timer.stop()
self.monitor_loop.quit()
def set_maa(self, mode, index):
"""配置MAA运行参数"""
logger.info(f"{self.name} | 配置MAA运行参数: {mode}/{index}")
# 配置MAA前关闭可能未正常退出的MAA进程
System.kill_process(self.maa_exe_path)
# 预导入MAA配置文件
if mode == "设置MAA_用户":
@@ -667,15 +696,34 @@ class MaaManager(QObject):
data["Current"] = "Default" # 切换配置
for i in range(1, 9):
data["Global"][f"Timer.Timer{i}"] = "False" # 时间设置
data["Configurations"]["Default"][
"MainFunction.PostActions"
] = "12" # 完成后退出MAA和模拟器
if (
[i for i, _ in enumerate(self.user_list) if _[2] == index][0]
== len(self.user_list) - 1
) or (
self.data[
self.user_list[
[i for i, _ in enumerate(self.user_list) if _[2] == index][0]
+ 1
][2]
][15]
== "beta"
):
data["Configurations"]["Default"][
"MainFunction.PostActions"
] = "12" # 完成后退出MAA和模拟器
else:
method_dict = {"NoAction": "8", "ExitGame": "9", "ExitEmulator": "12"}
data["Configurations"]["Default"]["MainFunction.PostActions"] = (
method_dict[self.set["RunSet"]["TaskTransitionMethod"]]
) # 完成后行为
data["Configurations"]["Default"][
"Start.RunDirectly"
] = "True" # 启动MAA后直接运行
data["Configurations"]["Default"][
"Start.OpenEmulatorAfterLaunch"
] = "True" # 启动MAA后自动开启模拟器
data["Configurations"]["Default"]["Start.OpenEmulatorAfterLaunch"] = (
"True" if self.if_open_emulator else "False"
) # 启动MAA后自动开启模拟器
if Config.global_config.get(Config.global_config.function_IfSilence):
data["Global"]["Start.MinimizeDirectly"] = "True" # 启动MAA后直接最小化
@@ -888,7 +936,6 @@ class MaaManager(QObject):
"Start.RunDirectly"
] = "True" # 启动MAA后直接运行
data["Global"]["Start.MinimizeDirectly"] = "True" # 启动MAA后直接最小化
# v5.1.12版本对以下字段处理
# 启动MAA后直接运行
data["Configurations"]["Default"]["Start.OpenEmulatorAfterLaunch"] = "True"
# 启动MAA后自动开启模拟器
@@ -896,15 +943,9 @@ class MaaManager(QObject):
data["Global"]["GUI.UseTray"] = "True" # 显示托盘图标
data["Global"]["GUI.MinimizeToTray"] = "True" # 最小化时隐藏至托盘
# 启动MAA后自动开启模拟器
if "启动模拟器" in mode:
data["Configurations"]["Default"][
"Start.OpenEmulatorAfterLaunch"
] = "True"
elif "仅切换账号" in mode:
data["Configurations"]["Default"][
"Start.OpenEmulatorAfterLaunch"
] = "False"
data["Configurations"]["Default"]["Start.OpenEmulatorAfterLaunch"] = (
"True" if self.if_open_emulator else "False"
) # 启动MAA后自动开启模拟器
if self.data[index][15] == "simple":
@@ -1016,6 +1057,14 @@ class MaaManager(QObject):
"TaskQueue.Reclamation.IsChecked"
] = "False" # 生息演算
# 启动模拟器仅生效一次
if (
"设置MAA" not in mode
and self.if_open_emulator
and self.set["RunSet"]["TaskTransitionMethod"] != "ExitEmulator"
):
self.if_open_emulator = False
# 覆写配置文件
with self.maa_set_path.open(mode="w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
@@ -1024,6 +1073,9 @@ class MaaManager(QObject):
def agree_bilibili(self, if_agree):
"""向MAA写入Bilibili协议相关任务"""
logger.info(
f"{self.name} | Bilibili协议相关任务状态: {"启用" if if_agree else "禁用"}"
)
with self.maa_tasks_path.open(mode="r", encoding="utf-8") as f:
data = json.load(f)

View File

@@ -34,6 +34,7 @@ import win32process
import winreg
import psutil
import subprocess
from pathlib import Path
from app.core import Config
@@ -50,7 +51,7 @@ class _SystemHandler:
self.set_Sleep()
self.set_SelfStart()
def set_Sleep(self):
def set_Sleep(self) -> None:
"""同步系统休眠状态"""
if Config.global_config.get(Config.global_config.function_IfAllowSleep):
@@ -62,7 +63,7 @@ class _SystemHandler:
# 恢复系统电源状态
ctypes.windll.kernel32.SetThreadExecutionState(self.ES_CONTINUOUS)
def set_SelfStart(self):
def set_SelfStart(self) -> None:
"""同步开机自启"""
if (
@@ -90,7 +91,7 @@ class _SystemHandler:
winreg.DeleteValue(key, "AUTO_MAA")
winreg.CloseKey(key)
def set_power(self, mode):
def set_power(self, mode) -> None:
if sys.platform.startswith("win"):
@@ -144,7 +145,7 @@ class _SystemHandler:
self.main_window.close()
def is_startup(self):
def is_startup(self) -> bool:
"""判断程序是否已经开机自启"""
key = winreg.OpenKey(
@@ -162,7 +163,7 @@ class _SystemHandler:
winreg.CloseKey(key)
return False
def get_window_info(self):
def get_window_info(self) -> list:
"""获取当前窗口信息"""
def callback(hwnd, window_info):
@@ -176,5 +177,29 @@ class _SystemHandler:
win32gui.EnumWindows(callback, window_info)
return window_info
def kill_process(self, path: Path) -> None:
"""根据路径中止进程"""
for pid in self.search_pids(path):
killprocess = subprocess.Popen(
f"taskkill /F /T /PID {pid}",
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
killprocess.wait()
def search_pids(self, path: Path) -> list:
"""根据路径查找进程PID"""
pids = []
for proc in psutil.process_iter(["pid", "exe"]):
try:
if proc.info["exe"] and proc.info["exe"].lower() == str(path).lower():
pids.append(proc.info["pid"])
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
# 进程可能在此期间已结束或无法访问,忽略这些异常
pass
return pids
System = _SystemHandler()

View File

@@ -52,7 +52,7 @@ from typing import List, Dict
import json
from app.core import Config, Task_manager, Task, MainInfoBar
from app.core import Config, TaskManager, Task, MainInfoBar
class DispatchCenter(QWidget):
@@ -92,7 +92,7 @@ class DispatchCenter(QWidget):
dispatch_box = DispatchBox(task.name, self)
dispatch_box.top_bar.button.clicked.connect(
lambda: Task_manager.stop_task(task.name)
lambda: TaskManager.stop_task(task.name)
)
task.create_task_list.connect(dispatch_box.info.task.create_task)
@@ -128,7 +128,7 @@ class DispatchCenter(QWidget):
self.script_list["主调度台"].top_bar.button.clicked.disconnect()
self.script_list["主调度台"].top_bar.button.setText("中止任务")
self.script_list["主调度台"].top_bar.button.clicked.connect(
lambda: Task_manager.stop_task(task.name)
lambda: TaskManager.stop_task(task.name)
)
task.create_task_list.connect(
self.script_list["主调度台"].info.task.create_task
@@ -166,20 +166,31 @@ class DispatchCenter(QWidget):
"""更新顶栏"""
list = []
queue_numb, member_numb = 0, 0
if (Config.app_path / "config/QueueConfig").exists():
for json_file in (Config.app_path / "config/QueueConfig").glob("*.json"):
list.append(f"队列 - {json_file.stem}")
queue_numb += 1
if (Config.app_path / "config/MaaConfig").exists():
for subdir in (Config.app_path / "config/MaaConfig").iterdir():
if subdir.is_dir():
list.append(f"实例 - Maa - {subdir.name}")
member_numb += 1
self.script_list["主调度台"].top_bar.object.clear()
self.script_list["主调度台"].top_bar.object.addItems(list)
self.script_list["主调度台"].top_bar.object.setCurrentIndex(-1)
self.script_list["主调度台"].top_bar.mode.setCurrentIndex(-1)
self.script_list["主调度台"].top_bar.mode.clear()
self.script_list["主调度台"].top_bar.mode.addItems(["自动代理", "人工排查"])
if queue_numb == 1:
self.script_list["主调度台"].top_bar.object.setCurrentIndex(0)
elif member_numb == 1:
self.script_list["主调度台"].top_bar.object.setCurrentIndex(queue_numb)
else:
self.script_list["主调度台"].top_bar.object.setCurrentIndex(-1)
self.script_list["主调度台"].top_bar.mode.setCurrentIndex(0)
class DispatchBox(QWidget):
@@ -223,7 +234,6 @@ class DispatchBox(QWidget):
self.object = ComboBox()
self.object.setPlaceholderText("请选择调度对象")
self.mode = ComboBox()
self.mode.addItems(["自动代理", "人工排查"])
self.mode.setPlaceholderText("请选择调度模式")
self.button = PushButton("开始任务")
@@ -276,7 +286,7 @@ class DispatchBox(QWidget):
info = json.load(f)
logger.info(f"用户添加任务:{name}")
Task_manager.add_task(f"{self.mode.currentText()}_主调度台", name, info)
TaskManager.add_task(f"{self.mode.currentText()}_主调度台", name, info)
elif self.object.currentText().split(" - ")[0] == "实例":
@@ -285,7 +295,7 @@ class DispatchBox(QWidget):
info = {"Queue": {"Member_1": name}}
logger.info(f"用户添加任务:{name}")
Task_manager.add_task(
TaskManager.add_task(
f"{self.mode.currentText()}_主调度台", "自定义队列", info
)

View File

@@ -26,10 +26,7 @@ v4.2
"""
from loguru import logger
from PySide6.QtWidgets import (
QApplication,
QSystemTrayIcon,
)
from PySide6.QtWidgets import QSystemTrayIcon
from qfluentwidgets import (
Action,
PushButton,
@@ -39,15 +36,18 @@ from qfluentwidgets import (
InfoBar,
InfoBarPosition,
setTheme,
isDarkTheme,
SystemThemeListener,
Theme,
MSFluentWindow,
NavigationItemPosition,
qconfig,
)
from PySide6.QtGui import QIcon, QCloseEvent
from PySide6.QtCore import Qt
from PySide6.QtCore import Qt, QTimer
import json
from app.core import Config, Task_manager, Main_timer, MainInfoBar
from app.core import Config, TaskManager, MainTimer, MainInfoBar
from app.services import Notify, Crypto, System
from .setting import Setting
from .member_manager import MemberManager
@@ -63,7 +63,7 @@ class AUTO_MAA(MSFluentWindow):
self.setWindowIcon(QIcon(str(Config.app_path / "resources/icons/AUTO_MAA.ico")))
self.setWindowTitle("AUTO_MAA")
setTheme(Theme.AUTO)
setTheme(Theme.AUTO, lazy=True)
self.splashScreen = SplashScreen(self.windowIcon(), self)
self.show_ui("显示主窗口", if_quick=True)
@@ -143,22 +143,17 @@ class AUTO_MAA(MSFluentWindow):
self.tray_menu.addSeparator()
# 开始任务菜单项
# self.tray_menu.addActions(
# [
# Action(
# FluentIcon.PLAY,
# "运行自动代理",
# triggered=lambda: self.start_task("自动代理"),
# ),
# Action(
# FluentIcon.PLAY,
# "运行人工排查",
# triggered=lambda: self.start_task("人工排查"),
# ),
# Action(FluentIcon.PAUSE, "中止当前任务", triggered=self.stop_task),
# ]
# )
# self.tray_menu.addSeparator()
self.tray_menu.addActions(
[
Action(FluentIcon.PLAY, "运行自动代理", triggered=self.start_main_task),
Action(
FluentIcon.PAUSE,
"中止所有任务",
triggered=lambda: TaskManager.stop_task("ALL"),
),
]
)
self.tray_menu.addSeparator()
# 退出主程序菜单项
self.tray_menu.addAction(
@@ -169,8 +164,8 @@ class AUTO_MAA(MSFluentWindow):
self.tray.setContextMenu(self.tray_menu)
self.tray.activated.connect(self.on_tray_activated)
Task_manager.create_gui.connect(self.dispatch_center.add_board)
Task_manager.connect_gui.connect(self.dispatch_center.connect_main_board)
TaskManager.create_gui.connect(self.dispatch_center.add_board)
TaskManager.connect_gui.connect(self.dispatch_center.connect_main_board)
self.setting.ui.card_IfShowTray.checkedChanged.connect(
lambda: self.show_ui("配置托盘")
)
@@ -178,6 +173,23 @@ class AUTO_MAA(MSFluentWindow):
self.splashScreen.finish()
self.themeListener = SystemThemeListener(self)
self.themeListener.systemThemeChanged.connect(self.switch_theme)
self.themeListener.start()
def switch_theme(self):
"""切换主题"""
setTheme(Theme.AUTO, lazy=True)
QTimer.singleShot(100, lambda: setTheme(Theme.AUTO, lazy=True))
# 云母特效启用时需要增加重试机制
if self.isMicaEffectEnabled():
QTimer.singleShot(
100,
lambda: self.windowEffect.setMicaEffect(self.winId(), isDarkTheme()),
)
def start_up_task(self) -> None:
"""启动时任务"""
@@ -212,6 +224,11 @@ class AUTO_MAA(MSFluentWindow):
info.addWidget(Up)
info.show()
# 直接运行主任务
if Config.global_config.get(Config.global_config.start_IfRunDirectly):
self.start_main_task()
def set_min_method(self) -> None:
"""设置最小化方法"""
@@ -230,40 +247,32 @@ class AUTO_MAA(MSFluentWindow):
if reason == QSystemTrayIcon.DoubleClick:
self.show_ui("显示主窗口")
# def start_task(self, mode):
# """调起对应任务"""
# if self.main.MaaManager.isRunning():
# Notify.push_notification(
# f"无法运行{mode}",
# "当前已有任务正在运行,请在该任务结束后重试",
# "当前已有任务正在运行,请在该任务结束后重试",
# 3,
# )
# else:
# self.main.maa_starter(mode)
def start_main_task(self) -> None:
"""启动主任务"""
# def stop_task(self):
# """中止当前任务"""
# if self.main.MaaManager.isRunning():
# if (
# self.main.MaaManager.mode == "自动代理"
# or self.main.MaaManager.mode == "人工排查"
# ):
# self.main.maa_ender(f"{self.main.MaaManager.mode}_结束")
# elif "设置MAA" in self.main.MaaManager.mode:
# Notify.push_notification(
# "正在设置MAA",
# "正在运行设置MAA任务无法中止",
# "正在运行设置MAA任务无法中止",
# 3,
# )
# else:
# Notify.push_notification(
# "无任务运行!",
# "当前无任务正在运行,无需中止",
# "当前无任务正在运行,无需中止",
# 3,
# )
if (Config.app_path / "config/QueueConfig/调度队列_1.json").exists():
with (Config.app_path / "config/QueueConfig/调度队列_1.json").open(
mode="r", encoding="utf-8"
) as f:
info = json.load(f)
logger.info("自动添加任务调度队列_1")
TaskManager.add_task("自动代理_主调度台", "主任务队列", info)
elif (Config.app_path / "config/MaaConfig/脚本_1").exists():
info = {"Queue": {"Member_1": "脚本_1"}}
logger.info("自动添加任务脚本_1")
TaskManager.add_task("自动代理_主调度台", "主任务队列", info)
else:
logger.worning("启动主任务失败:未找到有效的主任务配置文件")
MainInfoBar.push_info_bar(
"warning", "启动主任务失败", "“调度队列_1”与“脚本_1”均不存在", -1
)
def show_ui(self, mode: str, if_quick: bool = False) -> None:
"""配置窗口状态"""
@@ -330,13 +339,17 @@ class AUTO_MAA(MSFluentWindow):
self.show_ui("隐藏到托盘", if_quick=True)
# 清理各功能线程
Main_timer.Timer.stop()
Main_timer.Timer.deleteLater()
Task_manager.stop_task("ALL")
MainTimer.Timer.stop()
MainTimer.Timer.deleteLater()
TaskManager.stop_task("ALL")
# 关闭数据库连接
Config.close_database()
# 关闭主题监听
self.themeListener.terminate()
self.themeListener.deleteLater()
logger.info("AUTO_MAA主程序关闭")
logger.info("----------------END----------------")

View File

@@ -46,9 +46,12 @@ from qfluentwidgets import (
HeaderCardWidget,
CommandBar,
ExpandGroupSettingCard,
ComboBoxSettingCard,
PushSettingCard,
)
from PySide6.QtCore import Qt
import requests
import time
from functools import partial
from pathlib import Path
from typing import List
@@ -56,8 +59,9 @@ from datetime import datetime, timedelta
import json
import shutil
from app.core import Config, MainInfoBar, Task_manager
from app.core import Config, MainInfoBar, TaskManager
from app.services import Crypto
from app.utils import Updater
from .Widget import (
LineEditMessageBox,
LineEditSettingCard,
@@ -107,14 +111,21 @@ class MemberManager(QWidget):
]
)
self.tools.addSeparator()
self.key = Action(
FluentIcon.HIDE,
"显示/隐藏密码",
checkable=True,
triggered=self.show_password,
)
self.tools.addAction(
self.key,
Action(
FluentIcon.DOWNLOAD,
"脚本下载器",
triggered=self.member_downloader,
)
)
self.tools.addSeparator()
self.tools.addAction(
Action(
FluentIcon.HIDE,
"显示/隐藏密码",
checkable=True,
triggered=self.show_password,
)
)
layout.addWidget(self.tools)
@@ -291,6 +302,64 @@ class MemberManager(QWidget):
self.member_manager.show_SettingBox(index + 1)
def member_downloader(self):
"""脚本下载器"""
choice = ComboBoxMessageBox(
self.window(),
"选择一个脚本类型以下载相应脚本",
["选择脚本类型"],
[["MAA"]],
)
if choice.exec() and choice.input[0].currentIndex() != -1:
if choice.input[0].currentText() == "MAA":
folder = QFileDialog.getExistingDirectory(
self, "选择MAA下载目录", str(Config.app_path)
)
if not folder:
logger.warning("选择MAA下载目录时未选择文件夹")
MainInfoBar.push_info_bar(
"warning", "警告", "未选择MAA下载目录", 5000
)
return None
# 从mirrorc服务器获取最新版本信息
for _ in range(3):
try:
response = requests.get(
"https://mirrorc.top/api/resources/MAA/latest?user_agent=MaaWpfGui&os=win&arch=x64&channel=beta"
)
maa_info = response.json()
break
except Exception as e:
err = e
time.sleep(0.1)
else:
choice = MessageBox(
"错误",
f"获取版本信息时出错:\n{err}",
self.window(),
)
choice.cancelButton.hide()
choice.buttonLayout.insertStretch(1)
if choice.exec():
return None
maa_version = list(
map(
int,
maa_info["data"]["version_name"][1:]
.replace("-beta", "")
.split("."),
)
)
while len(maa_version) < 4:
maa_version.append(0)
self.downloader = Updater(Path(folder), "MAA", maa_version, [])
self.downloader.ui.show()
def show_password(self):
if Config.PASSWORD == "":
@@ -522,7 +591,7 @@ class MaaSettingBox(QWidget):
)
)
self.card_Set.clicked.connect(
lambda: Task_manager.add_task("设置MAA_全局", self.name, None)
lambda: TaskManager.add_task("设置MAA_全局", self.name, None)
)
Layout.addWidget(self.card_Name)
@@ -578,9 +647,13 @@ class MaaSettingBox(QWidget):
parent,
)
widget = QWidget()
Layout = QVBoxLayout(widget)
self.card_TaskTransitionMethod = ComboBoxSettingCard(
configItem=Config.maa_config.RunSet_TaskTransitionMethod,
icon=FluentIcon.PAGE_RIGHT,
title="任务切换方式",
content="简洁用户列表下相邻两个任务间的切换方式",
texts=["直接切换账号", "重启明日方舟", "重启模拟器"],
)
self.ProxyTimesLimit = SpinBoxSettingCard(
(0, 1024),
FluentIcon.PAGE_RIGHT,
@@ -588,7 +661,6 @@ class MaaSettingBox(QWidget):
"当用户本日代理成功次数超过该阈值时跳过代理阈值为“0”时视为无代理次数上限",
Config.maa_config.RunSet_ProxyTimesLimit,
)
self.AnnihilationTimeLimit = SpinBoxSettingCard(
(1, 1024),
FluentIcon.PAGE_RIGHT,
@@ -596,7 +668,6 @@ class MaaSettingBox(QWidget):
"MAA日志无变化时间超过该阈值视为超时单位为分钟",
Config.maa_config.RunSet_AnnihilationTimeLimit,
)
self.RoutineTimeLimit = SpinBoxSettingCard(
(1, 1024),
FluentIcon.PAGE_RIGHT,
@@ -604,7 +675,6 @@ class MaaSettingBox(QWidget):
"MAA日志无变化时间超过该阈值视为超时单位为分钟",
Config.maa_config.RunSet_RoutineTimeLimit,
)
self.RunTimesLimit = SpinBoxSettingCard(
(1, 1024),
FluentIcon.PAGE_RIGHT,
@@ -613,14 +683,15 @@ class MaaSettingBox(QWidget):
Config.maa_config.RunSet_RunTimesLimit,
)
widget = QWidget()
Layout = QVBoxLayout(widget)
Layout.addWidget(self.card_TaskTransitionMethod)
Layout.addWidget(self.ProxyTimesLimit)
Layout.addWidget(self.AnnihilationTimeLimit)
Layout.addWidget(self.RoutineTimeLimit)
Layout.addWidget(self.RunTimesLimit)
self.viewLayout.setContentsMargins(0, 0, 0, 0)
self.viewLayout.setSpacing(0)
self.addGroupWidget(widget)
class UserSettingCard(HeaderCardWidget):
@@ -746,7 +817,7 @@ class MaaSettingBox(QWidget):
):
set_book = ["routine", "annihilation"]
Task_manager.add_task(
TaskManager.add_task(
"设置MAA_用户",
self.name,
{

View File

@@ -363,7 +363,7 @@ class Setting(QWidget):
def show_notice(self, if_show: bool = True):
"""显示公告"""
# 从远程服务器获取最新版本信息
# 从远程服务器获取最新公告
for _ in range(3):
try:
response = requests.get(
@@ -454,10 +454,10 @@ class FunctionSettingCard(HeaderCardWidget):
configItem=Config.global_config.function_IfSilence,
)
self.card_BossKey = LineEditSettingCard(
text="请输入安卓模拟器老",
text="请输入安卓模拟器老",
icon=FluentIcon.PAGE_RIGHT,
title="模拟器老",
content="输入模拟器老快捷键,以“+”分隔",
title="模拟器老",
content="输入模拟器老快捷键,以“+”分隔",
configItem=Config.global_config.function_BossKey,
)
@@ -484,8 +484,8 @@ class StartSettingCard(HeaderCardWidget):
)
self.card_IfRunDirectly = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="启动后直接运行",
content="启动AUTO_MAA后自动运行任务(暂不可用)",
title="启动后直接运行主任务",
content="启动AUTO_MAA后自动运行自动代理任务,优先级:调度队列 1 > 脚本 1",
configItem=Config.global_config.start_IfRunDirectly,
)
@@ -750,11 +750,11 @@ class OtherSettingCard(HeaderCardWidget):
content="查看AUTO_MAA的最新公告",
)
self.card_UserDocs = HyperlinkCard(
url="https://docs.qq.com/aio/DQ2NwUHRiWGtMWHBy",
text="查看使用指南",
url="https://clozya.github.io/AUTOMAA_docs",
text="访问",
icon=FluentIcon.PAGE_RIGHT,
title="使用指南",
content="查看AUTO_MAA的使用教程和文档",
title="AUTO_MAA官方文档站",
content="访问AUTO_MAA的官方文档站,获取使用指南和项目相关信息",
)
self.card_Association = self.AssociationSettingCard()

View File

@@ -70,7 +70,7 @@ class UpdateProcess(QThread):
self.name = name
self.main_version = main_version
self.updater_version = updater_version
self.download_path = app_path / "AUTO_MAA_Update.zip" # 临时下载文件的路径
self.download_path = app_path / "DOWNLOAD_TEMP.zip" # 临时下载文件的路径
self.version_path = app_path / "resources/version.json"
def run(self) -> None:
@@ -160,7 +160,7 @@ class UpdateProcess(QThread):
zip_ref.extractall(self.app_path)
break
except PermissionError:
self.info.emit("解压出错:AUTO_MAA正在运行,正在等待其关闭")
self.info.emit(f"解压出错:{self.name}正在运行,正在等待其关闭")
time.sleep(1)
self.info.emit("正在删除临时文件")
@@ -178,14 +178,17 @@ class UpdateProcess(QThread):
return None
# 更新version文件
with open(self.version_path, "r", encoding="utf-8") as f:
version_info = json.load(f)
if self.name == "AUTO_MAA更新器":
version_info["updater_version"] = ".".join(map(str, self.updater_version))
elif self.name == "AUTO_MAA主程序":
version_info["main_version"] = ".".join(map(str, self.main_version))
with open(self.version_path, "w", encoding="utf-8") as f:
json.dump(version_info, f, ensure_ascii=False, indent=4)
if self.name in ["AUTO_MAA主程序", "AUTO_MAA更新器"]:
with open(self.version_path, "r", encoding="utf-8") as f:
version_info = json.load(f)
if self.name == "AUTO_MAA主程序":
version_info["main_version"] = ".".join(map(str, self.main_version))
elif self.name == "AUTO_MAA更新器":
version_info["updater_version"] = ".".join(
map(str, self.updater_version)
)
with open(self.version_path, "w", encoding="utf-8") as f:
json.dump(version_info, f, ensure_ascii=False, indent=4)
# 主程序更新完成后打开AUTO_MAA
if self.name == "AUTO_MAA主程序":
@@ -194,6 +197,12 @@ class UpdateProcess(QThread):
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
elif self.name == "MAA":
subprocess.Popen(
str(self.app_path / "MAA.exe"),
shell=True,
creationflags=subprocess.CREATE_NO_WINDOW,
)
self.accomplish.emit()
@@ -239,6 +248,9 @@ class UpdateProcess(QThread):
url_list.append(
f"https://gitee.com/DLmaster_361/AUTO_MAA/releases/download/{version_text(self.main_version)}/AUTO_MAA_{version_text(self.main_version)}.zip"
)
url_list.append(
f"https://jp-download.fearr.xyz/AUTO_MAA/AUTO_MAA_{version_text(self.main_version)}.zip"
)
for i in range(len(PROXY_list)):
url_list.append(
f"{PROXY_list[i]}https://github.com/DLmaster361/AUTO_MAA/releases/download/{version_text(self.main_version)}/AUTO_MAA_{version_text(self.main_version)}.zip"
@@ -247,10 +259,21 @@ class UpdateProcess(QThread):
url_list.append(
f"https://gitee.com/DLmaster_361/AUTO_MAA/releases/download/{version_text(self.main_version)}/Updater_{version_text(self.updater_version)}.zip"
)
url_list.append(
f"https://jp-download.fearr.xyz/AUTO_MAA/Updater_{version_text(self.updater_version)}.zip"
)
for i in range(len(PROXY_list)):
url_list.append(
f"{PROXY_list[i]}https://github.com/DLmaster361/AUTO_MAA/releases/download/{version_text(self.main_version)}/Updater_{version_text(self.updater_version)}.zip"
)
elif self.name == "MAA":
url_list.append(
f"https://jp-download.fearr.xyz/MAA/MAA-{version_text(self.main_version)}-win-x64.zip"
)
for i in range(len(PROXY_list)):
url_list.append(
f"{PROXY_list[i]}https://github.com/MaaAssistantArknights/MaaAssistantArknights/releases/download/{version_text(self.main_version)}/MAA-{version_text(self.main_version)}-win-x64.zip"
)
return url_list
@@ -265,7 +288,12 @@ class Updater(QObject):
self.ui.setWindowTitle("AUTO_MAA更新器")
self.ui.resize(700, 70)
self.ui.setWindowIcon(
QIcon(str(app_path / "resources/icons/AUTO_MAA_Updater.ico"))
QIcon(
str(
Path(sys.argv[0]).resolve().parent
/ "resources/icons/AUTO_MAA_Updater.ico"
)
)
)
# 创建垂直布局

View File

@@ -1,5 +1,7 @@
#主界面
"MainFunction.PostActions": "12" #完成后
"MainFunction.PostActions": "8" #完成后退出MAA
"MainFunction.PostActions": "9" #完成后退出MAA和游戏
"MainFunction.PostActions": "12" #完成后退出MAA和模拟器
"TaskQueue.WakeUp.IsChecked": "True" #开始唤醒
"TaskQueue.Recruiting.IsChecked": "True" #自动公招
"TaskQueue.Base.IsChecked": "True" #基建换班

View File

@@ -1,7 +1,7 @@
{
"main_version": "4.2.3.0",
"updater_version": "1.1.1.3",
"announcement": "\n## 新增功能\n- 添加用户每日代理次数上限功能 #15\n- 新增代理成功消息推送渠道Server酱与企业微信群机器人推送\n- 添加更新类别可选项\n- 添加调度队列完成任务后行为选项\n- 初步完成`托管bilibili游戏隐私政策`功能\n## 修复BUG\n- 修复自定义基建无法正常使用的问题\n- 修正人工排查文案\n- 修复高级MAA配置序号错位\n- 修复高级用户列表无法配置问题\n- 修复主调度台选项乱动问题\n- 修复更新器文件夹定位问题\n- 修复窗口记忆功能失效问题\n## 程序优化\n- 优化弹窗逻辑\n- 优化静默判定逻辑\n- 调整MAA设置目录时打开当前已配置的目录位置\n- 邮箱推送功能调整,改由用户提供发信邮箱",
"main_version": "4.2.4.0",
"updater_version": "1.1.2.0",
"announcement": "\n## 新增功能\n- 添加`简洁用户列表下相邻两个任务间的切换方式`可选项\n- 恢复启动后直接运行主任务功能以及相关托盘菜单\n## 修复BUG\n- 修复静默代理标记移除异常情况\n- 适配深色模式 #18\n## 程序优化\n- 优化MAA关闭方法\n- 添加高级代理文件校验过程\n- 升级日志监看方法\n- 优化主调度台默认选项\n- 配置MAA前关闭可能未正常退出的MAA进程\n- 接入镜像源",
"proxy_list": [
"",
"https://gitproxy.click/",