就,天天重构,淦!

This commit is contained in:
shenjack 2023-06-22 13:34:14 +08:00
parent 226fcbfce8
commit 996fb72b54
7 changed files with 118 additions and 122 deletions

View File

@ -4,6 +4,10 @@
# All rights reserved # All rights reserved
# ------------------------------- # -------------------------------
import time
import logging.config
from pathlib import Path
from Difficult_Rocket.api.types import Options, Version from Difficult_Rocket.api.types import Options, Version
game_version = Version("0.8.3.0") # 游戏版本 game_version = Version("0.8.3.0") # 游戏版本
@ -70,6 +74,22 @@ class _DR_status(Options):
DR_status = _DR_status() DR_status = _DR_status()
def load_logging():
with open('./configs/logger.toml') as f:
import rtoml
logger_config = rtoml.load(f)
log_path = logger_config['handlers']['file']['filename']
log_path = f"logs/{log_path.format(time.strftime('%Y-%m-%d %H-%M-%S', time.gmtime(time.time_ns() / 1000_000_000)))}"
if not Path('logs/').is_dir():
Path('logs/').mkdir()
logger_config['handlers']['file']['filename'] = log_path
logging.config.dictConfig(logger_config)
load_logging()
if DR_status.playing: if DR_status.playing:
from Difficult_Rocket.utils.thread import new_thread from Difficult_Rocket.utils.thread import new_thread
@ -80,4 +100,4 @@ if DR_status.playing:
@new_thread('think') @new_thread('think')
def think(some_thing_to_think): def think(some_thing_to_think):
gotcha = think_it(some_thing_to_think) gotcha = think_it(some_thing_to_think)
return gotcha return gotcha

View File

@ -256,7 +256,7 @@ class ClientWindow(Window):
self.set_icon(pyglet.image.load('./textures/icon.png')) self.set_icon(pyglet.image.load('./textures/icon.png'))
self.load_fonts() self.load_fonts()
self.screen_list['DR_debug'] = DRDEBUGScreen(self) self.screen_list['DR_debug'] = DRDEBUGScreen(self)
self.game.dispatch_event('on_client_start', game=self.game, client=self) self.game.dispatch_mod_event('on_client_start', game=self.game, client=self)
def load_fonts(self) -> None: def load_fonts(self) -> None:
fonts_folder_path = self.main_config['runtime']['fonts_folder'] fonts_folder_path = self.main_config['runtime']['fonts_folder']
@ -383,7 +383,7 @@ class ClientWindow(Window):
self.logger.info(tr().language_available().format(os.listdir('./configs/lang'))) self.logger.info(tr().language_available().format(os.listdir('./configs/lang')))
self.save_info() self.save_info()
elif command.find('mods'): elif command.find('mods'):
for mod in self.game.mod_module: for mod in self.game.mod_manager.loaded_mod_modules.values():
self.logger.info(f"mod: {mod.name} id: {mod.mod_id} version: {mod.version}") self.logger.info(f"mod: {mod.name} id: {mod.mod_id} version: {mod.version}")
@_call_screen_after @_call_screen_after
@ -483,7 +483,7 @@ class ClientWindow(Window):
@_call_screen_before @_call_screen_before
def on_close(self, source: str = 'window') -> None: def on_close(self, source: str = 'window') -> None:
self.game.dispatch_event('on_close', game=self.game, client=self, source=source) self.game.dispatch_mod_event('on_close', game=self.game, client=self, source=source)
self.logger.info(tr().window.game.stop_get().format(tr().game[source]())) self.logger.info(tr().window.game.stop_get().format(tr().game[source]()))
self.logger.info(tr().window.game.stop()) self.logger.info(tr().window.game.stop())
# self.fps_log.check_list = False # self.fps_log.check_list = False

View File

@ -11,27 +11,21 @@ github: @shenjackyuanjie
gitee: @shenjackyuanjie gitee: @shenjackyuanjie
""" """
import sys
import time import time
import logging import logging
import traceback import traceback
import importlib
import importlib.util
import logging.config import logging.config
import multiprocessing import multiprocessing
from io import StringIO from io import StringIO
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, List, Optional, Dict, TypeVar from typing import List, Optional, Dict
if TYPE_CHECKING:
from Difficult_Rocket.api.mod import ModInfo
else:
ModInfo = TypeVar('ModInfo')
from Difficult_Rocket.utils import tools from Difficult_Rocket.utils import tools
from Difficult_Rocket.api.types import Options from Difficult_Rocket.api.types import Options
from Difficult_Rocket.utils.translate import tr from Difficult_Rocket.utils.translate import tr
from Difficult_Rocket.runtime import DR_runtime from Difficult_Rocket.runtime import DR_runtime
from Difficult_Rocket.mod.loader import ModManager
from Difficult_Rocket.utils.thread import new_thread from Difficult_Rocket.utils.thread import new_thread
from Difficult_Rocket.crash import write_info_to_cache from Difficult_Rocket.crash import write_info_to_cache
from Difficult_Rocket import client, server, DR_status from Difficult_Rocket import client, server, DR_status
@ -78,75 +72,21 @@ class Game(Options):
console_class: Console = Console console_class: Console = Console
main_config: Dict main_config: Dict
logging_config: Dict
logger: logging.Logger logger: logging.Logger
mod_module: List["ModInfo"] = [] mod_manager: ModManager
def init_logger(self) -> None: def dispatch_mod_event(self, event_name: str, *args, **kwargs) -> None:
log_path = self.logging_config['handlers']['file']['filename'] self.mod_manager.dispatch_event(event_name, *args, **kwargs)
log_path = f"logs/{log_path.format(time.strftime('%Y-%m-%d %H-%M-%S' , time.gmtime(DR_runtime.start_time_ns / 1000_000_000)))}"
mkdir = False
if not Path('logs/').is_dir():
Path('logs/').mkdir()
mkdir = True
self.logging_config['handlers']['file']['filename'] = log_path
logging.config.dictConfig(self.logging_config)
self.logger = logging.getLogger('main')
if mkdir:
self.logger.info(tr().main.logger.mkdir())
def init_mods(self) -> None: def init_mods(self) -> None:
"""验证/加载 mod""" """验证/加载 mod"""
self.mod_module = [] from Difficult_Rocket.mod import loader as mod_loader
mods = [] mod_loader.logger = logging.getLogger('mod_manager')
mod_path = Path(DR_runtime.mod_path) self.mod_manager = ModManager()
if not mod_path.exists(): mod_class = self.mod_manager.load_mods()
self.logger.info(tr().main.mod.find.faild.no_mod_folder()) self.mod_manager.init_mods(mod_class)
return self.dispatch_mod_event('on_load', game=self)
# 寻找有效 mod
paths = mod_path.iterdir()
sys.path.append(DR_runtime.mod_path)
for mod_path in paths:
try:
if mod_path.name == '__pycache__':
continue
self.logger.info(tr().main.mod.find.start().format(mod_path))
if mod_path.is_dir():
if importlib.util.find_spec(mod_path.name) is not None:
mods.append(mod_path.name)
else:
self.logger.warning(tr().main.mod.load.faild.info().format(mod_path.name, tr().main.mod.find.faild.no_spec()))
elif mod_path.suffix in ('.pyz', '.zip', '.pyd', '.py'):
if importlib.util.find_spec(mod_path.name) is not None:
mods.append(mod_path.name)
except ImportError as e:
self.logger.warning(tr().main.mod.find.faild().format(mod_path, e))
self.logger.info(tr().main.mod.find.done())
# 加载有效 mod
module = []
for mod in mods:
try:
self.logger.info(tr().main.mod.load.start().format(mod))
mod_module = importlib.import_module(mod)
if not hasattr(mod_module, "mod_class"):
self.logger.warning(tr().main.mod.load.faild.info().format(mod, tr().main.mod.load.faild.no_mod_class()))
del mod_module # 释放内存
continue
mod_class: type(ModInfo) = mod_module.mod_class
mod_class = mod_class()
module.append(mod_class)
self.logger.info(tr().main.mod.load.info().format(mod_class.mod_id, mod_class.version))
except ImportError as e:
self.logger.warning(tr().main.mod.load.faild.info().format(mod, e))
self.logger.info(tr().main.mod.load.done())
self.mod_module = module
mod_list = []
for mod in module:
mod_list.append((mod.mod_id, mod.version))
# 调用 on_load
self.dispatch_event('on_load', game=self)
DR_runtime.DR_Mod_List = mod_list
def init_console(self) -> None: def init_console(self) -> None:
self.console = self.console_class() self.console = self.console_class()
@ -166,32 +106,15 @@ class Game(Options):
else: else:
self.client.start() self.client.start()
def dispatch_event(self, event_name: str, *args, **kwargs) -> None:
"""向 mod 分发事件"""
for mod in self.mod_module:
if hasattr(mod, event_name):
try:
getattr(mod, event_name)(*args, **kwargs)
except Exception:
error = traceback.format_exc()
self.logger.error(tr().main.mod.event.error().format(event_name, error, mod.mod_id))
def log_env(self) -> None: def log_env(self) -> None:
cache_steam = StringIO() self.logger.info(f'\n{self.as_markdown()}')
write_info_to_cache(cache_steam)
text = cache_steam.getvalue()
self.logger.info(text)
self.flush_option()
config_cache = self.logging_config.copy()
self.logging_config = {"logging_config": "too long to show"}
self.logger.info(f"\n{self.as_markdown()}")
self.logging_config = config_cache
def setup(self) -> None: def setup(self) -> None:
self.client = client.Client(game=self, net_mode='local') self.client = client.Client(game=self, net_mode='local')
self.server = server.Server(net_mode='local') self.server = server.Server(net_mode='local')
def init(self, **kwargs) -> bool: def init(self, **kwargs) -> bool:
self.logger = logging.getLogger('main')
self.load_file() self.load_file()
self.setup() self.setup()
self.log_env() self.log_env()
@ -199,9 +122,6 @@ class Game(Options):
def load_file(self) -> bool: def load_file(self) -> bool:
"""加载文件""" """加载文件"""
self.logging_config = tools.load_file('configs/logger.toml')
self.init_logger()
self.init_mods() self.init_mods()
self.init_console() self.init_console()
return True return True

View File

@ -4,14 +4,21 @@
# All rights reserved # All rights reserved
# ------------------------------- # -------------------------------
import sys
import time
import logging import logging
import traceback
import importlib
from pathlib import Path from pathlib import Path
from typing import List, Dict, Optional from typing import List, Dict, Optional
from Difficult_Rocket.api.screen import BaseScreen
from Difficult_Rocket.api.types import Options, Version
from Difficult_Rocket.mod.api import ModInfo from Difficult_Rocket.mod.api import ModInfo
# from Difficult_Rocket import DR_status, DR_runtime from Difficult_Rocket.utils.translate import tr
from Difficult_Rocket.api.types import Options, Version
logger = logging.getLogger('mod_manager')
ONE_FILE_SUFFIX = ('.py', '.pyc', '.pyd')
PACKAGE_SUFFIX = ('.pyz', '.zip', '.dr_mod')
class ModManager(Options): class ModManager(Options):
@ -20,21 +27,68 @@ class ModManager(Options):
mods_path: List[Path] = [Path('./mods')] mods_path: List[Path] = [Path('./mods')]
loaded_mod_modules: Dict[str, ModInfo] = {} loaded_mod_modules: Dict[str, ModInfo] = {}
def find_mods(self) -> List[Path]: def dispatch_event(self, event_name: str, *args, **kwargs):
""" """
查找mods文件夹下的所有mod 分发事件
:param event_name:
:param args:
:param kwargs:
:return: :return:
""" """
for mod in self.loaded_mod_modules.values():
if hasattr(mod, event_name):
try:
getattr(mod, event_name)(*args, **kwargs)
except Exception as e:
logger.error(tr().mod.event.error().format(mod, event_name, e, traceback.format_exc()))
def load_mods(self, extra_path: Optional[List[Path]] = None) -> List[type(ModInfo)]:
"""
加载所有 mod (可提供额外的 mod 路径)
:param extra_path: 额外的 mod 路径
:return:
"""
find_path = self.mods_path + (extra_path if extra_path is not None else [])
sys.path += [str(path_) for path_ in find_path]
mods = [] mods = []
for path in self.mods_path: start_time = time.time()
logger.info(tr().mod.load.start().format(find_path))
for path in find_path:
if not path.exists(): if not path.exists():
path.mkdir(parents=True) path.mkdir(parents=True)
continue continue
for mod in path.iterdir(): for mod in path.iterdir():
... try:
if mod.name == '__pycache__':
def init(self) -> None: # 忽略 __pycache__ 文件夹 (Python 编译文件)
self.logger = logging.getLogger('client') continue
self.logger.name = 'mod_manager' logger.info(tr().mod.load.loading().format(mod))
self.logger.info('Mod Manager init') if mod.is_dir() or mod.suffix in PACKAGE_SUFFIX or mod.suffix in ONE_FILE_SUFFIX:
# 文件夹 mod
loading_mod = importlib.import_module(mod.name)
if not hasattr(loading_mod, 'mod_class'):
logger.warning(tr().mod.load.faild.no_mod_class().format(mod))
continue
mod_class: type(ModInfo) = loading_mod.mod_class # 获取 mod 类
mods.append(mod_class)
except ImportError:
logger.warning(tr().mod.load.faild.error().format(mod))
logger.info(tr().mod.load.use_time().format(time.time() - start_time))
return mods
def init_mods(self, mods: List[type(ModInfo)]):
"""
加载 mod
:param mods:
:return:
"""
start_time = time.time()
for mod_class in mods:
try:
init_mod = mod_class()
self.loaded_mod_modules[init_mod.name] = init_mod
logger.info(tr().mod.init.success().format(init_mod, init_mod.version))
except Exception as e:
logger.error(tr().mod.init.faild().format(mod_class, e, traceback.format_exc()))
continue
logger.info(tr().mod.init.use_time().format(time.time() - start_time))

View File

@ -140,12 +140,12 @@ class Translates:
def __str__(self): def __str__(self):
if not any(not x[0] for x in self._get_list): if not any(not x[0] for x in self._get_list):
return self._value return str(self._value)
if self._config.crack_normal: if self._config.crack_normal:
return f'{".".join(f"{gets[1]}({gets[0]})" for gets in self._get_list)}' return f'{".".join(f"{gets[1]}({gets[0]})" for gets in self._get_list)}'
elif self._config.insert_crack: elif self._config.insert_crack:
return f'{self._value}.{".".join(gets[1] for gets in self._get_list if not gets[0])}' return f'{self._value}.{".".join(gets[1] for gets in self._get_list if not gets[0])}'
return self._value return str(self._value)
class Tr: class Tr:

View File

@ -20,16 +20,18 @@ logger.logfile_level = "日志文件记录级别:"
logger.logfile_fmt = "日志文件记录格式:" logger.logfile_fmt = "日志文件记录格式:"
logger.logfile_datefmt = "日志文件日期格式:" logger.logfile_datefmt = "日志文件日期格式:"
game_start.at = "游戏主线程开始于:" game_start.at = "游戏主线程开始于:"
mod.find.start = "正在校验 Mod: {}"
mod.find.faild.no_spec = "importlib 无法找到 spec" [mod]
mod.find.faild.no_mod_folder = "没有找到 Mod 文件夹" load.start = "开始加载路径 {} 下的 Mod"
mod.find.done = "所有 Mod 校验完成" load.use_time = "Mod 加载消耗时间: {} 秒"
mod.load.start = "正在加载 Mod: {}" load.done = "所有 Mod 加载完成"
mod.load.info = "mod id: {} 版本号: {}" load.loading = "正在加载 Mod: {}"
mod.load.faild.info = "Mod 加载失败: {} 错误信息: {}" load.faild.error = "Mod 加载失败: {} 错误信息: {}"
mod.load.faild.no_mod_class = "没有找到 Mod 类" load.faild.no_mod_class = "Mod 加载失败: {} 没有找到 Mod 类"
mod.load.done = "所有 Mod 加载完成" init.success = "mod id: {} 版本号: {}"
mod.event.error = "Mod 事件 {} 发生错误 {} Mod: {}" init.faild = "Mod 初始化失败: {} 错误信息: {}\n堆栈信息: {}"
init.use_time = "Mod 初始化消耗时间: {} 秒"
event.error = "Mod 事件 {} 发生错误 {} Mod: {}\n堆栈信息: {}"
[client] [client]
setup.start = "客户端加载开始" setup.start = "客户端加载开始"

View File

@ -22,7 +22,7 @@ datefmt = "%Y-%m-%d %H:%M:%S"
[handlers.console] [handlers.console]
class = "logging.StreamHandler" class = "logging.StreamHandler"
formatter = "file" formatter = "file"
level = "DEBUG" level = "INFO"
[handlers.file] [handlers.file]
class = "logging.FileHandler" class = "logging.FileHandler"