DR mod api update

This commit is contained in:
shenjack-mac 2023-04-26 11:18:11 +08:00
parent 82df6e52e6
commit d0eabf1f57
5 changed files with 48 additions and 21 deletions

View File

@ -13,6 +13,7 @@ from MCDR.version import Version
# from DR # from DR
from Difficult_Rocket.main import Game from Difficult_Rocket.main import Game
from Difficult_Rocket import DR_runtime, Options from Difficult_Rocket import DR_runtime, Options
from Difficult_Rocket.client import ClientWindow
""" """
@ -66,7 +67,7 @@ class ModInfo(Options):
""" 服务器停止时调用 """ """ 服务器停止时调用 """
print(f'Mod {self.mod_id} server stop') print(f'Mod {self.mod_id} server stop')
def on_client_start(self, game: Game): def on_client_start(self, game: Game, client: ClientWindow):
""" 客户端启动时调用 """ """ 客户端启动时调用 """
print(f'Mod {self.mod_id} client start') print(f'Mod {self.mod_id} client start')

View File

@ -12,7 +12,7 @@ import inspect
import functools import functools
import traceback import traceback
from typing import List, Callable from typing import Callable, Dict
from decimal import Decimal from decimal import Decimal
# third function # third function
@ -25,6 +25,7 @@ from pyglet.window import Window
from pyglet.window import key, mouse from pyglet.window import key, mouse
# Difficult_Rocket function # Difficult_Rocket function
# from Difficult_Rocket.main import Game
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.command import line, tree from Difficult_Rocket.command import line, tree
@ -62,7 +63,7 @@ class ClientOption(Options):
class Client: class Client:
def __init__(self, net_mode='local'): def __init__(self, game: "Game", net_mode='local'):
start_time = time.time_ns() start_time = time.time_ns()
# logging # logging
self.logger = logging.getLogger('client') self.logger = logging.getLogger('client')
@ -74,7 +75,9 @@ class Client:
self.process_name = 'Client process' self.process_name = 'Client process'
self.process_pid = os.getpid() self.process_pid = os.getpid()
self.net_mode = net_mode self.net_mode = net_mode
self.window = ClientWindow(net_mode=self.net_mode, width=self.config.width, height=self.config.height, self.game = game
self.window = ClientWindow(game=game, net_mode=self.net_mode,
width=self.config.width, height=self.config.height,
fullscreen=self.config.fullscreen, caption=self.config.caption, fullscreen=self.config.fullscreen, caption=self.config.caption,
resizable=self.config.resizeable, visible=self.config.visible, resizable=self.config.resizeable, visible=self.config.visible,
file_drops=True) file_drops=True)
@ -108,7 +111,7 @@ def _call_screen_after(func: Callable) -> Callable:
@functools.wraps(func) @functools.wraps(func)
def warped(self: "ClientWindow", *args, **kwargs): def warped(self: "ClientWindow", *args, **kwargs):
result = func(self, *args, **kwargs) result = func(self, *args, **kwargs)
for a_screen in self.screen_list: for title, a_screen in self.screen_list.items():
a_screen.window_pointer = self a_screen.window_pointer = self
# 提前帮子窗口设置好指针 # 提前帮子窗口设置好指针
if hasattr(a_screen, func.__name__): if hasattr(a_screen, func.__name__):
@ -125,7 +128,7 @@ def _call_screen_after(func: Callable) -> Callable:
def _call_screen_before(func: Callable) -> Callable: def _call_screen_before(func: Callable) -> Callable:
@functools.wraps(func) @functools.wraps(func)
def warped(self: "ClientWindow", *args, **kwargs): def warped(self: "ClientWindow", *args, **kwargs):
for a_screen in self.screen_list: for title, a_screen in self.screen_list.items():
a_screen.window_pointer = self a_screen.window_pointer = self
# 提前帮子窗口设置好指针 # 提前帮子窗口设置好指针
if hasattr(a_screen, func.__name__): if hasattr(a_screen, func.__name__):
@ -142,7 +145,7 @@ def _call_screen_before(func: Callable) -> Callable:
class ClientWindow(Window): class ClientWindow(Window):
def __init__(self, net_mode='local', *args, **kwargs): def __init__(self, game: "Game", net_mode='local', *args, **kwargs):
""" """
@param net_mode: @param net_mode:
@ -155,6 +158,7 @@ class ClientWindow(Window):
self.logger = logging.getLogger('client') self.logger = logging.getLogger('client')
self.logger.info(tr().window.setup.start()) self.logger.info(tr().window.setup.start())
# value # value
self.game = game
self.net_mode = net_mode self.net_mode = net_mode
self.run_input = False self.run_input = False
# configs # configs
@ -170,7 +174,7 @@ class ClientWindow(Window):
# frame # frame
self.frame = pyglet.gui.Frame(self, order=20) self.frame = pyglet.gui.Frame(self, order=20)
self.M_frame = pyglet.gui.MovableFrame(self, modifier=key.LCTRL) self.M_frame = pyglet.gui.MovableFrame(self, modifier=key.LCTRL)
self.screen_list: List[BaseScreen] = [] self.screen_list: Dict[str, BaseScreen] = {}
# setup # setup
self.setup() self.setup()
# 命令显示 # 命令显示
@ -199,8 +203,9 @@ class ClientWindow(Window):
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['DR_debug'] = DRDEBUGScreen(self)
self.screen_list.append(DRScreen(self)) self.screen_list['DR_main'] = DRScreen(self)
self.game.dispatch_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']
@ -243,8 +248,8 @@ class ClientWindow(Window):
client api client api
""" """
def add_sub_screen(self, sub_screen: type(BaseScreen)): def add_sub_screen(self, title: str, sub_screen: type(BaseScreen)):
self.screen_list.append(sub_screen(self)) self.screen_list[title] = sub_screen(self)
""" """
draws and some event draws and some event

View File

@ -75,19 +75,22 @@ class Game:
def load_mods(self) -> None: def load_mods(self) -> None:
mods = [] mods = []
paths = Path(DR_runtime.mod_path).iterdir() paths = Path(DR_runtime.mod_path).iterdir()
sys.path.append(DR_runtime.mod_path)
for mod_path in paths: for mod_path in paths:
try: try:
if mod_path.name == '__pycache__':
continue
self.logger.info(tr().main.mod.find.start().format(mod_path)) self.logger.info(tr().main.mod.find.start().format(mod_path))
if mod_path.is_dir() and mod_path.name != '__pycache__': if mod_path.is_dir():
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:
self.logger.warning(tr().main.mod.load.failed.info().format(mod_path.name, tr().main.mod.find.failed.no_spce())) 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'): elif mod_path.suffix in ('.pyz', '.zip', '.pyd', '.py'):
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)
except ImportError as e: except ImportError as e:
self.logger.warning(tr().main.mod.find.failed().format(mod_path, e)) self.logger.warning(tr().main.mod.find.faild().format(mod_path, e))
self.logger.info(tr().main.mod.find.done()) self.logger.info(tr().main.mod.find.done())
module = [] module = []
for mod in mods: for mod in mods:
@ -95,7 +98,7 @@ class Game:
self.logger.info(tr().main.mod.load.start().format(mod)) self.logger.info(tr().main.mod.load.start().format(mod))
mod_module = importlib.import_module(mod) mod_module = importlib.import_module(mod)
if not hasattr(mod_module, "mod_class"): 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())) self.logger.warning(tr().main.mod.load.faild.info().format(mod, tr().main.mod.load.faild.no_mod_class()))
del mod_module # 释放内存 del mod_module # 释放内存
continue continue
mod_class = mod_module.mod_class mod_class = mod_module.mod_class
@ -103,14 +106,26 @@ class Game:
module.append(mod_class) module.append(mod_class)
self.logger.info(tr().main.mod.load.info().format(mod_class.mod_id, mod_class.version)) self.logger.info(tr().main.mod.load.info().format(mod_class.mod_id, mod_class.version))
except ImportError as e: except ImportError as e:
self.logger.warning(tr().main.mod.load.failed().format(mod, e)) self.logger.warning(tr().main.mod.load.faild().format(mod, e))
self.logger.info(tr().main.mod.load.done()) self.logger.info(tr().main.mod.load.done())
self.loaded_mods = module self.loaded_mods = module
mod_list = []
for mod in module:
mod_list.append((mod.mod_id, mod.version))
DR_runtime.DR_Mod_List = mod_list
def dispatch_event(self, event_name: str, *args, **kwargs) -> None:
for mod in self.loaded_mods:
if hasattr(mod, event_name):
try:
getattr(mod, event_name)(*args, **kwargs)
except Exception as e:
self.logger.error(tr().main.mod.event.error().format(event_name, e, mod.mod_id))
def setup(self) -> None: def setup(self) -> None:
self.client = client.Client(net_mode='local')
self.server = server.Server(net_mode='local')
self.load_mods() self.load_mods()
self.client = client.Client(game=self, net_mode='local')
self.server = server.Server(net_mode='local')
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

@ -29,6 +29,7 @@ mod.load.info = "mod id: {} 版本号: {}"
mod.load.faild.info = "Mod 加载失败: {} 错误信息: {}" mod.load.faild.info = "Mod 加载失败: {} 错误信息: {}"
mod.load.faild.no_mod_class = "没有找到 Mod 类" mod.load.faild.no_mod_class = "没有找到 Mod 类"
mod.load.done = "所有 Mod 加载完成" mod.load.done = "所有 Mod 加载完成"
mod.event.error = "Mod 事件 {} 发生错误 {} Mod: {}"
[client] [client]
setup.start = "客户端加载开始" setup.start = "客户端加载开始"

View File

@ -7,13 +7,14 @@
from .sr1_ship import SR1ShipRender 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.main import Game from Difficult_Rocket.main import Game
from Difficult_Rocket.api.mod import ModInfo
from Difficult_Rocket.client import ClientWindow
class DR_mod(ModInfo): class DR_mod(ModInfo):
mod_id = "Difficult_Rocket_mod" mod_id = "difficult_rocket_mod"
name = "Difficult Rocket mod" name = "Difficult Rocket mod"
version = Version("0.7.2.2") version = Version("0.7.2.2")
@ -30,5 +31,9 @@ class DR_mod(ModInfo):
def on_load(self, game: Game): def on_load(self, game: Game):
... ...
def on_client_start(self, game: Game, client: ClientWindow):
print('DR_mod: on_client_start')
client.add_sub_screen("SR1_ship", SR1ShipRender)
mod_class = DR_mod mod_class = DR_mod