优雅的crash report

This commit is contained in:
shenjack 2022-08-21 14:59:35 +08:00
parent eff0775054
commit 7ef356c7a6
2 changed files with 70 additions and 26 deletions

View File

@ -11,7 +11,7 @@ github: @shenjackyuanjie
gitee: @shenjackyuanjie
"""
from typing import Any, Dict, Callable, Union
from typing import Any, Dict, Callable, Union, Tuple, List, Type
from libs.MCDR.version import Version
@ -25,14 +25,35 @@ class Options:
"""
_options: Dict[str, Union[Callable, object]] = {}
def option(self) -> dict:
def option(self) -> Dict[str, Any]:
values = {}
for option, a_fun in self._options.items():
if isinstance(a_fun, Callable):
values[option] = a_fun() # 例子: {'language': self.language}
else:
values[option] = a_fun
return {**values, **self.__dict__}
for ann in self.__annotations__: # 获取类型注释
values[ann] = getattr(self, ann, None) if getattr(self, ann, None) else self.__annotations__[ann]
for option, a_fun in self._options.items(): # 获取额外内容
values[option] = a_fun
for option, a_fun in values.items(): # 检查是否为 property
if a_fun is bool and getattr(self, option, None) is not None:
values[option] = False
if isinstance(a_fun, property):
values[option] = getattr(self, option)
return values
def option_with_len(self) -> list[list[Tuple[str, Any, Any]] | int | Any]:
options = self.option()
max_len_key = 1
max_len_value = 1
max_len_value_t = 1
option_list = []
for key, value in options.items():
value_t = type(value) if not isinstance(type(value), type(value)) else value
# value_t = type(value) if type(value) is not type(type(value)) else value
max_len_key = max(max_len_key, len(key))
max_len_value = max(max_len_value, len(str(value)))
max_len_value_t = max(max_len_value_t, len(str(value_t)))
option_list.append((key, value, value_t))
return [option_list, max_len_key, max_len_value, max_len_value_t]
@classmethod
def add_option(cls, name, value: Union[Callable, object]) -> Dict:
@ -45,22 +66,23 @@ class _DR_option(Options):
DR 的整体配置存储类
"""
# runtime options
InputBox_use_TextEntry = False
use_local_logging = False
record_threads = True
InputBox_use_TextEntry: bool = False
use_local_logging: bool = False
record_threads: bool = True
# tests
playing = False
debugging = False
crash_report_test = True
playing: bool = False
debugging: bool = False
crash_report_test: bool = True
class _DR_runtime(Options):
"""
DR 的运行时配置
"""
# game statue
DR_version: Version = game_version
# run status
start_time_ns: int = None
client_setup_time_ns: int = None
@ -69,6 +91,9 @@ class _DR_runtime(Options):
# game options
_language = 'zh-CN'
def __init__(self):
self._options = {'language': self.language}
@property
def language(self):
return self._language
@ -83,14 +108,12 @@ class _DR_runtime(Options):
translate.tr._update_lang()
_DR_runtime.add_option('language', _DR_runtime.language)
# _DR_runtime.add_option('language', _DR_runtime.language)
DR_option = _DR_option()
DR_runtime = _DR_runtime()
print(_DR_runtime.__dict__)
if DR_option.playing:
from .utils import new_thread

View File

@ -18,7 +18,7 @@ import platform
import traceback
import threading
import multiprocessing
from typing import Optional
from typing import Optional, TextIO
# import psutil
# for more system info
@ -71,6 +71,11 @@ def to_code(string: str):
return f'`{string}`'
def write_markdown_tablet(crash_file: TextIO, tablet: list) -> None:
a_len, b_len, c_len = tablet[0]
...
def create_crash_report(info: str = None) -> None:
crash_info = crash_info_handler(info)
if 'crash_report' not in os.listdir('./'):
@ -85,15 +90,31 @@ def create_crash_report(info: str = None) -> None:
# 运行状态信息
from Difficult_Rocket import DR_option, DR_runtime
crash_file.write(Run_message)
crash_file.write(markdown_line_handler(f'DR Version: {Difficult_Rocket.game_version}', level=1))
crash_file.write(markdown_line_handler(f'DR language: {DR_option.language}', level=1))
crash_file.write(markdown_line_handler(f'DR language: {DR_runtime.language}', level=1))
crash_file.write(markdown_line_handler(f'Running Dir: {os.path.abspath(os.curdir)}', level=1))
option_with_len = DR_runtime.option_with_len()
option_with_len[1] = max(option_with_len[1], 6)
option_with_len[2] = max(option_with_len[2], 5)
option_with_len[3] = max(option_with_len[3], 10)
crash_file.write(f'\n| Option{" " * (option_with_len[1] - 4)} | Value{" " * (option_with_len[2] - 3)} | Value Type{" " * (option_with_len[3] - 8)} |\n')
crash_file.write(f'|:{"-" * (option_with_len[1] + 3)}|:{"-" * (option_with_len[2] + 3)}|:{"-" * (option_with_len[3] + 3)}|\n')
for a, b, c in option_with_len[0]:
b, c = str(b), str(c)
crash_file.write(f'| `{a}`{" " * (option_with_len[1] - len(a))} | `{b}`{" " * (option_with_len[2] - len(b))} | `{c}`{" " * (option_with_len[3] - len(c))} |\n')
# # DR 的游戏设置
crash_file.write(DR_configs)
for key, value in Difficult_Rocket.DR_option.option().items():
crash_file.write(markdown_line_handler(f'Option: {to_code(key)} Type: {to_code(type(key))}', level=1))
crash_file.write(markdown_line_handler(f'Value: {to_code(value)}', level=2))
print(DR_option.option(), DR_runtime.option(), DR_option.__dict__)
option_with_len = DR_option.option_with_len()
option_with_len[1] = max(option_with_len[1], 6)
option_with_len[2] = max(option_with_len[2], 5)
option_with_len[3] = max(option_with_len[3], 10)
crash_file.write(f'| Option{" " * (option_with_len[1] - 4)} | Value{" " * (option_with_len[2] - 3)} | Value Type{" " * (option_with_len[3] - 8)} |\n')
crash_file.write(f'|:{"-" * (option_with_len[1] + 3)}|:{"-" * (option_with_len[2] + 3)}|:{"-" * (option_with_len[3] + 3)}|\n')
for a, b, c in option_with_len[0]:
b, c = str(b), str(c)
crash_file.write(f'| `{a}`{" " * (option_with_len[1] - len(a))} | `{b}`{" " * (option_with_len[2] - len(b))} | `{c}`{" " * (option_with_len[3] - len(c))} |\n')
# 多进程信息
crash_file.write(Process_message)
for process in all_process:
@ -108,7 +129,7 @@ def create_crash_report(info: str = None) -> None:
crash_file.write(markdown_line_handler(f'{thread.name}', code=True))
crash_file.write(markdown_line_handler(f'order: {all_thread.index(thread)}', level=2))
crash_file.write(markdown_line_handler(f'Ident: {thread.ident}', level=2))
crash_file.write(markdown_line_handler(f'Daemon: {thread.isDaemon()}', level=2))
crash_file.write(markdown_line_handler(f'Daemon: {thread.daemon}', level=2))
crash_file.write(markdown_line_handler(f'Running: {thread.is_alive()}', level=2))
# Python 信息
crash_file.write(Python_message)