Files
AUTO-MAS-test/main.py
2025-07-19 21:38:38 +08:00

316 lines
9.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AUTO_MAA:A MAA Multi Account Management and Automation Tool
# Copyright © 2024-2025 DLmaster361
# This file is part of AUTO_MAA.
# AUTO_MAA is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
# AUTO_MAA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with AUTO_MAA. If not, see <https://www.gnu.org/licenses/>.
# Contact: DLmaster_361@163.com
"""
AUTO_MAA
AUTO_MAA主程序
v4.4
作者DLmaster_361
"""
import os
import sys
# Nuitka环境检测和修复
def setup_nuitka_compatibility():
"""设置Nuitka打包环境的兼容性"""
# 检测打包环境
is_nuitka = (
hasattr(sys, "frozen")
or "nuitka" in sys.modules
or "Temp\\AUTO_MAA" in str(sys.executable)
or os.path.basename(sys.executable) == "AUTO_MAA.exe"
)
if is_nuitka:
# 修复PySide6 QTimer问题
try:
from PySide6.QtCore import QTimer
original_singleShot = QTimer.singleShot
@staticmethod
def safe_singleShot(*args, **kwargs):
if len(args) >= 2:
msec = args[0]
callback = args[-1]
# 确保使用正确的调用签名
return original_singleShot(msec, callback)
return original_singleShot(*args, **kwargs)
QTimer.singleShot = safe_singleShot
except Exception as e:
pass
# 立即应用兼容性修复
setup_nuitka_compatibility()
# 屏蔽广告
import builtins
original_print = builtins.print
def no_print(*args, **kwargs):
if (
args
and isinstance(args[0], str)
and "QFluentWidgets Pro is now released." in args[0]
):
return
return original_print(*args, **kwargs)
builtins.print = no_print
import ctypes
import traceback
from PySide6.QtWidgets import QApplication
from qfluentwidgets import FluentTranslator
def is_admin() -> bool:
"""检查当前程序是否以管理员身份运行"""
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def show_system_error(title: str, message: str, detailed_error: str = None):
"""使用系统级消息框显示错误"""
try:
# Windows系统消息框
if sys.platform == "win32":
# 组合完整的错误信息
full_message = message
if detailed_error:
# 限制详细错误信息长度,避免消息框过大
if len(detailed_error) > 2000:
detailed_error = (
detailed_error[:2000] + "\n\n... (错误信息过长已截断)"
)
full_message += f"\n\n详细错误信息:\n{detailed_error}"
# 使用ctypes调用Windows API
ctypes.windll.user32.MessageBoxW(
0, # 父窗口句柄
full_message, # 消息内容
title, # 标题
0x10 | 0x0, # MB_ICONERROR | MB_OK
)
# Linux系统 - 尝试使用zenity或kdialog
elif sys.platform.startswith("linux"):
full_message = message
if detailed_error:
full_message += f"\n\n详细错误:\n{detailed_error[:1000]}"
try:
# 尝试zenity (GNOME)
os.system(
f'zenity --error --title="{title}" --text="{full_message}" 2>/dev/null'
)
except:
try:
# 尝试kdialog (KDE)
os.system(
f'kdialog --error "{full_message}" --title "{title}" 2>/dev/null'
)
except:
# 降级到控制台输出
print(f"错误: {title}")
print(f"消息: {message}")
if detailed_error:
print(f"详细信息:\n{detailed_error}")
# macOS系统
elif sys.platform == "darwin":
full_message = message
if detailed_error:
full_message += f"\n\n详细错误:\n{detailed_error[:1000]}"
try:
os.system(
f'osascript -e \'display alert "{title}" message "{full_message}" as critical\''
)
except:
print(f"错误: {title}")
print(f"消息: {message}")
if detailed_error:
print(f"详细信息:\n{detailed_error}")
else:
# 其他系统降级到控制台输出
print(f"错误: {title}")
print(f"消息: {message}")
if detailed_error:
print(f"详细信息:\n{detailed_error}")
except Exception as e:
# 如果连系统消息框都失败了,输出到控制台
print(f"无法显示错误对话框: {e}")
print(f"原始错误: {title} - {message}")
if detailed_error:
print(f"详细错误信息:\n{detailed_error}")
def save_error_log(error_info: str):
"""保存错误日志到文件"""
try:
import datetime
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
log_dir = os.path.join(os.path.dirname(__file__), "debug")
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, f"crash_{timestamp}.log")
with open(log_file, "w", encoding="utf-8") as f:
f.write(f"AUTO_MAA 崩溃日志\n")
f.write(f"时间: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"Python版本: {sys.version}\n")
f.write(f"平台: {sys.platform}\n")
f.write(f"工作目录: {os.getcwd()}\n")
f.write("=" * 50 + "\n")
f.write(error_info)
return log_file
except:
return None
def main():
"""主程序入口"""
application = None
try:
# 创建QApplication
application = QApplication(sys.argv)
# 安装翻译器
translator = FluentTranslator()
application.installTranslator(translator)
try:
# 导入主窗口模块
from app.ui.main_window import AUTO_MAA
# 创建主窗口
window = AUTO_MAA()
window.show_ui("显示主窗口", if_start=True)
window.start_up_task()
except ImportError as e:
error_msg = f"模块导入失败: {str(e)}"
detailed_error = traceback.format_exc()
log_file = save_error_log(f"{error_msg}\n\n{detailed_error}")
if log_file:
error_msg += f"\n\n错误日志已保存到: {log_file}"
show_system_error("模块导入错误", error_msg, detailed_error)
return
except Exception as e:
error_msg = f"主窗口创建失败: {str(e)}"
detailed_error = traceback.format_exc()
log_file = save_error_log(f"{error_msg}\n\n{detailed_error}")
if log_file:
error_msg += f"\n\n错误日志已保存到: {log_file}"
show_system_error("窗口创建错误", error_msg, detailed_error)
return
# 启动事件循环
sys.exit(application.exec())
except Exception as e:
error_msg = f"应用程序启动失败: {str(e)}"
detailed_error = traceback.format_exc()
log_file = save_error_log(f"{error_msg}\n\n{detailed_error}")
if log_file:
error_msg += f"\n\n错误日志已保存到: {log_file}"
# 尝试显示错误对话框
show_system_error("应用程序启动错误", error_msg, detailed_error)
# 如果有应用程序实例,确保正确退出
if application:
try:
application.quit()
except:
pass
sys.exit(1)
def handle_exception(exc_type, exc_value, exc_traceback):
"""全局异常处理器"""
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
error_msg = f"未处理的异常: {exc_type.__name__}: {str(exc_value)}"
detailed_error = "".join(
traceback.format_exception(exc_type, exc_value, exc_traceback)
)
log_file = save_error_log(f"{error_msg}\n\n{detailed_error}")
if log_file:
error_msg += f"\n\n错误日志已保存到: {log_file}"
show_system_error("程序异常", error_msg, detailed_error)
# 设置全局异常处理器
sys.excepthook = handle_exception
if __name__ == "__main__":
try:
if is_admin():
main()
else:
ctypes.windll.shell32.ShellExecuteW(
None, "runas", sys.executable, os.path.realpath(sys.argv[0]), None, 1
)
sys.exit(0)
except Exception as e:
error_msg = f"程序启动失败: {str(e)}"
detailed_error = traceback.format_exc()
log_file = save_error_log(f"{error_msg}\n\n{detailed_error}")
if log_file:
error_msg += f"\n\n错误日志已保存到: {log_file}"
show_system_error("启动错误", error_msg, detailed_error)
sys.exit(1)