From ee40fdb3c36b84d78c7d5ae05262bb031b67ebcd Mon Sep 17 00:00:00 2001 From: DLmaster Date: Wed, 1 Jan 2025 11:54:55 +0800 Subject: [PATCH 1/2] Merge branch 'main' --- .github/workflows/python-app.yml | 28 ++-- app/config.py | 55 ++++---- app/models/MAA.py | 105 +++++++-------- app/services/notification.py | 4 +- app/services/security.py | 90 ++++++------- app/ui/gui.py | 218 ++++++++++++------------------- app/utils/Updater.py | 27 ++-- app/utils/package.py | 51 ++++---- update_info.txt | 10 -- 9 files changed, 243 insertions(+), 345 deletions(-) delete mode 100644 update_info.txt diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index c5b0d5a..8b14e97 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -77,9 +77,9 @@ jobs: - name: Read version id: read_version run: | - $MAIN_VERSION=(Get-Content -Path "update_info.txt" -TotalCount 1).Trim() + $MAIN_VERSION=(Get-Content -Path "version_info.txt" -TotalCount 1).Trim() "AUTO_MAA_version=$MAIN_VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append - $UPDATER_VERSION=(Get-Content -Path "update_info.txt" -TotalCount 2 | Select-Object -Index 1).Trim() + $UPDATER_VERSION=(Get-Content -Path "version_info.txt" -TotalCount 2 | Select-Object -Index 1).Trim() "updater_version=$UPDATER_VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append - name: Create Zip id: create_zip @@ -93,11 +93,11 @@ jobs: path: | AUTO_MAA_${{ env.AUTO_MAA_version }}.zip Updater_${{ env.updater_version }}.zip - - name: Upload Update_Info Artifact + - name: Upload Version_Info Artifact uses: actions/upload-artifact@v4 with: - name: update_info - path: update_info.txt + name: version_info + path: version_info.txt publish_release: name: Publish release needs: build_AUTO_MAA @@ -111,15 +111,15 @@ jobs: pattern: AUTO_MAA_* merge-multiple: true path: artifacts - - name: Download Update_Info + - name: Download Version_Info uses: actions/download-artifact@v4 with: - name: update_info + name: version_info path: ./ - name: Check if release exists id: check_if_release_exists run: | - release_id=$(gh release view $(sed 's/\r$//g' <(head -n 1 update_info.txt)) --json id --jq .id || true) + release_id=$(gh release view $(sed 's/\r$//g' <(head -n 1 version_info.txt)) --json id --jq .id || true) if [[ -z $release_id ]]; then echo "release_exists=false" >> $GITHUB_OUTPUT else @@ -133,9 +133,9 @@ jobs: run: | set -xe shopt -s nullglob - NAME="$(sed 's/\r$//g' <(head -n 1 update_info.txt))" - TAGNAME="$(sed 's/\r$//g' <(head -n 1 update_info.txt))" - NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 update_info.txt))" + NAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))" + TAGNAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))" + NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 version_info.txt))" NOTES_TAIL="\`\`\`本release通过GitHub Actions自动构建\`\`\`" NOTES="$NOTES_MAIN

$NOTES_TAIL" gh release create "$TAGNAME" --target "main" --title "$NAME" --notes "$NOTES" artifacts/* @@ -147,9 +147,9 @@ jobs: run: | set -xe shopt -s nullglob - NAME="$(sed 's/\r$//g' <(head -n 1 update_info.txt))" - TAGNAME="$(sed 's/\r$//g' <(head -n 1 update_info.txt))" - NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 update_info.txt))" + NAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))" + TAGNAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))" + NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 version_info.txt))" NOTES_TAIL="\`\`\`本release通过GitHub Actions自动构建\`\`\`" NOTES="$NOTES_MAIN

$NOTES_TAIL" gh release delete "$TAGNAME" --yes diff --git a/app/config.py b/app/config.py index 9be1336..c5264e5 100644 --- a/app/config.py +++ b/app/config.py @@ -29,6 +29,7 @@ import sqlite3 import json import os import sys +from pathlib import Path from typing import Dict, Union @@ -36,17 +37,15 @@ class AppConfig: def __init__(self) -> None: - self.app_path = os.path.normpath( - os.path.dirname(os.path.realpath(sys.argv[0])) - ) # 获取软件自身的路径 + self.app_path = Path.cwd() # 获取软件根目录 self.app_path_sys = os.path.realpath(sys.argv[0]) # 获取软件自身的路径 self.app_name = os.path.basename(self.app_path) # 获取软件自身的名称 - self.database_path = os.path.normpath(f"{self.app_path}/data/data.db") - self.config_path = os.path.normpath(f"{self.app_path}/config/gui.json") - self.key_path = os.path.normpath(f"{self.app_path}/data/key") - self.gameid_path = os.path.normpath(f"{self.app_path}/data/gameid.txt") - self.version_path = os.path.normpath(f"{self.app_path}/resources/version.json") + self.database_path = self.app_path / "data/data.db" + self.config_path = self.app_path / "config/gui.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.initialize() @@ -57,40 +56,32 @@ class AppConfig: """初始化程序的配置文件""" # 检查目录 - os.makedirs(os.path.normpath(f"{self.app_path}/data"), exist_ok=True) - os.makedirs(os.path.normpath(f"{self.app_path}/config"), exist_ok=True) - os.makedirs( - os.path.normpath(f"{self.app_path}/data/MAAconfig/simple"), exist_ok=True - ) - os.makedirs( - os.path.normpath(f"{self.app_path}/data/MAAconfig/beta"), exist_ok=True - ) - os.makedirs( - os.path.normpath(f"{self.app_path}/data/MAAconfig/Default"), exist_ok=True - ) + (self.app_path / "config").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 os.path.exists(self.version_path): + if not self.version_path.exists(): version = { "main_version": "0.0.0.0", "updater_version": "0.0.0.0", } - with open(self.version_path, "w", encoding="utf-8") as f: + with self.version_path.open(mode="w", encoding="utf-8") as f: json.dump(version, f, indent=4) # 生成配置文件 - if not os.path.exists(self.config_path): + if not self.config_path.exists(): config = {"Default": {}} - with open(self.config_path, "w", encoding="utf-8") as f: + with self.config_path.open(mode="w", encoding="utf-8") as f: json.dump(config, f, indent=4) # 生成预设gameid替换方案文件 - if not os.path.exists(self.gameid_path): - with open(self.gameid_path, "w", encoding="utf-8") as f: - print( - "龙门币:CE-6\n技能:CA-5\n红票:AP-5\n经验:LS-6\n剿灭模式:Annihilation", - file=f, - ) + 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", + ) def check_config(self) -> None: """检查配置文件字段完整性并补全""" @@ -136,7 +127,7 @@ class AppConfig: ] # 导入配置文件 - with open(self.config_path, "r", encoding="utf-8") as f: + with self.config_path.open(mode="r", encoding="utf-8") as f: config = json.load(f) # 检查并补充缺失的字段 @@ -154,7 +145,7 @@ class AppConfig: """检查用户数据库文件并处理数据库版本更新""" # 生成用户数据库 - if not os.path.exists(self.database_path): + if not self.database_path.exists(): db = sqlite3.connect(self.database_path) cur = db.cursor() cur.execute( @@ -244,5 +235,5 @@ class AppConfig: def save_config(self) -> None: """保存配置文件""" - with open(self.config_path, "w", encoding="utf-8") as f: + with self.config_path.open(mode="w", encoding="utf-8") as f: json.dump(self.content, f, indent=4) diff --git a/app/models/MAA.py b/app/models/MAA.py index af9796f..e268645 100644 --- a/app/models/MAA.py +++ b/app/models/MAA.py @@ -32,6 +32,7 @@ import os import subprocess import shutil import time +from pathlib import Path from app import AppConfig @@ -59,16 +60,11 @@ class MaaManager(QtCore.QThread): def configure(self): """提取配置信息""" - self.set_path = os.path.normpath( - f"{self.config.content["Default"]["MaaSet.path"]}/config/gui.json" - ) - self.log_path = os.path.normpath( - f"{self.config.content["Default"]["MaaSet.path"]}/debug/gui.log" - ) - self.maa_path = os.path.normpath( - f"{self.config.content["Default"]["MaaSet.path"]}/MAA.exe" - ) - self.json_path = os.path.normpath(f"{self.config.app_path}/data/MAAconfig") + self.maa_root_path = Path(self.config.content["Default"]["MaaSet.path"]) + self.set_path = self.maa_root_path / "config/gui.json" + self.log_path = self.maa_root_path / "debug/gui.log" + self.maa_path = self.maa_root_path / "MAA.exe" + self.json_path = self.config.app_path / "data/MAAconfig" self.routine = self.config.content["Default"]["TimeLimit.routine"] self.annihilation = self.config.content["Default"]["TimeLimit.annihilation"] self.num = self.config.content["Default"]["TimesLimit.run"] @@ -500,33 +496,29 @@ class MaaManager(QtCore.QThread): # 保存运行日志 end_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") - with open( - os.path.normpath(f"{self.config.app_path}/log.txt"), - "w", - encoding="utf-8", - ) as f: - print(f"任务开始时间:{begin_time},结束时间:{end_time}", file=f) - print( - f"已完成数:{len(over_index)},未完成数:{len(error_index) + len(wait_index)}\n", - file=f, + end_log = ( + f"任务开始时间:{begin_time},结束时间:{end_time}\n" + f"已完成数:{len(over_index)},未完成数:{len(error_index) + len(wait_index)}\n\n" + ) + + if len(error_index) != 0: + end_log += ( + f"{self.mode[2:4]}未成功的用户:\n" + f"{"\n".join([self.data[_][0] for _ in error_index])}\n" ) - if len(error_index) != 0: - print(f"{self.mode[2:4]}未成功的用户:", file=f) - print("\n".join([self.data[_][0] for _ in error_index]), file=f) - wait_index = [ - _ for _ in all_index if (not _ in over_index + error_index) - ] - if len(wait_index) != 0: - print(f"\n未开始{self.mode[2:4]}的用户:", file=f) - print("\n".join([self.data[_][0] for _ in wait_index]), file=f) + wait_index = [_ for _ in all_index if (not _ in over_index + error_index)] + if len(wait_index) != 0: + end_log += ( + f"\n未开始{self.mode[2:4]}的用户:\n" + f"{"\n".join([self.data[_][0] for _ in wait_index])}\n" + ) + + (self.config.app_path / "log.txt").write_text( + end_log, + encoding="utf-8", + ) # 恢复GUI运行面板 - with open( - os.path.normpath(f"{self.config.app_path}/log.txt"), - "r", - encoding="utf-8", - ) as f: - end_log = f.read() self.update_gui.emit("", "", "", "", end_log) # 推送代理结果通知 @@ -553,7 +545,7 @@ class MaaManager(QtCore.QThread): logs = [] if_log_start = False - with open(self.log_path, "r", encoding="utf-8") as f: + with self.log_path.open(mode="r", encoding="utf-8") as f: for entry in f: if not if_log_start: try: @@ -618,20 +610,18 @@ class MaaManager(QtCore.QThread): # 预导入MAA配置文件 if mode == "设置MAA_用户": set_book = ["simple", "beta"] - if os.path.exists( - os.path.normpath( - f"{self.json_path}/{set_book[self.get_json_path[0]]}/{self.get_json_path[1]}/{self.get_json_path[2]}/gui.json" - ) - ): + if ( + self.json_path + / f"{set_book[self.get_json_path[0]]}/{self.get_json_path[1]}/{self.get_json_path[2]}/gui.json" + ).exists(): shutil.copy( - os.path.normpath( - f"{self.json_path}/{set_book[self.get_json_path[0]]}/{self.get_json_path[1]}/{self.get_json_path[2]}/gui.json" - ), + self.json_path + / f"{set_book[self.get_json_path[0]]}/{self.get_json_path[1]}/{self.get_json_path[2]}/gui.json", self.set_path, ) else: shutil.copy( - os.path.normpath(f"{self.json_path}/Default/gui.json"), + self.json_path / "Default/gui.json", self.set_path, ) elif (mode == "设置MAA_全局") or ( @@ -639,32 +629,27 @@ class MaaManager(QtCore.QThread): and self.data[index][15] == "simple" ): shutil.copy( - os.path.normpath(f"{self.json_path}/Default/gui.json"), + self.json_path / "Default/gui.json", self.set_path, ) elif "日常代理" in mode and self.data[index][15] == "beta": if mode == "日常代理_剿灭": shutil.copy( - os.path.normpath( - f"{self.json_path}/beta/{self.data[index][16]}/annihilation/gui.json" - ), + self.json_path + / f"beta/{self.data[index][16]}/annihilation/gui.json", self.set_path, ) elif mode == "日常代理_日常": shutil.copy( - os.path.normpath( - f"{self.json_path}/beta/{self.data[index][16]}/routine/gui.json" - ), + self.json_path / f"beta/{self.data[index][16]}/routine/gui.json", self.set_path, ) elif "人工排查" in mode and self.data[index][15] == "beta": shutil.copy( - os.path.normpath( - f"{self.json_path}/beta/{self.data[index][16]}/routine/gui.json" - ), + self.json_path / f"beta/{self.data[index][16]}/routine/gui.json", self.set_path, ) - with open(self.set_path, "r", encoding="utf-8") as f: + with self.set_path.open(mode="r", encoding="utf-8") as f: data = json.load(f) # 日常代理配置 @@ -1000,7 +985,7 @@ class MaaManager(QtCore.QThread): ] = "False" # 生息演算 # 覆写配置文件 - with open(self.set_path, "w", encoding="utf-8") as f: + with self.set_path.open(mode="w", encoding="utf-8") as f: json.dump(data, f, indent=4) return True @@ -1009,12 +994,10 @@ class MaaManager(QtCore.QThread): """获取模拟器路径""" # 读取配置文件 - with open(self.set_path, "r", encoding="utf-8") as f: + with self.set_path.open(mode="r", encoding="utf-8") as f: set = json.load(f) - # 获取模拟器路径 - return os.path.normpath( - set["Configurations"]["Default"]["Start.EmulatorPath"] - ) + # 获取模拟器路径 + return Path(set["Configurations"]["Default"]["Start.EmulatorPath"]) def server_date(self): """获取当前的服务器日期""" diff --git a/app/services/notification.py b/app/services/notification.py index 2a56872..d8c45f8 100644 --- a/app/services/notification.py +++ b/app/services/notification.py @@ -48,9 +48,7 @@ class Notification: title=title, message=message, app_name="AUTO_MAA", - app_icon=os.path.normpath( - f"{self.config.app_path}/resources/icons/AUTO_MAA.ico" - ), + app_icon=self.config.app_path / "resources/icons/AUTO_MAA.ico", timeout=t, ticker=ticker, toast=True, diff --git a/app/services/security.py b/app/services/security.py index 4fbd3b1..b39dc00 100644 --- a/app/services/security.py +++ b/app/services/security.py @@ -47,32 +47,27 @@ class CryptoHandler: """配置管理密钥""" # 生成目录 - os.makedirs(os.path.normpath(f"{self.config.app_path}/data/key"), exist_ok=True) + self.config.key_path.mkdir(parents=True, exist_ok=True) # 生成RSA密钥对 key = RSA.generate(2048) public_key_local = key.publickey() private_key = key # 保存RSA公钥 - with open( - os.path.normpath(f"{self.config.app_path}/data/key/public_key.pem"), "wb" - ) as f: - f.write(public_key_local.exportKey()) + (self.config.app_path / "data/key/public_key.pem").write_bytes( + public_key_local.exportKey() + ) # 生成密钥转换与校验随机盐 PASSWORD_salt = secrets.token_hex(random.randint(32, 1024)) - with open( - os.path.normpath(f"{self.config.app_path}/data/key/PASSWORDsalt.txt"), - "w", + (self.config.app_path / "data/key/PASSWORDsalt.txt").write_text( + PASSWORD_salt, encoding="utf-8", - ) as f: - print(PASSWORD_salt, file=f) + ) verify_salt = secrets.token_hex(random.randint(32, 1024)) - with open( - os.path.normpath(f"{self.config.app_path}/data/key/verifysalt.txt"), - "w", + (self.config.app_path / "data/key/verifysalt.txt").write_text( + verify_salt, encoding="utf-8", - ) as f: - print(verify_salt, file=f) + ) # 将管理密钥转化为AES-256密钥 AES_password = hashlib.sha256( (PASSWORD + PASSWORD_salt).encode("utf-8") @@ -81,29 +76,23 @@ class CryptoHandler: AES_password_verify = hashlib.sha256( AES_password + verify_salt.encode("utf-8") ).digest() - with open( - os.path.normpath( - f"{self.config.app_path}/data/key/AES_password_verify.bin" - ), - "wb", - ) as f: - f.write(AES_password_verify) + (self.config.app_path / "data/key/AES_password_verify.bin").write_bytes( + AES_password_verify + ) # AES-256加密RSA私钥并保存密文 AES_key = AES.new(AES_password, AES.MODE_ECB) private_key_local = AES_key.encrypt(pad(private_key.exportKey(), 32)) - with open( - os.path.normpath(f"{self.config.app_path}/data/key/private_key.bin"), "wb" - ) as f: - f.write(private_key_local) + (self.config.app_path / "data/key/private_key.bin").write_bytes( + private_key_local + ) def encryptx(self, note: str) -> bytes: """加密数据""" # 读取RSA公钥 - with open( - os.path.normpath(f"{self.config.app_path}/data/key/public_key.pem"), "rb" - ) as f: - public_key_local = RSA.import_key(f.read()) + public_key_local = RSA.import_key( + (self.config.app_path / "data/key/public_key.pem").read_bytes() + ) # 使用RSA公钥对数据进行加密 cipher = PKCS1_OAEP.new(public_key_local) encrypted = cipher.encrypt(note.encode("utf-8")) @@ -113,29 +102,24 @@ class CryptoHandler: """解密数据""" # 读入RSA私钥密文、盐与校验哈希值 - with open( - os.path.normpath(f"{self.config.app_path}/data/key/private_key.bin"), "rb" - ) as f: - private_key_local = f.read().strip() - with open( - os.path.normpath(f"{self.config.app_path}/data/key/PASSWORDsalt.txt"), - "r", - encoding="utf-8", - ) as f: - PASSWORD_salt = f.read().strip() - with open( - os.path.normpath(f"{self.config.app_path}/data/key/verifysalt.txt"), - "r", - encoding="utf-8", - ) as f: - verify_salt = f.read().strip() - with open( - os.path.normpath( - f"{self.config.app_path}/data/key/AES_password_verify.bin" - ), - "rb", - ) as f: - AES_password_verify = f.read().strip() + private_key_local = ( + (self.config.app_path / "data/key/private_key.bin").read_bytes().strip() + ) + PASSWORD_salt = ( + (self.config.app_path / "data/key/PASSWORDsalt.txt") + .read_text(encoding="utf-8") + .strip() + ) + verify_salt = ( + (self.config.app_path / "data/key/verifysalt.txt") + .read_text(encoding="utf-8") + .strip() + ) + AES_password_verify = ( + (self.config.app_path / "data/key/AES_password_verify.bin") + .read_bytes() + .strip() + ) # 将管理密钥转化为AES-256密钥并验证 AES_password = hashlib.sha256( (PASSWORD + PASSWORD_salt).encode("utf-8") diff --git a/app/ui/gui.py b/app/ui/gui.py index 9cb7ef1..ea7fcc1 100644 --- a/app/ui/gui.py +++ b/app/ui/gui.py @@ -52,9 +52,9 @@ from PySide6.QtGui import QIcon, QCloseEvent from PySide6 import QtCore from functools import partial from typing import List, Tuple +from pathlib import Path import json import datetime -import os import ctypes import subprocess import shutil @@ -150,17 +150,13 @@ class Main(QWidget): ] # 导入ui配置 - self.ui = uiLoader.load( - os.path.normpath(f"{self.config.app_path}/resources/gui/main.ui") - ) + self.ui = uiLoader.load(self.config.app_path / "resources/gui/main.ui") self.ui.setWindowIcon( - QIcon( - os.path.normpath(f"{self.config.app_path}/resources/icons/AUTO_MAA.ico") - ) + QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico")) ) # 生成管理密钥 - if not os.path.exists(self.config.key_path): + if not self.config.key_path.exists(): while True: self.PASSWORD, ok_pressed = QInputDialog.getText( self.ui, @@ -608,9 +604,7 @@ class Main(QWidget): self.config.content["Default"]["SelfSet.MainIndex"] ) - self.maa_path.setText( - os.path.normpath(self.config.content["Default"]["MaaSet.path"]) - ) + self.maa_path.setText(str(Path(self.config.content["Default"]["MaaSet.path"]))) self.routine.setValue(self.config.content["Default"]["TimeLimit.routine"]) self.annihilation.setValue( self.config.content["Default"]["TimeLimit.annihilation"] @@ -688,7 +682,7 @@ class Main(QWidget): """添加一位新用户""" # 判断是否已设置管理密钥 - if not os.path.exists(self.config.key_path): + if not self.config.key_path.exists(): QMessageBox.critical( self.ui, "错误", @@ -752,15 +746,13 @@ class Main(QWidget): ), ) self.config.db.commit() - if os.path.exists( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}" - ) - ): + if ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}" + ).exists(): shutil.rmtree( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}" - ) + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}" ) # 后续用户补位 if self.user_set.currentIndex() == 0: @@ -773,18 +765,16 @@ class Main(QWidget): (i - 1, self.user_mode_list[self.user_set.currentIndex()], i), ) self.config.db.commit() - if os.path.exists( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}" - ) - ): - os.rename( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}" - ), - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i - 1}" - ), + if ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}" + ).exists(): + ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}" + ).rename( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i - 1}", ) # 同步最终结果至GUI @@ -841,18 +831,15 @@ class Main(QWidget): ), ) self.config.db.commit() - if os.path.exists( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}" - ) - ): + if ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}" + ).exists(): shutil.move( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}" - ), - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[1 - self.user_set.currentIndex()]}/{other_numb}" - ), + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}", + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[1 - self.user_set.currentIndex()]}/{other_numb}", ) # 后续用户补位 for i in range(row + 1, current_numb): @@ -861,19 +848,18 @@ class Main(QWidget): (i - 1, self.user_mode_list[self.user_set.currentIndex()], i), ) self.config.db.commit(), - if os.path.exists( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}" - ) - ): - os.rename( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}" - ), - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i - 1}" - ), + if ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}" + ).exists(): + ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i}" + ).rename( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{i - 1}" ) + self.update_user_info("normal") def get_maa_config(self, info): @@ -881,31 +867,22 @@ class Main(QWidget): # 获取全局MAA配置文件 if info == ["Default"]: - os.makedirs( - os.path.normpath(f"{self.config.app_path}/data/MAAconfig/Default"), - exist_ok=True, - ) shutil.copy( - os.path.normpath( - f"{self.config.content["Default"]["MaaSet.path"]}/config/gui.json" - ), - os.path.normpath(f"{self.config.app_path}/data/MAAconfig/Default"), + Path(self.config.content["Default"]["MaaSet.path"]) / "config/gui.json", + self.config.app_path / "data/MAAconfig/Default", ) # 获取基建配置文件 elif info[2] == "infrastructure": infrastructure_path = self.read("file_path_infrastructure") if infrastructure_path: - os.makedirs( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/infrastructure" - ), - exist_ok=True, - ) + ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/infrastructure" + ).mkdir(parents=True, exist_ok=True) shutil.copy( infrastructure_path, - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/infrastructure/infrastructure.json" - ), + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/infrastructure/infrastructure.json", ) return True else: @@ -917,19 +894,14 @@ class Main(QWidget): return False # 获取高级用户MAA配置文件 elif info[2] in ["routine", "annihilation"]: - os.makedirs( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}" - ), - exist_ok=True, - ) + ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}" + ).mkdir(parents=True, exist_ok=True) shutil.copy( - os.path.normpath( - f"{self.config.content["Default"]["MaaSet.path"]}/config/gui.json" - ), - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}" - ), + Path(self.config.content["Default"]["MaaSet.path"]) / "config/gui.json", + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}", ) def change_user_Item(self, item: QTableWidget, mode): @@ -952,7 +924,7 @@ class Main(QWidget): if item.column() in [6, 7, 8]: # 关卡号 # 导入与应用特殊关卡规则 games = {} - with open(self.config.gameid_path, encoding="utf-8") as f: + with self.config.gameid_path.open(mode="r", encoding="utf-8") as f: gameids = f.readlines() for line in gameids: if ":" in line: @@ -1006,11 +978,10 @@ class Main(QWidget): index == 2 or ( index == 0 - and not os.path.exists( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}/infrastructure/infrastructure.json" - ), - ) + and not ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}/infrastructure/infrastructure.json" + ).exists() ) ) ): @@ -1026,11 +997,10 @@ class Main(QWidget): index == 2 or ( index == 0 - and not os.path.exists( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}/{column}/gui.json" - ), - ) + and not ( + self.config.app_path + / f"data/MAAconfig/{self.user_mode_list[self.user_set.currentIndex()]}/{row}/{column}/gui.json" + ).exists() ) ) ): @@ -1097,16 +1067,14 @@ class Main(QWidget): return None # 验证MAA路径 - if os.path.normpath( - self.config.content["Default"]["MaaSet.path"] - ) != os.path.normpath(self.maa_path.text()): - if os.path.exists( - os.path.normpath(f"{self.maa_path.text()}/MAA.exe") - ) and os.path.exists( - os.path.normpath(f"{self.maa_path.text()}/config/gui.json") - ): - self.config.content["Default"]["MaaSet.path"] = os.path.normpath( - self.maa_path.text() + if Path(self.config.content["Default"]["MaaSet.path"]) != Path( + self.maa_path.text() + ): + if (Path(self.maa_path.text()) / "MAA.exe").exists() and ( + Path(self.maa_path.text()) / "config/gui.json" + ).exists(): + self.config.content["Default"]["MaaSet.path"] = str( + Path(self.maa_path.text()) ) self.get_maa_config(["Default"]) else: @@ -1358,17 +1326,13 @@ class Main(QWidget): """启动MaaManager线程运行任务""" # 检查MAA路径是否可用 - if not ( - os.path.exists( - os.path.normpath( - f"{self.config.content["Default"]["MaaSet.path"]}/MAA.exe" - ) - ) - and os.path.exists( - os.path.normpath( - f"{self.config.content["Default"]["MaaSet.path"]}/config/gui.json" - ) - ) + if ( + not ( + Path(self.config.content["Default"]["MaaSet.path"]) / "MAA.exe" + ).exists() + and ( + Path(self.config.content["Default"]["MaaSet.path"]) / "config/gui.json" + ).exists() ): QMessageBox.critical(self.ui, "错误", "您还未正确配置MAA路径!") return None @@ -1437,12 +1401,8 @@ class Main(QWidget): elif "结束" in mode: shutil.copy( - os.path.normpath( - f"{self.config.app_path}/data/MAAconfig/Default/gui.json" - ), - os.path.normpath( - f"{self.config.content["Default"]["MaaSet.path"]}/config" - ), + self.config.app_path / "data/MAAconfig/Default/gui.json", + Path(self.config.content["Default"]["MaaSet.path"]) / "config", ) self.user_add.setEnabled(True) self.user_del.setEnabled(True) @@ -1474,7 +1434,7 @@ class Main(QWidget): """检查版本更新,调起文件下载进程""" # 从本地版本信息文件获取当前版本信息 - with open(self.config.version_path, "r", encoding="utf-8") as f: + with self.config.version_path.open(mode="r", encoding="utf-8") as f: version_current = json.load(f) main_version_current = list( map(int, version_current["main_version"].split(".")) @@ -1483,7 +1443,7 @@ class Main(QWidget): map(int, version_current["updater_version"].split(".")) ) # 检查更新器是否存在 - if not os.path.exists(os.path.normpath(f"{self.config.app_path}/Updater.exe")): + if not (self.config.app_path / "Updater.exe").exists(): updater_version_current = [0, 0, 0, 0] # 从远程服务器获取最新版本信息 @@ -1565,7 +1525,7 @@ class Main(QWidget): """更新主程序""" subprocess.Popen( - os.path.normpath(f"{self.config.app_path}/Updater.exe"), + str(self.config.app_path / "Updater.exe"), shell=True, creationflags=subprocess.CREATE_NO_WINDOW, ) @@ -1597,17 +1557,13 @@ class AUTO_MAA(QMainWindow): self.main = Main(config=config, notify=notify, crypto=crypto) self.setCentralWidget(self.main.ui) self.setWindowIcon( - QIcon( - os.path.normpath(f"{self.config.app_path}/resources/icons/AUTO_MAA.ico") - ) + QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico")) ) self.setWindowTitle("AUTO_MAA") # 创建系统托盘及其菜单 self.tray = QSystemTrayIcon( - QIcon( - os.path.normpath(f"{self.config.app_path}/resources/icons/AUTO_MAA.ico") - ), + QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico")), self, ) self.tray.setToolTip("AUTO_MAA") diff --git a/app/utils/Updater.py b/app/utils/Updater.py index b846699..8f50f43 100644 --- a/app/utils/Updater.py +++ b/app/utils/Updater.py @@ -32,6 +32,7 @@ import zipfile import requests import subprocess import time +from pathlib import Path from PySide6.QtWidgets import ( QApplication, @@ -53,7 +54,7 @@ class UpdateProcess(QThread): accomplish = Signal() def __init__( - self, app_path: str, name: str, main_version: list, updater_version: list + self, app_path: Path, name: str, main_version: list, updater_version: list ) -> None: super(UpdateProcess, self).__init__() @@ -61,10 +62,8 @@ class UpdateProcess(QThread): self.name = name self.main_version = main_version self.updater_version = updater_version - self.download_path = os.path.normpath( - f"{app_path}/AUTO_MAA_Update.zip" - ) # 临时下载文件的路径 - self.version_path = os.path.normpath(f"{app_path}/resources/version.json") + self.download_path = app_path / "AUTO_MAA_Update.zip" # 临时下载文件的路径 + self.version_path = app_path / "resources/version.json" def run(self) -> None: @@ -185,7 +184,7 @@ class UpdateProcess(QThread): # 主程序更新完成后打开AUTO_MAA if self.name == "AUTO_MAA主程序": subprocess.Popen( - os.path.normpath(f"{self.app_path}/AUTO_MAA.exe"), + str(self.app_path / "AUTO_MAA.exe"), shell=True, creationflags=subprocess.CREATE_NO_WINDOW, ) @@ -252,7 +251,7 @@ class UpdateProcess(QThread): class Updater(QObject): def __init__( - self, app_path: str, name: str, main_version: list, updater_version: list + self, app_path: Path, name: str, main_version: list, updater_version: list ) -> None: super().__init__() @@ -260,7 +259,7 @@ class Updater(QObject): self.ui.setWindowTitle("AUTO_MAA更新器") self.ui.resize(700, 70) self.ui.setWindowIcon( - QIcon(os.path.normpath(f"{app_path}/resources/icons/AUTO_MAA_Updater.ico")) + QIcon(str(app_path / "resources/icons/AUTO_MAA_Updater.ico")) ) # 创建垂直布局 @@ -292,7 +291,7 @@ class Updater(QObject): class AUTO_MAA_Updater(QApplication): def __init__( - self, app_path: str, name: str, main_version: list, updater_version: list + self, app_path: Path, name: str, main_version: list, updater_version: list ) -> None: super().__init__() @@ -303,14 +302,12 @@ class AUTO_MAA_Updater(QApplication): if __name__ == "__main__": # 获取软件自身的路径 - app_path = os.path.normpath(os.path.dirname(os.path.realpath(sys.argv[0]))) + app_path = Path.cwd() # 从本地版本信息文件获取当前版本信息 - if os.path.exists(os.path.normpath(f"{app_path}/resources/version.json")): - with open( - os.path.normpath(f"{app_path}/resources/version.json"), - "r", - encoding="utf-8", + if (app_path / "resources/version.json").exists(): + with (app_path / "resources/version.json").open( + mode="r", encoding="utf-8" ) as f: version_current = json.load(f) main_version_current = list( diff --git a/app/utils/package.py b/app/utils/package.py index 060d047..5120980 100644 --- a/app/utils/package.py +++ b/app/utils/package.py @@ -29,19 +29,22 @@ import os import json import shutil import subprocess +from pathlib import Path from app import version_text if __name__ == "__main__": - with open("resources/version.json", "r", encoding="utf-8") as f: + root_path = Path.cwd() + + with (root_path / "resources/version.json").open(mode="r", encoding="utf-8") as f: version = json.load(f) main_version_numb = list(map(int, version["main_version"].split("."))) updater_version_numb = list(map(int, version["updater_version"].split("."))) - print("Packaging AUTO-MAA main program ...") + print("Packaging AUTO_MAA main program ...") result = subprocess.run( f"powershell -Command nuitka --standalone --onefile --mingw64" @@ -52,9 +55,8 @@ if __name__ == "__main__": f" --product-version={version["main_version"]}" f" --file-description='AUTO_MAA Component'" f" --copyright='Copyright © 2024 DLmaster361'" - f" --assume-yes-for-downloads --show-progress" - f" --output-filename=AUTO_MAA --remove-output" - f" main.py", + f" --assume-yes-for-downloads --output-filename=AUTO_MAA" + f" --remove-output main.py", shell=True, capture_output=True, text=True, @@ -62,21 +64,20 @@ if __name__ == "__main__": print(result.stdout) print(result.stderr) - print("AUTO-MAA main program packaging completed !") + print("AUTO_MAA main program packaging completed !") - shutil.copy(os.path.normpath("app/utils/Updater.py"), os.path.normpath(".")) + shutil.copy(root_path / "app/utils/Updater.py", root_path) - with open(os.path.normpath("Updater.py"), "r", encoding="utf-8") as f: - file_content = f.read() + file_content = (root_path / "Updater.py").read_text(encoding="utf-8") - file_content = file_content.replace( - "from .version import version_text", "from app import version_text" + (root_path / "Updater.py").write_text( + file_content.replace( + "from .version import version_text", "from app import version_text" + ), + encoding="utf-8", ) - with open(os.path.normpath("Updater.py"), "w", encoding="utf-8") as f: - f.write(file_content) - - print("Packaging AUTO-MAA update program ...") + print("Packaging AUTO_MAA update program ...") result = subprocess.run( f"powershell -Command nuitka --standalone --onefile --mingw64" @@ -84,12 +85,11 @@ if __name__ == "__main__": f" --windows-icon-from-ico=resources\\icons\\AUTO_MAA_Updater.ico" f" --company-name='AUTO_MAA Team' --product-name=AUTO_MAA" f" --file-version={version["updater_version"]}" - f" --product-version={version["updater_version"]}" + f" --product-version={version["main_version"]}" f" --file-description='AUTO_MAA Component'" f" --copyright='Copyright © 2024 DLmaster361'" - f" --assume-yes-for-downloads --show-progress" - f" --output-filename=Updater --remove-output" - f" Updater.py", + f" --assume-yes-for-downloads --output-filename=Updater" + f" --remove-output Updater.py", shell=True, capture_output=True, text=True, @@ -97,12 +97,11 @@ if __name__ == "__main__": print(result.stdout) print(result.stderr) - print("AUTO-MAA update program packaging completed !") + print("AUTO_MAA update program packaging completed !") - os.remove(os.path.normpath("Updater.py")) + os.remove(root_path / "Updater.py") - with open("update_info.txt", "w", encoding="utf-8") as f: - print( - f"{version_text(main_version_numb)}\n{version_text(updater_version_numb)}{version["announcement"]}", - file=f, - ) + (root_path / "version_info.txt").write_text( + f"{version_text(main_version_numb)}\n{version_text(updater_version_numb)}{version["announcement"]}", + encoding="utf-8", + ) diff --git a/update_info.txt b/update_info.txt deleted file mode 100644 index a5556c9..0000000 --- a/update_info.txt +++ /dev/null @@ -1,10 +0,0 @@ -v4.2.0 -v1.1.0 -## 新增功能 -- 提供完整打包代码 -## 修复BUG -- 同步MAA`v5.11.1`的字段修改 -- 清除自动化中无效的整合流程 -## 程序优化 -- 调整项目结构,模块化各功能组件 -- 改用`nuitka`编译,压缩软件体积,提升运行速度 From f54e83673ff88a7ef7c2c7736543ff054039d61d Mon Sep 17 00:00:00 2001 From: DLmaster Date: Wed, 1 Jan 2025 21:50:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90UI?= =?UTF-8?q?=E7=BE=8E=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/config.py | 5 +- app/services/notification.py | 2 +- app/ui/gui.py | 478 +++++++++++++++++++++-------------- app/utils/Updater.py | 7 +- main.py | 1 + requirements.txt | 1 + resources/gui/main.ui | 184 +++++++++----- resources/version.json | 6 +- 8 files changed, 416 insertions(+), 268 deletions(-) diff --git a/app/config.py b/app/config.py index c5264e5..8323da6 100644 --- a/app/config.py +++ b/app/config.py @@ -49,8 +49,6 @@ class AppConfig: # 检查文件完整性 self.initialize() - self.check_config() - self.check_database() def initialize(self) -> None: """初始化程序的配置文件""" @@ -83,6 +81,9 @@ class AppConfig: encoding="utf-8", ) + self.check_config() + self.check_database() + def check_config(self) -> None: """检查配置文件字段完整性并补全""" diff --git a/app/services/notification.py b/app/services/notification.py index d8c45f8..4afd7f5 100644 --- a/app/services/notification.py +++ b/app/services/notification.py @@ -48,7 +48,7 @@ class Notification: title=title, message=message, app_name="AUTO_MAA", - app_icon=self.config.app_path / "resources/icons/AUTO_MAA.ico", + app_icon=str(self.config.app_path / "resources/icons/AUTO_MAA.ico"), timeout=t, ticker=ticker, toast=True, diff --git a/app/ui/gui.py b/app/ui/gui.py index ea7fcc1..d19fd28 100644 --- a/app/ui/gui.py +++ b/app/ui/gui.py @@ -26,26 +26,35 @@ v4.2 """ from PySide6.QtWidgets import ( - QWidget, - QMainWindow, - QApplication, - QSystemTrayIcon, - QMenu, - QInputDialog, - QFileDialog, - QMessageBox, - QLineEdit, - QTabWidget, - QToolBox, - QTableWidget, - QTableWidgetItem, - QComboBox, - QPushButton, - QHeaderView, - QSpinBox, - QTimeEdit, - QCheckBox, - QTextBrowser, + QWidget, # + QMainWindow, # + QApplication, # + QSystemTrayIcon, # + QFileDialog, # + QTabWidget, # + QToolBox, # + QComboBox, # + QTableWidgetItem, # + QHeaderView, # +) +from qfluentwidgets import ( + Action, + PushButton, + LineEdit, + PasswordLineEdit, + TextBrowser, + TableWidget, + TimePicker, + ComboBox, + CheckBox, + SpinBox, + FluentIcon, + RoundMenu, + MessageBox, + MessageBoxBase, + HeaderCardWidget, + BodyLabel, + SubtitleLabel, ) from PySide6.QtUiTools import QUiLoader from PySide6.QtGui import QIcon, QCloseEvent @@ -149,32 +158,22 @@ class Main(QWidget): "-", ] + uiLoader.registerCustomWidget(PushButton) + uiLoader.registerCustomWidget(LineEdit) + uiLoader.registerCustomWidget(TextBrowser) + uiLoader.registerCustomWidget(TableWidget) + uiLoader.registerCustomWidget(TimePicker) + uiLoader.registerCustomWidget(SpinBox) + uiLoader.registerCustomWidget(CheckBox) + uiLoader.registerCustomWidget(HeaderCardWidget) + uiLoader.registerCustomWidget(BodyLabel) + # 导入ui配置 self.ui = uiLoader.load(self.config.app_path / "resources/gui/main.ui") self.ui.setWindowIcon( QIcon(str(self.config.app_path / "resources/icons/AUTO_MAA.ico")) ) - # 生成管理密钥 - if not self.config.key_path.exists(): - while True: - self.PASSWORD, ok_pressed = QInputDialog.getText( - self.ui, - "请设置管理密钥", - "未检测到管理密钥,请设置您的管理密钥:", - QLineEdit.Password, - "", - ) - if ok_pressed and self.PASSWORD != "": - self.crypto.get_PASSWORD(self.PASSWORD) - break - else: - choice = QMessageBox.question( - self.ui, "确认", "您没有输入管理密钥,确定要暂时跳过这一步吗?" - ) - if choice == QMessageBox.Yes: - break - # 初始化控件 self.main_tab: QTabWidget = self.ui.findChild(QTabWidget, "tabWidget_main") self.main_tab.currentChanged.connect(self.change_config) @@ -182,141 +181,144 @@ class Main(QWidget): self.user_set: QToolBox = self.ui.findChild(QToolBox, "toolBox_userset") self.user_set.currentChanged.connect(lambda: self.update_user_info("normal")) - self.user_list_simple: QTableWidget = self.ui.findChild( - QTableWidget, "tableWidget_userlist_simple" + self.user_list_simple: TableWidget = self.ui.findChild( + TableWidget, "tableWidget_userlist_simple" ) self.user_list_simple.itemChanged.connect( lambda item: self.change_user_Item(item, "simple") ) - self.user_list_beta: QTableWidget = self.ui.findChild( - QTableWidget, "tableWidget_userlist_beta" + self.user_list_beta: TableWidget = self.ui.findChild( + TableWidget, "tableWidget_userlist_beta" ) self.user_list_beta.itemChanged.connect( lambda item: self.change_user_Item(item, "beta") ) - self.user_add: QPushButton = self.ui.findChild(QPushButton, "pushButton_new") + self.user_add: PushButton = self.ui.findChild(PushButton, "pushButton_new") + self.user_add.setIcon(FluentIcon.ADD_TO) self.user_add.clicked.connect(self.add_user) - self.user_del: QPushButton = self.ui.findChild(QPushButton, "pushButton_del") + self.user_del: PushButton = self.ui.findChild(PushButton, "pushButton_del") + self.user_del.setIcon(FluentIcon.REMOVE_FROM) self.user_del.clicked.connect(self.del_user) - self.user_switch: QPushButton = self.ui.findChild( - QPushButton, "pushButton_switch" + self.user_switch: PushButton = self.ui.findChild( + PushButton, "pushButton_switch" ) + self.user_switch.setIcon(FluentIcon.MOVE) self.user_switch.clicked.connect(self.switch_user) - self.read_PASSWORD: QPushButton = self.ui.findChild( - QPushButton, "pushButton_password" + self.read_PASSWORD: PushButton = self.ui.findChild( + PushButton, "pushButton_password" ) + self.read_PASSWORD.setIcon(FluentIcon.HIDE) self.read_PASSWORD.clicked.connect(lambda: self.read("key")) - self.refresh: QPushButton = self.ui.findChild(QPushButton, "pushButton_refresh") + self.refresh: PushButton = self.ui.findChild(PushButton, "pushButton_refresh") + self.refresh.setIcon(FluentIcon.SYNC) self.refresh.clicked.connect(lambda: self.update_user_info("clear")) - self.run_now: QPushButton = self.ui.findChild(QPushButton, "pushButton_runnow") + self.run_now: PushButton = self.ui.findChild(PushButton, "pushButton_runnow") + self.run_now.setIcon(FluentIcon.PLAY) self.run_now.clicked.connect(lambda: self.maa_starter("日常代理")) - self.check_start: QPushButton = self.ui.findChild( - QPushButton, "pushButton_checkstart" + self.check_start: PushButton = self.ui.findChild( + PushButton, "pushButton_checkstart" ) + self.check_start.setIcon(FluentIcon.PLAY) self.check_start.clicked.connect(lambda: self.maa_starter("人工排查")) - self.maa_path: QLineEdit = self.ui.findChild(QLineEdit, "lineEdit_MAApath") + self.maa_path: LineEdit = self.ui.findChild(LineEdit, "lineEdit_MAApath") self.maa_path.textChanged.connect(self.change_config) self.maa_path.setReadOnly(True) - self.get_maa_path: QPushButton = self.ui.findChild( - QPushButton, "pushButton_getMAApath" + self.get_maa_path: PushButton = self.ui.findChild( + PushButton, "pushButton_getMAApath" ) + self.get_maa_path.setIcon(FluentIcon.FOLDER) self.get_maa_path.clicked.connect(lambda: self.read("file_path_maa")) - self.set_maa: QPushButton = self.ui.findChild(QPushButton, "pushButton_setMAA") + self.set_maa: PushButton = self.ui.findChild(PushButton, "pushButton_setMAA") + self.set_maa.setIcon(FluentIcon.SETTING) self.set_maa.clicked.connect(lambda: self.maa_starter("设置MAA_全局")) - self.routine: QSpinBox = self.ui.findChild(QSpinBox, "spinBox_routine") + self.routine: SpinBox = self.ui.findChild(SpinBox, "spinBox_routine") self.routine.valueChanged.connect(self.change_config) - self.annihilation: QSpinBox = self.ui.findChild( - QSpinBox, "spinBox_annihilation" - ) + self.annihilation: SpinBox = self.ui.findChild(SpinBox, "spinBox_annihilation") self.annihilation.valueChanged.connect(self.change_config) - self.num: QSpinBox = self.ui.findChild(QSpinBox, "spinBox_numt") + self.num: SpinBox = self.ui.findChild(SpinBox, "spinBox_numt") self.num.valueChanged.connect(self.change_config) - self.if_self_start: QCheckBox = self.ui.findChild( - QCheckBox, "checkBox_ifselfstart" + self.if_self_start: CheckBox = self.ui.findChild( + CheckBox, "checkBox_ifselfstart" ) self.if_self_start.stateChanged.connect(self.change_config) - self.if_sleep: QCheckBox = self.ui.findChild(QCheckBox, "checkBox_ifsleep") + self.if_sleep: CheckBox = self.ui.findChild(CheckBox, "checkBox_ifsleep") self.if_sleep.stateChanged.connect(self.change_config) - self.if_proxy_directly: QCheckBox = self.ui.findChild( - QCheckBox, "checkBox_ifproxydirectly" + self.if_proxy_directly: CheckBox = self.ui.findChild( + CheckBox, "checkBox_ifproxydirectly" ) self.if_proxy_directly.stateChanged.connect(self.change_config) - self.if_send_mail: QCheckBox = self.ui.findChild( - QCheckBox, "checkBox_ifsendmail" - ) + self.if_send_mail: CheckBox = self.ui.findChild(CheckBox, "checkBox_ifsendmail") self.if_send_mail.stateChanged.connect(self.change_config) - self.mail_address: QLineEdit = self.ui.findChild( - QLineEdit, "lineEdit_mailaddress" + self.mail_address: LineEdit = self.ui.findChild( + LineEdit, "lineEdit_mailaddress" ) self.mail_address.textChanged.connect(self.change_config) - self.if_send_error_only: QCheckBox = self.ui.findChild( - QCheckBox, "checkBox_ifonlyerror" + self.if_send_error_only: CheckBox = self.ui.findChild( + CheckBox, "checkBox_ifonlyerror" ) self.if_send_error_only.stateChanged.connect(self.change_config) - self.if_silence: QCheckBox = self.ui.findChild(QCheckBox, "checkBox_silence") + self.if_silence: CheckBox = self.ui.findChild(CheckBox, "checkBox_silence") self.if_silence.stateChanged.connect(self.change_config) - self.boss_key: QLineEdit = self.ui.findChild(QLineEdit, "lineEdit_boss") + self.boss_key: LineEdit = self.ui.findChild(LineEdit, "lineEdit_boss") self.boss_key.textChanged.connect(self.change_config) - self.if_to_tray: QCheckBox = self.ui.findChild(QCheckBox, "checkBox_iftotray") + self.if_to_tray: CheckBox = self.ui.findChild(CheckBox, "checkBox_iftotray") self.if_to_tray.stateChanged.connect(self.change_config) - self.check_update: QCheckBox = self.ui.findChild( - QPushButton, "pushButton_check_update" + self.check_update: PushButton = self.ui.findChild( + PushButton, "pushButton_check_update" ) + self.check_update.setIcon(FluentIcon.UPDATE) self.check_update.clicked.connect(self.check_version) - self.tips: QTextBrowser = self.ui.findChild(QTextBrowser, "textBrowser_tips") + self.tips: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_tips") self.tips.setOpenExternalLinks(True) - self.run_text: QTextBrowser = self.ui.findChild(QTextBrowser, "textBrowser_run") - self.wait_text: QTextBrowser = self.ui.findChild( - QTextBrowser, "textBrowser_wait" + self.run_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_run") + self.wait_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_wait") + self.over_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_over") + self.error_text: TextBrowser = self.ui.findChild( + TextBrowser, "textBrowser_error" ) - self.over_text: QTextBrowser = self.ui.findChild( - QTextBrowser, "textBrowser_over" - ) - self.error_text: QTextBrowser = self.ui.findChild( - QTextBrowser, "textBrowser_error" - ) - self.log_text: QTextBrowser = self.ui.findChild(QTextBrowser, "textBrowser_log") + self.log_text: TextBrowser = self.ui.findChild(TextBrowser, "textBrowser_log") - self.start_time: List[Tuple[QCheckBox, QTimeEdit]] = [] + self.start_time: List[Tuple[CheckBox, TimePicker]] = [] for i in range(10): self.start_time.append( [ - self.ui.findChild(QCheckBox, f"checkBox_t{i + 1}"), - self.ui.findChild(QTimeEdit, f"timeEdit_{i + 1}"), + self.ui.findChild(CheckBox, f"checkBox_t{i + 1}"), + self.ui.findChild(TimePicker, f"timeEdit_{i + 1}"), ] ) self.start_time[i][0].stateChanged.connect(self.change_config) self.start_time[i][1].timeChanged.connect(self.change_config) - self.change_password: QPushButton = self.ui.findChild( - QPushButton, "pushButton_changePASSWORD" + self.change_password: PushButton = self.ui.findChild( + PushButton, "pushButton_changePASSWORD" ) + self.change_password.setIcon(FluentIcon.VPN) self.change_password.clicked.connect(self.change_PASSWORD) # 初始化线程 @@ -345,6 +347,24 @@ class Main(QWidget): if self.config.content["Default"]["SelfSet.IfProxyDirectly"] == "True": self.maa_starter("日常代理") + def check_PASSWORD(self) -> None: + """检查并配置管理密钥""" + + if self.config.key_path.exists(): + return None + + while True: + + if self.read("setkey"): + self.crypto.get_PASSWORD(self.PASSWORD) + break + else: + choice = MessageBox( + "确认", "您没有输入管理密钥,确定要暂时跳过这一步吗?", self.ui + ) + if choice.exec(): + break + def change_PASSWORD(self) -> None: """修改管理密钥""" @@ -353,24 +373,30 @@ class Main(QWidget): data = self.config.cur.fetchall() if len(data) == 0: - QMessageBox.information(self.ui, "验证通过", "当前无用户,验证自动通过") + choice = MessageBox("验证通过", "当前无用户,验证自动通过", self.ui) + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) # 获取新的管理密钥 - while True: - PASSWORD_new = self.read("newkey") - if PASSWORD_new == 0: - choice = QMessageBox.question( - self.ui, - "确认", - "您没有输入新的管理密钥,是否取消修改管理密钥?", - ) - if choice == QMessageBox.Yes: - break - else: - # 修改管理密钥 - self.PASSWORD = PASSWORD_new - self.crypto.get_PASSWORD(self.PASSWORD) - QMessageBox.information(self.ui, "操作成功", "管理密钥修改成功") - break + if choice.exec(): + while True: + PASSWORD_new = self.read("newkey") + if PASSWORD_new == None: + choice = MessageBox( + "确认", + "您没有输入新的管理密钥,是否取消修改管理密钥?", + self.ui, + ) + if choice.exec(): + break + else: + # 修改管理密钥 + self.PASSWORD = PASSWORD_new + self.crypto.get_PASSWORD(self.PASSWORD) + choice = MessageBox("操作成功", "管理密钥修改成功", self.ui) + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + break else: # 验证管理密钥 if_change = True @@ -378,18 +404,22 @@ class Main(QWidget): if self.read("oldkey"): # 验证旧管理密钥 if not self.crypto.check_PASSWORD(self.PASSWORD): - QMessageBox.critical(self.ui, "错误", "管理密钥错误") + choice = MessageBox("错误", "管理密钥错误", self.ui) + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + pass else: # 获取新的管理密钥 while True: PASSWORD_new = self.read("newkey") - if PASSWORD_new == 0: - choice = QMessageBox.question( - self.ui, + if PASSWORD_new == None: + choice = MessageBox( "确认", "您没有输入新的管理密钥,是否取消修改管理密钥?", + self.ui, ) - if choice == QMessageBox.Yes: + if choice.exec(): if_change = False break # 修改管理密钥 @@ -398,16 +428,21 @@ class Main(QWidget): data, self.PASSWORD, PASSWORD_new ) self.PASSWORD = PASSWORD_new - QMessageBox.information( - self.ui, "操作成功", "管理密钥修改成功" + choice = MessageBox( + "操作成功", "管理密钥修改成功", self.ui ) - if_change = False - break + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + if_change = False + break else: - choice = QMessageBox.question( - self.ui, "确认", "您没有输入管理密钥,是否取消修改管理密钥?" + choice = MessageBox( + "确认", + "您没有输入管理密钥,是否取消修改管理密钥?", + self.ui, ) - if choice == QMessageBox.Yes: + if choice.exec(): break def update_user_info(self, operation: str) -> None: @@ -444,7 +479,7 @@ class Main(QWidget): # 生成表格组件 if j == 2: - item = QComboBox() + item = ComboBox() item.addItems(["官服", "B服"]) if value == "Official": item.setCurrentIndex(0) @@ -524,7 +559,7 @@ class Main(QWidget): # 生成表格组件 if j in [4, 9, 10]: - item = QComboBox() + item = ComboBox() if j == 4: item.addItems(["启用", "禁用"]) elif j in [9, 10]: @@ -579,11 +614,11 @@ class Main(QWidget): # 设置列表可编辑状态 if self.if_user_list_editable: - self.user_list_simple.setEditTriggers(QTableWidget.AllEditTriggers) - self.user_list_beta.setEditTriggers(QTableWidget.AllEditTriggers) + self.user_list_simple.setEditTriggers(TableWidget.AllEditTriggers) + self.user_list_beta.setEditTriggers(TableWidget.AllEditTriggers) else: - self.user_list_simple.setEditTriggers(QTableWidget.NoEditTriggers) - self.user_list_beta.setEditTriggers(QTableWidget.NoEditTriggers) + self.user_list_simple.setEditTriggers(TableWidget.NoEditTriggers) + self.user_list_beta.setEditTriggers(TableWidget.NoEditTriggers) # 允许GUI改变被同步到本地数据库 self.if_update_database = True @@ -683,12 +718,15 @@ class Main(QWidget): # 判断是否已设置管理密钥 if not self.config.key_path.exists(): - QMessageBox.critical( - self.ui, + choice = MessageBox( "错误", "请先设置管理密钥再执行添加用户操作", + self.ui, ) - return None + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + return None # 插入预设用户数据 set_book = [ @@ -719,8 +757,11 @@ class Main(QWidget): # 判断选择合理性 if row == -1: - QMessageBox.critical(self.ui, "错误", "请选中一个用户后再执行删除操作") - return None + choice = MessageBox("错误", "请选中一个用户后再执行删除操作", self.ui) + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + return None # 确认待删除用户信息 self.config.cur.execute( @@ -731,12 +772,10 @@ class Main(QWidget): ), ) data = self.config.cur.fetchall() - choice = QMessageBox.question( - self.ui, "确认", f"确定要删除用户 {data[0][0]} 吗?" - ) + choice = MessageBox("确认", f"确定要删除用户 {data[0][0]} 吗?", self.ui) # 删除用户 - if choice == QMessageBox.Yes: + if choice.exec(): # 删除所选用户 self.config.cur.execute( "DELETE FROM adminx WHERE mode = ? AND uid = ?", @@ -791,8 +830,11 @@ class Main(QWidget): # 判断选择合理性 if row == -1: - QMessageBox.critical(self.ui, "错误", "请选中一个用户后再执行切换操作") - return None + choice = MessageBox("错误", "请选中一个用户后再执行切换操作", self.ui) + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + return None # 确认待切换用户信息 self.config.cur.execute( @@ -805,14 +847,14 @@ class Main(QWidget): data = self.config.cur.fetchall() mode_list = ["简洁", "高级"] - choice = QMessageBox.question( - self.ui, + choice = MessageBox( "确认", f"确定要将用户 {data[0][0]} 转为{mode_list[1 - self.user_set.currentIndex()]}配置模式吗?", + self.ui, ) # 切换用户 - if choice == QMessageBox.Yes: + if choice.exec(): self.config.cur.execute("SELECT * FROM adminx WHERE True") data = self.config.cur.fetchall() if self.user_set.currentIndex() == 0: @@ -886,12 +928,15 @@ class Main(QWidget): ) return True else: - QMessageBox.critical( - self.ui, + choice = MessageBox( "错误", "未选择自定义基建文件", + self.ui, ) - return False + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + return False # 获取高级用户MAA配置文件 elif info[2] in ["routine", "annihilation"]: ( @@ -904,7 +949,7 @@ class Main(QWidget): / f"data/MAAconfig/{self.user_mode_list[info[0]]}/{info[1]}/{info[2]}", ) - def change_user_Item(self, item: QTableWidget, mode): + def change_user_Item(self, item: TableWidget, mode): """将GUI中发生修改的用户配置表中的一般信息同步至本地数据库""" # 验证能否写入本地数据库 @@ -1078,11 +1123,13 @@ class Main(QWidget): ) self.get_maa_config(["Default"]) else: - QMessageBox.critical( - self.ui, + choice = MessageBox( "错误", "该路径下未找到MAA.exe或MAA配置文件,请重新设置MAA路径!", + self.ui, ) + if choice.exec(): + pass self.config.content["Default"][ "SelfSet.MainIndex" @@ -1135,7 +1182,7 @@ class Main(QWidget): self.config.content["Default"][f"TimeSet.set{i + 1}"] = "True" else: self.config.content["Default"][f"TimeSet.set{i + 1}"] = "False" - time = self.start_time[i][1].time().toString("HH:mm") + time = self.start_time[i][1].getTime().toString("HH:mm") self.config.content["Default"][f"TimeSet.run{i + 1}"] = time # 将配置信息同步至本地JSON文件 @@ -1153,40 +1200,78 @@ class Main(QWidget): def read(self, operation): """弹出对话框组件进行读入""" + class InputMessageBox(MessageBoxBase): + """输入对话框""" + + def __init__(self, parent, title: str, content: str, mode: str): + super().__init__(parent) + self.title = SubtitleLabel(title) + + if mode == "明文": + self.input = LineEdit() + elif mode == "密码": + self.input = PasswordLineEdit() + + self.input.setPlaceholderText(content) + self.input.setClearButtonEnabled(True) + + # 将组件添加到布局中 + self.viewLayout.addWidget(self.title) + self.viewLayout.addWidget(self.input) + # 读入PASSWORD if operation == "key": - self.PASSWORD, ok_pressed = QInputDialog.getText( - self.ui, "请输入管理密钥", "管理密钥:", QLineEdit.Password, "" - ) - if ok_pressed and self.PASSWORD != "": + + choice = InputMessageBox(self.ui, "请输入管理密钥", "管理密钥", "密码") + if choice.exec() and choice.input.text() != "": + self.PASSWORD = choice.input.text() self.update_user_info("normal") + elif operation == "oldkey": - self.PASSWORD, ok_pressed = QInputDialog.getText( - self.ui, "请输入旧的管理密钥", "旧管理密钥:", QLineEdit.Password, "" + + choice = InputMessageBox( + self.ui, "请输入旧的管理密钥", "旧管理密钥", "密码" ) - if ok_pressed and self.PASSWORD != "": + if choice.exec() and choice.input.text() != "": + self.PASSWORD = choice.input.text() return True else: return False + elif operation == "newkey": - new_PASSWORD, ok_pressed = QInputDialog.getText( - self.ui, "请输入新的管理密钥", "新管理密钥:", QLineEdit.Password, "" + + choice = InputMessageBox( + self.ui, "请输入新的管理密钥", "新管理密钥", "密码" ) - if ok_pressed and new_PASSWORD != "": - return new_PASSWORD + if choice.exec() and choice.input.text() != "": + return choice.input.text() else: return None + elif operation == "setkey": + + choice = InputMessageBox( + self.ui, + "未检测到管理密钥,请设置您的管理密钥", + "管理密钥", + "密码", + ) + if choice.exec() and choice.input.text() != "": + self.PASSWORD = choice.input.text() + return True + else: + return False + # 读入选择 elif operation == "question_runner": - choice = QMessageBox.question( - self.ui, + choice = MessageBox( self.MaaManager.question_title, self.MaaManager.question_info, + None, ) - if choice == QMessageBox.Yes: + if choice.exec(): self.MaaManager.question_choice = "Yes" - elif choice == QMessageBox.No: + else: self.MaaManager.question_choice = "No" # 读入MAA文件目录 @@ -1334,8 +1419,11 @@ class Main(QWidget): Path(self.config.content["Default"]["MaaSet.path"]) / "config/gui.json" ).exists() ): - QMessageBox.critical(self.ui, "错误", "您还未正确配置MAA路径!") - return None + choice = MessageBox("错误", "您还未正确配置MAA路径!", self.ui) + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + return None self.maa_running_set(f"{mode}_开始") @@ -1458,12 +1546,15 @@ class Main(QWidget): err = e time.sleep(0.1) else: - QMessageBox.critical( - self.ui, + choice = MessageBox( "错误", f"获取版本信息时出错:\n{err}", + self.ui, ) - return None + choice.cancelButton.hide() + choice.buttonLayout.insertStretch(1) + if choice.exec(): + return None main_version_remote = list(map(int, version_remote["main_version"].split("."))) updater_version_remote = list( @@ -1490,12 +1581,12 @@ class Main(QWidget): ) # 询问是否开始版本更新 - choice = QMessageBox.question( - self.ui, + choice = MessageBox( "版本更新", f"发现新版本:\n{main_version_info}{updater_version_info} 更新说明:\n{version_remote['announcement'].replace("\n# ","\n !").replace("\n## ","\n - ").replace("\n- ","\n · ")}\n\n是否开始更新?\n\n 注意:主程序更新时AUTO_MAA将自动关闭", + self.ui, ) - if choice == QMessageBox.No: + if not choice.exec(): return None # 更新更新器 @@ -1567,25 +1658,36 @@ class AUTO_MAA(QMainWindow): self, ) self.tray.setToolTip("AUTO_MAA") - self.tray_menu = QMenu() + self.tray_menu = RoundMenu() # 显示主界面菜单项 - show_main = self.tray_menu.addAction("显示主界面") - show_main.triggered.connect(self.show_main) + self.tray_menu.addAction( + Action(FluentIcon.CAFE, "显示主界面", triggered=self.show_main) + ) + self.tray_menu.addSeparator() # 开始任务菜单项 - start_task_1 = self.tray_menu.addAction("运行日常代理") - start_task_1.triggered.connect(lambda: self.start_task("日常代理")) - - start_task_2 = self.tray_menu.addAction("运行人工排查") - start_task_2.triggered.connect(lambda: self.start_task("人工排查")) - - stop_task = self.tray_menu.addAction("中止当前任务") - stop_task.triggered.connect(self.stop_task) + 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() # 退出主程序菜单项 - kill = self.tray_menu.addAction("退出主程序") - kill.triggered.connect(self.kill_main) + self.tray_menu.addAction( + Action(FluentIcon.POWER_BUTTON, "退出主程序", triggered=self.kill_main) + ) # 设置托盘菜单 self.tray.setContextMenu(self.tray_menu) diff --git a/app/utils/Updater.py b/app/utils/Updater.py index 8f50f43..86a335f 100644 --- a/app/utils/Updater.py +++ b/app/utils/Updater.py @@ -38,9 +38,8 @@ from PySide6.QtWidgets import ( QApplication, QDialog, QVBoxLayout, - QLabel, - QProgressBar, ) +from qfluentwidgets import ProgressBar, BodyLabel from PySide6.QtGui import QIcon from PySide6.QtCore import QObject, QThread, Signal @@ -265,10 +264,10 @@ class Updater(QObject): # 创建垂直布局 self.Layout_v = QVBoxLayout(self.ui) - self.info = QLabel("正在初始化", self.ui) + self.info = BodyLabel("正在初始化", self.ui) self.Layout_v.addWidget(self.info) - self.progress = QProgressBar(self.ui) + self.progress = ProgressBar(self.ui) self.progress.setRange(0, 0) self.Layout_v.addWidget(self.progress) diff --git a/main.py b/main.py index 0857c79..f185b0d 100644 --- a/main.py +++ b/main.py @@ -38,4 +38,5 @@ if __name__ == "__main__": application = QApplication(sys.argv) window = AUTO_MAA(config=config, notify=notify, crypto=crypto) + window.main.check_PASSWORD() sys.exit(application.exec()) diff --git a/requirements.txt b/requirements.txt index 5c175d2..b66d50a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ plyer PySide6 +PySide6-Fluent-Widgets[full] psutil pywin32 pyautogui diff --git a/resources/gui/main.ui b/resources/gui/main.ui index ccb3832..eb11ac9 100644 --- a/resources/gui/main.ui +++ b/resources/gui/main.ui @@ -39,21 +39,21 @@ - + 新建 - + 删除 - + 转为 @@ -73,14 +73,14 @@ - + 显示密码 - + 刷新 @@ -107,7 +107,7 @@ - + 用户名 @@ -191,7 +191,7 @@ - + 用户名 @@ -253,7 +253,7 @@ 定时执行 - + @@ -266,7 +266,7 @@ - + true @@ -288,7 +288,7 @@ - + @@ -303,7 +303,7 @@ - + true @@ -325,7 +325,7 @@ - + @@ -340,7 +340,7 @@ - + true @@ -362,7 +362,7 @@ - + @@ -377,7 +377,7 @@ - + true @@ -399,7 +399,7 @@ - + @@ -414,7 +414,7 @@ - + true @@ -436,7 +436,7 @@ - + @@ -451,7 +451,7 @@ - + true @@ -473,7 +473,7 @@ - + @@ -488,7 +488,7 @@ - + true @@ -510,7 +510,7 @@ - + @@ -525,7 +525,7 @@ - + true @@ -547,7 +547,7 @@ - + @@ -562,7 +562,7 @@ - + true @@ -584,7 +584,7 @@ - + @@ -599,7 +599,7 @@ - + true @@ -621,7 +621,7 @@ - + @@ -651,7 +651,7 @@ - + 调度器 @@ -671,14 +671,14 @@ - + 开始排查 - + 立即执行 @@ -706,7 +706,7 @@ - + @@ -728,7 +728,7 @@ - + @@ -750,7 +750,7 @@ - + @@ -772,7 +772,7 @@ - + @@ -796,7 +796,7 @@ - + @@ -816,7 +816,7 @@ MAA设置 - + @@ -827,17 +827,17 @@ - + MAA路径 - + - + 浏览 @@ -857,7 +857,7 @@ - + 设置MAA @@ -874,8 +874,8 @@ 执行限制 - - + + QFrame::Shape::StyledPanel @@ -885,7 +885,7 @@ - + 日常限制 @@ -905,11 +905,11 @@ - + - 100 - 0 + 140 + 30 @@ -930,7 +930,7 @@ - + QFrame::Shape::StyledPanel @@ -940,7 +940,7 @@ - + 剿灭限制 @@ -960,11 +960,11 @@ - + - 100 - 0 + 140 + 30 @@ -985,7 +985,7 @@ - + QFrame::Shape::StyledPanel @@ -995,7 +995,7 @@ - + 运行失败重试次数上限 @@ -1015,11 +1015,11 @@ - + - 100 - 0 + 140 + 30 @@ -1072,7 +1072,7 @@ - + 后台静默代理 @@ -1092,7 +1092,7 @@ - + 安卓模拟器老板键 @@ -1124,7 +1124,7 @@ - + 通过邮件通知结果 @@ -1144,14 +1144,14 @@ - + 收信邮箱地址 - + 仅推送异常信息 @@ -1170,7 +1170,7 @@ - + 最小化到托盘 @@ -1202,7 +1202,7 @@ - + 启动AUTO_MAA后直接代理 @@ -1247,7 +1247,7 @@ - + 开机自动启动AUTO_MAA @@ -1279,7 +1279,7 @@ - + AUTO_MAA启动时禁止电脑休眠 @@ -1350,7 +1350,7 @@ - + 修改管理密钥 @@ -1408,7 +1408,7 @@ - + 检查版本更新 @@ -1440,7 +1440,7 @@ - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> @@ -1451,6 +1451,8 @@ li.checked::marker { content: "\2612"; } </style></head><body style=" font-family:'Microsoft YaHei UI'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">致用户:</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> 这是AUTO_MAA_v4.2.0-beta.1,项目初步进行界面美化。希望大家喜欢这个新年礼物!</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> 使用本程序前,请先仔细阅读README.md。</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> 对于B服用户,由于我们无权替您同意用户协议,若出现用户协议弹窗,您需要自行完成确认,否则可能造成MAA卡死,代理任务失败。</p> @@ -1468,7 +1470,7 @@ li.checked::marker { content: "\2612"; } - + 注意:在设置页执行的所有更改,不会对正在执行的任务生效;正在执行任务时,用户管理页无法编辑。 @@ -1496,6 +1498,48 @@ li.checked::marker { content: "\2612"; } + + + PushButton + QPushButton +
qfluentwidgets
+
+ + TimePicker + QTimeEdit +
qfluentwidgets
+
+ + TableWidget + QTableWidget +
qfluentwidgets
+
+ + LineEdit + QLineEdit +
qfluentwidgets
+
+ + SpinBox + QSpinBox +
qfluentwidgets
+
+ + CheckBox + QCheckBox +
qfluentwidgets
+
+ + TextBrowser + QTextBrowser +
qfluentwidgets
+
+ + BodyLabel + QLabel +
qfluentwidgets
+
+
diff --git a/resources/version.json b/resources/version.json index 6d64931..fbe690f 100644 --- a/resources/version.json +++ b/resources/version.json @@ -1,7 +1,7 @@ { - "main_version": "4.2.0.0", - "updater_version": "1.1.0.0", - "announcement": "\n## 新增功能\n- 提供完整打包代码\n## 修复BUG\n- 同步MAA`v5.11.1`的字段修改\n- 清除自动化中无效的整合流程\n## 程序优化\n- 调整项目结构,模块化各功能组件\n- 改用`nuitka`编译,压缩软件体积,提升运行速度", + "main_version": "4.2.0.1", + "updater_version": "1.1.0.1", + "announcement": "\n## 新增功能\n- 初步引入`qfluentwidgets`,UI界面美化", "proxy_list":[ "", "https://gitproxy.click/",