diff --git a/.github/ISSUE_TEMPLATE/01_bug.yaml b/.github/ISSUE_TEMPLATE/01_bug.yaml index b8797d36..72fde5c0 100644 --- a/.github/ISSUE_TEMPLATE/01_bug.yaml +++ b/.github/ISSUE_TEMPLATE/01_bug.yaml @@ -32,10 +32,10 @@ body: - type: textarea attributes: - label: Log files 日志文件 + label: Log file 日志文件 description: > - View log files in the "logs" directory. Please upload the log file as an attachment instead of copying its contents. + Run LunaTranslator_debug.exe to reproduce the error, and then upload the generated log_*.txt file. - 在"logs"目录中获取日志文件。请将日志文件以附件的形式上传,而不是将其中的内容复制。 + 运行LunaTranslator_debug.exe复现错误,然后上传产生的log_*.txt文件。 validations: required: true \ No newline at end of file diff --git a/LunaTranslator/LunaTranslator/LunaTranslator_main.py b/LunaTranslator/LunaTranslator/LunaTranslator_main.py index c1351a5d..1c666963 100644 --- a/LunaTranslator/LunaTranslator/LunaTranslator_main.py +++ b/LunaTranslator/LunaTranslator/LunaTranslator_main.py @@ -188,50 +188,6 @@ def switchdir(): pass -class Lockedfile: - def __init__(self) -> None: - self.collect = queue.Queue() - threading.Thread(target=self.__write).start() - - def __write(self): - data = self.collect.get() - os.makedirs("logs", exist_ok=True) - file = open( - f"logs/{time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime())}.txt", - "w", - encoding="utf8", - errors="ignore", - ) - while True: - file.write(data) - file.flush() - data = self.collect.get() - - def write(self, data): - self.collect.put(data) - - -lockedfile = Lockedfile() - - -class debugoutput(io.IOBase): - def __init__(self, file: io.TextIOBase) -> None: - super().__init__() - self.originfile = file - - def write(self, data): - self.originfile.write(data) - lockedfile.write(data) - - def flush(self): - self.originfile.flush() - - -def savelogs(): - sys.stderr = debugoutput(sys.stderr) - sys.stdout = debugoutput(sys.stdout) - - def urlprotocol(): import argparse, gobject, sys from urllib.parse import urlsplit @@ -239,9 +195,9 @@ def urlprotocol(): parser = argparse.ArgumentParser() parser.add_argument("--URLProtocol", required=False) - args = parser.parse_args() - URLProtocol: str = args.URLProtocol try: + args = parser.parse_args() + URLProtocol: str = args.URLProtocol if URLProtocol: print(URLProtocol) result = urlsplit(URLProtocol) @@ -266,7 +222,6 @@ if __name__ == "__main__": checklang() checkintegrity() checkpermission() - savelogs() urlprotocol() loadmainui() app.exit(app.exec()) diff --git a/LunaTranslator/files/defaultconfig/config.json b/LunaTranslator/files/defaultconfig/config.json index 1a208b03..dd78f53f 100644 --- a/LunaTranslator/files/defaultconfig/config.json +++ b/LunaTranslator/files/defaultconfig/config.json @@ -348,7 +348,7 @@ "button_color_close": "#D32424", "button_color_normal": "#FFFFFF", "textthreaddelay": 500, - "maxBufferSize": 10000, + "maxBufferSize": 3000, "maxHistorySize": 1000000, "yuanjiao_r": 5, "qwebinspectgeo": [ diff --git a/docs/en/start.md b/docs/en/start.md index d8ec2fcf..0b4ea13f 100644 --- a/docs/en/start.md +++ b/docs/en/start.md @@ -10,15 +10,12 @@ Make sure not to download the source code by mistake! ### Launch -After unzipping, you can see the following files. Use **LunaTranslator.exe** to start. - -![img](https://image.lunatranslator.org/zh/startup.png) **LunaTranslator.exe** will start in normal mode. **LunaTranslator_admin.exe** will start with administrator privileges. Some games require administrator privileges to HOOK, so use this only when necessary; otherwise, start in normal mode. -**LunaTranslator_debug.exe** will display the command line and show the log during runtime. If you encounter a bug, please run this program and attach the log. +**LunaTranslator_debug.exe** will generate log file. When submitting bug feedback, please be sure to run the program and reproduce the bug, and then submit the generated log file. #### Note diff --git a/docs/ru/start.md b/docs/ru/start.md index 8050c81c..1b7d8500 100644 --- a/docs/ru/start.md +++ b/docs/ru/start.md @@ -10,15 +10,12 @@ ### Запуск -После распаковки вы увидите следующие файлы, запустите **LunaTranslator.exe**. - -![img](https://image.lunatranslator.org/zh/startup.png) **LunaTranslator.exe** запускается в обычном режиме **LunaTranslator_admin.exe** запускается с правами администратора, некоторые игры требуют прав администратора для HOOK, используйте его только в этом случае, в остальных случаях запускайте в обычном режиме. -**LunaTranslator_debug.exe** запускается с командной строкой и отображает логи во время работы. Если вы сталкиваетесь с ошибками, запустите этот программу и приложите логи. +**LunaTranslator_debug.exe** создаст файлы журналов. Отправляя отзыв об ошибке, обязательно используйте эту программу для запуска и воспроизведения ошибки, а затем отправьте созданный файл журнала. #### Внимание diff --git a/docs/zh/start.md b/docs/zh/start.md index 1a597869..578775a7 100644 --- a/docs/zh/start.md +++ b/docs/zh/start.md @@ -10,17 +10,12 @@ ### 启动 -解压后可以看到下列文件,使用**LunaTranslator.exe**启动即可 - - -![img](https://image.lunatranslator.org/zh/startup.png) - **LunaTranslator.exe** 会以普通模式启动 **LunaTranslator_admin.exe** 会以管理员权限启动,部分游戏需要管理员权限才能HOOK,仅这时需要使用这个,其他时候普通模式启动即可。 -**LunaTranslator_debug.exe** 会显示命令行启动,并显示运行时的log。如果遇到有bug,请运行这个程序并附上log。 +**LunaTranslator_debug.exe** 会生成log文件。提交bug反馈时,务必请使用该程序运行并复现bug,然后提交生成的log文件。 diff --git a/plugins/exec/CMakeLists.txt b/plugins/exec/CMakeLists.txt index 3d40598f..368967d8 100644 --- a/plugins/exec/CMakeLists.txt +++ b/plugins/exec/CMakeLists.txt @@ -15,11 +15,11 @@ generate_product_version( set(sources PyStand.cpp luna.rc ${versioninfo}) -#add_executable(LunaTranslator_debug ${sources}) -#target_compile_definitions(LunaTranslator_debug PRIVATE PYSTAND_CONSOLE) +add_executable(LunaTranslator_debug ${sources}) +target_compile_definitions(LunaTranslator_debug PRIVATE PYSTAND_CONSOLE) add_executable(LunaTranslator WIN32 ${sources}) add_executable(LunaTranslator_admin WIN32 ${sources}) set_target_properties(LunaTranslator_admin PROPERTIES LINK_FLAGS " /MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\" ") -#target_precompile_headers(LunaTranslator_debug REUSE_FROM pch) +target_precompile_headers(LunaTranslator_debug REUSE_FROM pch) target_precompile_headers(LunaTranslator_admin REUSE_FROM pch) target_precompile_headers(LunaTranslator REUSE_FROM pch) \ No newline at end of file diff --git a/plugins/exec/PyStand.cpp b/plugins/exec/PyStand.cpp index e0307adb..4bb01137 100644 --- a/plugins/exec/PyStand.cpp +++ b/plugins/exec/PyStand.cpp @@ -1,6 +1,11 @@  #include "PyStand.h" +#include +#include +#include +#include + //--------------------------------------------------------------------- // dtor //--------------------------------------------------------------------- @@ -250,52 +255,63 @@ int PyStand::DetectScript() // init script //--------------------------------------------------------------------- const auto init_script = - L"import sys\n" - L"import os\n" - L"PYSTAND = os.environ['PYSTAND']\n" - L"PYSTAND_HOME = os.environ['PYSTAND_HOME']\n" - L"PYSTAND_RUNTIME = os.environ['PYSTAND_RUNTIME']\n" - L"PYSTAND_SCRIPT = os.environ['PYSTAND_SCRIPT']\n" - L"sys.path_origin = [n for n in sys.path]\n" - L"sys.PYSTAND = PYSTAND\n" - L"sys.PYSTAND_HOME = PYSTAND_HOME\n" - L"sys.PYSTAND_SCRIPT = PYSTAND_SCRIPT\n" - L"def MessageBox(msg, info = 'Message'):\n" - L" import ctypes\n" - L" ctypes.windll.user32.MessageBoxW(None, str(msg), str(info), 0)\n" - L" return 0\n" - L"os.MessageBox = MessageBox\n" + LR"( +import sys +import os +PYSTAND = os.environ['PYSTAND'] +PYSTAND_HOME = os.environ['PYSTAND_HOME'] +PYSTAND_RUNTIME = os.environ['PYSTAND_RUNTIME'] +PYSTAND_SCRIPT = os.environ['PYSTAND_SCRIPT'] +sys.path_origin = [n for n in sys.path] +sys.PYSTAND = PYSTAND +sys.PYSTAND_HOME = PYSTAND_HOME +sys.PYSTAND_SCRIPT = PYSTAND_SCRIPT +def MessageBox(msg, info = 'Message'): + import ctypes + ctypes.windll.user32.MessageBoxW(None, str(msg), str(info), 0) + return 0 +os.MessageBox = MessageBox +sys.stdout=sys.stderr +)" #ifndef PYSTAND_CONSOLE - L"try:\n" - L" fd = os.open('CONOUT$', os.O_RDWR | os.O_BINARY)\n" - L" fp = os.fdopen(fd, 'w')\n" - L" sys.stdout = fp\n" - L" sys.stderr = fp\n" - L" attached = True\n" - L"except Exception as e:\n" - L" fp = open(os.devnull, 'w', errors='ignore')\n" - L" sys.stdout = fp\n" - L" sys.stderr = fp\n" - L" attached = False\n" + LR"( +try: + fd = os.open('CONOUT$', os.O_RDWR | os.O_BINARY) + fp = os.fdopen(fd, 'w') + sys.stdout = fp + sys.stderr = fp + attached = True +except Exception as e: + fp = open(os.devnull, 'w', errors='ignore') + sys.stdout = fp + sys.stderr = fp + attached = False +)" #endif - L"sys.argv = [PYSTAND_SCRIPT] + sys.argv[1:]\n" - L"text = open(PYSTAND_SCRIPT, 'rb').read()\n" - L"environ = {'__file__': PYSTAND_SCRIPT, '__name__': '__main__'}\n" - L"environ['__package__'] = None\n" + LR"( +sys.argv = [PYSTAND_SCRIPT] + sys.argv[1:] +text = open(PYSTAND_SCRIPT, 'rb').read() +environ = {'__file__': PYSTAND_SCRIPT, '__name__': '__main__'} +environ['__package__'] = None +)" #ifndef PYSTAND_CONSOLE - L"try:\n" - L" code = compile(text, PYSTAND_SCRIPT, 'exec')\n" - L" exec(code, environ)\n" - L"except Exception:\n" - L" if attached:\n" - L" raise\n" - L" import traceback, io\n" - L" sio = io.StringIO()\n" - L" traceback.print_exc(file = sio)\n" - L" os.MessageBox(sio.getvalue(), 'Error')\n" + LR"( +try: + code = compile(text, PYSTAND_SCRIPT, 'exec') + exec(code, environ) +except Exception: + if attached: + raise + import traceback, io + sio = io.StringIO() + traceback.print_exc(file = sio) + os.MessageBox(sio.getvalue(), 'Error') +)" #else - L"code = compile(text, PYSTAND_SCRIPT, 'exec')\n" - L"exec(code, environ)\n" + LR"( +code = compile(text, PYSTAND_SCRIPT, 'exec') +exec(code, environ) +)" #endif ""; @@ -310,12 +326,7 @@ const auto init_script = //! mode: win //! int: objs -#ifdef PYSTAND_CONSOLE int main() -#else -int WINAPI -WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int show) -#endif { { // 当更新进行时,禁止启动 @@ -330,6 +341,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int show) return 3; } #ifndef PYSTAND_CONSOLE + // winmain下的stderr没有任何卵用,对于崩溃时的stderr根本显示不出来,所以还是用控制台来保存log吧。 if (AttachConsole(ATTACH_PARENT_PROCESS)) { freopen("CONOUT$", "w", stdout); @@ -347,8 +359,27 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int show) SetEnvironmentVariableA("PYSTAND_STDIN", fn.c_str()); } } +#else + { + auto getCurrentTimestamp = [] + { + auto now = std::chrono::system_clock::now(); + std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); + std::tm now_tm = *std::localtime(&now_time_t); + std::ostringstream oss; + oss << std::put_time(&now_tm, "log_%Y-%m-%d-%H-%M-%S.txt"); + return oss.str(); + }; + auto curr = getCurrentTimestamp(); + freopen(curr.c_str(), "a", stderr); + } #endif int hr = ps.RunString(init_script); - // printf("finalize\n"); return hr; } + +int WINAPI +WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int show) +{ + return main(); +} \ No newline at end of file