some mod loading

This commit is contained in:
shenjack 2023-04-24 23:08:43 +08:00
parent ed3e0c2d5a
commit 9183e56a2d
5 changed files with 82 additions and 31 deletions

View File

@ -151,34 +151,30 @@ class _DR_runtime(Options):
return True return True
return False return False
def load_mods(self) -> None:
mod_list = self.find_mods()
def find_mods(self) -> List[str]: def find_mods(self) -> List[str]:
mods = [] mods = []
paths = Path(self.mod_path).iterdir() paths = Path(self.mod_path).iterdir()
sys.path.append(self.mod_path) sys.path.append(self.mod_path)
for mod_path in paths: # for mod_path in paths:
try: # try:
if mod_path.is_dir() and mod_path.name != '__pycache__': # 处理文件夹 mod # if mod_path.is_dir() and mod_path.name != '__pycache__': # 处理文件夹 mod
if importlib.util.find_spec(mod_path.name) is not None: # if importlib.util.find_spec(mod_path.name) is not None:
mods.append(mod_path.name) # mods.append(mod_path.name)
else: # else:
print(f'can not import mod {mod_path} because importlib can not find spec') # print(f'can not import mod {mod_path} because importlib can not find spec')
elif mod_path.suffix in ('.pyz', '.zip'): # 处理压缩包 mod # elif mod_path.suffix in ('.pyz', '.zip'): # 处理压缩包 mod
if importlib.util.find_spec(mod_path.name) is not None: # if importlib.util.find_spec(mod_path.name) is not None:
mods.append(mod_path.name) # mods.append(mod_path.name)
elif mod_path.suffix == '.pyd': # pyd 扩展 mod # elif mod_path.suffix == '.pyd': # pyd 扩展 mod
if importlib.util.find_spec(mod_path.name) is not None: # if importlib.util.find_spec(mod_path.name) is not None:
mods.append(mod_path.name) # mods.append(mod_path.name)
elif mod_path.suffix == '.py': # 处理单文件 mod # elif mod_path.suffix == '.py': # 处理单文件 mod
print(f'importing mod {mod_path=} {mod_path.stem}') # print(f'importing mod {mod_path=} {mod_path.stem}')
if importlib.util.find_spec(mod_path.stem) is not None: # if importlib.util.find_spec(mod_path.stem) is not None:
mods.append(mod_path.stem) # mods.append(mod_path.stem)
except ImportError: # except ImportError:
print(f'ImportError when loading mod {mod_path}') # print(f'ImportError when loading mod {mod_path}')
traceback.print_exc() # traceback.print_exc()
return mods return mods

View File

@ -11,6 +11,7 @@ from typing import Tuple, List, Optional
from MCDR.version import Version from MCDR.version import Version
# from DR # from DR
from Difficult_Rocket.main import Game
from Difficult_Rocket import DR_runtime, Options from Difficult_Rocket import DR_runtime, Options
@ -53,10 +54,22 @@ class ModInfo(Options):
config: Options = Options() # mod 配置存储 config: Options = Options() # mod 配置存储
old_mod: Optional["ModInfo"] = None # 旧的mod实例 old_mod: Optional["ModInfo"] = None # 旧的mod实例
def on_load(self): def on_load(self, game: Game):
""" 加载时调用 """ """ 加载时调用 """
print(f'Mod {self.mod_id} loaded') print(f'Mod {self.mod_id} loaded')
def on_unload(self): def on_server_start(self, game: Game):
""" 服务器启动时调用 """
print(f'Mod {self.mod_id} server start')
def on_server_stop(self, game: Game):
""" 服务器停止时调用 """
print(f'Mod {self.mod_id} server stop')
def on_client_start(self, game: Game):
""" 客户端启动时调用 """
print(f'Mod {self.mod_id} client start')
def on_unload(self, game: Game):
""" 卸载时调用 """ """ 卸载时调用 """
print(f'Mod {self.mod_id} unloaded') print(f'Mod {self.mod_id} unloaded')

View File

@ -195,8 +195,8 @@ class ClientWindow(Window):
def setup(self): def setup(self):
self.set_icon(pyglet.image.load('./textures/icon.png')) self.set_icon(pyglet.image.load('./textures/icon.png'))
self.logger.info(f"=== finding mods from {DR_runtime.mod_path} ===") # self.logger.info(f"=== finding mods from {DR_runtime.mod_path} ===")
self.logger.info(f'find mods: {DR_runtime.find_mods()}') # self.logger.info(f'find mods: {DR_runtime.find_mods()}')
self.load_fonts() self.load_fonts()
# TODO 读取配置文件,加载不同的屏幕,解耦 # TODO 读取配置文件,加载不同的屏幕,解耦
self.screen_list.append(DRDEBUGScreen(self)) self.screen_list.append(DRDEBUGScreen(self))

View File

@ -15,16 +15,19 @@ import os
import sys import sys
import time import time
import logging import logging
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
if __name__ == '__main__': # been start will not run this if __name__ == '__main__': # been start will not run this
sys.path.append('/bin/libs') sys.path.append('/bin/libs')
sys.path.append('/bin') sys.path.append('/bin')
from Difficult_Rocket import client, server, DR_option from Difficult_Rocket import client, server, DR_option, DR_runtime
from Difficult_Rocket.crash import write_info_to_cache from Difficult_Rocket.crash import write_info_to_cache
from Difficult_Rocket.utils import tools from Difficult_Rocket.utils import tools
@ -58,6 +61,9 @@ class Game:
# version check # version check
self.log_env() self.log_env()
self.python_version_check() self.python_version_check()
self.loaded_mods = []
# self.client = client.Client
# self.server = server.Server
self.setup() self.setup()
def log_env(self) -> None: def log_env(self) -> None:
@ -66,9 +72,45 @@ class Game:
text = cache_steam.getvalue() text = cache_steam.getvalue()
self.logger.info(text) self.logger.info(text)
def load_mods(self) -> None:
mods = []
paths = Path(DR_runtime.mod_path).iterdir()
for mod_path in paths:
try:
self.logger.info(tr().main.mod.find.start().format(mod_path))
if mod_path.is_dir() and mod_path.name != '__pycache__':
if importlib.util.find_spec(mod_path.name) is not None:
mods.append(mod_path.name)
else:
self.logger.warning(tr().main.mod.load.failed.info().format(mod_path.name, tr().main.mod.find.failed.no_spce()))
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.failed().format(mod_path, e))
self.logger.info(tr().main.mod.find.done())
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.failed.info().format(mod, tr().main.mod.load.failed.no_mod_class()))
del mod_module # 释放内存
continue
mod_class = 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.failed().format(mod, e))
self.logger.info(tr().main.mod.load.done())
self.loaded_mods = module
def setup(self) -> None: def setup(self) -> None:
self.client = client.Client(net_mode='local') self.client = client.Client(net_mode='local')
self.server = server.Server(net_mode='local') self.server = server.Server(net_mode='local')
# self.load_mods()
def python_version_check(self) -> None: # best 3.8+ and write at 3.8.10 def python_version_check(self) -> None: # best 3.8+ and write at 3.8.10
self.logger.info(f"{tr().main.version.now_on()} {self.on_python_v}") self.logger.info(f"{tr().main.version.now_on()} {self.on_python_v}")

View File

@ -8,7 +8,7 @@ from .sr1_ship import SR1ShipRender
from MCDR.version import Version from MCDR.version import Version
from Difficult_Rocket.api.mod import ModInfo from Difficult_Rocket.api.mod import ModInfo
from Difficult_Rocket.client import ClientWindow from Difficult_Rocket.main import Game
class DR_mod(ModInfo): class DR_mod(ModInfo):
@ -27,7 +27,7 @@ class DR_mod(ModInfo):
# DR_Api_version = # DR Api版本 # DR_Api_version = # DR Api版本
# 同理 不管 API 版本 这东西要是不兼容了才是大问题 # 同理 不管 API 版本 这东西要是不兼容了才是大问题
def on_load(self): def on_load(self, game: Game):
... ...