From b2818c0cd603972917173d5f0decdc7026127e0b Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Fri, 5 May 2023 00:46:46 +0800 Subject: [PATCH 01/20] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=B0=8F=E4=B8=9C?= =?UTF-8?q?=E8=A5=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Difficult_Rocket/api/screen.py | 64 ++++++++++--------- Difficult_Rocket/api/types/SR1/ship.py | 7 -- Difficult_Rocket/mod/api/__init__.py | 1 + configs/main.toml | 4 +- .../Difficult_Rocket_rs/src/src/lib.rs | 14 ++++ .../Difficult_Rocket_rs/src/src/sr1_data.rs | 2 +- 6 files changed, 51 insertions(+), 41 deletions(-) diff --git a/Difficult_Rocket/api/screen.py b/Difficult_Rocket/api/screen.py index 2d37657..4260821 100644 --- a/Difficult_Rocket/api/screen.py +++ b/Difficult_Rocket/api/screen.py @@ -4,7 +4,7 @@ # All rights reserved # ------------------------------- -from typing import List, TYPE_CHECKING +from typing import List, TYPE_CHECKING, TypeVar from os import PathLike # from pyglet.window import Window @@ -15,6 +15,8 @@ from Difficult_Rocket.command.api import CommandText if TYPE_CHECKING: from Difficult_Rocket.client import ClientWindow +else: + ClientWindow = TypeVar("ClientWindow") class BaseScreen(EventDispatcher): @@ -22,28 +24,28 @@ class BaseScreen(EventDispatcher): DR 的 页面API """ - def __init__(self, main_window: "ClientWindow"): + def __init__(self, main_window: ClientWindow): super().__init__() self.focus = False self.window_pointer = main_window if TYPE_CHECKING: - def on_command(self, command: CommandText, window: "ClientWindow"): + def on_command(self, command: CommandText, window: ClientWindow): """ 命令输入事件 """ - def on_message(self, message: CommandText, window: "ClientWindow"): + def on_message(self, message: CommandText, window: ClientWindow): """ 消息输入事件 """ - def draw_update(self, tick: float, window: "ClientWindow"): + def draw_update(self, tick: float, window: ClientWindow): """ 画面更新 """ - def draw_batch(self, window: "ClientWindow"): + def draw_batch(self, window: ClientWindow): """ 画面绘制 """ @@ -51,7 +53,7 @@ class BaseScreen(EventDispatcher): """ Pyglet 定义的事件 """ - def on_activate(self, window: "ClientWindow"): + def on_activate(self, window: ClientWindow): """The window was activated. This event can be triggered by clicking on the title bar, bringing @@ -62,7 +64,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_close(self, window: "ClientWindow"): + def on_close(self, window: ClientWindow): """The user attempted to close the window. This event can be triggered by clicking on the "X" control box in @@ -75,7 +77,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_context_lost(self, window: "ClientWindow"): + def on_context_lost(self, window: ClientWindow): """The window's GL context was lost. When the context is lost no more GL methods can be called until it @@ -87,7 +89,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_context_state_lost(self, window: "ClientWindow"): + def on_context_state_lost(self, window: ClientWindow): """The state of the window's GL context was lost. pyglet may sometimes need to recreate the window's GL context if @@ -100,7 +102,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_deactivate(self, window: "ClientWindow"): + def on_deactivate(self, window: ClientWindow): """The window was deactivated. This event can be triggered by clicking on another application @@ -110,7 +112,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_draw(self, window: "ClientWindow"): + def on_draw(self, window: ClientWindow): """The window contents must be redrawn. The `EventLoop` will dispatch this event when the window @@ -130,7 +132,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_expose(self, window: "ClientWindow"): + def on_expose(self, window: ClientWindow): """A portion of the window needs to be redrawn. This event is triggered when the window first appears, and any time @@ -145,7 +147,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_file_drop(self, x: int, y: int, paths: List[PathLike] , window: "ClientWindow"): + def on_file_drop(self, x: int, y: int, paths: List[PathLike] , window: ClientWindow): """File(s) were dropped into the window, will return the position of the cursor and a list of paths to the files that were dropped. @@ -154,7 +156,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_hide(self, window: "ClientWindow"): + def on_hide(self, window: ClientWindow): """The window was hidden. This event is triggered when a window is minimised @@ -163,7 +165,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_key_press(self, symbol: int, modifiers: int, window: "ClientWindow"): + def on_key_press(self, symbol: int, modifiers: int, window: ClientWindow): """A key on the keyboard was pressed (and held down). Since pyglet 1.1 the default handler dispatches the :py:meth:`~pyglet.window.Window.on_close` @@ -178,7 +180,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_key_release(self, symbol: int, modifiers: int, window: "ClientWindow"): + def on_key_release(self, symbol: int, modifiers: int, window: ClientWindow): """A key on the keyboard was released. :Parameters: @@ -190,7 +192,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_mouse_motion(self, x: int, y: int, dx: int, dy: int, window: "ClientWindow"): + def on_mouse_motion(self, x: int, y: int, dx: int, dy: int, window: ClientWindow): """The mouse was moved with no buttons held down. :Parameters: @@ -206,7 +208,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"): + def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: ClientWindow): """The mouse was moved with one or more mouse buttons pressed. This event will continue to be fired even if the mouse leaves @@ -230,7 +232,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_mouse_press(self, x: int, y: int, button: int, modifiers: int, window: "ClientWindow"): + def on_mouse_press(self, x: int, y: int, button: int, modifiers: int, window: ClientWindow): """A mouse button was pressed (and held down). :Parameters: @@ -247,7 +249,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_mouse_release(self, x: int, y: int, button: int, modifiers: int, window: "ClientWindow"): + def on_mouse_release(self, x: int, y: int, button: int, modifiers: int, window: ClientWindow): """A mouse button was released. :Parameters: @@ -264,7 +266,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_mouse_scroll(self, x: int, y: int, scroll_x: float, scroll_y: float, window: "ClientWindow"): + def on_mouse_scroll(self, x: int, y: int, scroll_x: float, scroll_y: float, window: ClientWindow): """The mouse wheel was scrolled. Note that most mice have only a vertical scroll wheel, so @@ -285,7 +287,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_mouse_enter(self, x: int, y: int, window: "ClientWindow"): + def on_mouse_enter(self, x: int, y: int, window: ClientWindow): """The mouse was moved into the window. This event will not be triggered if the mouse is currently being @@ -300,7 +302,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_mouse_leave(self, x: int, y: int, window: "ClientWindow"): + def on_mouse_leave(self, x: int, y: int, window: ClientWindow): """The mouse was moved outside of the window. This event will not be triggered if the mouse is currently being @@ -316,7 +318,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_move(self, x: int, y: int, window: "ClientWindow"): + def on_move(self, x: int, y: int, window: ClientWindow): """The window was moved. :Parameters: @@ -331,7 +333,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_refresh(self, dt, window: "ClientWindow"): + def on_refresh(self, dt, window: ClientWindow): """The window contents must be redrawn. The `EventLoop` will dispatch this event when the window @@ -350,7 +352,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_resize(self, width: int, height: int, window: "ClientWindow"): + def on_resize(self, width: int, height: int, window: ClientWindow): """The window was resized. The window will have the GL context when this event is dispatched; @@ -365,7 +367,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_show(self, window: "ClientWindow"): + def on_show(self, window: ClientWindow): """The window was shown. This event is triggered when a window is restored after being @@ -374,7 +376,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_text(self, text: str, window: "ClientWindow"): + def on_text(self, text: str, window: ClientWindow): """The user input some text. Typically this is called after :py:meth:`~pyglet.window.Window.on_key_press` and before @@ -393,7 +395,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_text_motion(self, motion: int, window: "ClientWindow"): + def on_text_motion(self, motion: int, window: ClientWindow): """The user moved the text input cursor. Typically this is called after :py:meth:`~pyglet.window.Window.on_key_press` and before @@ -429,7 +431,7 @@ class BaseScreen(EventDispatcher): :event: """ - def on_text_motion_select(self, motion: int, window: "ClientWindow"): + def on_text_motion_select(self, motion: int, window: ClientWindow): """The user moved the text input cursor while extending the selection. diff --git a/Difficult_Rocket/api/types/SR1/ship.py b/Difficult_Rocket/api/types/SR1/ship.py index 0c7dca1..8fcca51 100644 --- a/Difficult_Rocket/api/types/SR1/ship.py +++ b/Difficult_Rocket/api/types/SR1/ship.py @@ -10,10 +10,3 @@ mail: 3695888@qq.com github: @shenjackyuanjie gitee: @shenjackyuanjie """ - -# system function -from xml.etree import ElementTree as ET - -# Difficult_Rocket function - -# libs function diff --git a/Difficult_Rocket/mod/api/__init__.py b/Difficult_Rocket/mod/api/__init__.py index f212ad7..b1fe624 100644 --- a/Difficult_Rocket/mod/api/__init__.py +++ b/Difficult_Rocket/mod/api/__init__.py @@ -86,3 +86,4 @@ class ModInfo(Options): def on_unload(self, game: Game): """ 卸载时调用 """ print(f'Mod {self.mod_id} unloaded') + diff --git a/configs/main.toml b/configs/main.toml index 45bfbf9..fd82563 100644 --- a/configs/main.toml +++ b/configs/main.toml @@ -7,8 +7,8 @@ fonts_folder = "libs/fonts" [window] style = "None" -width = 1305 -height = 722 +width = 1920 +height = 1017 visible = true gui_scale = 1 caption = "Difficult Rocket v{DR_version}|DR_rs v{DR_Rust_get_version}" diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs index cb41705..6c86b43 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs @@ -16,6 +16,16 @@ mod types; use pyo3::prelude::*; +const MOD_PATH: String = String::from("mods"); + +enum LoadState { + init, + wait_start, + pre_start, + running, + clean, +} + #[pyfunction] fn get_version_str() -> String { "0.2.7.0".to_string() } @@ -44,3 +54,7 @@ fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } + +pub fn run() {} + +fn init() {} diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs index 0465ded..1fe6e46 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs @@ -125,7 +125,7 @@ pub mod part_list { pub fn to_damage(&self) -> crate::types::sr1::Damage { crate::types::sr1::Damage { disconnect: self.disconnect, - explode: self.explode, + explode: self.explode.to_owned(), explosion_power: self.explosion_power.unwrap_or(100), explosion_size: self.explosion_size.unwrap_or(100), } From da2958de1e61648f7868e8675d3803fb6b075ab7 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Fri, 5 May 2023 21:58:38 +0800 Subject: [PATCH 02/20] sync pyglet update (fix TextInput --- libs/pyglet/__init__.py | 2 +- libs/pyglet/canvas/win32.py | 15 +++--- libs/pyglet/extlibs/png.py | 8 +-- libs/pyglet/font/ttf.py | 10 ++-- libs/pyglet/font/win32.py | 46 ++++++++--------- libs/pyglet/font/win32query.py | 50 +++++++++---------- libs/pyglet/gui/widgets.py | 1 + libs/pyglet/libs/win32/context_managers.py | 57 ++++++++++++++++++++++ libs/pyglet/text/caret.py | 23 +++++++-- libs/pyglet/text/layout.py | 1 + 10 files changed, 144 insertions(+), 69 deletions(-) create mode 100644 libs/pyglet/libs/win32/context_managers.py diff --git a/libs/pyglet/__init__.py b/libs/pyglet/__init__.py index 388c023..a2cc176 100644 --- a/libs/pyglet/__init__.py +++ b/libs/pyglet/__init__.py @@ -9,7 +9,7 @@ import sys from typing import TYPE_CHECKING #: The release version -version = '2.0.5' +version = '2.0.6' __version__ = version MIN_PYTHON_VERSION = 3, 8 diff --git a/libs/pyglet/canvas/win32.py b/libs/pyglet/canvas/win32.py index 31c08bb..52cdf52 100644 --- a/libs/pyglet/canvas/win32.py +++ b/libs/pyglet/canvas/win32.py @@ -3,6 +3,7 @@ from .base import Display, Screen, ScreenMode, Canvas from pyglet.libs.win32 import _user32 from pyglet.libs.win32.constants import * from pyglet.libs.win32.types import * +from pyglet.libs.win32.context_managers import device_context class Win32Display(Display): @@ -30,13 +31,13 @@ class Win32Screen(Screen): self._handle = handle def get_matching_configs(self, template): - hdc = _user32.GetDC(0) - canvas = Win32Canvas(self.display, 0, hdc) - configs = template.match(canvas) - # XXX deprecate config's being screen-specific - for config in configs: - config.screen = self - _user32.ReleaseDC(0, hdc) + with device_context(None) as hdc: + canvas = Win32Canvas(self.display, 0, hdc) + configs = template.match(canvas) + # XXX deprecate config's being screen-specific + for config in configs: + config.screen = self + return configs def get_device_name(self): diff --git a/libs/pyglet/extlibs/png.py b/libs/pyglet/extlibs/png.py index 815440d..34fb15e 100644 --- a/libs/pyglet/extlibs/png.py +++ b/libs/pyglet/extlibs/png.py @@ -991,7 +991,7 @@ def unpack_rows(rows): to being a sequence of bytes. """ for row in rows: - fmt = f'!{len(row)}' + fmt = f'!{len(row)}H' yield bytearray(struct.pack(fmt, *row)) @@ -1722,7 +1722,7 @@ class Reader: "PLTE chunk is required before bKGD chunk.") self.background = struct.unpack('B', data) else: - self.background = struct.unpack(f"!{self.color_planes}", + self.background = struct.unpack(f"!{self.color_planes}H", data) except struct.error: raise FormatError("bKGD chunk has incorrect length.") @@ -1744,7 +1744,7 @@ class Reader: f"tRNS chunk is not valid with colour type {self.color_type}.") try: self.transparent = \ - struct.unpack(f"!{self.color_planes}", data) + struct.unpack(f"!{self.color_planes}H", data) except struct.error: raise FormatError("tRNS chunk has incorrect length.") @@ -1977,7 +1977,7 @@ class Reader: pixels = itertrns(pixels) targetbitdepth = None if self.sbit: - sbit = struct.unpack(f'{len(self.sbit)}', self.sbit) + sbit = struct.unpack(f'{len(self.sbit)}B', self.sbit) targetbitdepth = max(sbit) if targetbitdepth > info['bitdepth']: raise Error(f'sBIT chunk {sbit!r} exceeds bitdepth {self.bitdepth}') diff --git a/libs/pyglet/font/ttf.py b/libs/pyglet/font/ttf.py index df319da..c503735 100644 --- a/libs/pyglet/font/ttf.py +++ b/libs/pyglet/font/ttf.py @@ -367,16 +367,16 @@ class TruetypeInfo: # a fuckwit. header = _read_cmap_format4Header(self._data, offset) seg_count = header.seg_count_x2 // 2 - array_size = struct.calcsize(f'>{seg_count}') - end_count = self._read_array(f'>{seg_count}', + array_size = struct.calcsize(f'>{seg_count}H') + end_count = self._read_array(f'>{seg_count}H', offset + header.size) - start_count = self._read_array(f'>{seg_count}', + start_count = self._read_array(f'>{seg_count}H', offset + header.size + array_size + 2) - id_delta = self._read_array(f'>{seg_count}', + id_delta = self._read_array(f'>{seg_count}H', offset + header.size + array_size + 2 + array_size) id_range_offset_address = \ offset + header.size + array_size + 2 + array_size + array_size - id_range_offset = self._read_array(f'>{seg_count}', + id_range_offset = self._read_array(f'>{seg_count}H', id_range_offset_address) character_map = {} for i in range(0, seg_count): diff --git a/libs/pyglet/font/win32.py b/libs/pyglet/font/win32.py index be7b225..e4b696e 100644 --- a/libs/pyglet/font/win32.py +++ b/libs/pyglet/font/win32.py @@ -9,6 +9,7 @@ from pyglet.font import base from pyglet.font import win32query import pyglet.image from pyglet.libs.win32.constants import * +from pyglet.libs.win32.context_managers import device_context from pyglet.libs.win32.types import * from pyglet.libs.win32 import _gdi32 as gdi32, _user32 as user32 from pyglet.libs.win32 import _kernel32 as kernel32 @@ -195,14 +196,13 @@ class Win32Font(base.Font): self.hfont = gdi32.CreateFontIndirectW(byref(self.logfont)) # Create a dummy DC for coordinate mapping - dc = user32.GetDC(0) - metrics = TEXTMETRIC() - gdi32.SelectObject(dc, self.hfont) - gdi32.GetTextMetricsA(dc, byref(metrics)) - self.ascent = metrics.tmAscent - self.descent = -metrics.tmDescent - self.max_glyph_width = metrics.tmMaxCharWidth - user32.ReleaseDC(0, dc) + with device_context(None) as dc: + metrics = TEXTMETRIC() + gdi32.SelectObject(dc, self.hfont) + gdi32.GetTextMetricsA(dc, byref(metrics)) + self.ascent = metrics.tmAscent + self.descent = -metrics.tmDescent + self.max_glyph_width = metrics.tmMaxCharWidth def __del__(self): gdi32.DeleteObject(self.hfont) @@ -210,22 +210,22 @@ class Win32Font(base.Font): @staticmethod def get_logfont(name, size, bold, italic, dpi): # Create a dummy DC for coordinate mapping - dc = user32.GetDC(0) - if dpi is None: - dpi = 96 - logpixelsy = dpi + with device_context(None) as dc: + if dpi is None: + dpi = 96 + logpixelsy = dpi + + logfont = LOGFONTW() + # Conversion of point size to device pixels + logfont.lfHeight = int(-size * logpixelsy // 72) + if bold: + logfont.lfWeight = FW_BOLD + else: + logfont.lfWeight = FW_NORMAL + logfont.lfItalic = italic + logfont.lfFaceName = name + logfont.lfQuality = ANTIALIASED_QUALITY - logfont = LOGFONTW() - # Conversion of point size to device pixels - logfont.lfHeight = int(-size * logpixelsy // 72) - if bold: - logfont.lfWeight = FW_BOLD - else: - logfont.lfWeight = FW_NORMAL - logfont.lfItalic = italic - logfont.lfFaceName = name - logfont.lfQuality = ANTIALIASED_QUALITY - user32.ReleaseDC(0, dc) return logfont @classmethod diff --git a/libs/pyglet/font/win32query.py b/libs/pyglet/font/win32query.py index ace9975..91b101b 100644 --- a/libs/pyglet/font/win32query.py +++ b/libs/pyglet/font/win32query.py @@ -71,6 +71,7 @@ appropriate typeface name and create the font using CreateFont or CreateFontIndirect. """ +from pyglet.libs.win32.context_managers import device_context DEBUG = False @@ -385,36 +386,33 @@ def query(charset=DEFAULT_CHARSET): global FONTDB # 1. Get device context of the entire screen - hdc = user32.GetDC(None) + with device_context(None) as hdc: - # 2. Call EnumFontFamiliesExA (ANSI version) + # 2. Call EnumFontFamiliesExA (ANSI version) - # 2a. Call with empty font name to query all available fonts - # (or fonts for the specified charset) - # - # NOTES: - # - # * there are fonts that don't support ANSI charset - # * for DEFAULT_CHARSET font is passed to callback function as - # many times as charsets it supports + # 2a. Call with empty font name to query all available fonts + # (or fonts for the specified charset) + # + # NOTES: + # + # * there are fonts that don't support ANSI charset + # * for DEFAULT_CHARSET font is passed to callback function as + # many times as charsets it supports - # [ ] font name should be less than 32 symbols with terminating \0 - # [ ] check double purpose - enumerate all available font names - # - enumerate all available charsets for a single font - # - other params? + # [ ] font name should be less than 32 symbols with terminating \0 + # [ ] check double purpose - enumerate all available font names + # - enumerate all available charsets for a single font + # - other params? - logfont = LOGFONTW(0, 0, 0, 0, 0, 0, 0, 0, charset, 0, 0, 0, 0, '') - FONTDB = [] # clear cached FONTDB for enum_font_names callback - res = gdi32.EnumFontFamiliesExW( - hdc, # handle to device context - ctypes.byref(logfont), - enum_font_names, # pointer to callback function - 0, # lParam - application-supplied data - 0) # dwFlags - reserved = 0 - # res here is the last value returned by callback function - - # 3. Release DC - user32.ReleaseDC(None, hdc) + logfont = LOGFONTW(0, 0, 0, 0, 0, 0, 0, 0, charset, 0, 0, 0, 0, '') + FONTDB = [] # clear cached FONTDB for enum_font_names callback + res = gdi32.EnumFontFamiliesExW( + hdc, # handle to device context + ctypes.byref(logfont), + enum_font_names, # pointer to callback function + 0, # lParam - application-supplied data + 0) # dwFlags - reserved = 0 + # res here is the last value returned by callback function return FONTDB diff --git a/libs/pyglet/gui/widgets.py b/libs/pyglet/gui/widgets.py index f72b008..a65acc8 100644 --- a/libs/pyglet/gui/widgets.py +++ b/libs/pyglet/gui/widgets.py @@ -438,6 +438,7 @@ class TextEntry(WidgetBase): def _set_focus(self, value): self._focus = value self._caret.visible = value + self._caret.layout = self._layout def update_groups(self, order): self._outline.group = Group(order=order + 1, parent=self._user_group) diff --git a/libs/pyglet/libs/win32/context_managers.py b/libs/pyglet/libs/win32/context_managers.py new file mode 100644 index 0000000..9deec64 --- /dev/null +++ b/libs/pyglet/libs/win32/context_managers.py @@ -0,0 +1,57 @@ +""" +Win32 resources as handy context managers. + +These are intended to help keep loader code clean & stable at the price +of a tiny bit of execution speed. Performance-critical code should avoid +using these helpers in favor of direct win32 API calls. + +Before:: + + def loader_function(arg): + context_handle = user32.GetResource(None) + + result = calculation(arg) + + # Easily forgotten! + user32.ReleaseResource(context_handle) + + return result + +After:: + + def loader_function(arg): + + with resource_context() as context_handle: + result = calculation(arg) + + return result + +""" +from contextlib import contextmanager +from typing import Optional, Generator +from ctypes.wintypes import HANDLE +from ctypes import WinError +from pyglet.libs.win32 import _user32 as user32 + + +@contextmanager +def device_context(window_handle: Optional[int] = None) -> Generator[HANDLE, None, None]: + """ + A Windows device context wrapped as a context manager. + + Args: + window_handle: A specific window handle to use, if any. + Raises: + WinError: Raises if a device context cannot be acquired or released + Yields: + HANDLE: the managed drawing context handle to auto-close. + + """ + if not (_dc := user32.GetDC(window_handle)): + raise WinError() + + try: + yield _dc + finally: + if not user32.ReleaseDC(None, _dc): + raise WinError() diff --git a/libs/pyglet/text/caret.py b/libs/pyglet/text/caret.py index eaa4781..5ee69d2 100644 --- a/libs/pyglet/text/caret.py +++ b/libs/pyglet/text/caret.py @@ -85,8 +85,10 @@ class Caret: """ from pyglet import gl self._layout = layout - batch = batch or layout.batch - group = layout.foreground_decoration_group + + self._custom_batch = True if batch else False + self._batch = batch or layout.batch + self._group = layout.foreground_decoration_group # Handle both 3 and 4 byte colors r, g, b, *a = color @@ -96,7 +98,7 @@ class Caret: colors = r, g, b, self._visible_alpha, r, g, b, self._visible_alpha - self._list = group.program.vertex_list(2, gl.GL_LINES, batch, group, colors=('Bn', colors)) + self._list = self._group.program.vertex_list(2, gl.GL_LINES, batch, self._group, colors=('Bn', colors)) self._ideal_x = None self._ideal_line = None self._next_attributes = {} @@ -105,6 +107,21 @@ class Caret: layout.push_handlers(self) + @property + def layout(self): + return self._layout + + @layout.setter + def layout(self, layout): + if self._layout == layout and self._group == layout.group: + return + + from pyglet import gl + self._layout = layout + batch = self._batch if self._custom_batch else layout.batch + self._group = layout.foreground_decoration_group + self._batch.migrate(self._list, gl.GL_LINES, self._group, batch) + def delete(self): """Remove the caret from its batch. diff --git a/libs/pyglet/text/layout.py b/libs/pyglet/text/layout.py index 24910e3..59d59f8 100644 --- a/libs/pyglet/text/layout.py +++ b/libs/pyglet/text/layout.py @@ -958,6 +958,7 @@ class TextLayout: def group(self, group): self._user_group = group self._initialize_groups() + self.group_cache.clear() self._update() @property From 9e1819b0d7b1f66a414144cb5931eb9fd3414102 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sat, 6 May 2023 22:12:08 +0800 Subject: [PATCH 03/20] fix const --- mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs index 6c86b43..4eef625 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/lib.rs @@ -16,7 +16,7 @@ mod types; use pyo3::prelude::*; -const MOD_PATH: String = String::from("mods"); +// const MOD_PATH: String = String::from("mods"); enum LoadState { init, @@ -55,6 +55,6 @@ fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> { Ok(()) } -pub fn run() {} +// pub fn run() {} -fn init() {} +// fn init() {} From 321782b945431bc8b2e133988eedd6b3fb5c8cb5 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sat, 6 May 2023 22:46:38 +0800 Subject: [PATCH 04/20] remove DR_Rs build from nuitka-win --- nuitka-win.ps1 | 7 ------- 1 file changed, 7 deletions(-) diff --git a/nuitka-win.ps1 b/nuitka-win.ps1 index 4feda60..82594fe 100644 --- a/nuitka-win.ps1 +++ b/nuitka-win.ps1 @@ -10,13 +10,6 @@ if (-Not (Test-Path -Path "./.github/workflows/env.ps1")) ./.github/workflows/env.ps1 -Set-Location libs -Set-Location Difficult_Rocket_rs -Set-Location src -python3.8 setup.py build -python post_build.py -Set-Location ../../.. - $arg = @() # 输出配置 $arg += @("--standalone") From 6737473dd44da4f412fd2388ec8be07c6758907e Mon Sep 17 00:00:00 2001 From: shenjack-mac <3695888@qq.com> Date: Tue, 9 May 2023 20:48:06 +0800 Subject: [PATCH 05/20] update nuitka-mac --- nuitka-mac.ps1 | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/nuitka-mac.ps1 b/nuitka-mac.ps1 index 0a272d4..ac2304d 100644 --- a/nuitka-mac.ps1 +++ b/nuitka-mac.ps1 @@ -10,13 +10,6 @@ if (-Not (Test-Path -Path "./.github/workflows/env.ps1")) ./.github/workflows/env.ps1 -Set-Location libs -Set-Location Difficult_Rocket_rs -Set-Location src -python3.9 setup.py build -python3 post_build.py -Set-Location ../../.. - $arg = @() # 输出配置 $arg += @("--standalone") @@ -44,11 +37,11 @@ python3.9 -m nuitka $arg $args DR.py $end_time = Get-Uptime $out = $end_time.TotalMilliseconds - $start_time.TotalMilliseconds + Write-Output $end_time.TotalSeconds $start_time.TotalSeconds $out s Write-Output $start_time $end_time Write-Output "--clang --lto=no and ($args)" -Copy-Item .\libs\pyglet\ .\build\nuitka-mac\DR.dist -Recurse # --include-data-dir=./libs/pyglet=./pyglet # --run # --disable-ccache From d26f8d0d917c9626a43cdc6878058e7da4136d2e Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Wed, 10 May 2023 00:52:56 +0800 Subject: [PATCH 06/20] update Options --- Difficult_Rocket/crash/__init__.py | 27 +++++---------------------- Difficult_Rocket/utils/options.py | 17 +++++++++++++++++ configs/main.toml | 4 ++-- docs/src/update_logs.md | 12 ++++++++++++ 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/Difficult_Rocket/crash/__init__.py b/Difficult_Rocket/crash/__init__.py index 5d6f2b8..e7a8316 100644 --- a/Difficult_Rocket/crash/__init__.py +++ b/Difficult_Rocket/crash/__init__.py @@ -19,7 +19,7 @@ import traceback import threading import multiprocessing from pathlib import Path -from typing import Optional, Union, TextIO +from typing import Optional, Union # import psutil # for more system info @@ -73,18 +73,6 @@ def to_code(string: str): return f'`{string}`' -def write_markdown_tablet(crash_file: TextIO, tablet: list) -> None: - a_len = max(tablet[1], 6) - b_len = max(tablet[2], 5) - c_len = max(tablet[3], 10) - crash_file.write(f'\n| Option{" " * (a_len - 4)} | Value{" " * (b_len - 3)} | Value Type{" " * (c_len - 8)} |\n') - crash_file.write(f'|:{"-" * (a_len + 3)}|:{"-" * (b_len + 3)}|:{"-" * (c_len + 3)}|\n') - for a, b, c in tablet[0]: - b, c = str(b), str(c) - crash_file.write( - f'| `{a}`{" " * (a_len - len(a))} | `{b}`{" " * (b_len - len(b))} | `{c}`{" " * (c_len - len(c))} |\n') - - def create_crash_report(info: Optional[str] = None) -> None: crash_info = crash_info_handler(info) if 'crash_report' not in os.listdir('./'): @@ -116,8 +104,10 @@ def write_info_to_cache(cache_stream): cache_stream.write(markdown_line_handler(f'DR Version: {Difficult_Rocket.game_version}', level=1)) cache_stream.write(markdown_line_handler(f'DR language: {DR_runtime.language}', level=1)) cache_stream.write(markdown_line_handler(f'Running Dir: {Path(os.curdir).resolve()}', level=1)) - write_options(DR_runtime, cache_stream, DR_configs) - write_options(DR_option, cache_stream, Process_message) + cache_stream.write(f"\n{DR_runtime.as_markdown()}") + cache_stream.write(DR_configs) + cache_stream.write(f"\n{DR_option.as_markdown()}") + cache_stream.write(Process_message) for process in all_process: process: multiprocessing.Process cache_stream.write(markdown_line_handler(f'{process.name}', code=True)) @@ -148,13 +138,6 @@ def write_info_to_cache(cache_stream): cache_stream.write(markdown_line_handler(f'version: {to_code(platform.version())}', level=1)) -def write_options(arg0, cache_stream, arg2): - result = arg0.option_with_len() - write_markdown_tablet(crash_file=cache_stream, tablet=result) - # # DR 的游戏设置 - cache_stream.write(arg2) - - if __name__ == '__main__': os.chdir('../../') try: diff --git a/Difficult_Rocket/utils/options.py b/Difficult_Rocket/utils/options.py index f5bdfa6..530a9d6 100644 --- a/Difficult_Rocket/utils/options.py +++ b/Difficult_Rocket/utils/options.py @@ -5,6 +5,7 @@ # ------------------------------- import traceback +from io import StringIO from dataclasses import dataclass from typing import get_type_hints, Type, List, Union, Dict, Any, Callable, Tuple, Optional, TYPE_CHECKING @@ -137,6 +138,22 @@ class Options: option_list.append((key, value, value_t)) return [option_list, max_len_key, max_len_value, max_len_value_t] + def as_markdown(self) -> str: + value = self.option_with_len() + cache = StringIO() + option_len = max(value[1], len('Option')) + value_len = max(value[2], len('Value')) + value_type_len = max(value[3], len('Value Type')) + cache.write(f"| Option{' '*(option_len-3)}| Value{' '*(value_len-2)}| Value Type{' '*(value_type_len-7)}|\n") + cache.write(f'|:{"-" * (option_len+3)}|:{"-" * (value_len+3)}|:{"-" * (value_type_len + 3)}|\n') + for option, value, value_t in value[0]: + cache.write(f"| `{option}`{' '* (option_len - len(option))} " + f"| `{value}`{' '* (value_len - len(str(value)))} " + f"| `{value_t}`{' '* (value_type_len - len(str(value_t)))} |\n") + result = cache.getvalue() + cache.close() + return result + @classmethod def add_option(cls, name: str, value: Union[Callable, object]) -> Dict: if not hasattr(cls, 'options'): diff --git a/configs/main.toml b/configs/main.toml index fd82563..3899362 100644 --- a/configs/main.toml +++ b/configs/main.toml @@ -7,8 +7,8 @@ fonts_folder = "libs/fonts" [window] style = "None" -width = 1920 -height = 1017 +width = 1261 +height = 935 visible = true gui_scale = 1 caption = "Difficult Rocket v{DR_version}|DR_rs v{DR_Rust_get_version}" diff --git a/docs/src/update_logs.md b/docs/src/update_logs.md index 0ff3874..549172d 100644 --- a/docs/src/update_logs.md +++ b/docs/src/update_logs.md @@ -70,6 +70,10 @@ - Completely removed the `DR_rust` part - 现在 `client` 不会在 `setup()` 中调用 `DR_runtime` 的 `find_mods()` 方法 - Now `client` will not call the `find_mods()` method of `DR_runtime` in `setup()` +- `Difficult_Rocket.crash` + - Remove `write_options` method + - Remove `write_markdown_tablet` method + - Replace with `Option().as_markdown()` ### Changes @@ -101,6 +105,14 @@ - 大重构,移除定义,改为引用 - Big refactoring, remove definition, change to reference +### Add + +- `Difficult_Rocket.api.types.Options` + - 添加 `as_markdown` 方法 + - 用于方便的用人类可读的 Markdown 格式 直接输出一个已经实例化的 `Options` 类的所有字段 + - Add `as_markdown` method + - Used to easily output all fields of an instantiated `Options` class in a human-readable Markdown format + ### Docs - `howto/translate.md` From 5f19db607c56f25a5df471a72b3b2862f1823873 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Wed, 10 May 2023 18:39:42 +0800 Subject: [PATCH 07/20] add .to_owned() --- mods/dr_game/Difficult_Rocket_rs/src/src/python.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs index 4c49275..c7d52e9 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs @@ -28,7 +28,7 @@ pub mod data { fn get_name(&self) -> String { self.data.name.clone() } #[getter] - fn get_mass(&self) -> f64 { self.data.mass } + fn get_mass(&self) -> f64 { self.data.mass.to_owned() } } impl PySR1PartType { @@ -101,9 +101,9 @@ pub mod data { fn get_description(&self) -> String { self.ship.description.clone() } - fn get_lift_off(&self) -> bool { self.ship.lift_off } + fn get_lift_off(&self) -> bool { self.ship.lift_off.to_owned() } - fn get_touch_ground(&self) -> bool { self.ship.touch_ground } + fn get_touch_ground(&self) -> bool { self.ship.touch_ground.to_owned() } } } From c888c7e2da25137839c1a9af911df2f4eb3990d7 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Thu, 11 May 2023 00:31:13 +0800 Subject: [PATCH 08/20] options -> _options --- Difficult_Rocket/utils/options.py | 18 +++++++++--------- docs/src/update_logs.md | 4 +++- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Difficult_Rocket/utils/options.py b/Difficult_Rocket/utils/options.py index 530a9d6..06a6ec4 100644 --- a/Difficult_Rocket/utils/options.py +++ b/Difficult_Rocket/utils/options.py @@ -51,7 +51,7 @@ class Options: :param kwargs: """ if TYPE_CHECKING: - self.options: Dict[str, Union[Callable, object]] = {} + self._options: Dict[str, Union[Callable, object]] = {} self.flush_option() for option, value in kwargs.items(): if option not in self.cached_options: @@ -67,7 +67,7 @@ class Options: self.flush_option() if TYPE_CHECKING: - options: Dict[str, Union[Callable, object]] = {} + _options: Dict[str, Union[Callable, object]] = {} def init(self, **kwargs) -> None: """ 如果子类定义了这个函数,则会在 __init__ 之后调用这个函数 """ @@ -90,9 +90,9 @@ class Options: if values[ann] is None: values[ann] = self.__annotations__[ann] - if not hasattr(self, 'options'): - self.options: Dict[str, Union[Callable, object]] = {} - for option, a_fun in self.options.items(): # 获取额外内容 + if not hasattr(self, '_options'): + self._options: Dict[str, Union[Callable, object]] = {} + for option, a_fun in self._options.items(): # 获取额外内容 values[option] = a_fun for option, a_fun in values.items(): # 检查是否为 property @@ -156,10 +156,10 @@ class Options: @classmethod def add_option(cls, name: str, value: Union[Callable, object]) -> Dict: - if not hasattr(cls, 'options'): - cls.options: Dict[str, Union[Callable, object]] = {} - cls.options[name] = value - return cls.options + if not hasattr(cls, '_options'): + cls._options: Dict[str, Union[Callable, object]] = {} + cls._options[name] = value + return cls._options @staticmethod def init_option(options_class: Type['Options'], init_value: Optional[dict] = None) -> 'Options': diff --git a/docs/src/update_logs.md b/docs/src/update_logs.md index 549172d..1c5a2ce 100644 --- a/docs/src/update_logs.md +++ b/docs/src/update_logs.md @@ -104,10 +104,12 @@ - `Difficult_Rocket.api` - 大重构,移除定义,改为引用 - Big refactoring, remove definition, change to reference +- `Difficult_Rocket.api.types.Options` ( `Difficult_Rocket.utils.options.Options` ) + - `options` -> `_options` ### Add -- `Difficult_Rocket.api.types.Options` +- `Difficult_Rocket.api.types.Options` ( `Difficult_Rocket.utils.options.Options` ) - 添加 `as_markdown` 方法 - 用于方便的用人类可读的 Markdown 格式 直接输出一个已经实例化的 `Options` 类的所有字段 - Add `as_markdown` method From 251e68b48dd132f11b338dbc62355cbf2a81d9b3 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Thu, 11 May 2023 00:35:42 +0800 Subject: [PATCH 09/20] typing change --- Difficult_Rocket/utils/options.py | 6 +++--- docs/src/update_logs.md | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Difficult_Rocket/utils/options.py b/Difficult_Rocket/utils/options.py index 06a6ec4..32bc06c 100644 --- a/Difficult_Rocket/utils/options.py +++ b/Difficult_Rocket/utils/options.py @@ -124,19 +124,19 @@ class Options: self.cached_options = self.option() return self.cached_options - def option_with_len(self) -> List[Union[List[Tuple[str, Any, Any]], int, Any]]: + def option_with_len(self) -> Tuple[List[Tuple[str, Union[Any, Type], Type]], int, int, int]: options = self.flush_option() max_len_key = 1 max_len_value = 1 max_len_value_t = 1 option_list = [] for key, value in options.items(): - value_t = value if isinstance(value, Type) else type(value) + value_t = value if isinstance(value, Type) else type(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] + return option_list, max_len_key, max_len_value, max_len_value_t def as_markdown(self) -> str: value = self.option_with_len() diff --git a/docs/src/update_logs.md b/docs/src/update_logs.md index 1c5a2ce..8f27b7a 100644 --- a/docs/src/update_logs.md +++ b/docs/src/update_logs.md @@ -106,6 +106,10 @@ - Big refactoring, remove definition, change to reference - `Difficult_Rocket.api.types.Options` ( `Difficult_Rocket.utils.options.Options` ) - `options` -> `_options` + - `option_with_len(self) ->` + - 修改 返回值 类型+类型注释 + - Modify the return value type + type annotation + - `List[Union[List[Tuple[str, Any, Any]], int, Any]]:` -> `Tuple[List[Tuple[str, Union[Any, Type], Type]], int, int, int]` ### Add From 2ae539974e77a981367fb2981a10caecf15c2c68 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Thu, 11 May 2023 06:26:08 +0800 Subject: [PATCH 10/20] options docs string --- Difficult_Rocket/utils/options.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Difficult_Rocket/utils/options.py b/Difficult_Rocket/utils/options.py index 32bc06c..bcaac38 100644 --- a/Difficult_Rocket/utils/options.py +++ b/Difficult_Rocket/utils/options.py @@ -39,7 +39,12 @@ class OptionNotFound(OptionsError): class Options: """ - Difficult Rocket 的游戏配置的存储基类 + 一个用于存储选项 / 提供 API 定义 的类 + 用法: + 继承 Options 类 + 在类里定义 option: typing + (可选 定义 name: str = 'Option Base' 用于在打印的时候显示名字) + """ name = 'Option Base' cached_options: Dict[str, Union[str, Any]] = {} From 582ce53c8aaa1010f02570bf24e617d002a1968a Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Fri, 12 May 2023 21:06:56 +0800 Subject: [PATCH 11/20] add typing remove utils.new_thread --- Difficult_Rocket/__init__.py | 3 +- Difficult_Rocket/client/__init__.py | 5 +- Difficult_Rocket/command/line.py | 2 +- Difficult_Rocket/utils/new_thread.py | 155 -------------------------- Difficult_Rocket/utils/options.py | 26 ++++- Difficult_Rocket/utils/thread.py | 157 +++++++++++++++++++++++++-- docs/src/update_logs.md | 4 + 7 files changed, 179 insertions(+), 173 deletions(-) delete mode 100644 Difficult_Rocket/utils/new_thread.py diff --git a/Difficult_Rocket/__init__.py b/Difficult_Rocket/__init__.py index 5aadb0a..f654bda 100644 --- a/Difficult_Rocket/__init__.py +++ b/Difficult_Rocket/__init__.py @@ -5,7 +5,6 @@ # ------------------------------- import sys -import warnings import importlib import traceback import contextlib @@ -14,7 +13,7 @@ from pathlib import Path from typing import Optional, List, Tuple from Difficult_Rocket.api.types import Options -from Difficult_Rocket.utils.new_thread import new_thread +from Difficult_Rocket.utils.thread import new_thread from libs.MCDR.version import Version diff --git a/Difficult_Rocket/client/__init__.py b/Difficult_Rocket/client/__init__.py index 1fa7b13..14568ae 100644 --- a/Difficult_Rocket/client/__init__.py +++ b/Difficult_Rocket/client/__init__.py @@ -32,12 +32,11 @@ from Difficult_Rocket.utils import tools from Difficult_Rocket.api.types import Options from Difficult_Rocket.command import line, tree from Difficult_Rocket.utils.translate import tr -from Difficult_Rocket import DR_runtime, DR_option +from Difficult_Rocket import DR_runtime from Difficult_Rocket.api.screen import BaseScreen -from Difficult_Rocket.utils.new_thread import new_thread +from Difficult_Rocket.utils.thread import new_thread from Difficult_Rocket.client.fps.fps_log import FpsLogger from Difficult_Rocket.client.guis.widgets import InputBox -from Difficult_Rocket.exception.command import CommandError from Difficult_Rocket.exception.language import LanguageNotFound from Difficult_Rocket.client.screen import DRScreen, DRDEBUGScreen diff --git a/Difficult_Rocket/command/line.py b/Difficult_Rocket/command/line.py index 46ce8f1..a536c8c 100644 --- a/Difficult_Rocket/command/line.py +++ b/Difficult_Rocket/command/line.py @@ -27,7 +27,7 @@ from pyglet.graphics import Batch, Group # from DR from Difficult_Rocket.utils import translate from Difficult_Rocket.command.api import CommandText -from Difficult_Rocket.utils.new_thread import new_thread +from Difficult_Rocket.utils.thread import new_thread class CommandLineTextEntry(widgets.TextEntry): diff --git a/Difficult_Rocket/utils/new_thread.py b/Difficult_Rocket/utils/new_thread.py deleted file mode 100644 index c76838a..0000000 --- a/Difficult_Rocket/utils/new_thread.py +++ /dev/null @@ -1,155 +0,0 @@ -# ------------------------------- -# Difficult Rocket -# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com -# All rights reserved -# ------------------------------- - -import functools -import inspect -import threading -from typing import Optional, Callable, Union, List - -""" -This part of code come from MCDReforged(https://github.com/Fallen-Breath/MCDReforged) -Very thanks to Fallen_Breath and other coder who helped MCDR worked better -GNU Lesser General Public License v3.0(GNU LGPL v3) -(have some changes) -""" - -__all__ = [ - 'new_thread', - 'FunctionThread' -] - - -record_thread = False -record_destination: List[Callable[['FunctionThread'], None]] = [] - - -def copy_signature(target: Callable, origin: Callable) -> Callable: - """ - Copy the function signature of origin into target - """ - # https://stackoverflow.com/questions/39926567/python-create-decorator-preserving-function-arguments - target.__signature__ = inspect.signature(origin) - return target - - -class FunctionThread(threading.Thread): - """ - A Thread subclass which is used in decorator :func:`new_thread` to wrap a synchronized function call - """ - __NONE = object() - - def __init__(self, target, name, args, kwargs, daemon): - super().__init__(target=target, args=args, kwargs=kwargs, name=name, daemon=daemon) - self.__return_value = self.__NONE - self.__error = None - - def wrapped_target(*args_, **kwargs_): - try: - self.__return_value = target(*args_, **kwargs_) - except Exception as e: - self.__error = e - raise e from None - - self._target = wrapped_target - - def get_return_value(self, block: bool = False, timeout: Optional[float] = None): - """ - Get the return value of the original function - - If an exception has occurred during the original function call, the exception will be risen again here - - Examples:: - - >>> import time - >>> @new_thread - ... def do_something(text: str): - ... time.sleep(1) - ... return text - - >>> do_something('task').get_return_value(block=True) - 'task' - - :param block: If it should join the thread before getting the return value to make sure the function invocation finishes - :param timeout: The maximum timeout for the thread join - :raise RuntimeError: If the thread is still alive when getting return value. Might be caused by ``block=False`` - while the thread is still running, or thread join operation times out - :return: The return value of the original function - """ - if block: - self.join(timeout) - if self.__return_value is self.__NONE: - if self.is_alive(): - raise RuntimeError('The thread is still running') - raise self.__error - return self.__return_value - - -def new_thread(arg: Optional[Union[str, Callable]] = None, - daemon: bool = False, - log_thread: bool = True): - """ - This is a one line solution to make your function executes in parallels. - When decorated with this decorator, functions will be executed in a new daemon thread - - This decorator only changes the return value of the function to the created ``Thread`` object. - Beside the return value, it reserves all signatures of the decorated function, - so you can safely use the decorated function as if there's no decorating at all - - It's also a simple compatible upgrade method for old MCDR 0.x plugins - - The return value of the decorated function is changed to the ``Thread`` object that executes this function - - The decorated function has 1 extra field: - - * ``original`` field: The original undecorated function - - Examples:: - - >>> import time - - >>> @new_thread('My Plugin Thread') - ... def do_something(text: str): - ... time.sleep(1) - ... print(threading.current_thread().name) - >>> callable(do_something.original) - True - >>> t = do_something('foo') - >>> isinstance(t, FunctionThread) - True - >>> t.join() - My Plugin Thread - - :param arg: A :class:`str`, the name of the thread. It's recommend to specify the thread name, so when you - log something by ``server.logger``, a meaningful thread name will be displayed - instead of a plain and meaningless ``Thread-3`` - :param daemon: If the thread should be a daemon thread - :param log_thread: If the thread should be logged to callback defined in record_destination - """ - - def wrapper(func): - @functools.wraps(func) # to preserve the origin function information - def wrap(*args, **kwargs): - thread = FunctionThread(target=func, args=args, kwargs=kwargs, name=thread_name, daemon=daemon) - if record_thread: - for destination in record_destination: - destination(thread) - thread.start() - return thread - - # bring the signature of the func to the wrap function - # so inspect.getfullargspec(func) works correctly - copy_signature(wrap, func) - wrap.original = func # access this field to get the original function - return wrap - - # Directly use @new_thread without ending brackets case, e.g. @new_thread - if isinstance(arg, Callable): - thread_name = None - return wrapper(arg) - # Use @new_thread with ending brackets case, e.g. @new_thread('A'), @new_thread() - else: - thread_name = arg - return wrapper diff --git a/Difficult_Rocket/utils/options.py b/Difficult_Rocket/utils/options.py index bcaac38..b8586e9 100644 --- a/Difficult_Rocket/utils/options.py +++ b/Difficult_Rocket/utils/options.py @@ -41,10 +41,14 @@ class Options: """ 一个用于存储选项 / 提供 API 定义 的类 用法: - 继承 Options 类 - 在类里定义 option: typing - (可选 定义 name: str = 'Option Base' 用于在打印的时候显示名字) - + 存储配置: 继承 Options 类 + 在类里定义 option: typing + (可选 定义 name: str = 'Option Base' 用于在打印的时候显示名字) + 提供 API 接口: 继承 Options 类 + 在类里定义 option: typing + 定义 一些需要的方法 + 子类: 继承 新的 Options 类 + 实现定义的方法 """ name = 'Option Base' cached_options: Dict[str, Union[str, Any]] = {} @@ -130,6 +134,10 @@ class Options: return self.cached_options def option_with_len(self) -> Tuple[List[Tuple[str, Union[Any, Type], Type]], int, int, int]: + """ + 返回一个可以用于打印的 option 列表 + :return: + """ options = self.flush_option() max_len_key = 1 max_len_value = 1 @@ -144,6 +152,10 @@ class Options: return option_list, max_len_key, max_len_value, max_len_value_t def as_markdown(self) -> str: + """ + 返回一个 markdown 格式的 option 字符串 + :return: markdown 格式的 option 字符串 + """ value = self.option_with_len() cache = StringIO() option_len = max(value[1], len('Option')) @@ -161,6 +173,12 @@ class Options: @classmethod def add_option(cls, name: str, value: Union[Callable, object]) -> Dict: + """ + 向配置类中添加一个额外的配置 + :param name: 配置的名字 + :param value: 用于获取配置的函数或者类 + :return: 配置类的所有配置 + """ if not hasattr(cls, '_options'): cls._options: Dict[str, Union[Callable, object]] = {} cls._options[name] = value diff --git a/Difficult_Rocket/utils/thread.py b/Difficult_Rocket/utils/thread.py index eb8e5a1..975e829 100644 --- a/Difficult_Rocket/utils/thread.py +++ b/Difficult_Rocket/utils/thread.py @@ -11,20 +11,24 @@ github: @shenjackyuanjie gitee: @shenjackyuanjie """ +import functools +import inspect import threading - -from typing import Union from threading import Lock +from typing import Optional, Callable, Union, List -from Difficult_Rocket import DR_option, crash from Difficult_Rocket.exception.threading import LockTimeOutError +__all__ = [ + 'new_thread', + 'FunctionThread', + 'ThreadLock', + 'record_thread', + 'record_destination', +] -class Threads(threading.Thread): - def run(self): - if DR_option.record_thread: - crash.all_thread.append(self) - super().run() +record_thread = False +record_destination: List[Callable[['FunctionThread'], None]] = [] class ThreadLock: @@ -44,6 +48,143 @@ class ThreadLock: self.lock.release() +""" +This part of code come from MCDReforged(https://github.com/Fallen-Breath/MCDReforged) +Very thanks to Fallen_Breath and other coder who helped MCDR worked better +GNU Lesser General Public License v3.0(GNU LGPL v3) +(have some changes) +""" + + +def copy_signature(target: Callable, origin: Callable) -> Callable: + """ + Copy the function signature of origin into target + """ + # https://stackoverflow.com/questions/39926567/python-create-decorator-preserving-function-arguments + target.__signature__ = inspect.signature(origin) + return target + + +class FunctionThread(threading.Thread): + """ + A Thread subclass which is used in decorator :func:`new_thread` to wrap a synchronized function call + """ + __NONE = object() + + def __init__(self, target, name, args, kwargs, daemon): + super().__init__(target=target, args=args, kwargs=kwargs, name=name, daemon=daemon) + self.__return_value = self.__NONE + self.__error = None + + def wrapped_target(*args_, **kwargs_): + try: + self.__return_value = target(*args_, **kwargs_) + except Exception as e: + self.__error = e + raise e from None + + self._target = wrapped_target + + def get_return_value(self, block: bool = False, timeout: Optional[float] = None): + """ + Get the return value of the original function + + If an exception has occurred during the original function call, the exception will be risen again here + + Examples:: + + >>> import time + >>> @new_thread + ... def do_something(text: str): + ... time.sleep(1) + ... return text + + >>> do_something('task').get_return_value(block=True) + 'task' + + :param block: If it should join the thread before getting the return value to make sure the function invocation finishes + :param timeout: The maximum timeout for the thread join + :raise RuntimeError: If the thread is still alive when getting return value. Might be caused by ``block=False`` + while the thread is still running, or thread join operation times out + :return: The return value of the original function + """ + if block: + self.join(timeout) + if self.__return_value is self.__NONE: + if self.is_alive(): + raise RuntimeError('The thread is still running') + raise self.__error + return self.__return_value + + +def new_thread(arg: Optional[Union[str, Callable]] = None, + daemon: bool = False, + log_thread: bool = True): + """ + This is a one line solution to make your function executes in parallels. + When decorated with this decorator, functions will be executed in a new daemon thread + + This decorator only changes the return value of the function to the created ``Thread`` object. + Beside the return value, it reserves all signatures of the decorated function, + so you can safely use the decorated function as if there's no decorating at all + + It's also a simple compatible upgrade method for old MCDR 0.x plugins + + The return value of the decorated function is changed to the ``Thread`` object that executes this function + + The decorated function has 1 extra field: + + * ``original`` field: The original undecorated function + + Examples:: + + >>> import time + + >>> @new_thread('My Plugin Thread') + ... def do_something(text: str): + ... time.sleep(1) + ... print(threading.current_thread().name) + >>> callable(do_something.original) + True + >>> t = do_something('foo') + >>> isinstance(t, FunctionThread) + True + >>> t.join() + My Plugin Thread + + :param arg: A :class:`str`, the name of the thread. It's recommend to specify the thread name, so when you + log something by ``server.logger``, a meaningful thread name will be displayed + instead of a plain and meaningless ``Thread-3`` + :param daemon: If the thread should be a daemon thread + :param log_thread: If the thread should be logged to callback defined in record_destination + """ + + def wrapper(func): + @functools.wraps(func) # to preserve the origin function information + def wrap(*args, **kwargs): + thread = FunctionThread(target=func, args=args, kwargs=kwargs, name=thread_name, daemon=daemon) + if record_thread: + for destination in record_destination: + destination(thread) + thread.start() + return thread + + # bring the signature of the func to the wrap function + # so inspect.getfullargspec(func) works correctly + copy_signature(wrap, func) + wrap.original = func # access this field to get the original function + return wrap + + # Directly use @new_thread without ending brackets case, e.g. @new_thread + if isinstance(arg, Callable): + thread_name = None + return wrapper(arg) + # Use @new_thread with ending brackets case, e.g. @new_thread('A'), @new_thread() + else: + thread_name = arg + return wrapper + + if __name__ == "__main__": from Difficult_Rocket.exception import TestError diff --git a/docs/src/update_logs.md b/docs/src/update_logs.md index 8f27b7a..f299b20 100644 --- a/docs/src/update_logs.md +++ b/docs/src/update_logs.md @@ -74,6 +74,10 @@ - Remove `write_options` method - Remove `write_markdown_tablet` method - Replace with `Option().as_markdown()` +- `Difficult_Rocket.utils.new_thread` + - Moved to `Diffiuclt_Rocket.utils.thread` +- `Difficult_Rocket.utils.thread` + - Remove `Threads` ### Changes From 08e2ae9ae202cc7468cd36b8247e0a11a506e48a Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 01:40:10 +0800 Subject: [PATCH 12/20] sync pyglet update --- libs/pyglet/__init__.py | 2 +- libs/pyglet/gui/widgets.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/pyglet/__init__.py b/libs/pyglet/__init__.py index a2cc176..6a71f88 100644 --- a/libs/pyglet/__init__.py +++ b/libs/pyglet/__init__.py @@ -9,7 +9,7 @@ import sys from typing import TYPE_CHECKING #: The release version -version = '2.0.6' +version = '2.0.7' __version__ = version MIN_PYTHON_VERSION = 3, 8 diff --git a/libs/pyglet/gui/widgets.py b/libs/pyglet/gui/widgets.py index a65acc8..40ec158 100644 --- a/libs/pyglet/gui/widgets.py +++ b/libs/pyglet/gui/widgets.py @@ -370,7 +370,7 @@ class TextEntry(WidgetBase): """ def __init__(self, text, x, y, width, - color=(255, 255, 255, 255), text_color=(0, 0, 0, 255), caret_color=(0, 0, 0), + color=(255, 255, 255, 255), text_color=(0, 0, 0, 255), caret_color=(0, 0, 0, 255), batch=None, group=None): """Create a text entry widget. @@ -387,8 +387,9 @@ class TextEntry(WidgetBase): The color of the outline box in RGBA format. `text_color` : (int, int, int, int) The color of the text in RGBA format. - `caret_color` : (int, int, int) - The color of the caret in RGB format. + `caret_color` : (int, int, int, int) + The color of the caret when it is visible in RGBA or RGB + format. `batch` : `~pyglet.graphics.Batch` Optional batch to add the text entry widget to. `group` : `~pyglet.graphics.Group` From 77e02fa3caa618c170eeaf251728e255896c96b2 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 01:40:34 +0800 Subject: [PATCH 13/20] update DR_rs and post_build script --- .../Difficult_Rocket_rs/src/post_build.py | 4 +- .../Difficult_Rocket_rs/src/src/python.rs | 20 +- .../Difficult_Rocket_rs/src/src/sr1_data.rs | 79 +--- .../Difficult_Rocket_rs/src/src/types.rs | 440 ++++++++++++------ mods/dr_game/__init__.py | 1 + 5 files changed, 324 insertions(+), 220 deletions(-) diff --git a/mods/dr_game/Difficult_Rocket_rs/src/post_build.py b/mods/dr_game/Difficult_Rocket_rs/src/post_build.py index d1838b4..d3b2507 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/post_build.py +++ b/mods/dr_game/Difficult_Rocket_rs/src/post_build.py @@ -7,9 +7,10 @@ import os import shutil import warnings import traceback +from pathlib import Path package_path = 'Difficult_Rocket_rs' -lib_path = '../lib' +lib_path = Path('../lib').resolve() build_path = 'build' if not os.path.exists(lib_path): @@ -28,7 +29,6 @@ for build_dir in builds: warnings.warn(f'package not found at {build_path}/{build_dir}') continue for file in os.listdir(os.path.join(build_path, build_dir, package_path)): - # file_name = os.path.join(lib_path, file.replace(package_path, f'{package_path}.{DR_runtime.DR_Rust_version}')) file_name = os.path.join(lib_path, file) shutil.rmtree(file_name, ignore_errors=True) try: diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs index c7d52e9..a543772 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/python.rs @@ -39,7 +39,7 @@ pub mod data { #[pyo3(name = "SR1PartList_rs")] #[pyo3(text_signature = "(file_path = './configs/PartList.xml', list_name = 'NewPartList')")] pub struct PySR1PartList { - pub part_list: SR1PartList, + pub data: SR1PartList, } #[pymethods] @@ -47,16 +47,16 @@ pub mod data { #[new] fn new(file_path: String, list_name: String) -> Self { let raw_part_list: RawPartList = RawPartList::from_file(file_path).unwrap(); - let part_list = raw_part_list.to_sr_part_list(Some(list_name)); - Self { part_list } + let data = raw_part_list.to_sr_part_list(Some(list_name)); + Self { data } } fn as_dict(&self) -> HashMap { - self.part_list.cache.iter().map(|(k, v)| (k.clone(), PySR1PartType::new(v.clone()))).collect() + self.data.get_cache().iter().map(|(k, v)| (k.clone(), PySR1PartType::new(v.clone()))).collect() } - fn get_part_type(&mut self, name: String) -> Option { - let part_type = self.part_list.cache.get(&name); + fn get_part_type(&self, name: String) -> Option { + let part_type = self.data.get_part_type(name.clone()); if let Some(part_type) = part_type { Some(PySR1PartType::new(part_type.clone())) } else { @@ -94,7 +94,7 @@ pub mod data { // 左下角,右上角 let mut max_box = get_max_box(&self.ship.parts, &self.part_list); todo!(); - img_pos + // img_pos } fn get_name(&self) -> String { self.ship.name.clone() } @@ -111,12 +111,6 @@ pub mod translate { use pyo3::prelude::*; use pyo3::types::PyDict; - #[derive(Clone)] - pub enum BoolString { - Bool(bool), - String(String), - } - #[pyclass] #[pyo3(name = "TranslateConfig_rs")] #[pyo3(text_signature = "(language, raise_error = False, replace_normal = False, add_error = False, is_result = False, keep_get = False)")] diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs index 1fe6e46..9e6f075 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/sr1_data.rs @@ -124,7 +124,7 @@ pub mod part_list { #[inline] pub fn to_damage(&self) -> crate::types::sr1::Damage { crate::types::sr1::Damage { - disconnect: self.disconnect, + disconnect: self.disconnect.to_owned(), explode: self.explode.to_owned(), explosion_power: self.explosion_power.unwrap_or(100), explosion_size: self.explosion_size.unwrap_or(100), @@ -299,9 +299,9 @@ pub mod part_list { description: self.description.clone(), sprite: self.sprite.clone(), p_type: self.r#type, - mass: self.mass, - width: self.width, - height: self.height, + mass: self.mass.to_owned(), + width: self.width.to_owned(), + height: self.height.to_owned(), friction: self.friction.unwrap_or(0.0), category: self.category.clone().unwrap_or("".to_string()), ignore_editor_intersections: self.ignore_editor_intersections.unwrap_or(false), @@ -419,9 +419,8 @@ pub mod ship { pub engine: Option, #[serde(rename = "Pod")] pub pod: Option, - #[serde(rename = "partType")] - pub part_type: SR1PartTypeEnum, + pub part_type_id: String, pub id: i64, pub x: f64, pub y: f64, @@ -519,58 +518,28 @@ pub mod ship { pub child_part: i64, } + impl Part { + /// 根据 Part 的原始数据猜测 Part 的类型 + /// jundroo 我日你先人 + fn guess_part_type(&self) -> SR1PartTypeEnum { todo!() } + } + impl SR1PartDataTrait for Part { fn to_sr_part_data(&self) -> SR1PartData { - let attr = match self.part_type { - SR1PartTypeEnum::tank => SR1PartDataAttr::Tank { - fuel: if let Some(tank) = &self.tank { tank.fuel } else { 0_f64 }, - }, - SR1PartTypeEnum::engine => SR1PartDataAttr::Engine { - fuel: if let Some(engine) = &self.engine { engine.fuel } else { 0_f64 }, - }, - SR1PartTypeEnum::solar => SR1PartDataAttr::Solar { - extension: self.extension.unwrap_or(0_f64), - }, - SR1PartTypeEnum::parachute => SR1PartDataAttr::Parachute { - chute_x: self.chute_x.unwrap_or(0_f64), - chute_y: self.chute_y.unwrap_or(0_f64), - chute_angle: self.chute_angle.unwrap_or(0_f64), - chute_height: self.chute_height.unwrap_or(0_f64), - inflate: i8_to_bool(self.inflate.unwrap_or(0_i8)), - inflation: i8_to_bool(self.inflation.unwrap_or(0_i8)), - deployed: i8_to_bool(self.deployed.unwrap_or(0_i8)), - rope: i8_to_bool(self.rope.unwrap_or(0_i8)), - }, - SR1PartTypeEnum::pod => { - let pod = self.pod.as_ref().unwrap(); // 一定是有的,别问我为什么 - let mut steps = Vec::new(); - for step in &pod.stages.steps { - let mut activates = Vec::new(); - for active in &step.activates { - activates.push((active.id, i8_to_bool(active.moved))) - } - steps.push(activates) - } - SR1PartDataAttr::Pod { - name: pod.name.clone(), - throttle: pod.throttle, - current_stage: pod.stages.current_stage, - steps, - } - } - _ => SR1PartDataAttr::None, - }; + let attr = SR1PartDataAttr::from_raw(&self, None, true); + let part_type = attr.get_part_type(); SR1PartData { attr, - x: self.x, - y: self.y, - id: self.id, - angle: self.angle, - angle_v: self.angle_v, + x: self.x.to_owned(), + y: self.y.to_owned(), + id: self.id.to_owned(), + angle: self.angle.to_owned(), + angle_v: self.angle_v.to_owned(), flip_x: i8_to_bool(self.flip_x.unwrap_or(0_i8)), flip_y: i8_to_bool(self.flip_y.unwrap_or(0_i8)), - editor_angle: self.editor_angle, - part_type: self.part_type, + editor_angle: self.editor_angle.to_owned(), + part_type, + part_type_id: self.part_type_id.clone(), active: i8_to_bool(self.activated.unwrap_or(0_i8)), explode: i8_to_bool(self.exploded.unwrap_or(0_i8)), } @@ -588,8 +557,6 @@ pub mod ship { } let disconnected = match &self.disconnected { Some(disconnect) => { - // let mut disconnect_parts = Vec::new(); - let mut disconnect_parts = Vec::new(); for disconnected_part in &disconnect.parts { let mut parts_vec = Vec::new(); @@ -611,8 +578,8 @@ pub mod ship { description: "".to_string(), parts, connections, - lift_off: i8_to_bool(self.lift_off), - touch_ground: i8_to_bool(self.touch_ground), + lift_off: i8_to_bool(self.lift_off.to_owned()), + touch_ground: i8_to_bool(self.touch_ground.to_owned()), disconnected, } } diff --git a/mods/dr_game/Difficult_Rocket_rs/src/src/types.rs b/mods/dr_game/Difficult_Rocket_rs/src/src/types.rs index c96b825..6bfe573 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/src/types.rs +++ b/mods/dr_game/Difficult_Rocket_rs/src/src/types.rs @@ -7,8 +7,8 @@ */ pub mod sr1 { + use std::cell::{Cell, RefCell}; use std::collections::HashMap; - use std::fs; use super::math::{Edge, Shape}; use crate::sr1_data::part_list::Damage as RawDamage; @@ -70,6 +70,22 @@ pub mod sr1 { } } + #[inline] + pub fn option_i8_to_option_bool(i: Option) -> Option { + match i { + Some(i) => Some(i8_to_bool(i)), + None => None, + } + } + + #[inline] + pub fn option_bool_to_option_i8(b: Option) -> Option { + match b { + Some(b) => Some(bool_to_i8(b)), + None => None, + } + } + #[derive(Debug, Copy, Clone)] pub enum SR1PartTypeAttr { Tank { @@ -122,10 +138,10 @@ pub mod sr1 { impl Damage { pub fn to_raw_damage(&self) -> RawDamage { RawDamage { - disconnect: self.disconnect, - explode: self.explode, - explosion_power: Some(self.explosion_power), - explosion_size: Some(self.explosion_size), + disconnect: self.disconnect.to_owned(), + explode: self.explode.to_owned(), + explosion_power: Some(self.explosion_power.to_owned()), + explosion_size: Some(self.explosion_size.to_owned()), } } } @@ -181,38 +197,49 @@ pub mod sr1 { #[derive(Debug, Clone)] pub struct SR1PartList { pub types: Vec, - pub cache: HashMap, + pub cache: RefCell>>, pub name: String, } impl SR1PartList { #[inline] pub fn new(name: String, types: Vec) -> SR1PartList { - let mut map = HashMap::new(); - for part in types.iter() { - map.insert(part.id.clone(), part.clone()); + SR1PartList { + types, + cache: RefCell::new(None), + name, } - SR1PartList { types, cache: map, name } } #[inline] pub fn from_file(file_name: String) -> Option { if let Some(raw_list) = RawPartList::from_file(file_name) { let sr_list = raw_list.to_sr_part_list(None); - let mut map = HashMap::new(); - for part in sr_list.types.iter() { - map.insert(part.id.clone(), part.clone()); - } + return Some(sr_list); } None } - #[inline] - pub fn get_part_type(self, type_name: String) -> Option { - if let Some(part) = self.cache.get(&type_name) { - return Some(part.clone()); + pub fn get_cache(&self) -> HashMap { + let mut cache = self.cache.borrow_mut(); + if cache.is_none() { + let mut map = HashMap::new(); + for part in self.types.iter() { + map.insert(part.id.to_owned(), part.to_owned()); + } + *cache = Some(map); + self.cache.replace(cache.to_owned()); + } + cache.to_owned().unwrap() + } + + #[inline] + pub fn get_part_type(&self, type_name: String) -> Option { + let cache = self.get_cache(); + match cache.get(&type_name) { + Some(part) => Some(part.to_owned()), + None => None, } - None } pub fn part_types_new(part_types: Vec, name: Option) -> Self { @@ -269,9 +296,9 @@ pub mod sr1 { let tank: Option = match &self.attr { Some(attr) => match attr { SR1PartTypeAttr::Tank { fuel, dry_mass, fuel_type } => Some(Tank { - fuel: *fuel, - dry_mass: *dry_mass, - fuel_type: Some(*fuel_type), + fuel: fuel.to_owned(), + dry_mass: dry_mass.to_owned(), + fuel_type: Some(fuel_type.to_owned()), }), _ => None, }, @@ -287,12 +314,12 @@ pub mod sr1 { fuel_type, throttle_exponential, } => Some(Engine { - power: *power, - consumption: *consumption, - throttle_exponential: Some(*throttle_exponential), - size: *size, - turn: *turn, - fuel_type: Some(*fuel_type), + power: power.to_owned(), + consumption: consumption.to_owned(), + throttle_exponential: Some(throttle_exponential.to_owned()), + size: size.to_owned(), + turn: turn.to_owned(), + fuel_type: Some(fuel_type.to_owned()), }), _ => None, }, @@ -301,9 +328,9 @@ pub mod sr1 { let rcs: Option = match &self.attr { Some(attr) => match attr { SR1PartTypeAttr::Rcs { power, consumption, size } => Some(Rcs { - power: *power, - consumption: *consumption, - size: *size, + power: power.to_owned(), + consumption: consumption.to_owned(), + size: size.to_owned(), }), _ => None, }, @@ -311,7 +338,9 @@ pub mod sr1 { }; let solar: Option = match &self.attr { Some(attr) => match attr { - SR1PartTypeAttr::Solar { charge_rate } => Some(Solar { charge_rate: *charge_rate }), + SR1PartTypeAttr::Solar { charge_rate } => Some(Solar { + charge_rate: charge_rate.to_owned(), + }), _ => None, }, _ => None, @@ -326,12 +355,12 @@ pub mod sr1 { length_speed, width, } => Some(Lander { - max_angle: *max_angle, - min_length: *min_length, - max_length: *max_length, - angle_speed: Some(*angle_speed), - length_speed: Some(*length_speed), - width: *width, + max_angle: max_angle.to_owned(), + min_length: min_length.to_owned(), + max_length: max_length.to_owned(), + angle_speed: Some(angle_speed.to_owned()), + length_speed: Some(length_speed.to_owned()), + width: width.to_owned(), }), _ => None, }, @@ -353,19 +382,19 @@ pub mod sr1 { description: self.description.clone(), sprite: self.sprite.clone(), r#type: self.p_type.clone(), - mass: self.mass, - width: self.width, - height: self.height, - friction: Some(self.friction), + mass: self.mass.to_owned(), + width: self.width.to_owned(), + height: self.height.to_owned(), + friction: Some(self.friction.to_owned()), category: Some(self.category.clone()), - ignore_editor_intersections: Some(self.ignore_editor_intersections), - disable_editor_rotation: Some(self.disable_editor_rotation), - can_explode: Some(self.can_explode), - cover_height: Some(self.cover_height), - sandbox_only: Some(self.sandbox_only), - drag: Some(self.drag), - hidden: Some(self.hidden), - buoyancy: Some(self.buoyancy), + ignore_editor_intersections: Some(self.ignore_editor_intersections.to_owned()), + disable_editor_rotation: Some(self.disable_editor_rotation.to_owned()), + can_explode: Some(self.can_explode.to_owned()), + cover_height: Some(self.cover_height.to_owned()), + sandbox_only: Some(self.sandbox_only.to_owned()), + drag: Some(self.drag.to_owned()), + hidden: Some(self.hidden.to_owned()), + buoyancy: Some(self.buoyancy.to_owned()), damage: Some(self.damage.to_raw_damage()), tank, engine, @@ -384,94 +413,94 @@ pub mod sr1 { #[inline] fn to_raw_part_data(&self) -> RawPartData { - let tank = match &self.attr { - SR1PartDataAttr::Tank { fuel } => Some(RawTank { fuel: *fuel }), - _ => None, + let (tank, engine) = if let Some(fuel) = &self.attr.fuel { + match self.part_type { + SR1PartTypeEnum::tank => (Some(RawTank { fuel: fuel.to_owned() }), None), + SR1PartTypeEnum::engine => (None, Some(RawEngine { fuel: fuel.to_owned() })), + _ => (None, None), + } + } else { + (None, None) }; - let engine = match &self.attr { - SR1PartDataAttr::Engine { fuel } => Some(RawEngine { fuel: *fuel }), - _ => None, - }; - let pod = match &self.attr { - SR1PartDataAttr::Pod { - name, - throttle, - current_stage, - steps, - } => Some({ + // let pod = match &self.attr { + // SR1PartDataAttr::Pod { + // name, + // throttle, + // current_stage, + // steps, + // } => Some({ + // let mut actives = Vec::new(); + // for step in steps { + // let mut steps_ = Vec::new(); + // for active in step { + // steps_.push(RawActivate { + // id: active.0, + // moved: bool_to_i8(active.1), + // }); + // } + // actives.push(RawStep { activates: steps_ }); + // } + // let stages = RawStaging { + // current_stage: *current_stage, + // steps: actives, + // }; + // RawPod { + // name: name.clone(), + // throttle: *throttle, + // stages, + // } + // }), + // _ => None, + // }; + let pod = match (&self.attr.name, &self.attr.throttle, &self.attr.current_stage, &self.attr.steps) { + (Some(name), Some(throttle), Some(current_stage), Some(steps)) => Some({ let mut actives = Vec::new(); for step in steps { let mut steps_ = Vec::new(); for active in step { steps_.push(RawActivate { - id: active.0, - moved: bool_to_i8(active.1), + id: active.0.to_owned(), + moved: bool_to_i8(active.1.to_owned()), }); } actives.push(RawStep { activates: steps_ }); } let stages = RawStaging { - current_stage: *current_stage, + current_stage: current_stage.to_owned(), steps: actives, }; RawPod { name: name.clone(), - throttle: *throttle, + throttle: throttle.to_owned(), stages, } }), _ => None, }; - let (chute_x, chute_y, chute_angle, chute_height, inflate, inflation, deployed, rope) = match &self.attr { - SR1PartDataAttr::Parachute { - chute_x, - chute_y, - chute_angle, - chute_height, - inflate, - inflation, - deployed, - rope, - } => ( - Some(*chute_x), - Some(*chute_y), - Some(*chute_angle), - Some(*chute_height), - Some(bool_to_i8(*inflate)), - Some(bool_to_i8(*inflation)), - Some(bool_to_i8(*deployed)), - Some(bool_to_i8(*rope)), - ), - _ => (None, None, None, None, None, None, None, None), - }; - let extension = match &self.attr { - SR1PartDataAttr::Solar { extension } => Some(*extension), - _ => None, - }; RawPartData { tank, engine, pod, - part_type: self.part_type, - id: self.id, - x: self.x, - y: self.y, - editor_angle: self.editor_angle, - angle: self.angle, - angle_v: self.angle_v, - flip_x: Some(bool_to_i8(self.flip_x)), - flip_y: Some(bool_to_i8(self.flip_y)), - chute_x, - chute_y, - chute_height, - extension, - inflate, - inflation, - exploded: Some(bool_to_i8(self.explode)), - rope, - chute_angle, - activated: Some(bool_to_i8(self.active)), - deployed, + part_type_id: self.part_type_id.clone(), + id: self.id.to_owned(), + x: self.x.to_owned(), + y: self.y.to_owned(), + editor_angle: self.editor_angle.to_owned(), + angle: self.angle.to_owned(), + angle_v: self.angle_v.to_owned(), + flip_x: Some(bool_to_i8(self.flip_x.to_owned())), + flip_y: Some(bool_to_i8(self.flip_y.to_owned())), + chute_x: self.attr.chute_x.to_owned(), + chute_y: self.attr.chute_y.to_owned(), + chute_height: self.attr.chute_height.to_owned(), + extension: self.attr.extension.to_owned(), + inflate: option_bool_to_option_i8(self.attr.inflate.to_owned()), + inflation: option_bool_to_option_i8(self.attr.inflation.to_owned()), + exploded: Some(bool_to_i8(self.explode.to_owned())), + rope: option_bool_to_option_i8(self.attr.rope.to_owned()), + chute_angle: self.attr.chute_angle.to_owned(), + activated: Some(bool_to_i8(self.active.to_owned())), + deployed: option_bool_to_option_i8(self.attr.deployed.to_owned()), } } } @@ -488,6 +517,7 @@ pub mod sr1 { pub angle_v: f64, // 状态属性 pub part_type: SR1PartTypeEnum, + pub part_type_id: String, pub editor_angle: i32, pub flip_x: bool, pub flip_y: bool, @@ -498,11 +528,11 @@ pub mod sr1 { impl SR1PartData { pub fn get_box(&self, part_type: &SR1PartType) -> (f64, f64, f64, f64) { - let width = part_type.width; - let height = part_type.height; - let radius = self.angle; + let width = part_type.width.to_owned(); + let height = part_type.height.to_owned(); + let radius = self.angle.to_owned(); let mut shape = Shape::new_width_height(width as f64, height as f64, Some(radius)); - shape.move_xy(Some(self.x), Some(self.y)); + shape.move_xy(Some(self.x.to_owned()), Some(self.y.to_owned())); let mut pos_box = (0_f64, 0_f64, 0_f64, 0_f64); match shape.bounds[0] { Edge::OneTimeLine(line) => { @@ -523,33 +553,145 @@ pub mod sr1 { } #[derive(Debug, Clone)] - pub enum SR1PartDataAttr { - Tank { - fuel: f64, - }, - Engine { - fuel: f64, - }, - Pod { - name: String, - throttle: f64, - current_stage: u32, - steps: Vec>, - }, - Solar { - extension: f64, - }, - Parachute { - chute_x: f64, - chute_y: f64, - chute_angle: f64, - chute_height: f64, - inflate: bool, - inflation: bool, - deployed: bool, - rope: bool, - }, - None, + pub struct SR1PartDataAttr { + // Tank | Engine + pub fuel: Option, + // Pod + pub name: Option, + pub throttle: Option, + pub current_stage: Option, + pub steps: Option>>, + // Solar + pub extension: Option, + // Parachute + pub chute_x: Option, + pub chute_y: Option, + pub chute_height: Option, + pub chute_angle: Option, + pub inflate: Option, + pub inflation: Option, + pub deployed: Option, + pub rope: Option, + // part_type + pub part_type: Cell>, + } + + impl SR1PartDataAttr { + pub fn guess_type(&self) -> SR1PartTypeEnum { + if let Some(part_type) = self.part_type.get() { + return part_type; + } + if self.fuel.is_some() { + self.part_type.set(Some(SR1PartTypeEnum::tank)); + return self.part_type.get().unwrap(); + } + if self.name.is_some() { + self.part_type.set(Some(SR1PartTypeEnum::pod)); + return self.part_type.get().unwrap(); + } + if self.extension.is_some() { + self.part_type.set(Some(SR1PartTypeEnum::solar)); + return self.part_type.get().unwrap(); + } + if self.chute_x.is_some() { + self.part_type.set(Some(SR1PartTypeEnum::parachute)); + return self.part_type.get().unwrap(); + } + SR1PartTypeEnum::strut // 默认为 Strut 开摆 + } + + pub fn get_part_type(&self) -> SR1PartTypeEnum { + if let Some(part_type) = self.part_type.get() { + return part_type; + } + self.guess_type() + } + pub fn new( + fuel: Option, + name: Option, + throttle: Option, + current_stage: Option, + steps: Option>>, + extension: Option, + chute_x: Option, + chute_y: Option, + chute_height: Option, + chute_angle: Option, + inflate: Option, + inflation: Option, + deployed: Option, + rope: Option, + part_type: Option, + ) -> Self { + SR1PartDataAttr { + fuel, + name, + throttle, + current_stage, + steps, + extension, + chute_x, + chute_y, + chute_height, + chute_angle, + inflate, + inflation, + deployed, + rope, + part_type: Cell::new(part_type), + } + } + + pub fn from_raw(raw_data: &RawPartData, part_type: Option, guess: bool) -> Self { + let fuel = if let Some(tank) = &raw_data.tank { + Some(tank.fuel.to_owned()) + } else if let Some(engine) = &raw_data.engine { + Some(engine.fuel.to_owned()) + } else { + None + }; + let (name, throttle, current_stage, steps) = if let Some(pod) = &raw_data.pod { + ( + Some(pod.name.to_owned()), + Some(pod.throttle.to_owned()), + Some(pod.stages.current_stage.to_owned()), + Some({ + let mut steps = Vec::new(); + for step in &pod.stages.steps { + let mut step_vec = Vec::new(); + for act in &step.activates { + step_vec.push((act.id.to_owned(), i8_to_bool(act.moved.to_owned()))); + } + steps.push(step_vec); + } + steps + }), + ) + } else { + (None, None, None, None) + }; + let results = SR1PartDataAttr { + fuel, + name, + throttle, + current_stage, + steps, + extension: raw_data.extension.to_owned(), + chute_x: raw_data.chute_x.to_owned(), + chute_y: raw_data.chute_y.to_owned(), + chute_height: raw_data.chute_height.to_owned(), + chute_angle: raw_data.chute_angle.to_owned(), + inflate: option_i8_to_option_bool(raw_data.inflate.to_owned()), + inflation: option_i8_to_option_bool(raw_data.inflation.to_owned()), + deployed: option_i8_to_option_bool(raw_data.deployed.to_owned()), + rope: option_i8_to_option_bool(raw_data.rope.to_owned()), + part_type: Cell::new(part_type), + }; + if guess & results.part_type.get().is_none() { + results.guess_type(); + } + results + } } #[derive(Debug, Clone)] @@ -619,8 +761,8 @@ pub mod sr1 { parts: RawParts { parts }, connects: connections, version: 1, - lift_off: bool_to_i8(self.lift_off), - touch_ground: bool_to_i8(self.touch_ground), + lift_off: bool_to_i8(self.lift_off.to_owned()), + touch_ground: bool_to_i8(self.touch_ground.to_owned()), disconnected, } } @@ -658,8 +800,8 @@ pub mod math { #[inline] pub fn distance(&self, other: &Point2D) -> f64 { - let dx = (other.x - self.x).powf(2.0); - let dy = (other.y - self.y).powf(2.0); + let dx = (other.x.to_owned() - self.x.to_owned()).powf(2.0); + let dy = (other.y.to_owned() - self.y.to_owned()).powf(2.0); (dx + dy).powf(0.5) } diff --git a/mods/dr_game/__init__.py b/mods/dr_game/__init__.py index cb7d047..79ab6f6 100644 --- a/mods/dr_game/__init__.py +++ b/mods/dr_game/__init__.py @@ -20,6 +20,7 @@ DR_rust_version = Version("0.2.7.0") # DR_mod 的 Rust 编写部分的兼容版 class _DR_mod_runtime(Options): + name = 'DR mod runtime' use_DR_rust: bool = True DR_rust_available: bool = False From 4de43f27ff796c0d001e4464aa06fa90d6607e01 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 01:41:03 +0800 Subject: [PATCH 14/20] add dr_rs build action --- .github/workflows/dr_rs.yml | 83 +++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 .github/workflows/dr_rs.yml diff --git a/.github/workflows/dr_rs.yml b/.github/workflows/dr_rs.yml new file mode 100644 index 0000000..dc30aef --- /dev/null +++ b/.github/workflows/dr_rs.yml @@ -0,0 +1,83 @@ +# 名称 +name: Build + +# 运行条件 +on: + # 触发条件 + push: + pull_request: + workflow_dispatch: + +# 主任务 +jobs: + build: + if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build skip]') == false }} + # 全都要! + strategy: + fail-fast: false + matrix: + os: [macos-latest, ubuntu-latest, windows-latest] + python-version: ["3.8", "3.10"] # 3.11 still not support by nuitka + + runs-on: ${{ matrix.os }} + + steps: + # Check-out repository + - name: Check out + uses: actions/checkout@v3 + + # 获取短 sha + - name: Get short commit sha + id: get_short_sha + shell: pwsh + run: | + # short_sha=$(echo ${GITHUB_SHA} | cut -c1-7) + # echo "short_sha=$short_sha" >> $GITHUB_OUTPUT + # echo $GITHUB_OUTPUT + $short_sha = Write-Output $env:GITHUB_SHA + $short_sha = $short_sha.substring(1,7) + Write-Output $short_sha + Write-Output "short_sha=$short_sha" >> $env:GITHUB_ENV + + + # 安装 Python + - name: Setup Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} # 为了支持 win7 我还是得用 3.8 + architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified + cache: 'pip' + cache-dependency-path: | + **/requirement-dev.txt + .github/workflows/requirement.txt + + # 安装依赖 + - name: Install env + run: | + pip install -r requirement-dev.txt + + # 提取 DR 版本和其他信息 + - name: Display Difficult-Rocket info + id: DR_info + shell: pwsh + run: | + $infos = python .github/workflows/get_info.py -github + Write-Output $infos >> $env:GITHUB_ENV + python .github/workflows/get_info.py + + # 编译 dr_rs + - name: Build dr_rs + shell: pwsh + run: | + Set-Location mods/dr_game/Difficult_Rocket_rs/src + python setup.py build + python post_build.py + python setup.py clean + + # Uploads artifact + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + name: DR_rs${{env.DR_version}}-${{runner.os}}${{matrix.python-version}}-Build.${{github.run_number}}+${{env.short_sha}} + path: | + mods/dr_game/Difficult_Rocket_rs/lib From e914930a0f6ff4989b55a77dceeda1f7ea2daa16 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 02:08:31 +0800 Subject: [PATCH 15/20] add nuitka build script --- libs/utils/nuitka.py | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 libs/utils/nuitka.py diff --git a/libs/utils/nuitka.py b/libs/utils/nuitka.py new file mode 100644 index 0000000..53f31d6 --- /dev/null +++ b/libs/utils/nuitka.py @@ -0,0 +1,56 @@ +# ------------------------------- +# Difficult Rocket +# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com +# All rights reserved +# ------------------------------- + +# 用于使用 nuitka 构建 DR +import platform +import traceback +from pathlib import Path +from typing import List + +from Difficult_Rocket.api.types import Options +from libs.MCDR.version import Version + + +class Status(Options): + name = 'Nuitka Build Status' + + output_path: Path = Path("./build/nuitka") + src_file: Path = Path('DR.py') + + # 以下为 nuitka 的参数 + use_lto: bool = False + use_clang: bool = True + use_msvc: bool = True + standalone: bool = True + company_name: str = 'tool-shenjack-workshop' + product_name: str = 'Difficult-Rocket' + product_version: Version + file_version: Version + icon_path: Path = Path('textures/icon.png') + + def init(self, **kwargs) -> None: + # 非 windows 平台不使用 msvc + if platform.system() != 'Windows': + self.use_msvc = False + + def load_file(self) -> bool: + try: + from Difficult_Rocket import DR_runtime + self.product_version = DR_runtime.DR_version + self.file_version = DR_runtime.Build_version + return True + except ImportError: + traceback.print_exc() + return False + + def gen_subprocess_cmd(self) -> List[str]: + # macos 和 非 macos icon 参数不同 + if platform.system() == 'Darwin': + icon_cmd = f"--macos-app-icon={self.icon_path.absolute()}" + elif platform.system() == 'Windows': + icon_cmd = f"--windows-icon-from-ico={self.icon_path.absolute()}" + else: + icon_cmd = "" From 0e5d0d9117b96c3ba2218e88547a4d857f6c851f Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 02:08:40 +0800 Subject: [PATCH 16/20] update vscode config --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 670301a..f4b6f22 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "rust-analyzer.linkedProjects": [ - "libs/Difficult_Rocket_rs/src/Cargo.toml", + "mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml", "libs/pyglet_rs/src/Cargo.toml", ], "python.analysis.extraPaths": [ From 697fdd484e6e3bfa172cbba7a562282729ba1016 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 02:09:44 +0800 Subject: [PATCH 17/20] rename build project --- .github/workflows/dr_rs.yml | 2 +- .github/workflows/nuitka.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dr_rs.yml b/.github/workflows/dr_rs.yml index dc30aef..5b179f1 100644 --- a/.github/workflows/dr_rs.yml +++ b/.github/workflows/dr_rs.yml @@ -10,7 +10,7 @@ on: # 主任务 jobs: - build: + build-dr-rs: if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build skip]') == false }} # 全都要! strategy: diff --git a/.github/workflows/nuitka.yml b/.github/workflows/nuitka.yml index 433dcd1..d4ad2af 100644 --- a/.github/workflows/nuitka.yml +++ b/.github/workflows/nuitka.yml @@ -10,7 +10,7 @@ on: # 主任务 jobs: - build: + build-nuitka: if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build skip]') == false }} # 全都要! strategy: From 55bbd24480f25b505d4e01802ea01ff75c5be447 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 02:15:57 +0800 Subject: [PATCH 18/20] rename again --- .github/workflows/dr_rs.yml | 2 +- .github/workflows/nuitka.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dr_rs.yml b/.github/workflows/dr_rs.yml index 5b179f1..450a08d 100644 --- a/.github/workflows/dr_rs.yml +++ b/.github/workflows/dr_rs.yml @@ -1,5 +1,5 @@ # 名称 -name: Build +name: Build DR rs # 运行条件 on: diff --git a/.github/workflows/nuitka.yml b/.github/workflows/nuitka.yml index d4ad2af..702a1d8 100644 --- a/.github/workflows/nuitka.yml +++ b/.github/workflows/nuitka.yml @@ -1,5 +1,5 @@ # 名称 -name: Build +name: Build DR nuitka # 运行条件 on: From e9d3a4a5553532ffdfd2ec26e9211c19d21eb55f Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 02:24:08 +0800 Subject: [PATCH 19/20] update DR_rs dependence [build skip] --- .github/workflows/nuitka.yml | 2 +- .../Difficult_Rocket_rs/src/Cargo.lock | 32 +++++++++---------- .../Difficult_Rocket_rs/src/Cargo.toml | 6 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/nuitka.yml b/.github/workflows/nuitka.yml index 702a1d8..08980f9 100644 --- a/.github/workflows/nuitka.yml +++ b/.github/workflows/nuitka.yml @@ -11,7 +11,7 @@ on: # 主任务 jobs: build-nuitka: - if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build skip]') == false }} + if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build rs skip]') == false }} # 全都要! strategy: fail-fast: false diff --git a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock index 039ffc5..1c583e2 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock +++ b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.lock @@ -343,9 +343,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb848f80438f926a9ebddf0a539ed6065434fd7aae03a89312a9821f81b8501" +checksum = "e3b1ac5b3731ba34fdaa9785f8d74d17448cd18f30cf19e0c7e7b1fdb5272109" dependencies = [ "cfg-if", "indoc", @@ -360,9 +360,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98a42e7f42e917ce6664c832d5eee481ad514c98250c49e0b03b20593e2c7ed0" +checksum = "9cb946f5ac61bb61a5014924910d936ebd2b23b705f7a4a3c40b05c720b079a3" dependencies = [ "once_cell", "target-lexicon", @@ -370,9 +370,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0707f0ab26826fe4ccd59b69106e9df5e12d097457c7b8f9c0fd1d2743eec4d" +checksum = "fd4d7c5337821916ea2a1d21d1092e8443cf34879e53a0ac653fbb98f44ff65c" dependencies = [ "libc", "pyo3-build-config", @@ -380,9 +380,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978d18e61465ecd389e1f235ff5a467146dc4e3c3968b90d274fe73a5dd4a438" +checksum = "a9d39c55dab3fc5a4b25bbd1ac10a2da452c4aca13bb450f22818a002e29648d" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -392,9 +392,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.18.2" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e0e1128f85ce3fca66e435e08aa2089a2689c1c48ce97803e13f63124058462" +checksum = "97daff08a4c48320587b5224cc98d609e3c27b6d437315bd40b605c98eeb5918" dependencies = [ "proc-macro2", "quote", @@ -475,9 +475,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.159" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] @@ -496,9 +496,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", @@ -695,6 +695,6 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "xml-rs" -version = "0.8.4" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" +checksum = "dc95a04ea24f543cd9be5aab44f963fa35589c99e18415c38fb2b17e133bf8d2" diff --git a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml index 9ac383d..b563714 100644 --- a/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml +++ b/mods/dr_game/Difficult_Rocket_rs/src/Cargo.toml @@ -23,11 +23,11 @@ codegen-units = 1 #features = ["serialize"] [dependencies.serde] -version = "1.0.157" +version = "1.0.163" features = ["derive"] [dependencies.xml-rs] -version = "0.8.4" +version = "0.8.10" [dependencies.serde-xml-rs] version = "0.6.0" @@ -37,5 +37,5 @@ version = "0.17.2" features = ["simd-stable"] [dependencies.pyo3] -version = "0.18.1" +version = "0.18.3" features = ["extension-module"] From 703f8eb8f7a4bcff15912a319168b7419cb7fe2b Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 14 May 2023 02:26:11 +0800 Subject: [PATCH 20/20] wrong file [build skip] [docs skip] --- .github/workflows/dr_rs.yml | 2 +- .github/workflows/nuitka.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dr_rs.yml b/.github/workflows/dr_rs.yml index 450a08d..8c09385 100644 --- a/.github/workflows/dr_rs.yml +++ b/.github/workflows/dr_rs.yml @@ -11,7 +11,7 @@ on: # 主任务 jobs: build-dr-rs: - if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build skip]') == false }} + if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build rs skip]') == false }} # 全都要! strategy: fail-fast: false diff --git a/.github/workflows/nuitka.yml b/.github/workflows/nuitka.yml index 08980f9..702a1d8 100644 --- a/.github/workflows/nuitka.yml +++ b/.github/workflows/nuitka.yml @@ -11,7 +11,7 @@ on: # 主任务 jobs: build-nuitka: - if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build rs skip]') == false }} + if: ${{!startsWith(github.event.ref, 'refs/tags/') && contains(github.event.head_commit.message, '[build skip]') == false }} # 全都要! strategy: fail-fast: false