feat(core): 增强日志记录和错误处理功能

- 更新日志记录机制,将日志文件存储在程序根目录下的log文件夹中,并使用日期+时间戳格式命名。
- 在多个模块中添加详细的错误处理逻辑,确保在发生异常时能够记录相关信息,便于后续排查。
- 优化UI管理器中的日志文件打开功能,增加对日志文件存在性和大小的检查,提升用户体验。
- 在下载管理器和补丁管理器中增强调试信息的记录,确保在关键操作中提供更清晰的反馈。
This commit is contained in:
欧阳淇淇
2025-08-07 00:31:24 +08:00
parent 19cdd5b8cd
commit d12739baab
16 changed files with 614 additions and 225 deletions

View File

@@ -4,6 +4,8 @@ from PySide6 import QtWidgets
from data.config import LOG_FILE
from utils.logger import setup_logger
from utils import Logger
import datetime
from data.config import APP_NAME
# 初始化logger
logger = setup_logger("debug_manager")
@@ -60,6 +62,25 @@ class DebugManager:
self.main_window.config["debug_mode"] = checked
self.main_window.save_config(self.main_window.config)
# 创建或删除debug_mode.txt标记文件
try:
from data.config import CACHE
debug_file = os.path.join(os.path.dirname(CACHE), "debug_mode.txt")
if checked:
# 确保目录存在
os.makedirs(os.path.dirname(debug_file), exist_ok=True)
# 创建标记文件
with open(debug_file, 'w', encoding='utf-8') as f:
f.write(f"Debug mode enabled at {os.path.abspath(debug_file)}\n")
logger.info(f"已创建调试模式标记文件: {debug_file}")
elif os.path.exists(debug_file):
# 删除标记文件
os.remove(debug_file)
logger.info(f"已删除调试模式标记文件: {debug_file}")
except Exception as e:
logger.warning(f"处理调试模式标记文件时发生错误: {e}")
# 更新打开log文件按钮状态
if hasattr(self, 'ui_manager') and hasattr(self.ui_manager, 'open_log_action'):
self.ui_manager.open_log_action.setEnabled(checked)
@@ -88,16 +109,32 @@ class DebugManager:
"""启动日志记录"""
if self.logger is None:
try:
if os.path.exists(LOG_FILE):
os.remove(LOG_FILE)
# 确保log目录存在
log_dir = os.path.dirname(LOG_FILE)
if not os.path.exists(log_dir):
os.makedirs(log_dir, exist_ok=True)
logger.info(f"已创建日志目录: {log_dir}")
# 创建新的日志文件,使用覆盖模式而不是追加模式
with open(LOG_FILE, 'w', encoding='utf-8') as f:
current_time = datetime.datetime.now()
formatted_date = current_time.strftime("%Y-%m-%d")
formatted_time = current_time.strftime("%H:%M:%S")
f.write(f"--- 新调试会话开始于 {os.path.basename(LOG_FILE)} ---\n")
f.write(f"--- 应用版本: {APP_NAME} ---\n")
f.write(f"--- 日期: {formatted_date} 时间: {formatted_time} ---\n\n")
logger.info(f"已创建日志文件: {os.path.abspath(LOG_FILE)}")
# 保存原始的 stdout 和 stderr
self.original_stdout = sys.stdout
self.original_stderr = sys.stderr
# 创建 Logger 实例
self.logger = Logger(LOG_FILE, self.original_stdout)
sys.stdout = self.logger
sys.stderr = self.logger
logger.info("--- Debug mode enabled ---")
logger.info(f"--- Debug mode enabled (log file: {os.path.abspath(LOG_FILE)}) ---")
except (IOError, OSError) as e:
QtWidgets.QMessageBox.critical(self.main_window, "错误", f"无法创建日志文件: {e}")
self.logger = None

View File

@@ -260,11 +260,19 @@ class DownloadManager:
disabled_patch_games = [] # 存储检测到禁用补丁的游戏
for game_version, game_dir in game_dirs.items():
# 检查游戏是否已安装补丁
if self.main_window.installed_status.get(game_version, False):
# 首先通过文件检查确认补丁是否已安装
is_patch_installed = self.main_window.patch_manager.check_patch_installed(game_dir, game_version)
# 同时考虑哈希检查结果
hash_check_passed = self.main_window.installed_status.get(game_version, False)
# 如果补丁文件存在或哈希检查通过,认为已安装
if is_patch_installed or hash_check_passed:
if debug_mode:
logger.info(f"DEBUG: {game_version} 已安装补丁,不需要再次安装")
logger.info(f"DEBUG: 文件检查结果: {is_patch_installed}, 哈希检查结果: {hash_check_passed}")
already_installed_games.append(game_version)
# 更新安装状态
self.main_window.installed_status[game_version] = True
else:
# 检查是否存在被禁用的补丁
is_disabled, disabled_path = self.main_window.patch_manager.check_patch_disabled(game_dir, game_version)
@@ -275,6 +283,7 @@ class DownloadManager:
else:
if debug_mode:
logger.info(f"DEBUG: {game_version} 未安装补丁,可以安装")
logger.info(f"DEBUG: 文件检查结果: {is_patch_installed}, 哈希检查结果: {hash_check_passed}")
installable_games.append(game_version)
status_message = ""
@@ -748,9 +757,35 @@ class DownloadManager:
self.main_window.setEnabled(True)
# 分析错误类型
error_type = "未知错误"
suggestion = ""
if "SSL/TLS handshake failure" in error:
error_type = "SSL/TLS连接失败"
suggestion = "可能是由于网络连接不稳定或证书问题,建议:\n1. 检查网络连接\n2. 尝试使用其他网络\n3. 确保系统时间和日期正确\n4. 可能需要使用代理或VPN"
elif "Connection timed out" in error or "read timed out" in error:
error_type = "连接超时"
suggestion = "下载服务器响应时间过长,建议:\n1. 检查网络连接\n2. 稍后重试\n3. 使用优化网络选项"
elif "404" in error:
error_type = "文件不存在"
suggestion = "请求的文件不存在或已移除,请联系开发者"
elif "403" in error:
error_type = "访问被拒绝"
suggestion = "服务器拒绝请求,可能需要使用优化网络选项"
elif "No space left on device" in error or "空间不足" in error:
error_type = "存储空间不足"
suggestion = "请确保有足够的磁盘空间用于下载和解压文件"
msg_box = QtWidgets.QMessageBox(self.main_window)
msg_box.setWindowTitle(f"下载失败 - {APP_NAME}")
msg_box.setText(f"\n文件获取失败: {game_version}\n错误: {error}\n\n是否重试?")
error_message = f"\n文件获取失败: {game_version}\n错误类型: {error_type}"
if suggestion:
error_message += f"\n\n可能的解决方案:\n{suggestion}"
error_message += "\n\n是否重试?"
msg_box.setText(error_message)
retry_button = msg_box.addButton("重试", QtWidgets.QMessageBox.ButtonRole.YesRole)
next_button = msg_box.addButton("下一个", QtWidgets.QMessageBox.ButtonRole.NoRole)

View File

@@ -1,5 +1,6 @@
import os
import re
from utils.logger import setup_logger
class GameDetector:
"""游戏检测器,用于识别游戏目录和版本"""
@@ -14,6 +15,7 @@ class GameDetector:
self.game_info = game_info
self.debug_manager = debug_manager
self.directory_cache = {} # 添加目录缓存
self.logger = setup_logger("game_detector")
def _is_debug_mode(self):
"""检查是否处于调试模式
@@ -37,7 +39,7 @@ class GameDetector:
debug_mode = self._is_debug_mode()
if debug_mode:
print(f"DEBUG: 尝试识别游戏版本: {game_dir}")
self.logger.debug(f"尝试识别游戏版本: {game_dir}")
# 先通过目录名称进行初步推测(这将作为递归搜索的提示)
dir_name = os.path.basename(game_dir).lower()
@@ -51,11 +53,11 @@ class GameDetector:
vol_num = vol_match.group(1)
potential_version = f"NEKOPARA Vol.{vol_num}"
if debug_mode:
print(f"DEBUG: 从目录名推测游戏版本: {potential_version}, 卷号: {vol_num}")
self.logger.debug(f"从目录名推测游戏版本: {potential_version}, 卷号: {vol_num}")
elif "after" in dir_name:
potential_version = "NEKOPARA After"
if debug_mode:
print(f"DEBUG: 从目录名推测游戏版本: NEKOPARA After")
self.logger.debug(f"从目录名推测游戏版本: NEKOPARA After")
# 检查是否为NEKOPARA游戏目录
# 通过检查游戏可执行文件来识别游戏版本
@@ -88,7 +90,7 @@ class GameDetector:
exe_path = os.path.join(game_dir, exe_variant)
if os.path.exists(exe_path):
if debug_mode:
print(f"DEBUG: 通过可执行文件确认游戏版本: {game_version}, 文件: {exe_variant}")
self.logger.debug(f"通过可执行文件确认游戏版本: {game_version}, 文件: {exe_variant}")
return game_version
# 如果没有直接匹配,尝试递归搜索
@@ -111,17 +113,17 @@ class GameDetector:
f"vol {vol_num}" in file_lower)) or
(is_after and "after" in file_lower)):
if debug_mode:
print(f"DEBUG: 通过递归搜索确认游戏版本: {potential_version}, 文件: {file}")
self.logger.debug(f"通过递归搜索确认游戏版本: {potential_version}, 文件: {file}")
return potential_version
# 如果仍然没有找到,基于目录名的推测返回结果
if potential_version:
if debug_mode:
print(f"DEBUG: 基于目录名返回推测的游戏版本: {potential_version}")
self.logger.debug(f"基于目录名返回推测的游戏版本: {potential_version}")
return potential_version
if debug_mode:
print(f"DEBUG: 无法识别游戏版本: {game_dir}")
self.logger.debug(f"无法识别游戏版本: {game_dir}")
return None
@@ -139,11 +141,11 @@ class GameDetector:
# 检查缓存中是否已有该目录的识别结果
if selected_folder in self.directory_cache:
if debug_mode:
print(f"DEBUG: 使用缓存的目录识别结果: {selected_folder}")
self.logger.debug(f"使用缓存的目录识别结果: {selected_folder}")
return self.directory_cache[selected_folder]
if debug_mode:
print(f"--- 开始识别目录: {selected_folder} ---")
self.logger.debug(f"--- 开始识别目录: {selected_folder} ---")
game_paths = {}
@@ -151,10 +153,10 @@ class GameDetector:
try:
all_dirs = [d for d in os.listdir(selected_folder) if os.path.isdir(os.path.join(selected_folder, d))]
if debug_mode:
print(f"DEBUG: 找到以下子目录: {all_dirs}")
self.logger.debug(f"找到以下子目录: {all_dirs}")
except Exception as e:
if debug_mode:
print(f"DEBUG: 无法读取目录 {selected_folder}: {str(e)}")
self.logger.debug(f"无法读取目录 {selected_folder}: {str(e)}")
return {}
for game, info in self.game_info.items():
@@ -162,7 +164,7 @@ class GameDetector:
expected_exe = info["exe"] # 标准可执行文件名
if debug_mode:
print(f"DEBUG: 搜索游戏 {game}, 预期目录: {expected_dir}, 预期可执行文件: {expected_exe}")
self.logger.debug(f"搜索游戏 {game}, 预期目录: {expected_dir}, 预期可执行文件: {expected_exe}")
# 尝试不同的匹配方法
found_dir = None
@@ -171,7 +173,7 @@ class GameDetector:
if expected_dir in all_dirs:
found_dir = expected_dir
if debug_mode:
print(f"DEBUG: 精确匹配成功: {expected_dir}")
self.logger.debug(f"精确匹配成功: {expected_dir}")
# 2. 大小写不敏感匹配
if not found_dir:
@@ -179,7 +181,7 @@ class GameDetector:
if expected_dir.lower() == dir_name.lower():
found_dir = dir_name
if debug_mode:
print(f"DEBUG: 大小写不敏感匹配成功: {dir_name}")
self.logger.debug(f"大小写不敏感匹配成功: {dir_name}")
break
# 3. 更模糊的匹配(允许特殊字符差异)
@@ -193,7 +195,7 @@ class GameDetector:
if pattern.match(dir_name):
found_dir = dir_name
if debug_mode:
print(f"DEBUG: 模糊匹配成功: {dir_name} 匹配模式 {pattern_text}")
self.logger.debug(f"模糊匹配成功: {dir_name} 匹配模式 {pattern_text}")
break
# 4. 如果还是没找到,尝试更宽松的匹配
@@ -203,7 +205,7 @@ class GameDetector:
if vol_match:
vol_num = vol_match.group(1)
if debug_mode:
print(f"DEBUG: 提取卷号: {vol_num}")
self.logger.debug(f"提取卷号: {vol_num}")
is_after = "after" in expected_dir.lower()
@@ -214,7 +216,7 @@ class GameDetector:
if is_after and "after" in dir_lower:
found_dir = dir_name
if debug_mode:
print(f"DEBUG: After特殊匹配成功: {dir_name}")
self.logger.debug(f"After特殊匹配成功: {dir_name}")
break
# 对于Vol特殊处理
@@ -224,7 +226,7 @@ class GameDetector:
if dir_vol_match and dir_vol_match.group(1) == vol_num:
found_dir = dir_name
if debug_mode:
print(f"DEBUG: 卷号匹配成功: {dir_name} 卷号 {vol_num}")
self.logger.debug(f"卷号匹配成功: {dir_name} 卷号 {vol_num}")
break
# 如果找到匹配的目录验证exe文件是否存在
@@ -267,7 +269,7 @@ class GameDetector:
exe_exists = True
found_exe = exe_variant
if debug_mode:
print(f"DEBUG: 验证成功,找到游戏可执行文件: {exe_variant}")
self.logger.debug(f"验证成功,找到游戏可执行文件: {exe_variant}")
break
# 如果没有直接找到,尝试递归搜索当前目录下的所有可执行文件
@@ -290,14 +292,14 @@ class GameDetector:
exe_exists = True
found_exe = os.path.relpath(exe_path, potential_path)
if debug_mode:
print(f"DEBUG: 通过递归搜索找到游戏可执行文件: {found_exe}")
self.logger.debug(f"通过递归搜索找到游戏可执行文件: {found_exe}")
break
elif "After" in game and "after" in file_lower:
exe_path = os.path.join(root, file)
exe_exists = True
found_exe = os.path.relpath(exe_path, potential_path)
if debug_mode:
print(f"DEBUG: 通过递归搜索找到After游戏可执行文件: {found_exe}")
self.logger.debug(f"通过递归搜索找到After游戏可执行文件: {found_exe}")
break
if exe_exists:
break
@@ -306,14 +308,14 @@ class GameDetector:
if exe_exists:
game_paths[game] = potential_path
if debug_mode:
print(f"DEBUG: 验证成功,将 {potential_path} 添加为 {game} 的目录")
self.logger.debug(f"验证成功,将 {potential_path} 添加为 {game} 的目录")
else:
if debug_mode:
print(f"DEBUG: 未找到任何可执行文件变体,游戏 {game}{potential_path} 未找到")
self.logger.debug(f"未找到任何可执行文件变体,游戏 {game}{potential_path} 未找到")
if debug_mode:
print(f"DEBUG: 最终识别的游戏目录: {game_paths}")
print(f"--- 目录识别结束 ---")
self.logger.debug(f"最终识别的游戏目录: {game_paths}")
self.logger.debug(f"--- 目录识别结束 ---")
# 将识别结果存入缓存
self.directory_cache[selected_folder] = game_paths
@@ -324,4 +326,4 @@ class GameDetector:
"""清除目录缓存"""
self.directory_cache = {}
if self._is_debug_mode():
print("DEBUG: 已清除目录缓存")
self.logger.debug("已清除目录缓存")

View File

@@ -1,6 +1,8 @@
import os
import shutil
import traceback
from PySide6.QtWidgets import QMessageBox
from utils.logger import setup_logger
class PatchManager:
"""补丁管理器,用于处理补丁的安装和卸载"""
@@ -17,6 +19,7 @@ class PatchManager:
self.game_info = game_info
self.debug_manager = debug_manager
self.installed_status = {} # 游戏版本的安装状态
self.logger = setup_logger("patch_manager")
def _is_debug_mode(self):
"""检查是否处于调试模式
@@ -70,7 +73,7 @@ class PatchManager:
debug_mode = self._is_debug_mode()
if debug_mode:
print(f"DEBUG: 开始卸载 {game_version} 补丁,目录: {game_dir}")
self.logger.debug(f"开始卸载 {game_version} 补丁,目录: {game_dir}")
if game_version not in self.game_info:
if not silent:
@@ -99,7 +102,7 @@ class PatchManager:
]
if debug_mode:
print(f"DEBUG: 查找以下可能的补丁文件路径: {patch_files_to_check}")
self.logger.debug(f"查找以下可能的补丁文件路径: {patch_files_to_check}")
# 查找并删除补丁文件,包括启用和禁用的
patch_file_found = False
@@ -110,7 +113,7 @@ class PatchManager:
os.remove(patch_path)
files_removed += 1
if debug_mode:
print(f"DEBUG: 已删除补丁文件: {patch_path}")
self.logger.debug(f"已删除补丁文件: {patch_path}")
# 检查被禁用的补丁文件(带.fain后缀
disabled_path = f"{patch_path}.fain"
@@ -119,11 +122,11 @@ class PatchManager:
os.remove(disabled_path)
files_removed += 1
if debug_mode:
print(f"DEBUG: 已删除被禁用的补丁文件: {disabled_path}")
self.logger.debug(f"已删除被禁用的补丁文件: {disabled_path}")
if not patch_file_found and debug_mode:
print(f"DEBUG: 未找到补丁文件,检查了以下路径: {patch_files_to_check}")
print(f"DEBUG: 也检查了禁用的补丁文件(.fain后缀")
self.logger.debug(f"未找到补丁文件,检查了以下路径: {patch_files_to_check}")
self.logger.debug(f"也检查了禁用的补丁文件(.fain后缀")
# 检查是否有额外的签名文件 (.sig)
if game_version == "NEKOPARA After":
@@ -134,7 +137,7 @@ class PatchManager:
os.remove(sig_file_path)
files_removed += 1
if debug_mode:
print(f"DEBUG: 已删除签名文件: {sig_file_path}")
self.logger.debug(f"已删除签名文件: {sig_file_path}")
# 检查被禁用补丁的签名文件
disabled_sig_path = f"{patch_path}.fain.sig"
@@ -142,7 +145,7 @@ class PatchManager:
os.remove(disabled_sig_path)
files_removed += 1
if debug_mode:
print(f"DEBUG: 已删除被禁用补丁的签名文件: {disabled_sig_path}")
self.logger.debug(f"已删除被禁用补丁的签名文件: {disabled_sig_path}")
# 删除patch文件夹
patch_folders_to_check = [
@@ -156,7 +159,7 @@ class PatchManager:
shutil.rmtree(patch_folder)
files_removed += 1
if debug_mode:
print(f"DEBUG: 已删除补丁文件夹: {patch_folder}")
self.logger.debug(f"已删除补丁文件夹: {patch_folder}")
# 删除game/patch文件夹
game_folders = ["game", "Game", "GAME"]
@@ -169,7 +172,7 @@ class PatchManager:
shutil.rmtree(game_patch_folder)
files_removed += 1
if debug_mode:
print(f"DEBUG: 已删除game/patch文件夹: {game_patch_folder}")
self.logger.debug(f"已删除game/patch文件夹: {game_patch_folder}")
# 删除配置文件
config_files = ["config.json", "Config.json", "CONFIG.JSON"]
@@ -185,7 +188,7 @@ class PatchManager:
os.remove(config_path)
files_removed += 1
if debug_mode:
print(f"DEBUG: 已删除配置文件: {config_path}")
self.logger.debug(f"已删除配置文件: {config_path}")
# 删除脚本文件
for script_file in script_files:
@@ -194,7 +197,7 @@ class PatchManager:
os.remove(script_path)
files_removed += 1
if debug_mode:
print(f"DEBUG: 已删除脚本文件: {script_path}")
self.logger.debug(f"已删除脚本文件: {script_path}")
# 更新安装状态
self.installed_status[game_version] = False
@@ -228,9 +231,9 @@ class PatchManager:
# 显示卸载失败消息
error_message = f"\n卸载 {game_version} 补丁时出错:\n\n{str(e)}\n"
if debug_mode:
print(f"DEBUG: 卸载错误 - {str(e)}")
self.logger.debug(f"卸载错误 - {str(e)}")
import traceback
print(f"DEBUG: 错误详情:\n{traceback.format_exc()}")
self.logger.debug(f"错误详情:\n{traceback.format_exc()}")
QMessageBox.critical(
None,
@@ -288,7 +291,7 @@ class PatchManager:
except Exception as e:
if debug_mode:
print(f"DEBUG: 卸载 {version} 时出错: {str(e)}")
self.logger.debug(f"卸载 {version} 时出错: {str(e)}")
fail_count += 1
results.append({
"version": version,
@@ -359,13 +362,13 @@ class PatchManager:
for patch_path in patch_files_to_check:
if os.path.exists(patch_path):
if debug_mode:
print(f"DEBUG: 找到补丁文件: {patch_path}")
self.logger.debug(f"找到补丁文件: {patch_path}")
return True
# 检查是否存在被禁用的补丁文件(带.fain后缀
disabled_path = f"{patch_path}.fain"
if os.path.exists(disabled_path):
if debug_mode:
print(f"DEBUG: 找到被禁用的补丁文件: {disabled_path}")
self.logger.debug(f"找到被禁用的补丁文件: {disabled_path}")
return True
# 检查是否有补丁文件夹
@@ -378,7 +381,7 @@ class PatchManager:
for patch_folder in patch_folders_to_check:
if os.path.exists(patch_folder):
if debug_mode:
print(f"DEBUG: 找到补丁文件夹: {patch_folder}")
self.logger.debug(f"找到补丁文件夹: {patch_folder}")
return True
# 检查game/patch文件夹
@@ -390,7 +393,7 @@ class PatchManager:
game_patch_folder = os.path.join(game_dir, game_folder, patch_folder)
if os.path.exists(game_patch_folder):
if debug_mode:
print(f"DEBUG: 找到game/patch文件夹: {game_patch_folder}")
self.logger.debug(f"找到game/patch文件夹: {game_patch_folder}")
return True
# 检查配置文件
@@ -405,7 +408,7 @@ class PatchManager:
config_path = os.path.join(game_path, config_file)
if os.path.exists(config_path):
if debug_mode:
print(f"DEBUG: 找到配置文件: {config_path}")
self.logger.debug(f"找到配置文件: {config_path}")
return True
# 检查脚本文件
@@ -413,12 +416,12 @@ class PatchManager:
script_path = os.path.join(game_path, script_file)
if os.path.exists(script_path):
if debug_mode:
print(f"DEBUG: 找到脚本文件: {script_path}")
self.logger.debug(f"找到脚本文件: {script_path}")
return True
# 没有找到补丁文件或文件夹
if debug_mode:
print(f"DEBUG: {game_version}{game_dir} 中没有安装补丁")
self.logger.debug(f"{game_version}{game_dir} 中没有安装补丁")
return False
def check_patch_disabled(self, game_dir, game_version):
@@ -454,11 +457,11 @@ class PatchManager:
for disabled_path in disabled_patch_files:
if os.path.exists(disabled_path):
if debug_mode:
print(f"DEBUG: 找到禁用的补丁文件: {disabled_path}")
self.logger.debug(f"找到禁用的补丁文件: {disabled_path}")
return True, disabled_path
if debug_mode:
print(f"DEBUG: {game_version}{game_dir} 的补丁未被禁用")
self.logger.debug(f"{game_version}{game_dir} 的补丁未被禁用")
return False, None
@@ -477,11 +480,11 @@ class PatchManager:
debug_mode = self._is_debug_mode()
if debug_mode:
print(f"DEBUG: 开始切换补丁状态 - 游戏版本: {game_version}, 游戏目录: {game_dir}, 操作: {operation}")
self.logger.debug(f"开始切换补丁状态 - 游戏版本: {game_version}, 游戏目录: {game_dir}, 操作: {operation}")
if game_version not in self.game_info:
if debug_mode:
print(f"DEBUG: 无法识别游戏版本: {game_version}")
self.logger.debug(f"无法识别游戏版本: {game_version}")
if not silent:
QMessageBox.critical(
None,
@@ -494,11 +497,11 @@ class PatchManager:
# 检查补丁是否已安装
is_patch_installed = self.check_patch_installed(game_dir, game_version)
if debug_mode:
print(f"DEBUG: 补丁安装状态检查结果: {is_patch_installed}")
self.logger.debug(f"补丁安装状态检查结果: {is_patch_installed}")
if not is_patch_installed:
if debug_mode:
print(f"DEBUG: {game_version} 未安装补丁,无法进行禁用/启用操作")
self.logger.debug(f"{game_version} 未安装补丁,无法进行禁用/启用操作")
if not silent:
QMessageBox.warning(
None,
@@ -512,7 +515,7 @@ class PatchManager:
# 检查当前状态
is_disabled, disabled_path = self.check_patch_disabled(game_dir, game_version)
if debug_mode:
print(f"DEBUG: 补丁禁用状态检查结果 - 是否禁用: {is_disabled}, 禁用路径: {disabled_path}")
self.logger.debug(f"补丁禁用状态检查结果 - 是否禁用: {is_disabled}, 禁用路径: {disabled_path}")
# 获取可能的补丁文件路径
install_path_base = os.path.basename(self.game_info[game_version]["install_path"])
@@ -528,7 +531,7 @@ class PatchManager:
]
if debug_mode:
print(f"DEBUG: 将检查以下可能的补丁文件: {patch_files_to_check}")
self.logger.debug(f"将检查以下可能的补丁文件: {patch_files_to_check}")
# 确定操作类型
if operation:
@@ -542,7 +545,7 @@ class PatchManager:
action_needed = True # 未指定操作类型,始终执行切换
if debug_mode:
print(f"DEBUG: 操作决策 - 操作类型: {operation}, 是否需要执行操作: {action_needed}")
self.logger.debug(f"操作决策 - 操作类型: {operation}, 是否需要执行操作: {action_needed}")
if not action_needed:
# 补丁已经是目标状态,无需操作
@@ -552,7 +555,7 @@ class PatchManager:
message = f"{game_version} 补丁已经是禁用状态"
if debug_mode:
print(f"DEBUG: {message}, 无需操作")
self.logger.debug(f"{message}, 无需操作")
if not silent:
QMessageBox.information(
@@ -569,17 +572,17 @@ class PatchManager:
# 从禁用文件名去掉.fain后缀
enabled_path = disabled_path[:-5] # 去掉.fain
if debug_mode:
print(f"DEBUG: 正在启用补丁 - 从 {disabled_path} 重命名为 {enabled_path}")
self.logger.debug(f"正在启用补丁 - 从 {disabled_path} 重命名为 {enabled_path}")
os.rename(disabled_path, enabled_path)
if debug_mode:
print(f"DEBUG: 已启用 {game_version} 的补丁,重命名文件成功")
self.logger.debug(f"已启用 {game_version} 的补丁,重命名文件成功")
action = "enable"
message = f"{game_version} 补丁已启用"
else:
# 未找到禁用的补丁文件,但状态是禁用
message = f"未找到禁用的补丁文件: {disabled_path}"
if debug_mode:
print(f"DEBUG: {message}")
self.logger.debug(f"{message}")
return {"success": False, "message": message, "action": "none"}
else:
# 当前是启用状态,需要禁用
@@ -589,24 +592,24 @@ class PatchManager:
if os.path.exists(patch_path):
active_patch_file = patch_path
if debug_mode:
print(f"DEBUG: 找到活跃的补丁文件: {active_patch_file}")
self.logger.debug(f"找到活跃的补丁文件: {active_patch_file}")
break
if active_patch_file:
# 给补丁文件添加.fain后缀禁用它
disabled_path = f"{active_patch_file}.fain"
if debug_mode:
print(f"DEBUG: 正在禁用补丁 - 从 {active_patch_file} 重命名为 {disabled_path}")
self.logger.debug(f"正在禁用补丁 - 从 {active_patch_file} 重命名为 {disabled_path}")
os.rename(active_patch_file, disabled_path)
if debug_mode:
print(f"DEBUG: 已禁用 {game_version} 的补丁,重命名文件成功")
self.logger.debug(f"已禁用 {game_version} 的补丁,重命名文件成功")
action = "disable"
message = f"{game_version} 补丁已禁用"
else:
# 未找到活跃的补丁文件,但状态是启用
message = f"未找到启用的补丁文件,请检查游戏目录: {game_dir}"
if debug_mode:
print(f"DEBUG: {message}")
self.logger.debug(f"{message}")
return {"success": False, "message": message, "action": "none"}
# 非静默模式下显示操作结果
@@ -619,7 +622,7 @@ class PatchManager:
)
if debug_mode:
print(f"DEBUG: 切换补丁状态操作完成 - 结果: 成功, 操作: {action}, 消息: {message}")
self.logger.debug(f"切换补丁状态操作完成 - 结果: 成功, 操作: {action}, 消息: {message}")
return {"success": True, "message": message, "action": action}
@@ -627,9 +630,9 @@ class PatchManager:
error_message = f"切换 {game_version} 补丁状态时出错: {str(e)}"
if debug_mode:
print(f"DEBUG: {error_message}")
self.logger.debug(f"{error_message}")
import traceback
print(f"DEBUG: 错误详情:\n{traceback.format_exc()}")
self.logger.debug(f"错误详情:\n{traceback.format_exc()}")
if not silent:
QMessageBox.critical(
@@ -657,28 +660,28 @@ class PatchManager:
results = []
if debug_mode:
print(f"DEBUG: 开始批量切换补丁状态 - 操作: {operation}, 游戏数量: {len(game_dirs)}")
print(f"DEBUG: 游戏列表: {list(game_dirs.keys())}")
self.logger.debug(f"开始批量切换补丁状态 - 操作: {operation}, 游戏数量: {len(game_dirs)}")
self.logger.debug(f"游戏列表: {list(game_dirs.keys())}")
for version, path in game_dirs.items():
try:
if debug_mode:
print(f"DEBUG: 处理游戏 {version}, 目录: {path}")
self.logger.debug(f"处理游戏 {version}, 目录: {path}")
# 在批量模式下使用静默操作
result = self.toggle_patch(path, version, operation=operation, silent=True)
if debug_mode:
print(f"DEBUG: 游戏 {version} 操作结果: {result}")
self.logger.debug(f"游戏 {version} 操作结果: {result}")
if result["success"]:
success_count += 1
if debug_mode:
print(f"DEBUG: 游戏 {version} 操作成功,操作类型: {result['action']}")
self.logger.debug(f"游戏 {version} 操作成功,操作类型: {result['action']}")
else:
fail_count += 1
if debug_mode:
print(f"DEBUG: 游戏 {version} 操作失败,原因: {result['message']}")
self.logger.debug(f"游戏 {version} 操作失败,原因: {result['message']}")
results.append({
"version": version,
@@ -689,9 +692,9 @@ class PatchManager:
except Exception as e:
if debug_mode:
print(f"DEBUG: 切换 {version} 补丁状态时出错: {str(e)}")
self.logger.debug(f"切换 {version} 补丁状态时出错: {str(e)}")
import traceback
print(f"DEBUG: 错误详情:\n{traceback.format_exc()}")
self.logger.debug(f"错误详情:\n{traceback.format_exc()}")
fail_count += 1
results.append({
@@ -702,7 +705,7 @@ class PatchManager:
})
if debug_mode:
print(f"DEBUG: 批量切换补丁状态完成 - 成功: {success_count}, 失败: {fail_count}")
self.logger.debug(f"批量切换补丁状态完成 - 成功: {success_count}, 失败: {fail_count}")
return success_count, fail_count, results

View File

@@ -647,16 +647,113 @@ class UIManager:
msg_box.exec()
def open_log_file(self):
"""打开log.txt文件"""
"""打开当前日志文件"""
try:
# 使用操作系统默认程序打开日志文件
if os.name == 'nt': # Windows
os.startfile(LOG_FILE)
else: # macOS 和 Linux
import subprocess
subprocess.call(['xdg-open', LOG_FILE])
# 检查日志文件是否存在
if os.path.exists(LOG_FILE):
# 获取日志文件大小
file_size = os.path.getsize(LOG_FILE)
if file_size == 0:
msg_box = self._create_message_box("提示", f"\n当前日志文件 {os.path.basename(LOG_FILE)} 存在但为空。\n\n日志文件位置:{os.path.abspath(LOG_FILE)}")
msg_box.exec()
return
# 根据文件大小决定是使用文本查看器还是直接打开
if file_size > 1024 * 1024: # 大于1MB
# 文件较大,显示警告
msg_box = self._create_message_box(
"警告",
f"\n日志文件较大 ({file_size / 1024 / 1024:.2f} MB),是否仍要打开?\n\n日志文件位置:{os.path.abspath(LOG_FILE)}",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
)
if msg_box.exec() != QMessageBox.StandardButton.Yes:
return
# 使用操作系统默认程序打开日志文件
if os.name == 'nt': # Windows
os.startfile(LOG_FILE)
else: # macOS 和 Linux
import subprocess
subprocess.call(['xdg-open', LOG_FILE])
else:
# 文件不存在,显示信息
# 搜索log文件夹下所有可能的日志文件
root_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
log_dir = os.path.join(root_dir, "log")
# 如果log文件夹不存在尝试创建它
if not os.path.exists(log_dir):
try:
os.makedirs(log_dir, exist_ok=True)
msg_box = self._create_message_box(
"信息",
f"\n日志文件夹不存在,已创建新的日志文件夹:\n{log_dir}\n\n请在启用调试模式后重试。"
)
msg_box.exec()
return
except Exception as e:
msg_box = self._create_message_box(
"错误",
f"\n创建日志文件夹失败:\n\n{str(e)}"
)
msg_box.exec()
return
# 搜索log文件夹中的日志文件
try:
log_files = [f for f in os.listdir(log_dir) if f.startswith("log-") and f.endswith(".txt")]
except Exception as e:
msg_box = self._create_message_box(
"错误",
f"\n无法读取日志文件夹:\n\n{str(e)}"
)
msg_box.exec()
return
if log_files:
# 按照修改时间排序,获取最新的日志文件
log_files.sort(key=lambda x: os.path.getmtime(os.path.join(log_dir, x)), reverse=True)
latest_log = os.path.join(log_dir, log_files[0])
# 获取最新日志文件的创建时间信息
try:
log_datetime = "-".join(os.path.basename(latest_log)[4:-4].split("-")[:2])
log_date = log_datetime.split("-")[0]
log_time = log_datetime.split("-")[1] if "-" in log_datetime else "未知时间"
date_info = f"日期: {log_date[:4]}-{log_date[4:6]}-{log_date[6:]} "
time_info = f"时间: {log_time[:2]}:{log_time[2:4]}:{log_time[4:]}"
except:
date_info = "日期未知 "
time_info = "时间未知"
msg_box = self._create_message_box(
"信息",
f"\n当前日志文件 {os.path.basename(LOG_FILE)} 不存在。\n\n"
f"发现最新的日志文件: {os.path.basename(latest_log)}\n"
f"({date_info}{time_info})\n\n"
f"是否打开此文件?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
)
if msg_box.exec() == QMessageBox.StandardButton.Yes:
if os.name == 'nt': # Windows
os.startfile(latest_log)
else: # macOS 和 Linux
import subprocess
subprocess.call(['xdg-open', latest_log])
return
# 如果没有找到任何日志文件或用户选择不打开最新的日志文件
msg_box = self._create_message_box(
"信息",
f"\n没有找到有效的日志文件。\n\n"
f"预期的日志文件夹:{log_dir}\n\n"
f"请确认调试模式已启用,并执行一些操作后再查看日志。"
)
msg_box.exec()
except Exception as e:
msg_box = self._create_message_box("错误", f"\n打开log.txt文件失败\n\n{str(e)}\n")
msg_box = self._create_message_box("错误", f"\n处理日志文件时出错\n\n{str(e)}\n\n文件位置:{os.path.abspath(LOG_FILE)}")
msg_box.exec()
def restore_hosts_backup(self):