mirror of
https://github.com/hyb-oyqq/FRAISEMOE-Addons-Installer-NEXT.git
synced 2026-01-01 11:40:45 +00:00
feat(main): 预加载云端配置并优化下载逻辑
- 在主线程中添加云端配置预加载功能 - 优化下载 URL 获取逻辑,使用预加载的配置数据 - 添加配置数据缺失和版本更新提示功能 - 调整动画系统,添加动画完成信号 - 重构部分代码以提高可维护性和可读性
This commit is contained in:
@@ -1,12 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
## Form generated from reading UI file 'install.ui'
|
|
||||||
##
|
|
||||||
## Created by: Qt User Interface Compiler version 6.9.1
|
|
||||||
##
|
|
||||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
||||||
################################################################################
|
|
||||||
from pic_data import img_data
|
from pic_data import img_data
|
||||||
from PySide6.QtGui import QPixmap
|
from PySide6.QtGui import QPixmap
|
||||||
import base64
|
import base64
|
||||||
@@ -42,8 +33,6 @@ class Ui_MainWindows(object):
|
|||||||
MainWindows.setAnimated(True)
|
MainWindows.setAnimated(True)
|
||||||
MainWindows.setDocumentMode(False)
|
MainWindows.setDocumentMode(False)
|
||||||
MainWindows.setDockNestingEnabled(False)
|
MainWindows.setDockNestingEnabled(False)
|
||||||
self.action_2 = QAction(MainWindows)
|
|
||||||
self.action_2.setObjectName(u"action_2")
|
|
||||||
self.centralwidget = QWidget(MainWindows)
|
self.centralwidget = QWidget(MainWindows)
|
||||||
self.centralwidget.setObjectName(u"centralwidget")
|
self.centralwidget.setObjectName(u"centralwidget")
|
||||||
self.centralwidget.setAutoFillBackground(True)
|
self.centralwidget.setAutoFillBackground(True)
|
||||||
@@ -140,8 +129,6 @@ class Ui_MainWindows(object):
|
|||||||
self.menubar.addAction(self.menu.menuAction())
|
self.menubar.addAction(self.menu.menuAction())
|
||||||
self.menubar.addAction(self.menu_2.menuAction())
|
self.menubar.addAction(self.menu_2.menuAction())
|
||||||
self.menu.addSeparator()
|
self.menu.addSeparator()
|
||||||
self.menu.addAction(self.action_2)
|
|
||||||
|
|
||||||
self.retranslateUi(MainWindows)
|
self.retranslateUi(MainWindows)
|
||||||
|
|
||||||
QMetaObject.connectSlotsByName(MainWindows)
|
QMetaObject.connectSlotsByName(MainWindows)
|
||||||
@@ -149,7 +136,6 @@ class Ui_MainWindows(object):
|
|||||||
|
|
||||||
def retranslateUi(self, MainWindows):
|
def retranslateUi(self, MainWindows):
|
||||||
MainWindows.setWindowTitle(QCoreApplication.translate("MainWindows", u" UI Test", None))
|
MainWindows.setWindowTitle(QCoreApplication.translate("MainWindows", u" UI Test", None))
|
||||||
self.action_2.setText(QCoreApplication.translate("MainWindows", u"\u68c0\u67e5\u66f4\u65b0(\u672a\u5b8c\u6210)", None))
|
|
||||||
self.loadbg.setText("")
|
self.loadbg.setText("")
|
||||||
self.vol1bg.setText("")
|
self.vol1bg.setText("")
|
||||||
self.vol2bg.setText("")
|
self.vol2bg.setText("")
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
from PySide6.QtCore import (QPropertyAnimation, QParallelAnimationGroup,
|
from PySide6.QtCore import (QObject, QPropertyAnimation, QParallelAnimationGroup,
|
||||||
QPoint, QEasingCurve, QTimer)
|
QPoint, QEasingCurve, QTimer, Signal)
|
||||||
from PySide6.QtWidgets import QGraphicsOpacityEffect
|
from PySide6.QtWidgets import QGraphicsOpacityEffect
|
||||||
|
|
||||||
class MultiStageAnimations:
|
class MultiStageAnimations(QObject):
|
||||||
def __init__(self, ui):
|
animation_finished = Signal()
|
||||||
|
def __init__(self, ui, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
self.ui = ui
|
self.ui = ui
|
||||||
# 获取画布尺寸
|
# 获取画布尺寸
|
||||||
self.canvas_width = ui.centralwidget.width()
|
self.canvas_width = ui.centralwidget.width()
|
||||||
@@ -141,6 +143,10 @@ class MultiStageAnimations:
|
|||||||
|
|
||||||
anim_group.addAnimation(pos_anim)
|
anim_group.addAnimation(pos_anim)
|
||||||
anim_group.addAnimation(opacity_anim)
|
anim_group.addAnimation(opacity_anim)
|
||||||
|
|
||||||
|
if item["widget"] == self.ui.exit_btn:
|
||||||
|
anim_group.finished.connect(self.animation_finished.emit)
|
||||||
|
|
||||||
anim_group.start()
|
anim_group.start()
|
||||||
self.animations.append(anim_group)
|
self.animations.append(anim_group)
|
||||||
def start_animations(self):
|
def start_animations(self):
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import base64
|
|||||||
|
|
||||||
# 配置信息
|
# 配置信息
|
||||||
app_data = {
|
app_data = {
|
||||||
"APP_VERSION": "1.1.0",
|
"APP_VERSION": "1.1.1",
|
||||||
"APP_NAME": "FRAISEMOE Addons Installer NEXT",
|
"APP_NAME": "FRAISEMOE Addons Installer NEXT",
|
||||||
"TEMP": "TEMP",
|
"TEMP": "TEMP",
|
||||||
"CACHE": "FRAISEMOE",
|
"CACHE": "FRAISEMOE",
|
||||||
|
|||||||
@@ -113,6 +113,56 @@ class ExtractionThread(QThread):
|
|||||||
self.finished.emit(False, f"\n文件操作失败,请重试\n\n【错误信息】:{e}\n", self.game_version)
|
self.finished.emit(False, f"\n文件操作失败,请重试\n\n【错误信息】:{e}\n", self.game_version)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigFetchThread(QThread):
|
||||||
|
finished = Signal(object, str) # data, error_message
|
||||||
|
|
||||||
|
def __init__(self, url, headers, debug_mode=False, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.url = url
|
||||||
|
self.headers = headers
|
||||||
|
self.debug_mode = debug_mode
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
if self.debug_mode:
|
||||||
|
print("--- Starting to fetch cloud config ---")
|
||||||
|
print(f"DEBUG: Requesting URL: {self.url}")
|
||||||
|
print(f"DEBUG: Using Headers: {self.headers}")
|
||||||
|
|
||||||
|
response = requests.get(self.url, headers=self.headers, timeout=10)
|
||||||
|
|
||||||
|
if self.debug_mode:
|
||||||
|
print(f"DEBUG: Response Status Code: {response.status_code}")
|
||||||
|
print(f"DEBUG: Response Headers: {response.headers}")
|
||||||
|
print(f"DEBUG: Response Text: {response.text}")
|
||||||
|
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
# 首先,总是尝试解析JSON
|
||||||
|
config_data = response.json()
|
||||||
|
|
||||||
|
# 检查是否是要求更新的错误信息
|
||||||
|
if config_data.get("message") == "请使用最新版本的FRAISEMOE Addons Installer NEXT进行下载安装":
|
||||||
|
self.finished.emit(None, "update_required")
|
||||||
|
return
|
||||||
|
|
||||||
|
# 检查是否是有效的配置文件
|
||||||
|
required_keys = [f"vol.{i+1}.data" for i in range(4)] + ["after.data"]
|
||||||
|
missing_keys = [key for key in required_keys if key not in config_data]
|
||||||
|
if missing_keys:
|
||||||
|
self.finished.emit(None, f"missing_keys:{','.join(missing_keys)}")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.finished.emit(config_data, "")
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
self.finished.emit(None, f"网络请求失败: {e}")
|
||||||
|
except (ValueError, json.JSONDecodeError) as e:
|
||||||
|
self.finished.emit(None, f"JSON解析失败: {e}")
|
||||||
|
finally:
|
||||||
|
if self.debug_mode:
|
||||||
|
print("--- Finished fetching cloud config ---")
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QMainWindow):
|
class MainWindow(QMainWindow):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -130,7 +180,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.setWindowTitle(f"{APP_NAME} v{APP_VERSION}")
|
self.setWindowTitle(f"{APP_NAME} v{APP_VERSION}")
|
||||||
|
|
||||||
# 初始化动画系统 (从animations.py导入)
|
# 初始化动画系统 (从animations.py导入)
|
||||||
self.animator = MultiStageAnimations(self.ui)
|
self.animator = MultiStageAnimations(self.ui, self)
|
||||||
|
|
||||||
# 初始化功能变量
|
# 初始化功能变量
|
||||||
self.selected_folder = ""
|
self.selected_folder = ""
|
||||||
@@ -146,6 +196,8 @@ class MainWindow(QMainWindow):
|
|||||||
self.optimization_done = False # 标记是否已执行过优选
|
self.optimization_done = False # 标记是否已执行过优选
|
||||||
self.logger = None
|
self.logger = None
|
||||||
self.hosts_manager = HostsManager() # 实例化HostsManager
|
self.hosts_manager = HostsManager() # 实例化HostsManager
|
||||||
|
self.cloud_config = None
|
||||||
|
self.config_fetch_thread = None
|
||||||
|
|
||||||
# 加载配置
|
# 加载配置
|
||||||
self.config = load_config()
|
self.config = load_config()
|
||||||
@@ -188,6 +240,11 @@ class MainWindow(QMainWindow):
|
|||||||
self.debug_action.triggered.connect(self.toggle_debug_mode)
|
self.debug_action.triggered.connect(self.toggle_debug_mode)
|
||||||
self.ui.menu.addAction(self.debug_action)
|
self.ui.menu.addAction(self.debug_action)
|
||||||
|
|
||||||
|
# 为未来功能预留的“切换下载源”按钮
|
||||||
|
self.switch_source_action = QAction("切换下载源", self)
|
||||||
|
self.switch_source_action.setEnabled(False) # 暂时禁用
|
||||||
|
self.ui.menu.addAction(self.switch_source_action)
|
||||||
|
|
||||||
# 根据初始配置决定是否开启Debug模式
|
# 根据初始配置决定是否开启Debug模式
|
||||||
if self.debug_action.isChecked():
|
if self.debug_action.isChecked():
|
||||||
self.start_logging()
|
self.start_logging()
|
||||||
@@ -199,7 +256,49 @@ class MainWindow(QMainWindow):
|
|||||||
QTimer.singleShot(100, self.start_animations)
|
QTimer.singleShot(100, self.start_animations)
|
||||||
|
|
||||||
def start_animations(self):
|
def start_animations(self):
|
||||||
|
self.ui.exit_btn.setEnabled(False)
|
||||||
|
self.animator.animation_finished.connect(self.on_animations_finished)
|
||||||
self.animator.start_animations()
|
self.animator.start_animations()
|
||||||
|
self.fetch_cloud_config()
|
||||||
|
|
||||||
|
def on_animations_finished(self):
|
||||||
|
self.ui.exit_btn.setEnabled(True)
|
||||||
|
|
||||||
|
def fetch_cloud_config(self):
|
||||||
|
headers = {"User-Agent": UA}
|
||||||
|
debug_mode = self.debug_action.isChecked()
|
||||||
|
self.config_fetch_thread = ConfigFetchThread(CONFIG_URL, headers, debug_mode, self)
|
||||||
|
self.config_fetch_thread.finished.connect(self.on_config_fetched)
|
||||||
|
self.config_fetch_thread.start()
|
||||||
|
|
||||||
|
def on_config_fetched(self, data, error_message):
|
||||||
|
if error_message:
|
||||||
|
if error_message == "update_required":
|
||||||
|
msg_box = msgbox_frame(
|
||||||
|
f"更新提示 - {APP_NAME}",
|
||||||
|
"\n当前版本过低,请及时更新。\n",
|
||||||
|
QtWidgets.QMessageBox.StandardButton.Ok,
|
||||||
|
)
|
||||||
|
msg_box.exec()
|
||||||
|
self.open_project_home_page()
|
||||||
|
self.shutdown_app(force_exit=True)
|
||||||
|
elif "missing_keys" in error_message:
|
||||||
|
missing_versions = error_message.split(":")[1]
|
||||||
|
msg_box = msgbox_frame(
|
||||||
|
f"配置缺失 - {APP_NAME}",
|
||||||
|
f'\n云端缺失下载链接,可能云服务器正在维护,不影响其他版本下载。\n当前缺失版本:"{missing_versions}"\n',
|
||||||
|
QtWidgets.QMessageBox.StandardButton.Ok,
|
||||||
|
)
|
||||||
|
msg_box.exec()
|
||||||
|
else:
|
||||||
|
# 其他错误暂时只在debug模式下打印
|
||||||
|
if self.debug_action.isChecked():
|
||||||
|
print(f"获取云端配置失败: {error_message}")
|
||||||
|
else:
|
||||||
|
self.cloud_config = data
|
||||||
|
if self.debug_action.isChecked():
|
||||||
|
print("--- Cloud config fetched successfully ---")
|
||||||
|
print(json.dumps(data, indent=2))
|
||||||
|
|
||||||
def toggle_debug_mode(self, checked):
|
def toggle_debug_mode(self, checked):
|
||||||
self.config["debug_mode"] = checked
|
self.config["debug_mode"] = checked
|
||||||
@@ -253,45 +352,51 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def get_download_url(self) -> dict:
|
def get_download_url(self) -> dict:
|
||||||
try:
|
try:
|
||||||
headers = {"User-Agent": UA}
|
if self.cloud_config:
|
||||||
if self.debug_action.isChecked():
|
if self.debug_action.isChecked():
|
||||||
print("--- Starting to get download URL ---")
|
print("--- Using pre-fetched cloud config ---")
|
||||||
print(f"DEBUG: Requesting URL: {CONFIG_URL}")
|
config_data = self.cloud_config
|
||||||
print(f"DEBUG: Using Headers: {headers}")
|
else:
|
||||||
|
# 如果没有预加载的配置,则同步获取
|
||||||
|
headers = {"User-Agent": UA}
|
||||||
|
response = requests.get(CONFIG_URL, headers=headers, timeout=10)
|
||||||
|
response.raise_for_status()
|
||||||
|
config_data = response.json()
|
||||||
|
|
||||||
response = requests.get(CONFIG_URL, headers=headers, timeout=10)
|
if not config_data:
|
||||||
|
raise ValueError("未能获取或解析配置数据")
|
||||||
|
|
||||||
if self.debug_action.isChecked():
|
|
||||||
print(f"DEBUG: Response Status Code: {response.status_code}")
|
|
||||||
print(f"DEBUG: Response Headers: {response.headers}")
|
|
||||||
print(f"DEBUG: Response Text: {response.text}")
|
|
||||||
|
|
||||||
response.raise_for_status()
|
|
||||||
|
|
||||||
# 从响应文本中提取有效的 JSON 部分
|
|
||||||
response_text = response.text
|
|
||||||
json_start_index = response_text.find('{')
|
|
||||||
if json_start_index == -1:
|
|
||||||
raise ValueError("响应中未找到有效的 JSON 对象")
|
|
||||||
|
|
||||||
json_text = response_text[json_start_index:]
|
|
||||||
config_data = json.loads(json_text)
|
|
||||||
|
|
||||||
if self.debug_action.isChecked():
|
if self.debug_action.isChecked():
|
||||||
print(f"DEBUG: Parsed JSON data: {json.dumps(config_data, indent=2)}")
|
print(f"DEBUG: Parsed JSON data: {json.dumps(config_data, indent=2)}")
|
||||||
|
|
||||||
# 修正键名检查,确保所有必需的键都存在
|
# 统一处理URL提取,确保返回扁平化的字典
|
||||||
required_keys = [f"vol.{i+1}.data" for i in range(4)] + ["after.data"]
|
urls = {}
|
||||||
if not all(key in config_data for key in required_keys):
|
for i in range(4):
|
||||||
missing_keys = [key for key in required_keys if key not in config_data]
|
key = f"vol.{i+1}.data"
|
||||||
raise ValueError(f"配置文件缺少必要的键: {', '.join(missing_keys)}")
|
if key in config_data and "url" in config_data[key]:
|
||||||
|
urls[f"vol{i+1}"] = config_data[key]["url"]
|
||||||
|
|
||||||
# 修正提取URL的逻辑,确保使用正确的键
|
if "after.data" in config_data and "url" in config_data["after.data"]:
|
||||||
urls = {
|
urls["after"] = config_data["after.data"]["url"]
|
||||||
f"vol{i+1}": config_data[f"vol.{i+1}.data"]["url"] for i in range(4)
|
|
||||||
} | {
|
# 检查是否成功提取了所有URL
|
||||||
"after": config_data["after.data"]["url"]
|
if len(urls) != 5:
|
||||||
}
|
missing_keys_map = {
|
||||||
|
f"vol{i+1}": f"vol.{i+1}.data" for i in range(4)
|
||||||
|
}
|
||||||
|
missing_keys_map["after"] = "after.data"
|
||||||
|
|
||||||
|
extracted_keys = set(urls.keys())
|
||||||
|
all_keys = set(missing_keys_map.keys())
|
||||||
|
missing_simple_keys = all_keys - extracted_keys
|
||||||
|
|
||||||
|
missing_original_keys = [missing_keys_map[k] for k in missing_simple_keys]
|
||||||
|
raise ValueError(f"配置文件缺少必要的键: {', '.join(missing_original_keys)}")
|
||||||
|
|
||||||
|
if self.debug_action.isChecked():
|
||||||
|
print(f"DEBUG: Extracted URLs: {urls}")
|
||||||
|
print("--- Finished getting download URL successfully ---")
|
||||||
|
return urls
|
||||||
if self.debug_action.isChecked():
|
if self.debug_action.isChecked():
|
||||||
print(f"DEBUG: Extracted URLs: {urls}")
|
print(f"DEBUG: Extracted URLs: {urls}")
|
||||||
print("--- Finished getting download URL successfully ---")
|
print("--- Finished getting download URL successfully ---")
|
||||||
@@ -367,7 +472,6 @@ class MainWindow(QMainWindow):
|
|||||||
else:
|
else:
|
||||||
QtWidgets.QMessageBox.critical(self, f"错误 - {APP_NAME}", "\n修改hosts文件失败,请检查程序是否以管理员权限运行。\n")
|
QtWidgets.QMessageBox.critical(self, f"错误 - {APP_NAME}", "\n修改hosts文件失败,请检查程序是否以管理员权限运行。\n")
|
||||||
|
|
||||||
self.setEnabled(True)
|
|
||||||
self.next_download_task()
|
self.next_download_task()
|
||||||
|
|
||||||
def start_download_with_ip(self, preferred_ip, url, _7z_path, game_version, game_folder, plugin_path):
|
def start_download_with_ip(self, preferred_ip, url, _7z_path, game_version, game_folder, plugin_path):
|
||||||
@@ -434,7 +538,6 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# --- Start Extraction in a new thread ---
|
# --- Start Extraction in a new thread ---
|
||||||
self.hash_msg_box = self.hash_manager.hash_pop_window()
|
self.hash_msg_box = self.hash_manager.hash_pop_window()
|
||||||
self.setEnabled(False)
|
|
||||||
|
|
||||||
self.extraction_thread = ExtractionThread(_7z_path, game_folder, plugin_path, game_version, self)
|
self.extraction_thread = ExtractionThread(_7z_path, game_folder, plugin_path, game_version, self)
|
||||||
self.extraction_thread.finished.connect(self.on_extraction_finished)
|
self.extraction_thread.finished.connect(self.on_extraction_finished)
|
||||||
@@ -443,7 +546,6 @@ class MainWindow(QMainWindow):
|
|||||||
def on_extraction_finished(self, success, error_message, game_version):
|
def on_extraction_finished(self, success, error_message, game_version):
|
||||||
if self.hash_msg_box and self.hash_msg_box.isVisible():
|
if self.hash_msg_box and self.hash_msg_box.isVisible():
|
||||||
self.hash_msg_box.close()
|
self.hash_msg_box.close()
|
||||||
self.setEnabled(True)
|
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
QtWidgets.QMessageBox.critical(self, f"错误 - {APP_NAME}", error_message)
|
QtWidgets.QMessageBox.critical(self, f"错误 - {APP_NAME}", error_message)
|
||||||
@@ -457,7 +559,7 @@ class MainWindow(QMainWindow):
|
|||||||
# 询问用户是否使用Cloudflare加速
|
# 询问用户是否使用Cloudflare加速
|
||||||
msg_box = QMessageBox(self)
|
msg_box = QMessageBox(self)
|
||||||
msg_box.setWindowTitle(f"下载优化 - {APP_NAME}")
|
msg_box.setWindowTitle(f"下载优化 - {APP_NAME}")
|
||||||
msg_box.setText("\n是否愿意通过Cloudflare加速来优化下载速度?\n\n这将临时修改系统的hosts文件,并需要管理员权限。")
|
msg_box.setText("是否愿意通过Cloudflare加速来优化下载速度?\n\n这将临时修改系统的hosts文件,并需要管理员权限。")
|
||||||
msg_box.setIcon(QMessageBox.Icon.Question)
|
msg_box.setIcon(QMessageBox.Icon.Question)
|
||||||
|
|
||||||
yes_button = msg_box.addButton("是,开启加速", QMessageBox.ButtonRole.YesRole)
|
yes_button = msg_box.addButton("是,开启加速", QMessageBox.ButtonRole.YesRole)
|
||||||
@@ -468,7 +570,6 @@ class MainWindow(QMainWindow):
|
|||||||
use_optimization = msg_box.clickedButton() == yes_button
|
use_optimization = msg_box.clickedButton() == yes_button
|
||||||
|
|
||||||
self.hash_msg_box = self.hash_manager.hash_pop_window()
|
self.hash_msg_box = self.hash_manager.hash_pop_window()
|
||||||
self.setEnabled(False)
|
|
||||||
|
|
||||||
install_paths = self.get_install_paths()
|
install_paths = self.get_install_paths()
|
||||||
|
|
||||||
@@ -488,7 +589,6 @@ class MainWindow(QMainWindow):
|
|||||||
QtWidgets.QMessageBox.critical(
|
QtWidgets.QMessageBox.critical(
|
||||||
self, f"错误 - {APP_NAME}", "\n网络状态异常或服务器故障,请重试\n"
|
self, f"错误 - {APP_NAME}", "\n网络状态异常或服务器故障,请重试\n"
|
||||||
)
|
)
|
||||||
self.setEnabled(True)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# --- 填充下载队列 ---
|
# --- 填充下载队列 ---
|
||||||
@@ -532,7 +632,6 @@ class MainWindow(QMainWindow):
|
|||||||
self.ip_optimizer_thread.start()
|
self.ip_optimizer_thread.start()
|
||||||
else:
|
else:
|
||||||
# 如果用户选择不优化,或已经优化过,直接开始下载
|
# 如果用户选择不优化,或已经优化过,直接开始下载
|
||||||
self.setEnabled(True)
|
|
||||||
self.next_download_task()
|
self.next_download_task()
|
||||||
|
|
||||||
def next_download_task(self):
|
def next_download_task(self):
|
||||||
@@ -578,7 +677,6 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def after_hash_compare(self, plugin_hash):
|
def after_hash_compare(self, plugin_hash):
|
||||||
self.hash_msg_box = self.hash_manager.hash_pop_window()
|
self.hash_msg_box = self.hash_manager.hash_pop_window()
|
||||||
self.setEnabled(False)
|
|
||||||
|
|
||||||
install_paths = self.get_install_paths()
|
install_paths = self.get_install_paths()
|
||||||
|
|
||||||
@@ -589,7 +687,6 @@ class MainWindow(QMainWindow):
|
|||||||
def on_after_hash_finished(self, result):
|
def on_after_hash_finished(self, result):
|
||||||
if self.hash_msg_box and self.hash_msg_box.isVisible():
|
if self.hash_msg_box and self.hash_msg_box.isVisible():
|
||||||
self.hash_msg_box.close()
|
self.hash_msg_box.close()
|
||||||
self.setEnabled(True)
|
|
||||||
|
|
||||||
if not result["passed"]:
|
if not result["passed"]:
|
||||||
game = result.get("game", "未知游戏")
|
game = result.get("game", "未知游戏")
|
||||||
@@ -639,50 +736,52 @@ class MainWindow(QMainWindow):
|
|||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
self.shutdown_app(event)
|
self.shutdown_app(event)
|
||||||
|
|
||||||
def shutdown_app(self, event=None):
|
def shutdown_app(self, event=None, force_exit=False):
|
||||||
self.hosts_manager.restore() # 恢复hosts文件
|
self.hosts_manager.restore() # 恢复hosts文件
|
||||||
self.stop_logging() # 确保在退出时停止日志记录
|
self.stop_logging() # 确保在退出时停止日志记录
|
||||||
reply = QtWidgets.QMessageBox.question(
|
|
||||||
self,
|
|
||||||
"退出程序",
|
|
||||||
"\n是否确定退出?\n",
|
|
||||||
QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
|
|
||||||
QtWidgets.QMessageBox.StandardButton.No,
|
|
||||||
)
|
|
||||||
|
|
||||||
if reply == QtWidgets.QMessageBox.StandardButton.Yes:
|
if not force_exit:
|
||||||
if (
|
reply = QtWidgets.QMessageBox.question(
|
||||||
self.current_download_thread
|
self,
|
||||||
and self.current_download_thread.isRunning()
|
"退出程序",
|
||||||
):
|
"\n是否确定退出?\n",
|
||||||
QtWidgets.QMessageBox.critical(
|
QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
|
||||||
self,
|
QtWidgets.QMessageBox.StandardButton.No,
|
||||||
f"错误 - {APP_NAME}",
|
)
|
||||||
"\n当前有下载任务正在进行,完成后再试\n",
|
if reply != QtWidgets.QMessageBox.StandardButton.Yes:
|
||||||
)
|
|
||||||
if event:
|
if event:
|
||||||
event.ignore()
|
event.ignore()
|
||||||
return
|
return
|
||||||
|
|
||||||
if os.path.exists(PLUGIN):
|
if (
|
||||||
for attempt in range(3):
|
self.current_download_thread
|
||||||
try:
|
and self.current_download_thread.isRunning()
|
||||||
shutil.rmtree(PLUGIN)
|
):
|
||||||
break
|
QtWidgets.QMessageBox.critical(
|
||||||
except Exception as e:
|
self,
|
||||||
if attempt == 2:
|
f"错误 - {APP_NAME}",
|
||||||
QtWidgets.QMessageBox.critical(
|
"\n当前有下载任务正在进行,完成后再试\n",
|
||||||
self,
|
)
|
||||||
f"错误 - {APP_NAME}",
|
|
||||||
f"\n清理缓存失败\n\n【错误信息】:{e}\n",
|
|
||||||
)
|
|
||||||
if event:
|
|
||||||
event.accept()
|
|
||||||
sys.exit(1)
|
|
||||||
if event:
|
if event:
|
||||||
event.accept()
|
event.ignore()
|
||||||
else:
|
return
|
||||||
sys.exit(0)
|
|
||||||
|
if os.path.exists(PLUGIN):
|
||||||
|
for attempt in range(3):
|
||||||
|
try:
|
||||||
|
shutil.rmtree(PLUGIN)
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
if attempt == 2:
|
||||||
|
QtWidgets.QMessageBox.critical(
|
||||||
|
self,
|
||||||
|
f"错误 - {APP_NAME}",
|
||||||
|
f"\n清理缓存失败\n\n【错误信息】:{e}\n",
|
||||||
|
)
|
||||||
|
if event:
|
||||||
|
event.accept()
|
||||||
|
sys.exit(1)
|
||||||
|
if event:
|
||||||
|
event.accept()
|
||||||
else:
|
else:
|
||||||
if event:
|
sys.exit(0)
|
||||||
event.ignore()
|
|
||||||
Reference in New Issue
Block a user