啥时候能有自动生成change log的东西啊喂(

This commit is contained in:
shenjack 2023-05-03 00:08:26 +08:00
parent 93b6f70dab
commit ca9b928658
12 changed files with 191 additions and 59 deletions

View File

@ -20,7 +20,7 @@ from libs.MCDR.version import Version
game_version = Version("0.7.2.2") # 游戏版本 game_version = Version("0.7.2.2") # 游戏版本
build_version = Version("1.2.1.0") # 编译文件版本(与游戏本体无关) build_version = Version("1.2.1.0") # 编译文件版本(与游戏本体无关)
Api_version = Version("0.0.2.0") # API 版本 Api_version = Version("0.1.0.0") # API 版本
__version__ = game_version __version__ = game_version
long_version: int = 15 long_version: int = 15

View File

@ -17,15 +17,10 @@ if TYPE_CHECKING:
else: else:
Game = TypeVar("Game") Game = TypeVar("Game")
ClientWindow = TypeVar("ClientWindow") ClientWindow = TypeVar("ClientWindow")
from Difficult_Rocket import DR_runtime from Difficult_Rocket import DR_runtime
from ..types import Options from ..types import Options
"""
加载mod时会更改的参数
这里的只是范例,实际加载时会根据mod配置修改
"""
RequireVersion = Tuple[Version, Version] RequireVersion = Tuple[Version, Version]
# 第一个是最低兼容版本,第二个是最高兼容版本 # 第一个是最低兼容版本,第二个是最高兼容版本
# 例如: ("1.0.0", "1.1.0") 表示从1.0.0版本开始兼容,到1.1.0版本结束兼容 # 例如: ("1.0.0", "1.1.0") 表示从1.0.0版本开始兼容,到1.1.0版本结束兼容
@ -60,9 +55,10 @@ class ModInfo(Options):
config: Options = Options() # mod 配置存储 config: Options = Options() # mod 配置存储
old_mod: Optional["ModInfo"] = None # 旧的mod实例 old_mod: Optional["ModInfo"] = None # 旧的mod实例
def on_load(self, game: Game, old_self: Optional["ModInfo"] = None): def on_load(self, game: Game, old_self: Optional["ModInfo"] = None) -> bool:
""" 加载时调用 """ """ 加载时调用 """
print(f'Mod {self.mod_id} loaded') print(f'Mod {self.mod_id} loaded')
return True
def on_server_start(self, game: Game): def on_server_start(self, game: Game):
""" 服务器启动时调用 """ """ 服务器启动时调用 """

View File

@ -22,13 +22,15 @@ import multiprocessing
from io import StringIO from io import StringIO
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
if __name__ == '__main__': # been start will not run this if __name__ == '__main__': # been start will not run this
sys.path.append('/bin/libs') sys.path.append('/bin/libs')
sys.path.append('/bin') sys.path.append('/bin')
from Difficult_Rocket import client, server, DR_option, DR_runtime from Difficult_Rocket import client, server, DR_option, DR_runtime
if TYPE_CHECKING:
from Difficult_Rocket.api.mod import ModInfo
from Difficult_Rocket.crash import write_info_to_cache from Difficult_Rocket.crash import write_info_to_cache
from Difficult_Rocket.utils import tools from Difficult_Rocket.utils import tools
from Difficult_Rocket.utils.translate import tr from Difficult_Rocket.utils.translate import tr
@ -105,7 +107,7 @@ class Game:
self.logger.warning(tr().main.mod.load.faild.info().format(mod, tr().main.mod.load.faild.no_mod_class())) self.logger.warning(tr().main.mod.load.faild.info().format(mod, tr().main.mod.load.faild.no_mod_class()))
del mod_module # 释放内存 del mod_module # 释放内存
continue continue
mod_class = mod_module.mod_class mod_class: type(ModInfo) = mod_module.mod_class
mod_class = mod_class() mod_class = mod_class()
module.append(mod_class) module.append(mod_class)
self.logger.info(tr().main.mod.load.info().format(mod_class.mod_id, mod_class.version)) self.logger.info(tr().main.mod.load.info().format(mod_class.mod_id, mod_class.version))

View File

@ -7,8 +7,8 @@ fonts_folder = "libs/fonts"
[window] [window]
style = "None" style = "None"
width = 1191 width = 2571
height = 886 height = 1510
visible = true visible = true
gui_scale = 1 gui_scale = 1
caption = "Difficult Rocket v{DR_version}|DR_rs v{DR_Rust_get_version}" caption = "Difficult Rocket v{DR_version}|DR_rs v{DR_Rust_get_version}"

View File

@ -22,13 +22,27 @@
- [![Readme-gitee](https://img.shields.io/badge/Readme-中文(点我!)-blue.svg?style=flat-square)](../../README.md) - [![Readme-gitee](https://img.shields.io/badge/Readme-中文(点我!)-blue.svg?style=flat-square)](../../README.md)
- Using [SemVer 2.0.0](https://semver.org/) to manage version - Using [SemVer 2.0.0](https://semver.org/) to manage version
## 202305 DR `0.8.0.0` + DR_api `0.1.0.0` + 15 ## 202305 DR `0.8.0.0` + DR_api `0.1.0.0` + DR_rs `0.2.7.0` + 15
> 啊哈! mod 加载来啦! > 啊哈! mod 加载来啦!
> 啊啊啊啊啊 大重构 api > 啊啊啊啊啊 大重构 api
### DR_rs `0.2.7.0`
- `__init__.py`
- 添加了 `SR1Ship_rs` 的 typing
- `name`
- `description`
- `lift_off`
- `touch_ground`
- `img_pos() -> Tuple[int, int, int, int]`
- 导出了 `SR1Ship_rs`
- Exported `SR1Ship_rs`
- `types::SR1PartData`
- `get_box(&self, part_type: &SR1PartType) -> (f64, f64, f64, f64)`
- `types::SR1Ship`
- `from_file`
### Remove ### Remove
@ -82,6 +96,13 @@
### Mod Loader ### Mod Loader
- `ModInfo` - `ModInfo`
- `on_load(game: Game, old_self: Optional[ModInfo]) -> bool`
- `game`: Game 对象 用于存储 DR SDK 的信息
- `old_self`: 旧的 ModInfo 对象, 可以用于从上次加载中恢复信息
- 返回值: 是否加载成功
- `game`: Game object used to store information about the DR SDK
- `old_self`: Old ModInfo object, can be used to restore information from the last load
- Return value: Whether the load is successful
## 20230422 DR `0.7.2.2` + DR_rs `0.2.6.1` + DR_api `0.0.2.0` + 14 ## 20230422 DR `0.7.2.2` + DR_rs `0.2.6.1` + DR_api `0.0.2.0` + 14

View File

@ -40,22 +40,16 @@ if TYPE_CHECKING:
@property @property
def dx(self) -> float: ... def dx(self) -> float: ...
@property @property
def dy(self) -> float: ... def dy(self) -> float: ...
@property @property
def zoom(self) -> float: ... def zoom(self) -> float: ...
@property @property
def position(self) -> Tuple[float, float]: ... def position(self) -> Tuple[float, float]: ...
@dx.setter @dx.setter
def dx(self, value: float) -> None: ... def dx(self, value: float) -> None: ...
@dy.setter @dy.setter
def dy(self, value: float) -> None: ... def dy(self, value: float) -> None: ...
@zoom.setter @zoom.setter
def zoom(self, value: float) -> None: ... def zoom(self, value: float) -> None: ...
@ -93,3 +87,17 @@ if TYPE_CHECKING:
def as_dict(self) -> Dict[str, SR1PartType_rs]: ... def as_dict(self) -> Dict[str, SR1PartType_rs]: ...
def get_part_type(self, name: str) -> SR1PartType_rs: ... def get_part_type(self, name: str) -> SR1PartType_rs: ...
class SR1Ship_rs:
""" 用于高效且省内存的读取 SR1Ship """
@property
def name(self) -> str: ...
@property
def description(self) -> str: ...
@property
def lift_off(self) -> bool: ...
@property
def touch_ground(self) -> bool: ...
@property
def img_pos(self) -> Tuple[int, int, int, int]: ...
""" -x -y +x +y 左下右上 """

View File

@ -12,7 +12,7 @@ package_path = 'Difficult_Rocket_rs'
setup( setup(
name='Difficult_Rocket_rs', name='Difficult_Rocket_rs',
version="0.2.6.2", version="0.2.7.0",
author='shenjackyuanjie', author='shenjackyuanjie',
author_email='3695888@qq.com', author_email='3695888@qq.com',
rust_extensions=[RustExtension(target="Difficult_Rocket_rs.Difficult_Rocket_rs", rust_extensions=[RustExtension(target="Difficult_Rocket_rs.Difficult_Rocket_rs",

View File

@ -17,7 +17,7 @@ mod types;
use pyo3::prelude::*; use pyo3::prelude::*;
#[pyfunction] #[pyfunction]
fn get_version_str() -> String { "0.2.6.2".to_string() } fn get_version_str() -> String { "0.2.7.0".to_string() }
#[pyfunction] #[pyfunction]
fn test_call(py_obj: &PyAny) -> PyResult<bool> { fn test_call(py_obj: &PyAny) -> PyResult<bool> {
@ -39,6 +39,7 @@ fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_class::<render::camera::CameraRs>()?; m.add_class::<render::camera::CameraRs>()?;
m.add_class::<render::camera::CenterCameraRs>()?; m.add_class::<render::camera::CenterCameraRs>()?;
m.add_class::<render::screen::PartFrame>()?; m.add_class::<render::screen::PartFrame>()?;
m.add_class::<python::data::PySR1Ship>()?;
m.add_class::<python::data::PySR1PartList>()?; m.add_class::<python::data::PySR1PartList>()?;
m.add_class::<python::data::PySR1PartType>()?; m.add_class::<python::data::PySR1PartType>()?;
Ok(()) Ok(())

View File

@ -13,8 +13,8 @@ pub mod data {
use crate::sr1_data::part_list::RawPartList; use crate::sr1_data::part_list::RawPartList;
use crate::sr1_data::ship::RawShip; use crate::sr1_data::ship::RawShip;
use crate::types::sr1::{SR1PartData, SR1PartListTrait};
use crate::types::sr1::{SR1PartList, SR1PartType, SR1Ship}; use crate::types::sr1::{SR1PartList, SR1PartType, SR1Ship};
use crate::types::sr1::{SR1PartListTrait, SR1ShipTrait};
#[pyclass] #[pyclass]
#[pyo3(name = "SR1PartType_rs")] #[pyo3(name = "SR1PartType_rs")]
@ -70,6 +70,12 @@ pub mod data {
} }
} }
#[pyclass]
#[pyo3(name = "SR1PartData_rs")]
pub struct PySR1PartData {
pub data: SR1PartData,
}
#[pyclass] #[pyclass]
#[pyo3(name = "SR1Ship_rs")] #[pyo3(name = "SR1Ship_rs")]
#[pyo3(text_signature = "(file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip')")] #[pyo3(text_signature = "(file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip')")]
@ -82,11 +88,29 @@ pub mod data {
impl PySR1Ship { impl PySR1Ship {
#[new] #[new]
fn new(file_path: String, part_list: String, ship_name: String) -> Self { fn new(file_path: String, part_list: String, ship_name: String) -> Self {
let raw_ship: RawShip = RawShip::from_file(file_path).unwrap(); let ship = SR1Ship::from_file(file_path, Some(ship_name)).unwrap();
let ship = raw_ship.to_sr_ship(Some(ship_name));
let part_list = SR1PartList::from_file(part_list).unwrap(); let part_list = SR1PartList::from_file(part_list).unwrap();
Self { ship, part_list } Self { ship, part_list }
} }
fn get_img_pos(&self) -> (i64, i64, i64, i64) {
let mut img_pos = (0, 0, 0, 0);
// -x, -y, +x, +y
// 左下角,右上角
for part in self.ship.types.iter() {
// let part_box = part
todo!("get_img_pos")
}
img_pos
}
fn get_name(&self) -> String { self.ship.name.clone() }
fn get_description(&self) -> String { self.ship.description.clone() }
fn get_lift_off(&self) -> bool { self.ship.lift_off }
fn get_touch_ground(&self) -> bool { self.ship.touch_ground }
} }
} }

View File

@ -8,7 +8,9 @@
pub mod sr1 { pub mod sr1 {
use std::collections::HashMap; use std::collections::HashMap;
use std::fs;
use super::math::{Edge, Shape};
use crate::sr1_data::part_list::Damage as RawDamage; use crate::sr1_data::part_list::Damage as RawDamage;
use crate::sr1_data::part_list::{AttachPoint, AttachPoints, Engine, Lander, Rcs, Shape as RawShape, Solar, Tank}; use crate::sr1_data::part_list::{AttachPoint, AttachPoints, Engine, Lander, Rcs, Shape as RawShape, Solar, Tank};
use crate::sr1_data::part_list::{RawPartList, RawPartType, SR1PartTypeEnum}; use crate::sr1_data::part_list::{RawPartList, RawPartType, SR1PartTypeEnum};
@ -179,31 +181,49 @@ pub mod sr1 {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SR1PartList { pub struct SR1PartList {
pub types: Vec<SR1PartType>, pub types: Vec<SR1PartType>,
pub cache: Option<HashMap<String, SR1PartType>>, pub cache: HashMap<String, SR1PartType>,
pub name: String, pub name: String,
} }
impl SR1PartList { impl SR1PartList {
#[inline]
pub fn new(name: String, types: Vec<SR1PartType>) -> SR1PartList {
let mut map = HashMap::new();
for part in types.iter() {
map.insert(part.id.clone(), part.clone());
}
SR1PartList {
types,
cache: map,
name,
}
}
#[inline] #[inline]
pub fn from_file(file_name: String) -> Option<SR1PartList> { pub fn from_file(file_name: String) -> Option<SR1PartList> {
if let Some(raw_list) = RawPartList::from_file(file_name) { if let Some(raw_list) = RawPartList::from_file(file_name) {
return Some(raw_list.to_sr_part_list(None)); 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());
}
} }
None None
} }
#[inline] #[inline]
pub fn get_hash_map(&mut self) -> HashMap<String, SR1PartType> { pub fn get_part_type(self, type_name: String) -> Option<SR1PartType> {
if let Some(map) = &self.cache { if let Some(part) = self.cache.get(&type_name) {
return map.clone(); return Some(part.clone());
} }
let mut map = HashMap::new(); None
for part in self.types.iter() {
map.insert(part.id.clone(), part.clone());
} }
self.cache = Some(map.clone());
map pub fn part_types_new(part_types: Vec<SR1PartType>, name: Option<String>) -> Self {
SR1PartList::new(name.unwrap_or("NewPartList".to_string()), part_types)
} }
pub fn insert_part(&mut self, part: SR1PartType) -> () { self.types.insert(0, part); }
} }
pub trait SR1PartTypeData { pub trait SR1PartTypeData {
@ -226,17 +246,6 @@ pub mod sr1 {
fn to_raw_ship(&self) -> RawShip; fn to_raw_ship(&self) -> RawShip;
} }
impl SR1PartList {
#[inline]
pub fn new(name: String, types: Vec<SR1PartType>) -> Self { SR1PartList { name, cache: None, types } }
pub fn part_types_new(part_types: Vec<SR1PartType>, name: Option<String>) -> Self {
SR1PartList::new(name.unwrap_or("NewPartList".to_string()), part_types)
}
pub fn insert_part(&mut self, part: SR1PartType) -> () { self.types.insert(0, part); }
}
impl SR1PartListTrait for SR1PartList { impl SR1PartListTrait for SR1PartList {
fn to_sr_part_list(&self, name: Option<String>) -> SR1PartList { fn to_sr_part_list(&self, name: Option<String>) -> SR1PartList {
return if let Some(name) = name { return if let Some(name) = name {
@ -491,6 +500,32 @@ pub mod sr1 {
pub explode: bool, pub explode: bool,
} }
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 mut shape = Shape::new_width_height(width as f64, height as f64, Some(radius));
shape.move_xy(Some(self.x), Some(self.y));
let mut pos_box = (0_f64, 0_f64, 0_f64, 0_f64);
match shape.bounds[0] {
Edge::OneTimeLine(line) => {
pos_box.0 = line.start.x;
pos_box.1 = line.start.y;
}
_ => {}
}
match shape.bounds[2] {
Edge::OneTimeLine(line) => {
pos_box.2 = line.start.x;
pos_box.3 = line.start.y;
}
_ => {}
}
pos_box
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum SR1PartDataAttr { pub enum SR1PartDataAttr {
Tank { Tank {
@ -532,6 +567,18 @@ pub mod sr1 {
pub disconnected: Option<Vec<(Vec<SR1PartData>, Option<Vec<Connection>>)>>, pub disconnected: Option<Vec<(Vec<SR1PartData>, Option<Vec<Connection>>)>>,
} }
impl SR1Ship {
pub fn from_file(file_name: String, ship_name: Option<String>) -> Option<Self> {
// 首先验证文件是否存在 不存在则返回None
if !std::path::Path::new(&file_name).exists() {
return None;
}
// 解析为 RawShip
let ship: RawShip = RawShip::from_file(file_name).unwrap();
Some(ship.to_sr_ship(ship_name))
}
}
impl SR1ShipTrait for SR1Ship { impl SR1ShipTrait for SR1Ship {
#[inline] #[inline]
fn to_sr_ship(&self, name: Option<String>) -> SR1Ship { fn to_sr_ship(&self, name: Option<String>) -> SR1Ship {
@ -582,6 +629,14 @@ pub mod sr1 {
} }
} }
} }
pub fn get_max_box(parts: &Vec<SR1PartData>, part_list: &SR1PartList) -> (f64, f64, f64, f64) {
let mut max_box = (0_f64, 0_f64, 0_f64, 0_f64);
for part in parts.iter() {
let part_type = part_list.get_part_type(part.part_type);
}
todo!("get_max_box")
}
} }
#[allow(unused)] #[allow(unused)]
@ -686,7 +741,7 @@ pub mod math {
} }
} }
pub fn new_width_height(width: f64, height: f64, angle: Option<f64>) -> Self { pub fn new_width_height(width: f64, height: f64, radius: Option<f64>) -> Self {
let d_width = width / 2.0; let d_width = width / 2.0;
let d_height = height / 2.0; let d_height = height / 2.0;
let mut edges: Vec<Edge> = vec![ let mut edges: Vec<Edge> = vec![
@ -695,17 +750,17 @@ pub mod math {
Edge::OneTimeLine(OneTimeLine::pos_new(d_width, d_height, -d_width, d_height)), Edge::OneTimeLine(OneTimeLine::pos_new(d_width, d_height, -d_width, d_height)),
Edge::OneTimeLine(OneTimeLine::pos_new(-d_width, d_height, -d_width, -d_height)), Edge::OneTimeLine(OneTimeLine::pos_new(-d_width, d_height, -d_width, -d_height)),
]; ];
if let Some(angle) = angle { if let Some(radius) = radius {
edges = edges edges = edges
.iter() .iter()
.map(|edge| match edge { .map(|edge| match edge {
Edge::OneTimeLine(line) => { Edge::OneTimeLine(line) => {
let start = line.start.rotate(angle); let start = line.start.rotate_radius(radius);
let end = line.end.rotate(angle); let end = line.end.rotate_radius(radius);
Edge::OneTimeLine(OneTimeLine::point_new(&start, &end)) Edge::OneTimeLine(OneTimeLine::point_new(&start, &end))
} }
Edge::CircularArc(arc) => { Edge::CircularArc(arc) => {
let pos = arc.pos.rotate(angle); let pos = arc.pos.rotate_radius(radius);
Edge::CircularArc(CircularArc { Edge::CircularArc(CircularArc {
r: arc.r, r: arc.r,
pos, pos,
@ -722,6 +777,25 @@ pub mod math {
bounds: edges, bounds: edges,
} }
} }
pub fn move_xy(&mut self, x: Option<f64>, y: Option<f64>) {
let x = x.unwrap_or(0.0);
let y = y.unwrap_or(0.0);
for edge in self.bounds.iter() {
match edge {
Edge::OneTimeLine(mut line) => {
line.start.x += x;
line.start.y += y;
line.end.x += x;
line.end.y += y;
}
Edge::CircularArc(mut arc) => {
arc.pos.x += x;
arc.pos.y += y;
}
}
}
}
} }
impl OneTimeLine { impl OneTimeLine {

View File

@ -26,7 +26,7 @@ class _DR_mod_runtime(Options):
DR_rust_version: Version = DR_rust_version DR_rust_version: Version = DR_rust_version
DR_rust_get_version: Optional[Version] = None DR_rust_get_version: Optional[Version] = None
def init(self, **kwargs) -> None: def init(self) -> None:
try: try:
from .Difficult_Rocket_rs import get_version_str from .Difficult_Rocket_rs import get_version_str
self.DR_rust_get_version = Version(get_version_str()) self.DR_rust_get_version = Version(get_version_str())
@ -36,12 +36,7 @@ class _DR_mod_runtime(Options):
warnings.warn(f'DR_rust builtin version is {self.DR_rust_version} but true version is {get_version_str()}.\n' warnings.warn(f'DR_rust builtin version is {self.DR_rust_version} but true version is {get_version_str()}.\n'
f'Builtin version {relationship} than true version') f'Builtin version {relationship} than true version')
self.use_DR_rust = self.use_DR_rust and self.DR_rust_available self.use_DR_rust = self.use_DR_rust and self.DR_rust_available
except Exception as e: except Exception:
try:
from .Difficult_Rocket_rs import get_version_str
print(type(get_version_str))
except:
...
traceback.print_exc() traceback.print_exc()
self.DR_rust_available = False self.DR_rust_available = False
self.use_DR_rust = False self.use_DR_rust = False
@ -69,11 +64,15 @@ class DR_mod(ModInfo):
# DR_Api_version = # DR Api版本 # DR_Api_version = # DR Api版本
# 同理 不管 API 版本 这东西要是不兼容了才是大问题 # 同理 不管 API 版本 这东西要是不兼容了才是大问题
def on_load(self, game: Game, old_self: Optional["DR_mod"] = None): def on_load(self, game: Game, old_self: Optional["DR_mod"] = None) -> bool:
if not DR_mod_runtime.DR_rust_available:
return False
if old_self: if old_self:
game.client.window.add_sub_screen("SR1_ship", old_self.screen) game.client.window.add_sub_screen("SR1_ship", old_self.screen)
else: else:
self.config.flush_option() self.config.flush_option()
print("DR_mod: on_load")
return True
def on_client_start(self, game: Game, client: ClientWindow): def on_client_start(self, game: Game, client: ClientWindow):
from .sr1_ship import SR1ShipRender from .sr1_ship import SR1ShipRender

View File

@ -19,6 +19,7 @@ from pyglet.math import Vec4
from pyglet.text import Label from pyglet.text import Label
from pyglet.shapes import Line from pyglet.shapes import Line
from pyglet.sprite import Sprite from pyglet.sprite import Sprite
from pyglet.image import Texture
from pyglet.graphics import Batch, Group from pyglet.graphics import Batch, Group
from . import DR_mod_runtime from . import DR_mod_runtime
@ -360,6 +361,12 @@ class SR1ShipRender(BaseScreen):
image_data = screenshot(self.window_pointer) image_data = screenshot(self.window_pointer)
image_data.save('test.png') image_data.save('test.png')
elif command.re_match('gen_img'):
if not self.rendered:
return
# ship_size = self.ship.size
base_textures = Texture.create(100, 100)
...
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"):
if not self.focus: if not self.focus: