Compare commits

..

15 Commits

Author SHA1 Message Date
DLmaster361
21e7df7c3e Merge branch 'dev' 2025-06-01 20:04:16 +08:00
DLmaster361
2d72ca66a4 fix(core): 修复网络模块子线程未及时销毁导致的程序崩溃 2025-06-01 19:52:22 +08:00
DLmaster361
4725a30165 fix(ui): 修复语音包禁忌二重奏 2025-06-01 04:31:29 +08:00
DLmaster361
f3c977f1b3 Merge branch 'main' into dev 2025-06-01 03:18:39 +08:00
DLmaster361
9a0e7265c6 feat(core): 语音功能上线 2025-06-01 03:16:56 +08:00
DLmaster361
3f8e2fbe6b Merge branch 'dev' 2025-05-31 13:37:06 +08:00
DLmaster361
590b13e916 ci: 移除测试打包流程 2025-05-31 13:36:09 +08:00
DLmaster361
0f6aee56e5 ci: 修正测试工作流名称 2025-05-31 11:21:13 +08:00
DLmaster361
daf18e7295 Merge branch 'dev' 2025-05-31 11:20:04 +08:00
DLmaster361
9bcc87f663 ci: 添加引入打包action的测试工作流 2025-05-31 11:19:36 +08:00
DLmaster361
e7205ce0aa fix(services): 非UI组件转为QObject类 2025-05-30 21:06:39 +08:00
DLmaster361
e3c4b2edc8 fix(core): 网络模块支持并发请求 2025-05-30 20:30:23 +08:00
DLmaster361
222a3b35a2 fix(maa): 修复ADB与模拟器相关日志信息报错时不显示 2025-05-29 21:06:09 +08:00
DLmaster361
cd5dfd56b2 Merge branch 'dev' 2025-05-28 23:13:15 +08:00
DLmaster361
7d5c6b8222 docs: 添加DeepWiki徽章 2025-05-28 23:12:56 +08:00
61 changed files with 347 additions and 184 deletions

View File

@@ -13,6 +13,7 @@
<a href="https://github.com/DLmaster361/AUTO_MAA/issues"><img alt="GitHub Issues" src="https://img.shields.io/github/issues/DLmaster361/AUTO_MAA?style=flat-square"></a> <a href="https://github.com/DLmaster361/AUTO_MAA/issues"><img alt="GitHub Issues" src="https://img.shields.io/github/issues/DLmaster361/AUTO_MAA?style=flat-square"></a>
<a href="https://github.com/DLmaster361/AUTO_MAA/graphs/contributors"><img alt="GitHub Contributors" src="https://img.shields.io/github/contributors/DLmaster361/AUTO_MAA?style=flat-square"></a> <a href="https://github.com/DLmaster361/AUTO_MAA/graphs/contributors"><img alt="GitHub Contributors" src="https://img.shields.io/github/contributors/DLmaster361/AUTO_MAA?style=flat-square"></a>
<a href="https://github.com/DLmaster361/AUTO_MAA/blob/main/LICENSE"><img alt="GitHub License" src="https://img.shields.io/github/license/DLmaster361/AUTO_MAA?style=flat-square"></a> <a href="https://github.com/DLmaster361/AUTO_MAA/blob/main/LICENSE"><img alt="GitHub License" src="https://img.shields.io/github/license/DLmaster361/AUTO_MAA?style=flat-square"></a>
<a href="https://deepwiki.com/DLmaster361/AUTO_MAA"><img alt="DeepWiki" src="https://deepwiki.com/badge.svg"></a>
<a href="https://mirrorchyan.com/zh/projects?rid=AUTO_MAA"><img alt="mirrorc" src="https://img.shields.io/badge/Mirror%E9%85%B1-%239af3f6?logo=countingworkspro&logoColor=4f46e5"></a> <a href="https://mirrorchyan.com/zh/projects?rid=AUTO_MAA"><img alt="mirrorc" src="https://img.shields.io/badge/Mirror%E9%85%B1-%239af3f6?logo=countingworkspro&logoColor=4f46e5"></a>
</p> </p>

View File

@@ -32,6 +32,7 @@ __license__ = "GPL-3.0 license"
from .config import QueueConfig, MaaConfig, MaaUserConfig, MaaPlanConfig, Config from .config import QueueConfig, MaaConfig, MaaUserConfig, MaaPlanConfig, Config
from .main_info_bar import MainInfoBar from .main_info_bar import MainInfoBar
from .network import Network from .network import Network
from .sound_player import SoundPlayer
from .task_manager import Task, TaskManager from .task_manager import Task, TaskManager
from .timer import MainTimer from .timer import MainTimer
@@ -43,6 +44,7 @@ __all__ = [
"MaaPlanConfig", "MaaPlanConfig",
"MainInfoBar", "MainInfoBar",
"Network", "Network",
"SoundPlayer",
"Task", "Task",
"TaskManager", "TaskManager",
"MainTimer", "MainTimer",

View File

@@ -185,6 +185,11 @@ class GlobalConfig(LQConfig):
"Function", "IfSkipMumuSplashAds", False, BoolValidator() "Function", "IfSkipMumuSplashAds", False, BoolValidator()
) )
self.voice_Enabled = ConfigItem("Voice", "Enabled", False, BoolValidator())
self.voice_Type = OptionsConfigItem(
"Voice", "Type", "simple", OptionsValidator(["simple", "noisy"])
)
self.start_IfSelfStart = ConfigItem( self.start_IfSelfStart = ConfigItem(
"Start", "IfSelfStart", False, BoolValidator() "Start", "IfSelfStart", False, BoolValidator()
) )
@@ -567,7 +572,7 @@ class MaaPlanConfig(LQConfig):
class AppConfig(GlobalConfig): class AppConfig(GlobalConfig):
VERSION = "4.3.8.0" VERSION = "4.3.9.0"
gameid_refreshed = Signal() gameid_refreshed = Signal()
PASSWORD_refreshed = Signal() PASSWORD_refreshed = Signal()
@@ -652,18 +657,20 @@ class AppConfig(GlobalConfig):
def get_gameid(self) -> None: def get_gameid(self) -> None:
# 从MAA服务器获取活动关卡信息 # 从MAA服务器获取活动关卡信息
Network.set_info( network = Network.add_task(
mode="get", mode="get",
url="https://api.maa.plus/MaaAssistantArknights/api/gui/StageActivity.json", url="https://api.maa.plus/MaaAssistantArknights/api/gui/StageActivity.json",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
gameid_infos: List[Dict[str, Union[str, Dict[str, Union[str, int]]]]] = ( gameid_infos: List[Dict[str, Union[str, Dict[str, Union[str, int]]]]] = (
Network.response_json["Official"]["sideStoryStage"] network_result["response_json"]["Official"]["sideStoryStage"]
) )
else: else:
logger.warning(f"无法从MAA服务器获取活动关卡信息:{Network.error_message}") logger.warning(
f"无法从MAA服务器获取活动关卡信息:{network_result['error_message']}"
)
gameid_infos = [] gameid_infos = []
ss_gameid_dict = {"value": [], "text": []} ss_gameid_dict = {"value": [], "text": []}

View File

@@ -30,6 +30,7 @@ from PySide6.QtCore import Qt
from qfluentwidgets import InfoBar, InfoBarPosition from qfluentwidgets import InfoBar, InfoBarPosition
from .config import Config from .config import Config
from .sound_player import SoundPlayer
class _MainInfoBar: class _MainInfoBar:
@@ -79,5 +80,10 @@ class _MainInfoBar:
if info_bar_item not in Config.info_bar_list: if info_bar_item not in Config.info_bar_list:
Config.info_bar_list.append(info_bar_item) Config.info_bar_list.append(info_bar_item)
if mode == "warning":
SoundPlayer.play("发生异常")
if mode == "error":
SoundPlayer.play("发生错误")
MainInfoBar = _MainInfoBar() MainInfoBar = _MainInfoBar()

View File

@@ -26,55 +26,46 @@ v4.3
""" """
from loguru import logger from loguru import logger
from PySide6.QtCore import QThread, QEventLoop, QTimer from PySide6.QtCore import QObject, QThread, QEventLoop
import re
import time import time
import requests import requests
from pathlib import Path from pathlib import Path
class _Network(QThread): class NetworkThread(QThread):
"""网络请求线程类"""
max_retries = 3 max_retries = 3
timeout = 10 timeout = 10
backoff_factor = 0.1 backoff_factor = 0.1
def __init__(self) -> None: def __init__(self, mode: str, url: str, path: Path = None) -> None:
super().__init__() super().__init__()
self.if_running = False self.setObjectName(
self.mode = None f"NetworkThread-{mode}-{re.sub(r'(&cdk=)[^&]+(&)', r'\1******\2', url)}"
self.url = None )
self.loop = QEventLoop()
self.wait_loop = QEventLoop()
@logger.catch
def run(self) -> None:
"""运行网络请求线程"""
self.if_running = True
if self.mode == "get":
self.get_json(self.url)
elif self.mode == "get_file":
self.get_file(self.url, self.path)
self.if_running = False
def set_info(self, mode: str, url: str, path: Path = None) -> None:
"""设置网络请求信息"""
while self.if_running:
QTimer.singleShot(self.backoff_factor * 1000, self.wait_loop.quit)
self.wait_loop.exec()
self.mode = mode self.mode = mode
self.url = url self.url = url
self.path = path self.path = path
self.stutus_code = None self.status_code = None
self.response_json = None self.response_json = None
self.error_message = None self.error_message = None
self.loop = QEventLoop()
@logger.catch
def run(self) -> None:
"""运行网络请求线程"""
if self.mode == "get":
self.get_json(self.url)
elif self.mode == "get_file":
self.get_file(self.url, self.path)
def get_json(self, url: str) -> None: def get_json(self, url: str) -> None:
"""通过get方法获取json数据""" """通过get方法获取json数据"""
@@ -83,12 +74,12 @@ class _Network(QThread):
for _ in range(self.max_retries): for _ in range(self.max_retries):
try: try:
response = requests.get(url, timeout=self.timeout) response = requests.get(url, timeout=self.timeout)
self.stutus_code = response.status_code self.status_code = response.status_code
self.response_json = response.json() self.response_json = response.json()
self.error_message = None self.error_message = None
break break
except Exception as e: except Exception as e:
self.stutus_code = response.status_code if response else None self.status_code = response.status_code if response else None
self.response_json = None self.response_json = None
self.error_message = str(e) self.error_message = str(e)
time.sleep(self.backoff_factor) time.sleep(self.backoff_factor)
@@ -105,16 +96,56 @@ class _Network(QThread):
if response.status_code == 200: if response.status_code == 200:
with open(path, "wb") as file: with open(path, "wb") as file:
file.write(response.content) file.write(response.content)
self.stutus_code = response.status_code self.status_code = response.status_code
else: else:
self.stutus_code = response.status_code self.status_code = response.status_code
self.error_message = "下载失败" self.error_message = "下载失败"
except Exception as e: except Exception as e:
self.stutus_code = response.status_code if response else None self.status_code = response.status_code if response else None
self.error_message = str(e) self.error_message = str(e)
self.loop.quit() self.loop.quit()
class _Network(QObject):
"""网络请求线程类"""
def __init__(self) -> None:
super().__init__()
self.task_queue = []
def add_task(self, mode: str, url: str, path: Path = None) -> NetworkThread:
"""添加网络请求任务"""
network_thread = NetworkThread(mode, url, path)
self.task_queue.append(network_thread)
network_thread.start()
return network_thread
def get_result(self, network_thread: NetworkThread) -> dict:
"""获取网络请求结果"""
result = {
"status_code": network_thread.status_code,
"response_json": network_thread.response_json,
"error_message": (
re.sub(r"(&cdk=)[^&]+(&)", r"\1******\2", network_thread.error_message)
if network_thread.error_message
else None
),
}
network_thread.quit()
network_thread.wait()
self.task_queue.remove(network_thread)
network_thread.deleteLater()
return result
Network = _Network() Network = _Network()

69
app/core/sound_player.py Normal file
View File

@@ -0,0 +1,69 @@
# AUTO_MAA:A MAA Multi Account Management and Automation Tool
# Copyright © 2024-2025 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/>.
# Contact: DLmaster_361@163.com
"""
AUTO_MAA
AUTO_MAA音效播放器
v4.3
作者DLmaster_361
"""
from loguru import logger
from PySide6.QtCore import QObject, QUrl
from PySide6.QtMultimedia import QSoundEffect
from pathlib import Path
from .config import Config
class _SoundPlayer(QObject):
def __init__(self):
super().__init__()
self.sounds_path = Config.app_path / "resources/sounds"
def play(self, sound_name: str):
if not Config.get(Config.voice_Enabled):
return
if (self.sounds_path / f"both/{sound_name}.wav").exists():
self.play_voice(self.sounds_path / f"both/{sound_name}.wav")
elif (
self.sounds_path / Config.get(Config.voice_Type) / f"{sound_name}.wav"
).exists():
self.play_voice(
self.sounds_path / Config.get(Config.voice_Type) / f"{sound_name}.wav"
)
def play_voice(self, sound_path: Path):
effect = QSoundEffect(self)
effect.setVolume(1)
effect.setSource(QUrl.fromLocalFile(sound_path))
effect.play()
SoundPlayer = _SoundPlayer()

View File

@@ -35,6 +35,7 @@ from typing import Dict, Union
from .config import Config from .config import Config
from .main_info_bar import MainInfoBar from .main_info_bar import MainInfoBar
from .network import Network from .network import Network
from .sound_player import SoundPlayer
from app.models import MaaManager from app.models import MaaManager
from app.services import System from app.services import System
@@ -44,6 +45,7 @@ class Task(QThread):
check_maa_version = Signal(str) check_maa_version = Signal(str)
push_info_bar = Signal(str, str, str, int) push_info_bar = Signal(str, str, str, int)
play_sound = Signal(str)
question = Signal(str, str) question = Signal(str, str)
question_response = Signal(bool) question_response = Signal(bool)
update_user_info = Signal(str, dict) update_user_info = Signal(str, dict)
@@ -59,6 +61,8 @@ class Task(QThread):
): ):
super(Task, self).__init__() super(Task, self).__init__()
self.setObjectName(f"Task-{mode}-{name}")
self.mode = mode self.mode = mode
self.name = name self.name = name
self.info = info self.info = info
@@ -82,6 +86,7 @@ class Task(QThread):
) )
self.task.check_maa_version.connect(self.check_maa_version.emit) self.task.check_maa_version.connect(self.check_maa_version.emit)
self.task.push_info_bar.connect(self.push_info_bar.emit) self.task.push_info_bar.connect(self.push_info_bar.emit)
self.task.play_sound.connect(self.play_sound.emit)
self.task.accomplish.connect(lambda: self.accomplish.emit([])) self.task.accomplish.connect(lambda: self.accomplish.emit([]))
self.task.run() self.task.run()
@@ -141,6 +146,7 @@ class Task(QThread):
self.question_response.disconnect() self.question_response.disconnect()
self.question_response.connect(self.task.question_response.emit) self.question_response.connect(self.task.question_response.emit)
self.task.push_info_bar.connect(self.push_info_bar.emit) self.task.push_info_bar.connect(self.push_info_bar.emit)
self.task.play_sound.connect(self.play_sound.emit)
self.task.create_user_list.connect(self.create_user_list.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_user_list.connect(self.update_user_list.emit)
self.task.update_log_text.connect(self.update_log_text.emit) self.task.update_log_text.connect(self.update_log_text.emit)
@@ -191,6 +197,7 @@ class _TaskManager(QObject):
logger.info(f"任务开始:{name}") logger.info(f"任务开始:{name}")
MainInfoBar.push_info_bar("info", "任务开始", name, 3000) MainInfoBar.push_info_bar("info", "任务开始", name, 3000)
SoundPlayer.play("任务开始")
Config.running_list.append(name) Config.running_list.append(name)
self.task_dict[name] = Task(mode, name, info) self.task_dict[name] = Task(mode, name, info)
@@ -199,6 +206,7 @@ class _TaskManager(QObject):
lambda title, content: self.push_dialog(name, title, content) lambda title, content: self.push_dialog(name, title, content)
) )
self.task_dict[name].push_info_bar.connect(MainInfoBar.push_info_bar) self.task_dict[name].push_info_bar.connect(MainInfoBar.push_info_bar)
self.task_dict[name].play_sound.connect(SoundPlayer.play)
self.task_dict[name].update_user_info.connect(Config.change_user_info) self.task_dict[name].update_user_info.connect(Config.change_user_info)
self.task_dict[name].accomplish.connect( self.task_dict[name].accomplish.connect(
lambda logs: self.remove_task(mode, name, logs) lambda logs: self.remove_task(mode, name, logs)
@@ -239,6 +247,7 @@ class _TaskManager(QObject):
logger.info(f"任务结束:{name}") logger.info(f"任务结束:{name}")
MainInfoBar.push_info_bar("info", "任务结束", name, 3000) MainInfoBar.push_info_bar("info", "任务结束", name, 3000)
SoundPlayer.play("任务结束")
self.task_dict[name].deleteLater() self.task_dict[name].deleteLater()
self.task_dict.pop(name) self.task_dict.pop(name)
@@ -277,20 +286,20 @@ class _TaskManager(QObject):
def check_maa_version(self, v: str): def check_maa_version(self, v: str):
"""检查MAA版本""" """检查MAA版本"""
Network.set_info( network = Network.add_task(
mode="get", mode="get",
url="https://mirrorchyan.com/api/resources/MAA/latest?user_agent=AutoMaaGui&os=win&arch=x64&channel=stable", url="https://mirrorchyan.com/api/resources/MAA/latest?user_agent=AutoMaaGui&os=win&arch=x64&channel=stable",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
maa_info = Network.response_json maa_info = network_result["response_json"]
else: else:
logger.warning(f"获取MAA版本信息时出错{Network.error_message}") logger.warning(f"获取MAA版本信息时出错{network_result['error_message']}")
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"warning", "warning",
"获取MAA版本信息时出错", "获取MAA版本信息时出错",
f"网络错误:{Network.stutus_code}", f"网络错误:{network_result['status_code']}",
5000, 5000,
) )
return None return None

View File

@@ -26,8 +26,7 @@ v4.3
""" """
from loguru import logger from loguru import logger
from PySide6.QtWidgets import QWidget from PySide6.QtCore import QObject, QTimer
from PySide6.QtCore import QTimer
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
import pyautogui import pyautogui
@@ -37,7 +36,7 @@ from .task_manager import TaskManager
from app.services import System from app.services import System
class _MainTimer(QWidget): class _MainTimer(QObject):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)

View File

@@ -50,6 +50,7 @@ class MaaManager(QObject):
question_response = Signal(bool) question_response = Signal(bool)
update_user_info = Signal(str, dict) update_user_info = Signal(str, dict)
push_info_bar = Signal(str, str, str, int) push_info_bar = Signal(str, str, str, int)
play_sound = Signal(str)
create_user_list = Signal(list) create_user_list = Signal(list)
update_user_list = Signal(list) update_user_list = Signal(list)
update_log_text = Signal(str) update_log_text = Signal(str)
@@ -88,6 +89,8 @@ class MaaManager(QObject):
self.question_response.connect(self.__capture_response) self.question_response.connect(self.__capture_response)
self.question_response.connect(self.question_loop.quit) self.question_response.connect(self.question_loop.quit)
self.wait_loop = QEventLoop()
self.interrupt.connect(self.quit_monitor) self.interrupt.connect(self.quit_monitor)
self.maa_version = None self.maa_version = None
@@ -426,11 +429,11 @@ class MaaManager(QObject):
# 任务开始前释放ADB # 任务开始前释放ADB
try: try:
logger.info(f"{self.name} | 释放ADB{self.ADB_address}")
subprocess.run( subprocess.run(
[self.ADB_path, "disconnect", self.ADB_address], [self.ADB_path, "disconnect", self.ADB_address],
creationflags=subprocess.CREATE_NO_WINDOW, creationflags=subprocess.CREATE_NO_WINDOW,
) )
logger.info(f"{self.name} | 释放ADB{self.ADB_address}")
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
# 忽略错误,因为可能本来就没有连接 # 忽略错误,因为可能本来就没有连接
logger.warning(f"{self.name} | 释放ADB时出现异常{e}") logger.warning(f"{self.name} | 释放ADB时出现异常{e}")
@@ -445,13 +448,13 @@ class MaaManager(QObject):
if self.if_open_emulator_process: if self.if_open_emulator_process:
try: try:
logger.info(
f"{self.name} | 启动模拟器:{self.emulator_path},参数:{self.emulator_arguments}"
)
self.emulator_process = subprocess.Popen( self.emulator_process = subprocess.Popen(
[self.emulator_path, *self.emulator_arguments], [self.emulator_path, *self.emulator_arguments],
creationflags=subprocess.CREATE_NO_WINDOW, creationflags=subprocess.CREATE_NO_WINDOW,
) )
logger.info(
f"{self.name} | 启动模拟器:{self.emulator_path},参数:{self.emulator_arguments}"
)
except Exception as e: except Exception as e:
logger.error(f"{self.name} | 启动模拟器时出现异常:{e}") logger.error(f"{self.name} | 启动模拟器时出现异常:{e}")
self.push_info_bar.emit( self.push_info_bar.emit(
@@ -511,10 +514,7 @@ class MaaManager(QObject):
"检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s" "检测到MAA进程完成代理任务\n正在等待相关程序结束\n请等待10s"
) )
for _ in range(10): self.sleep(10)
if self.isInterruptionRequested:
break
time.sleep(1)
else: else:
logger.error( logger.error(
f"{self.name} | 用户: {user[0]} - 代理任务异常: {self.maa_result}" f"{self.name} | 用户: {user[0]} - 代理任务异常: {self.maa_result}"
@@ -564,18 +564,19 @@ class MaaManager(QObject):
f"{user[0].replace("_", " ")}{mode_book[mode][5:7]}出现异常", f"{user[0].replace("_", " ")}{mode_book[mode][5:7]}出现异常",
1, 1,
) )
for _ in range(10): if i == self.set["RunSet"]["RunTimesLimit"] - 1:
if self.isInterruptionRequested: self.play_sound.emit("子任务失败")
break else:
time.sleep(1) self.play_sound.emit(self.maa_result)
self.sleep(10)
# 任务结束后释放ADB # 任务结束后释放ADB
try: try:
logger.info(f"{self.name} | 释放ADB{self.ADB_address}")
subprocess.run( subprocess.run(
[self.ADB_path, "disconnect", self.ADB_address], [self.ADB_path, "disconnect", self.ADB_address],
creationflags=subprocess.CREATE_NO_WINDOW, creationflags=subprocess.CREATE_NO_WINDOW,
) )
logger.info(f"{self.name} | 释放ADB{self.ADB_address}")
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
# 忽略错误,因为可能本来就没有连接 # 忽略错误,因为可能本来就没有连接
logger.warning(f"{self.name} | 释放ADB时出现异常{e}") logger.warning(f"{self.name} | 释放ADB时出现异常{e}")
@@ -619,6 +620,7 @@ class MaaManager(QObject):
}, },
user_data, user_data,
) )
self.play_sound.emit("六星喜报")
# 执行MAA解压更新动作 # 执行MAA解压更新动作
if self.maa_update_package: if self.maa_update_package:
@@ -630,15 +632,13 @@ class MaaManager(QObject):
self.update_log_text.emit( self.update_log_text.emit(
f"检测到MAA存在更新\nMAA正在执行更新动作\n请等待10s" f"检测到MAA存在更新\nMAA正在执行更新动作\n请等待10s"
) )
self.play_sound.emit("MAA更新")
self.set_maa("更新MAA", None) self.set_maa("更新MAA", None)
subprocess.Popen( subprocess.Popen(
[self.maa_exe_path], [self.maa_exe_path],
creationflags=subprocess.CREATE_NO_WINDOW, creationflags=subprocess.CREATE_NO_WINDOW,
) )
for _ in range(10): self.sleep(10)
if self.isInterruptionRequested:
break
time.sleep(1)
System.kill_process(self.maa_exe_path) System.kill_process(self.maa_exe_path)
logger.info(f"{self.name} | 更新动作结束") logger.info(f"{self.name} | 更新动作结束")
@@ -745,10 +745,7 @@ class MaaManager(QObject):
# 无命令行中止MAA与其子程序 # 无命令行中止MAA与其子程序
System.kill_process(self.maa_exe_path) System.kill_process(self.maa_exe_path)
self.if_open_emulator = True self.if_open_emulator = True
for _ in range(10): self.sleep(10)
if self.isInterruptionRequested:
break
time.sleep(1)
# 登录成功,结束循环 # 登录成功,结束循环
if run_book[0]: if run_book[0]:
@@ -756,6 +753,7 @@ class MaaManager(QObject):
# 登录失败,询问是否结束循环 # 登录失败,询问是否结束循环
elif not self.isInterruptionRequested: elif not self.isInterruptionRequested:
self.play_sound.emit("排查重试")
if not self.push_question( if not self.push_question(
"操作提示", "MAA未能正确登录到PRTS是否重试" "操作提示", "MAA未能正确登录到PRTS是否重试"
): ):
@@ -764,6 +762,7 @@ class MaaManager(QObject):
# 登录成功,录入人工排查情况 # 登录成功,录入人工排查情况
if run_book[0] and not self.isInterruptionRequested: if run_book[0] and not self.isInterruptionRequested:
self.play_sound.emit("排查录入")
if self.push_question( if self.push_question(
"操作提示", "请检查用户代理情况,该用户是否正确完成代理任务?" "操作提示", "请检查用户代理情况,该用户是否正确完成代理任务?"
): ):
@@ -885,6 +884,7 @@ class MaaManager(QObject):
self.maa_result = "任务被手动中止" self.maa_result = "任务被手动中止"
self.isInterruptionRequested = True self.isInterruptionRequested = True
self.wait_loop.quit()
def push_question(self, title: str, message: str) -> bool: def push_question(self, title: str, message: str) -> bool:
@@ -895,6 +895,12 @@ class MaaManager(QObject):
def __capture_response(self, response: bool) -> None: def __capture_response(self, response: bool) -> None:
self.response = response self.response = response
def sleep(self, time: int) -> None:
"""非阻塞型等待"""
QTimer.singleShot(time * 1000, self.wait_loop.quit)
self.wait_loop.exec()
def search_ADB_address(self) -> None: def search_ADB_address(self) -> None:
"""搜索ADB实际地址""" """搜索ADB实际地址"""
@@ -902,10 +908,7 @@ class MaaManager(QObject):
f"即将搜索ADB实际地址\n正在等待模拟器完成启动\n请等待{self.wait_time}s" f"即将搜索ADB实际地址\n正在等待模拟器完成启动\n请等待{self.wait_time}s"
) )
for _ in range(self.wait_time): self.sleep(self.wait_time)
if self.isInterruptionRequested:
break
time.sleep(1)
# 移除静默进程标记 # 移除静默进程标记
Config.silence_list.remove(self.emulator_path) Config.silence_list.remove(self.emulator_path)
@@ -968,6 +971,7 @@ class MaaManager(QObject):
with self.maa_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, ensure_ascii=False, indent=4) json.dump(data, f, ensure_ascii=False, indent=4)
self.play_sound.emit("ADB成功")
return None return None
else: else:
@@ -975,6 +979,8 @@ class MaaManager(QObject):
else: else:
logger.info(f"{self.name} | 无法连接到ADB地址{ADB_address}") logger.info(f"{self.name} | 无法连接到ADB地址{ADB_address}")
self.play_sound.emit("ADB失败")
def refresh_maa_log(self) -> None: def refresh_maa_log(self) -> None:
"""刷新MAA日志""" """刷新MAA日志"""

View File

@@ -34,8 +34,7 @@ from email.mime.text import MIMEText
from email.utils import formataddr from email.utils import formataddr
import requests import requests
from PySide6.QtCore import Signal from PySide6.QtCore import QObject, Signal
from PySide6.QtWidgets import QWidget
from loguru import logger from loguru import logger
from plyer import notification from plyer import notification
@@ -43,7 +42,7 @@ from app.core import Config
from app.services.security import Crypto from app.services.security import Crypto
class Notification(QWidget): class Notification(QObject):
push_info_bar = Signal(str, str, str, int) push_info_bar = Signal(str, str, str, int)

View File

@@ -48,7 +48,7 @@ from PySide6.QtGui import QTextCursor
from typing import List, Dict from typing import List, Dict
from app.core import Config, TaskManager, Task, MainInfoBar from app.core import Config, TaskManager, Task, MainInfoBar, SoundPlayer
from .Widget import StatefulItemCard, ComboBoxMessageBox, PivotArea from .Widget import StatefulItemCard, ComboBoxMessageBox, PivotArea

View File

@@ -78,6 +78,8 @@ class DownloadProcess(QThread):
) -> None: ) -> None:
super(DownloadProcess, self).__init__() super(DownloadProcess, self).__init__()
self.setObjectName(f"DownloadProcess-{url}-{start_byte}-{end_byte}")
self.url = url self.url = url
self.start_byte = start_byte self.start_byte = start_byte
self.end_byte = end_byte self.end_byte = end_byte
@@ -157,6 +159,8 @@ class ZipExtractProcess(QThread):
def __init__(self, name: str, app_path: Path, download_path: Path) -> None: def __init__(self, name: str, app_path: Path, download_path: Path) -> None:
super(ZipExtractProcess, self).__init__() super(ZipExtractProcess, self).__init__()
self.setObjectName(f"ZipExtractProcess-{name}")
self.name = name self.name = name
self.app_path = app_path self.app_path = app_path
self.download_path = download_path self.download_path = download_path

View File

@@ -51,7 +51,7 @@ from pathlib import Path
from typing import Union, List, Dict from typing import Union, List, Dict
from app.core import Config from app.core import Config, SoundPlayer
from .Widget import StatefulItemCard, QuantifiedItemCard, QuickExpandGroupCard from .Widget import StatefulItemCard, QuantifiedItemCard, QuickExpandGroupCard
@@ -83,6 +83,8 @@ class History(QWidget):
def reload_history(self, mode: str, start_date: QDate, end_date: QDate) -> None: def reload_history(self, mode: str, start_date: QDate, end_date: QDate) -> None:
"""加载历史记录界面""" """加载历史记录界面"""
SoundPlayer.play("历史记录查询")
while self.content_layout.count() > 0: while self.content_layout.count() > 0:
item = self.content_layout.takeAt(0) item = self.content_layout.takeAt(0)
if item.spacerItem(): if item.spacerItem():

View File

@@ -199,20 +199,22 @@ class Home(QWidget):
elif Config.get(Config.function_HomeImageMode) == "主题图像": elif Config.get(Config.function_HomeImageMode) == "主题图像":
# 从远程服务器获取最新主题图像 # 从远程服务器获取最新主题图像
Network.set_info( network = Network.add_task(
mode="get", mode="get",
url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/theme_image.json", url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/theme_image.json",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
theme_image = Network.response_json theme_image = network_result["response_json"]
else: else:
logger.warning(f"获取最新主题图像时出错:{Network.error_message}") logger.warning(
f"获取最新主题图像时出错:{network_result['error_message']}"
)
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"warning", "warning",
"获取最新主题图像时出错", "获取最新主题图像时出错",
f"网络错误:{Network.stutus_code}", f"网络错误:{network_result['status_code']}",
5000, 5000,
) )
return None return None
@@ -236,15 +238,15 @@ class Home(QWidget):
> time_local > time_local
): ):
Network.set_info( network = Network.add_task(
mode="get_file", mode="get_file",
url=theme_image["url"], url=theme_image["url"],
path=Config.app_path / "resources/images/Home/BannerTheme.jpg", path=Config.app_path / "resources/images/Home/BannerTheme.jpg",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
with (Config.app_path / "resources/theme_image.json").open( with (Config.app_path / "resources/theme_image.json").open(
mode="w", encoding="utf-8" mode="w", encoding="utf-8"
@@ -261,11 +263,13 @@ class Home(QWidget):
else: else:
logger.warning(f"下载最新主题图像时出错:{Network.error_message}") logger.warning(
f"下载最新主题图像时出错:{network_result['error_message']}"
)
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"warning", "warning",
"下载最新主题图像时出错", "下载最新主题图像时出错",
f"网络错误:{Network.stutus_code}", f"网络错误:{network_result['status_code']}",
5000, 5000,
) )

View File

@@ -45,7 +45,7 @@ from datetime import datetime, timedelta
import shutil import shutil
import darkdetect import darkdetect
from app.core import Config, TaskManager, MainTimer, MainInfoBar from app.core import Config, TaskManager, MainTimer, MainInfoBar, SoundPlayer
from app.services import Notify, Crypto, System from app.services import Notify, Crypto, System
from .home import Home from .home import Home
from .member_manager import MemberManager from .member_manager import MemberManager
@@ -285,6 +285,7 @@ class AUTO_MAA(MSFluentWindow):
and not self.window().isMaximized() and not self.window().isMaximized()
): ):
self.titleBar.maxBtn.click() self.titleBar.maxBtn.click()
SoundPlayer.play("欢迎回来")
self.show_ui("配置托盘") self.show_ui("配置托盘")
elif if_start: elif if_start:
if Config.get(Config.ui_maximized) and not self.window().isMaximized(): if Config.get(Config.ui_maximized) and not self.window().isMaximized():

View File

@@ -58,7 +58,15 @@ from typing import List
import shutil import shutil
import json import json
from app.core import Config, MainInfoBar, TaskManager, MaaConfig, MaaUserConfig, Network from app.core import (
Config,
MainInfoBar,
TaskManager,
MaaConfig,
MaaUserConfig,
Network,
SoundPlayer,
)
from app.services import Crypto from app.services import Crypto
from .downloader import DownloadManager from .downloader import DownloadManager
from .Widget import ( from .Widget import (
@@ -181,6 +189,7 @@ class MemberManager(QWidget):
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"success", "操作成功", f"添加脚本实例 脚本_{index}", 3000 "success", "操作成功", f"添加脚本实例 脚本_{index}", 3000
) )
SoundPlayer.play("添加脚本实例")
def del_setting_box(self): def del_setting_box(self):
"""删除一个脚本实例""" """删除一个脚本实例"""
@@ -221,6 +230,7 @@ class MemberManager(QWidget):
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"success", "操作成功", f"删除脚本实例 {name}", 3000 "success", "操作成功", f"删除脚本实例 {name}", 3000
) )
SoundPlayer.play("删除脚本实例")
def left_setting_box(self): def left_setting_box(self):
"""向左移动脚本实例""" """向左移动脚本实例"""
@@ -333,20 +343,20 @@ class MemberManager(QWidget):
return None return None
# 从远程服务器获取应用列表 # 从远程服务器获取应用列表
Network.set_info( network = Network.add_task(
mode="get", mode="get",
url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/apps_info.json", url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/apps_info.json",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
apps_info = Network.response_json apps_info = network_result["response_json"]
else: else:
logger.warning(f"获取应用列表时出错:{Network.error_message}") logger.warning(f"获取应用列表时出错:{network_result['error_message']}")
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"warning", "warning",
"获取应用列表时出错", "获取应用列表时出错",
f"网络错误:{Network.stutus_code}", f"网络错误:{network_result['status_code']}",
5000, 5000,
) )
return None return None
@@ -376,19 +386,19 @@ class MemberManager(QWidget):
return None return None
# 从mirrorc服务器获取最新版本信息 # 从mirrorc服务器获取最新版本信息
Network.set_info( network = Network.add_task(
mode="get", mode="get",
url=f"https://mirrorchyan.com/api/resources/{app_rid}/latest?user_agent=AutoMaaGui&cdk={Crypto.win_decryptor(Config.get(Config.update_MirrorChyanCDK))}&os={apps_info[app_name]["os"]}&arch={apps_info[app_name]["arch"]}&channel=stable", url=f"https://mirrorchyan.com/api/resources/{app_rid}/latest?user_agent=AutoMaaGui&cdk={Crypto.win_decryptor(Config.get(Config.update_MirrorChyanCDK))}&os={apps_info[app_name]["os"]}&arch={apps_info[app_name]["arch"]}&channel=stable",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
app_info = Network.response_json app_info = network_result["response_json"]
else: else:
if Network.response_json: if network_result["response_json"]:
app_info = Network.response_json app_info = network_result["response_json"]
if app_info["code"] != 0: if app_info["code"] != 0:
@@ -425,11 +435,11 @@ class MemberManager(QWidget):
return None return None
logger.warning(f"获取版本信息时出错:{Network.error_message}") logger.warning(f"获取版本信息时出错:{network_result['error_message']}")
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"warning", "warning",
"获取版本信息时出错", "获取版本信息时出错",
f"网络错误:{Network.stutus_code}", f"网络错误:{network_result['status_code']}",
5000, 5000,
) )
return None return None
@@ -885,6 +895,7 @@ class MemberManager(QWidget):
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"success", "操作成功", f"{self.name} 添加 用户_{index}", 3000 "success", "操作成功", f"{self.name} 添加 用户_{index}", 3000
) )
SoundPlayer.play("添加用户")
def del_user(self): def del_user(self):
"""删除一个用户""" """删除一个用户"""
@@ -944,6 +955,7 @@ class MemberManager(QWidget):
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"success", "操作成功", f"{self.name} 删除 {name}", 3000 "success", "操作成功", f"{self.name} 删除 {name}", 3000
) )
SoundPlayer.play("删除用户")
def left_user(self): def left_user(self):
"""向前移动用户""" """向前移动用户"""

View File

@@ -43,7 +43,7 @@ from qfluentwidgets import (
from typing import List, Dict, Union from typing import List, Dict, Union
import shutil import shutil
from app.core import Config, MainInfoBar, MaaPlanConfig from app.core import Config, MainInfoBar, MaaPlanConfig, SoundPlayer
from .Widget import ( from .Widget import (
ComboBoxMessageBox, ComboBoxMessageBox,
LineEditSettingCard, LineEditSettingCard,
@@ -129,6 +129,7 @@ class PlanManager(QWidget):
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"success", "操作成功", f"添加计划表 计划_{index}", 3000 "success", "操作成功", f"添加计划表 计划_{index}", 3000
) )
SoundPlayer.play("添加计划表")
def del_setting_box(self): def del_setting_box(self):
"""删除一个计划表""" """删除一个计划表"""
@@ -167,6 +168,7 @@ class PlanManager(QWidget):
logger.success(f"计划表 {name} 删除成功") logger.success(f"计划表 {name} 删除成功")
MainInfoBar.push_info_bar("success", "操作成功", f"删除计划表 {name}", 3000) MainInfoBar.push_info_bar("success", "操作成功", f"删除计划表 {name}", 3000)
SoundPlayer.play("删除计划表")
def left_setting_box(self): def left_setting_box(self):
"""向左移动计划表""" """向左移动计划表"""

View File

@@ -42,7 +42,7 @@ from qfluentwidgets import (
) )
from typing import List from typing import List
from app.core import QueueConfig, Config, MainInfoBar from app.core import QueueConfig, Config, MainInfoBar, SoundPlayer
from .Widget import ( from .Widget import (
SwitchSettingCard, SwitchSettingCard,
ComboBoxSettingCard, ComboBoxSettingCard,
@@ -116,6 +116,7 @@ class QueueManager(QWidget):
logger.success(f"调度队列_{index} 添加成功") logger.success(f"调度队列_{index} 添加成功")
MainInfoBar.push_info_bar("success", "操作成功", f"添加 调度队列_{index}", 3000) MainInfoBar.push_info_bar("success", "操作成功", f"添加 调度队列_{index}", 3000)
SoundPlayer.play("添加调度队列")
def del_setting_box(self): def del_setting_box(self):
"""删除一个调度队列实例""" """删除一个调度队列实例"""
@@ -154,6 +155,7 @@ class QueueManager(QWidget):
logger.success(f"{name} 删除成功") logger.success(f"{name} 删除成功")
MainInfoBar.push_info_bar("success", "操作成功", f"删除 {name}", 3000) MainInfoBar.push_info_bar("success", "操作成功", f"删除 {name}", 3000)
SoundPlayer.play("删除调度队列")
def left_setting_box(self): def left_setting_box(self):
"""向左移动调度队列实例""" """向左移动调度队列实例"""

View File

@@ -49,7 +49,7 @@ from packaging import version
from pathlib import Path from pathlib import Path
from typing import Dict, Union from typing import Dict, Union
from app.core import Config, MainInfoBar, Network from app.core import Config, MainInfoBar, Network, SoundPlayer
from app.services import Crypto, System, Notify from app.services import Crypto, System, Notify
from .downloader import DownloadManager from .downloader import DownloadManager
from .Widget import ( from .Widget import (
@@ -71,6 +71,7 @@ class Setting(QWidget):
self.setObjectName("设置") self.setObjectName("设置")
self.function = FunctionSettingCard(self) self.function = FunctionSettingCard(self)
self.voice = VoiceSettingCard(self)
self.start = StartSettingCard(self) self.start = StartSettingCard(self)
self.ui = UiSettingCard(self) self.ui = UiSettingCard(self)
self.notification = NotifySettingCard(self) self.notification = NotifySettingCard(self)
@@ -94,6 +95,7 @@ class Setting(QWidget):
content_layout = QVBoxLayout(content_widget) content_layout = QVBoxLayout(content_widget)
content_layout.setContentsMargins(0, 0, 11, 0) content_layout.setContentsMargins(0, 0, 11, 0)
content_layout.addWidget(self.function) content_layout.addWidget(self.function)
content_layout.addWidget(self.voice)
content_layout.addWidget(self.start) content_layout.addWidget(self.start)
content_layout.addWidget(self.ui) content_layout.addWidget(self.ui)
content_layout.addWidget(self.notification) content_layout.addWidget(self.notification)
@@ -262,31 +264,26 @@ class Setting(QWidget):
current_version = list(map(int, Config.VERSION.split("."))) current_version = list(map(int, Config.VERSION.split(".")))
if Network.if_running and if_show:
MainInfoBar.push_info_bar(
"warning", "请求速度过快", "上个网络请求还未结束,请稍等片刻", 5000
)
return None
# 从远程服务器获取最新版本信息 # 从远程服务器获取最新版本信息
Network.set_info( network = Network.add_task(
mode="get", mode="get",
url=f"https://mirrorchyan.com/api/resources/AUTO_MAA/latest?user_agent=AutoMaaGui&current_version={version_text(current_version)}&cdk={Crypto.win_decryptor(Config.get(Config.update_MirrorChyanCDK))}&channel={Config.get(Config.update_UpdateType)}", url=f"https://mirrorchyan.com/api/resources/AUTO_MAA/latest?user_agent=AutoMaaGui&current_version={version_text(current_version)}&cdk={Crypto.win_decryptor(Config.get(Config.update_MirrorChyanCDK))}&channel={Config.get(Config.update_UpdateType)}",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
version_info: Dict[str, Union[int, str, Dict[str, str]]] = ( version_info: Dict[str, Union[int, str, Dict[str, str]]] = network_result[
Network.response_json "response_json"
) ]
else: else:
if Network.response_json: if network_result["response_json"]:
version_info = Network.response_json version_info = network_result["response_json"]
if version_info["code"] != 0: if version_info["code"] != 0:
logger.error(f"获取版本信息时出错:{version_info["msg"]}") logger.error(f"获取版本信息时出错:{version_info['msg']}")
error_remark_dict = { error_remark_dict = {
1001: "获取版本信息的URL参数不正确", 1001: "获取版本信息的URL参数不正确",
@@ -319,11 +316,11 @@ class Setting(QWidget):
return None return None
logger.warning(f"获取版本信息时出错:{Network.error_message}") logger.warning(f"获取版本信息时出错:{network_result['error_message']}")
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"warning", "warning",
"获取版本信息时出错", "获取版本信息时出错",
f"网络错误:{Network.stutus_code}", f"网络错误:{network_result['status_code']}",
5000, 5000,
) )
return None return None
@@ -381,6 +378,7 @@ class Setting(QWidget):
all_version_info[key] = value.copy() all_version_info[key] = value.copy()
# 询问是否开始版本更新 # 询问是否开始版本更新
SoundPlayer.play("有新版本")
choice = NoticeMessageBox( choice = NoticeMessageBox(
self.window(), self.window(),
"版本更新", "版本更新",
@@ -406,20 +404,22 @@ class Setting(QWidget):
else: else:
# 从远程服务器获取代理信息 # 从远程服务器获取代理信息
Network.set_info( network = Network.add_task(
mode="get", mode="get",
url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/download_info.json", url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/download_info.json",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
download_info = Network.response_json download_info = network_result["response_json"]
else: else:
logger.warning(f"获取应用列表时出错:{Network.error_message}") logger.warning(
f"获取应用列表时出错:{network_result['error_message']}"
)
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"warning", "warning",
"获取应用列表时出错", "获取应用列表时出错",
f"网络错误:{Network.stutus_code}", f"网络错误:{network_result['status_code']}",
5000, 5000,
) )
return None return None
@@ -464,8 +464,10 @@ class Setting(QWidget):
3600000, 3600000,
if_force=True, if_force=True,
) )
SoundPlayer.play("有新版本")
else: else:
MainInfoBar.push_info_bar("success", "更新检查", "已是最新版本~", 3000) MainInfoBar.push_info_bar("success", "更新检查", "已是最新版本~", 3000)
SoundPlayer.play("无新版本")
def start_setup(self) -> None: def start_setup(self) -> None:
subprocess.Popen( subprocess.Popen(
@@ -488,20 +490,20 @@ class Setting(QWidget):
"""显示公告""" """显示公告"""
# 从远程服务器获取最新公告 # 从远程服务器获取最新公告
Network.set_info( network = Network.add_task(
mode="get", mode="get",
url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/notice.json", url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/notice.json",
) )
Network.start() network.loop.exec()
Network.loop.exec() network_result = Network.get_result(network)
if Network.stutus_code == 200: if network_result["status_code"] == 200:
notice = Network.response_json notice = network_result["response_json"]
else: else:
logger.warning(f"获取最新公告时出错:{Network.error_message}") logger.warning(f"获取最新公告时出错:{network_result['error_message']}")
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"warning", "warning",
"获取最新公告时出错", "获取最新公告时出错",
f"网络错误:{Network.stutus_code}", f"网络错误:{network_result['status_code']}",
5000, 5000,
) )
return None return None
@@ -533,6 +535,7 @@ class Setting(QWidget):
choice = NoticeMessageBox(self.window(), "公告", notice["notice_dict"]) choice = NoticeMessageBox(self.window(), "公告", notice["notice_dict"])
choice.button_cancel.hide() choice.button_cancel.hide()
choice.button_layout.insertStretch(0, 1) choice.button_layout.insertStretch(0, 1)
SoundPlayer.play("公告展示")
if choice.exec(): if choice.exec():
with (Config.app_path / "resources/notice.json").open( with (Config.app_path / "resources/notice.json").open(
mode="w", encoding="utf-8" mode="w", encoding="utf-8"
@@ -548,6 +551,7 @@ class Setting(QWidget):
MainInfoBar.push_info_bar( MainInfoBar.push_info_bar(
"info", "有新公告", "请前往设置界面查看公告", 3600000, if_force=True "info", "有新公告", "请前往设置界面查看公告", 3600000, if_force=True
) )
SoundPlayer.play("公告通知")
return None return None
@@ -656,6 +660,36 @@ class FunctionSettingCard(HeaderCardWidget):
self.addGroupWidget(widget) self.addGroupWidget(widget)
class VoiceSettingCard(HeaderCardWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setTitle("音效")
self.card_Enabled = SwitchSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="音效开关",
content="是否启用音效",
qconfig=Config,
configItem=Config.voice_Enabled,
parent=self,
)
self.card_Type = ComboBoxSettingCard(
icon=FluentIcon.PAGE_RIGHT,
title="音效模式",
content="选择音效的播放模式",
texts=["简洁", "聒噪"],
qconfig=Config,
configItem=Config.voice_Type,
parent=self,
)
Layout = QVBoxLayout()
Layout.addWidget(self.card_Enabled)
Layout.addWidget(self.card_Type)
self.viewLayout.addLayout(Layout)
class StartSettingCard(HeaderCardWidget): class StartSettingCard(HeaderCardWidget):
def __init__(self, parent=None): def __init__(self, parent=None):

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,53 +1,26 @@
{ {
"main_version": "4.3.8.0", "main_version": "4.3.9.0",
"version_info": { "version_info": {
"4.3.8.0": { "4.3.9.0": {
"新增功能": [ "修复bug": [
"吐司通知在主窗口隐藏时不再弹出" "修复网络模块子线程未及时销毁导致的程序崩溃"
] ]
}, },
"4.3.8.4": { "4.3.9.2": {
"新增功能": [
"支持为每一个用户执行独立通知",
"输入文本框适配文本插入操作",
"计划表功能上线",
"静默控制时长从全任务内缩短至搜索ADB时段内",
"UI界面添加自动日常代理任务序列设置项"
],
"修复bug": [ "修复bug": [
"修复雷电模拟器静默模式无法正常识别模拟器是否隐藏相关问题" "修复语音包禁忌二重奏"
] ]
}, },
"4.3.8.3": { "4.3.9.1": {
"新增功能": [ "新增功能": [
"用户仪表盘支持直接控制用户状态" "语音功能上线"
], ],
"修复bug": [ "修复bug": [
"修复雷电ADB端口号相关问题" "网络模块支持并发请求",
] "修复中止任务时程序异常卡顿"
},
"4.3.8.2": {
"新增功能": [
"添加ADB端口号宽幅适配能力"
],
"修复bug": [
"日志分析忽略MAA超时提示"
], ],
"程序优化": [ "程序优化": [
"配置类定义方法优化" "非UI组件转为QObject类"
]
},
"4.3.8.1": {
"新增功能": [
"自定义基建显示配置名称 #46",
"主调度台添加仅一次电源任务"
],
"修复bug": [
"电源相关选项改为所有任务完成后生效",
"适配MAAv5.16.3的ADB报错信息更改"
],
"程序优化": [
"UI样式优化进一步适配win10主题"
] ]
} }
} }