mirror of
https://github.com/hyb-oyqq/FRAISEMOE-Addons-Installer-NEXT.git
synced 2026-04-05 19:56:32 +00:00
feat(core): 集成补丁检测器以增强补丁管理功能
- 在主窗口中添加补丁检测器,支持补丁的检测和验证。 - 更新补丁管理器以使用补丁检测器进行补丁安装状态检查。 - 优化下载管理器和离线模式管理器,整合补丁检测逻辑,提升用户体验。 - 添加进度窗口以显示下载状态,增强用户反馈。 - 重构相关逻辑以支持新功能,确保代码可维护性和可读性。
This commit is contained in:
@@ -10,6 +10,7 @@ from PySide6.QtCore import QTimer, Qt, QPoint, QRect, QSize
|
||||
from PySide6.QtWidgets import QMainWindow, QMessageBox, QGraphicsOpacityEffect, QGraphicsColorizeEffect
|
||||
from PySide6.QtGui import QPalette, QColor, QPainterPath, QRegion, QFont
|
||||
from PySide6.QtGui import QAction # Added for menu actions
|
||||
from PySide6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QProgressBar, QLabel # Added for progress window
|
||||
|
||||
from ui.Ui_install import Ui_MainWindows
|
||||
from data.config import (
|
||||
@@ -26,7 +27,7 @@ from workers import (
|
||||
)
|
||||
from core import (
|
||||
MultiStageAnimations, UIManager, DownloadManager, DebugManager,
|
||||
WindowManager, GameDetector, PatchManager, ConfigManager
|
||||
WindowManager, GameDetector, PatchManager, ConfigManager, PatchDetector
|
||||
)
|
||||
from core.ipv6_manager import IPv6Manager
|
||||
from handlers import PatchToggleHandler, UninstallHandler
|
||||
@@ -79,16 +80,22 @@ class MainWindow(QMainWindow):
|
||||
# 5. 初始化其他管理器
|
||||
self.config_manager = ConfigManager(APP_NAME, CONFIG_URL, UA, self.debug_manager)
|
||||
self.game_detector = GameDetector(GAME_INFO, self.debug_manager)
|
||||
self.patch_manager = PatchManager(APP_NAME, GAME_INFO, self.debug_manager)
|
||||
self.patch_manager = PatchManager(APP_NAME, GAME_INFO, self.debug_manager, self)
|
||||
|
||||
# 6. 初始化离线模式管理器
|
||||
# 6. 初始化补丁检测模块
|
||||
self.patch_detector = PatchDetector(self)
|
||||
|
||||
# 7. 设置补丁检测器到补丁管理器
|
||||
self.patch_manager.set_patch_detector(self.patch_detector)
|
||||
|
||||
# 8. 初始化离线模式管理器
|
||||
from core.offline_mode_manager import OfflineModeManager
|
||||
self.offline_mode_manager = OfflineModeManager(self)
|
||||
|
||||
# 7. 初始化下载管理器 - 放在最后,因为它可能依赖于其他管理器
|
||||
# 9. 初始化下载管理器 - 放在最后,因为它可能依赖于其他管理器
|
||||
self.download_manager = DownloadManager(self)
|
||||
|
||||
# 8. 初始化功能处理程序
|
||||
# 10. 初始化功能处理程序
|
||||
self.uninstall_handler = UninstallHandler(self)
|
||||
self.patch_toggle_handler = PatchToggleHandler(self)
|
||||
|
||||
@@ -325,33 +332,40 @@ class MainWindow(QMainWindow):
|
||||
Args:
|
||||
url: 下载URL
|
||||
_7z_path: 7z文件保存路径
|
||||
game_version: 游戏版本名称
|
||||
game_version: 游戏版本
|
||||
|
||||
Returns:
|
||||
DownloadThread: 下载线程实例
|
||||
"""
|
||||
from workers import DownloadThread
|
||||
return DownloadThread(url, _7z_path, game_version, parent=self)
|
||||
return DownloadThread(url, _7z_path, game_version, self)
|
||||
|
||||
def create_progress_window(self):
|
||||
"""创建下载进度窗口
|
||||
"""创建进度窗口
|
||||
|
||||
Returns:
|
||||
ProgressWindow: 进度窗口实例
|
||||
QDialog: 进度窗口实例
|
||||
"""
|
||||
return ProgressWindow(self)
|
||||
progress_window = QDialog(self)
|
||||
progress_window.setWindowTitle(f"下载进度 - {APP_NAME}")
|
||||
progress_window.setFixedSize(400, 150)
|
||||
|
||||
def create_hash_thread(self, mode, install_paths):
|
||||
"""创建哈希检查线程
|
||||
layout = QVBoxLayout()
|
||||
|
||||
Args:
|
||||
mode: 检查模式,"pre"或"after"
|
||||
install_paths: 安装路径字典
|
||||
|
||||
Returns:
|
||||
HashThread: 哈希检查线程实例
|
||||
"""
|
||||
return HashThread(mode, install_paths, PLUGIN_HASH, self.installed_status, self)
|
||||
# 添加进度条
|
||||
progress_bar = QProgressBar()
|
||||
progress_bar.setRange(0, 100)
|
||||
progress_bar.setValue(0)
|
||||
layout.addWidget(progress_bar)
|
||||
|
||||
# 添加标签
|
||||
status_label = QLabel("准备下载...")
|
||||
layout.addWidget(status_label)
|
||||
|
||||
progress_window.setLayout(layout)
|
||||
progress_window.progress_bar = progress_bar
|
||||
progress_window.status_label = status_label
|
||||
|
||||
return progress_window
|
||||
|
||||
def create_extraction_thread(self, _7z_path, game_folder, plugin_path, game_version):
|
||||
"""创建解压线程
|
||||
@@ -367,121 +381,10 @@ class MainWindow(QMainWindow):
|
||||
"""
|
||||
return ExtractionThread(_7z_path, game_folder, plugin_path, game_version, self)
|
||||
|
||||
def after_hash_compare(self):
|
||||
"""进行安装后哈希比较"""
|
||||
# 禁用窗口已在安装流程开始时完成
|
||||
|
||||
# 检查是否处于离线模式
|
||||
is_offline = False
|
||||
if hasattr(self, 'offline_mode_manager'):
|
||||
is_offline = self.offline_mode_manager.is_in_offline_mode()
|
||||
|
||||
self.hash_msg_box = self.hash_manager.hash_pop_window(check_type="after", is_offline=is_offline)
|
||||
|
||||
install_paths = self.download_manager.get_install_paths()
|
||||
|
||||
self.hash_thread = self.create_hash_thread("after", install_paths)
|
||||
self.hash_thread.after_finished.connect(self.on_after_hash_finished)
|
||||
self.hash_thread.start()
|
||||
|
||||
def on_after_hash_finished(self, result):
|
||||
"""哈希比较完成后的处理
|
||||
|
||||
Args:
|
||||
result: 哈希比较结果
|
||||
"""
|
||||
# 确保哈希检查窗口关闭,无论是否还在显示
|
||||
if self.hash_msg_box:
|
||||
try:
|
||||
if self.hash_msg_box.isVisible():
|
||||
self.hash_msg_box.close()
|
||||
else:
|
||||
# 如果窗口已经不可见但没有关闭,也要尝试关闭
|
||||
self.hash_msg_box.close()
|
||||
except:
|
||||
pass # 忽略任何关闭窗口时的错误
|
||||
self.hash_msg_box = None
|
||||
|
||||
if not result["passed"]:
|
||||
# 启用窗口以显示错误消息
|
||||
self.setEnabled(True)
|
||||
|
||||
game = result.get("game", "未知游戏")
|
||||
message = result.get("message", "发生未知错误。")
|
||||
msg_box = msgbox_frame(
|
||||
f"文件校验失败 - {APP_NAME}",
|
||||
message,
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
msg_box.exec()
|
||||
|
||||
# 恢复窗口状态
|
||||
self.setEnabled(True)
|
||||
self.ui.start_install_text.setText("开始安装")
|
||||
|
||||
# 添加短暂延迟确保UI更新
|
||||
QTimer.singleShot(100, self.show_result)
|
||||
|
||||
def show_result(self):
|
||||
"""显示安装结果,区分不同情况"""
|
||||
# 获取当前安装状态
|
||||
installed_versions = [] # 成功安装的版本
|
||||
skipped_versions = [] # 已有补丁跳过的版本
|
||||
failed_versions = [] # 安装失败的版本
|
||||
not_found_versions = [] # 未找到的版本
|
||||
"""显示安装结果,调用patch_manager的show_result方法"""
|
||||
self.patch_manager.show_result()
|
||||
|
||||
# 获取所有游戏版本路径
|
||||
install_paths = self.download_manager.get_install_paths() if hasattr(self.download_manager, "get_install_paths") else {}
|
||||
|
||||
for game_version, is_installed in self.installed_status.items():
|
||||
# 只处理install_paths中存在的游戏版本
|
||||
if game_version in install_paths:
|
||||
path = install_paths[game_version]
|
||||
|
||||
# 检查游戏是否存在但未通过本次安装补丁
|
||||
if is_installed:
|
||||
# 游戏已安装补丁
|
||||
if hasattr(self, 'download_queue_history') and game_version not in self.download_queue_history:
|
||||
# 已有补丁,被跳过下载
|
||||
skipped_versions.append(game_version)
|
||||
else:
|
||||
# 本次成功安装
|
||||
installed_versions.append(game_version)
|
||||
else:
|
||||
# 游戏未安装补丁
|
||||
if os.path.exists(path):
|
||||
# 游戏文件夹存在,但安装失败
|
||||
failed_versions.append(game_version)
|
||||
else:
|
||||
# 游戏文件夹不存在
|
||||
not_found_versions.append(game_version)
|
||||
|
||||
# 构建结果信息
|
||||
result_text = f"\n安装结果:\n"
|
||||
|
||||
# 总数统计 - 不再显示已跳过的数量
|
||||
total_installed = len(installed_versions)
|
||||
total_failed = len(failed_versions)
|
||||
|
||||
result_text += f"安装成功:{total_installed} 个 安装失败:{total_failed} 个\n\n"
|
||||
|
||||
# 详细列表
|
||||
if installed_versions:
|
||||
result_text += f"【成功安装】:\n{chr(10).join(installed_versions)}\n\n"
|
||||
|
||||
if failed_versions:
|
||||
result_text += f"【安装失败】:\n{chr(10).join(failed_versions)}\n\n"
|
||||
|
||||
if not_found_versions:
|
||||
# 只有在真正检测到了游戏但未安装补丁时才显示
|
||||
result_text += f"【尚未安装补丁的游戏】:\n{chr(10).join(not_found_versions)}\n"
|
||||
|
||||
QMessageBox.information(
|
||||
self,
|
||||
f"安装完成 - {APP_NAME}",
|
||||
result_text
|
||||
)
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""窗口关闭事件处理
|
||||
|
||||
@@ -651,64 +554,18 @@ class MainWindow(QMainWindow):
|
||||
self.ui.start_install_text.setText("开始安装")
|
||||
return
|
||||
|
||||
# 显示游戏选择对话框
|
||||
dialog = QtWidgets.QDialog(self)
|
||||
dialog.setWindowTitle("选择要安装的游戏")
|
||||
dialog.resize(400, 300)
|
||||
# 显示文件检验窗口
|
||||
self.hash_msg_box = self.hash_manager.hash_pop_window(check_type="pre", is_offline=True)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout(dialog)
|
||||
# 获取安装路径
|
||||
install_paths = self.download_manager.get_install_paths()
|
||||
|
||||
# 添加"选择要安装的游戏"标签
|
||||
title_label = QtWidgets.QLabel("选择要安装的游戏", dialog)
|
||||
title_label.setFont(QFont(title_label.font().family(), title_label.font().pointSize(), QFont.Bold))
|
||||
layout.addWidget(title_label)
|
||||
|
||||
# 添加游戏列表控件
|
||||
list_widget = QtWidgets.QListWidget(dialog)
|
||||
list_widget.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection) # 允许多选
|
||||
for game_version in game_dirs.keys():
|
||||
list_widget.addItem(game_version)
|
||||
# 默认选中所有项目
|
||||
list_widget.item(list_widget.count() - 1).setSelected(True)
|
||||
layout.addWidget(list_widget)
|
||||
|
||||
# 添加全选按钮
|
||||
select_all_btn = QtWidgets.QPushButton("全选", dialog)
|
||||
select_all_btn.clicked.connect(lambda: list_widget.selectAll())
|
||||
layout.addWidget(select_all_btn)
|
||||
|
||||
# 添加确定和取消按钮
|
||||
buttons_layout = QtWidgets.QHBoxLayout()
|
||||
ok_button = QtWidgets.QPushButton("确定", dialog)
|
||||
cancel_button = QtWidgets.QPushButton("取消", dialog)
|
||||
buttons_layout.addWidget(ok_button)
|
||||
buttons_layout.addWidget(cancel_button)
|
||||
layout.addLayout(buttons_layout)
|
||||
|
||||
# 连接按钮事件
|
||||
ok_button.clicked.connect(dialog.accept)
|
||||
cancel_button.clicked.connect(dialog.reject)
|
||||
|
||||
# 显示对话框
|
||||
if dialog.exec() == QtWidgets.QDialog.DialogCode.Accepted:
|
||||
# 获取选择的游戏
|
||||
selected_games = [item.text() for item in list_widget.selectedItems()]
|
||||
|
||||
if selected_games:
|
||||
# 使用离线模式管理器进行安装
|
||||
self.offline_mode_manager.install_offline_patches(selected_games)
|
||||
else:
|
||||
QtWidgets.QMessageBox.information(
|
||||
self,
|
||||
f"通知 - {APP_NAME}",
|
||||
"\n未选择任何游戏,安装已取消。\n"
|
||||
)
|
||||
self.setEnabled(True)
|
||||
self.ui.start_install_text.setText("开始安装")
|
||||
else:
|
||||
# 用户取消了选择
|
||||
self.setEnabled(True)
|
||||
self.ui.start_install_text.setText("开始安装")
|
||||
# 创建并启动哈希线程进行预检查
|
||||
self.hash_thread = self.patch_detector.create_hash_thread("pre", install_paths)
|
||||
self.hash_thread.pre_finished.connect(
|
||||
lambda updated_status: self.patch_detector.on_offline_pre_hash_finished(updated_status, game_dirs)
|
||||
)
|
||||
self.hash_thread.start()
|
||||
else:
|
||||
# 在线模式下,检查版本是否过低
|
||||
if hasattr(self, 'version_warning') and self.version_warning:
|
||||
@@ -723,6 +580,8 @@ class MainWindow(QMainWindow):
|
||||
# 版本正常,使用原有的下载流程
|
||||
self.download_manager.file_dialog()
|
||||
|
||||
# 移除on_offline_pre_hash_finished方法
|
||||
|
||||
def check_and_set_offline_mode(self):
|
||||
"""检查是否有离线补丁文件,如果有则自动启用离线模式
|
||||
|
||||
|
||||
Reference in New Issue
Block a user