summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--src/lib.rs2
-rw-r--r--src/to_clt.rs17
-rw-r--r--src/to_clt/inv.rs16
-rw-r--r--src/to_clt/map.rs14
-rw-r--r--src/to_clt/media.rs411
-rw-r--r--src/to_clt/obj.rs4
7 files changed, 439 insertions, 26 deletions
diff --git a/Cargo.toml b/Cargo.toml
index eb9d99c..afbc3e4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,7 +15,6 @@ test = ["client", "server", "random"]
enumset = { git = "https://github.com/Lymia/enumset" }
generate-random = { git = "https://github.com/minetest-rust/generate-random", features = ["enumset"], optional = true }
mt_ser = { git = "https://github.com/minetest-rust/mt_ser" }
-#mt_ser = { path = "../mt_ser" }
rand = { version = "0.8.5", optional = true }
serde = { version = "1.0.152", features = ["derive"], optional = true }
serde_arrays = { version = "0.1.0", optional = true }
diff --git a/src/lib.rs b/src/lib.rs
index 36ffec9..77538cd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,6 @@
#![feature(iterator_try_collect)]
+pub use enumset;
pub use mt_ser;
#[cfg(feature = "random")]
@@ -16,6 +17,7 @@ use mt_ser::mt_derive;
use std::{
collections::{HashMap, HashSet},
fmt,
+ ops::RangeInclusive,
};
#[cfg(any(feature = "client", feature = "server"))]
diff --git a/src/to_clt.rs b/src/to_clt.rs
index 9848dae..3792018 100644
--- a/src/to_clt.rs
+++ b/src/to_clt.rs
@@ -170,10 +170,7 @@ pub enum ToCltPkt {
files: HashMap<String, Vec<u8>>, // name -> payload
} = 56,
#[mt(size = "u32", zlib)]
- NodeDefs {
- #[mt(const_before = "1u8")] // version
- defs: Vec<NodeDef>,
- } = 58,
+ NodeDefs(#[mt(const_before = "1u8")] NodeDefs) = 58,
AnnounceMedia {
files: HashMap<String, String>, // name -> base64 sha1 hash
url: String,
@@ -188,7 +185,7 @@ pub enum ToCltPkt {
id: u32,
name: String,
gain: f32,
- src_type: SoundSrcType,
+ source: SoundSource,
pos: [f32; 3],
src_obj_id: u16,
#[serde(rename = "loop")]
@@ -254,11 +251,11 @@ pub enum ToCltPkt {
AddParticleSpawner {
amount: u16,
duration: f32,
- pos: [[f32; 3]; 2],
- vel: [[f32; 3]; 2],
- acc: [[f32; 3]; 2],
- expiration_time: [f32; 2],
- size: [f32; 2],
+ pos: RangeInclusive<[f32; 3]>,
+ vel: RangeInclusive<[f32; 3]>,
+ acc: RangeInclusive<[f32; 3]>,
+ expiration_time: RangeInclusive<f32>,
+ size: RangeInclusive<f32>,
collide: bool,
#[mt(len = "u32")]
texture: String,
diff --git a/src/to_clt/inv.rs b/src/to_clt/inv.rs
index 2ada0a1..01eaa75 100644
--- a/src/to_clt/inv.rs
+++ b/src/to_clt/inv.rs
@@ -1,18 +1,20 @@
use super::*;
-use mt_ser::{DeserializeError, SerializeError};
-use std::io::{Read, Write};
#[mt_derive(to = "clt", custom)]
pub struct Inventory; // TODO
#[cfg(feature = "server")]
impl MtSerialize for Inventory {
- fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
+ fn mt_serialize<C: MtCfg>(
+ &self,
+ writer: &mut impl std::io::Write,
+ ) -> Result<(), mt_ser::SerializeError> {
"EndInventory\n".mt_serialize::<()>(writer)
}
}
-fn read_line(reader: &mut impl Read) -> Result<String, DeserializeError> {
+#[cfg(feature = "client")]
+fn read_line(reader: &mut impl std::io::Read) -> Result<String, mt_ser::DeserializeError> {
let utf8 = mt_ser::mt_deserialize_seq::<(), u8>(reader)?
.map_while(|x| match x {
Ok(0x0A) => None,
@@ -21,12 +23,14 @@ fn read_line(reader: &mut impl Read) -> Result<String, DeserializeError> {
.try_collect::<Vec<_>>()?;
String::from_utf8(utf8)
- .map_err(|e| DeserializeError::Other(format!("Invalid UTF-8: {e}").into()))
+ .map_err(|e| mt_ser::DeserializeError::Other(format!("Invalid UTF-8: {e}").into()))
}
#[cfg(feature = "client")]
impl MtDeserialize for Inventory {
- fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError> {
+ fn mt_deserialize<C: MtCfg>(
+ reader: &mut impl std::io::Read,
+ ) -> Result<Self, mt_ser::DeserializeError> {
loop {
match read_line(reader)?.as_str() {
"EndInventory" => return Ok(Self),
diff --git a/src/to_clt/map.rs b/src/to_clt/map.rs
index 296a23f..b35f2cd 100644
--- a/src/to_clt/map.rs
+++ b/src/to_clt/map.rs
@@ -1,5 +1,4 @@
use super::*;
-use mt_ser::{DeserializeError, SerializeError};
#[mt_derive(to = "clt", repr = "u8", enumset)]
pub enum MapBlockFlag {
@@ -32,11 +31,15 @@ pub struct NodeMeta {
#[derive(Debug)]
pub struct NodeMetasLen;
+#[cfg(any(feature = "client", feature = "server"))]
impl MtCfg for NodeMetasLen {
type Len = <DefCfg as MtCfg>::Len;
type Inner = <DefCfg as MtCfg>::Inner;
- fn write_len(len: usize, writer: &mut impl std::io::Write) -> Result<(), SerializeError> {
+ fn write_len(
+ len: usize,
+ writer: &mut impl std::io::Write,
+ ) -> Result<(), mt_ser::SerializeError> {
if len == 0 {
0u8.mt_serialize::<DefCfg>(writer)
} else {
@@ -45,11 +48,14 @@ impl MtCfg for NodeMetasLen {
}
}
- fn read_len(reader: &mut impl std::io::Read) -> Result<Self::Len, DeserializeError> {
+ fn read_len(reader: &mut impl std::io::Read) -> Result<Self::Len, mt_ser::DeserializeError> {
match u8::mt_deserialize::<DefCfg>(reader)? {
0 => Ok(0),
2 => DefCfg::read_len(reader),
- x => Err(DeserializeError::InvalidEnum("NodeMetasLen", Box::new(x))),
+ x => Err(mt_ser::DeserializeError::InvalidEnum(
+ "NodeMetasLen",
+ Box::new(x),
+ )),
}
}
}
diff --git a/src/to_clt/media.rs b/src/to_clt/media.rs
index 1ec1fd6..7176773 100644
--- a/src/to_clt/media.rs
+++ b/src/to_clt/media.rs
@@ -1,5 +1,73 @@
use super::*;
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Param1Type {
+ None = 0,
+ Light,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Param2Type {
+ Nibble = 0,
+ Byte,
+ Flowing,
+ FaceDir,
+ Mounted,
+ Leveled,
+ Rotation,
+ Mesh,
+ Color,
+ ColorFaceDir,
+ ColorMounted,
+ GrassLikeLevel,
+ ColorRotation,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum DrawType {
+ Cube = 0,
+ None,
+ Liquid,
+ Flowing,
+ GlassLike,
+ AllFaces,
+ AllFacesOpt,
+ Torch,
+ Sign,
+ Plant,
+ Fence,
+ Rail,
+ NodeBox,
+ GlassFrame,
+ Fire,
+ GlassFrameOpt,
+ Mesh,
+ RootedPlant,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Waving {
+ None = 0,
+ Plant,
+ Leaf,
+ Liquid,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Liquid {
+ None = 0,
+ Flowing,
+ Source,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum Alpha {
+ Blend = 0,
+ Mask, // either fully opaque or transparent
+ Opaque,
+ Legacy,
+}
+
#[mt_derive(to = "clt", repr = "u8", tag = "type")]
pub enum TileAnim {
None = 0,
@@ -13,15 +81,352 @@ pub enum TileAnim {
},
}
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum TileAlign {
+ None = 0,
+ World,
+ User,
+}
+
+#[mt_derive(to = "clt", enumset, custom)]
+pub enum TileFlag {
+ BackfaceCull,
+ TileHorizontal,
+ TileVertical,
+}
+
+#[mt_derive(to = "clt", repr = "u16", enumset)]
+enum TileFlagInternal {
+ BackfaceCull,
+ TileHorizontal,
+ TileVertical,
+ Color,
+ Scale,
+ Align,
+}
+
+#[mt_derive(to = "clt", custom)]
+pub struct TileDef {
+ // #[mt(const_before = "6u8")]
+ pub texture: String,
+ pub animation: TileAnim,
+ pub flags: EnumSet<TileFlag>,
+ pub color: Option<[u8; 3]>,
+ pub scale: Option<u8>,
+ pub align: Option<TileAlign>,
+}
+
+#[cfg(feature = "server")]
+impl MtSerialize for TileDef {
+ fn mt_serialize<C: MtCfg>(
+ &self,
+ writer: &mut impl std::io::Write,
+ ) -> Result<(), mt_ser::SerializeError> {
+ 6u8.mt_serialize::<DefCfg>(writer)?;
+ self.texture.mt_serialize::<DefCfg>(writer)?;
+ self.animation.mt_serialize::<DefCfg>(writer)?;
+
+ let mut flags: EnumSet<TileFlagInternal> = self
+ .flags
+ .iter()
+ .map(|f| match f {
+ TileFlag::BackfaceCull => TileFlagInternal::BackfaceCull,
+ TileFlag::TileHorizontal => TileFlagInternal::TileHorizontal,
+ TileFlag::TileVertical => TileFlagInternal::TileVertical,
+ })
+ .collect();
+
+ if self.color.is_some() {
+ flags.insert(TileFlagInternal::Color);
+ }
+
+ if self.scale.is_some() {
+ flags.insert(TileFlagInternal::Scale);
+ }
+
+ if self.align.is_some() {
+ flags.insert(TileFlagInternal::Align);
+ }
+
+ flags.mt_serialize::<DefCfg>(writer)?;
+ self.color.mt_serialize::<DefCfg>(writer)?;
+ self.scale.mt_serialize::<DefCfg>(writer)?;
+ self.align.mt_serialize::<DefCfg>(writer)?;
+
+ Ok(())
+ }
+}
+
+#[cfg(feature = "client")]
+impl MtDeserialize for TileDef {
+ fn mt_deserialize<C: MtCfg>(
+ reader: &mut impl std::io::Read,
+ ) -> Result<Self, mt_ser::DeserializeError> {
+ let const6u8 = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
+ if 6u8 != const6u8 {
+ return Err(mt_ser::DeserializeError::InvalidConst(
+ Box::new(const6u8),
+ Box::new(6u8),
+ ));
+ }
+
+ let texture = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
+ let animation = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
+
+ let flags_internal = EnumSet::<TileFlagInternal>::mt_deserialize::<DefCfg>(reader)?;
+
+ let color = if flags_internal.contains(TileFlagInternal::Color) {
+ Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
+ } else {
+ None
+ };
+
+ let scale = if flags_internal.contains(TileFlagInternal::Scale) {
+ Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
+ } else {
+ None
+ };
+
+ let align = if flags_internal.contains(TileFlagInternal::Align) {
+ Some(MtDeserialize::mt_deserialize::<DefCfg>(reader)?)
+ } else {
+ None
+ };
+
+ let flags = flags_internal
+ .iter()
+ .flat_map(|f| match f {
+ TileFlagInternal::BackfaceCull => Some(TileFlag::BackfaceCull),
+ TileFlagInternal::TileHorizontal => Some(TileFlag::TileHorizontal),
+ TileFlagInternal::TileVertical => Some(TileFlag::TileVertical),
+ _ => None,
+ })
+ .collect();
+
+ Ok(Self {
+ texture,
+ animation,
+ flags,
+ color,
+ scale,
+ align,
+ })
+ }
+}
+
+#[mt_derive(to = "clt", repr = "u8", tag = "type")]
+#[mt(const_before = "6u8")]
+pub enum NodeBox {
+ Cube = 0,
+ Fixed {
+ fixed: Vec<RangeInclusive<[f32; 3]>>,
+ },
+ Mounted {
+ wall_top: RangeInclusive<[f32; 3]>,
+ wall_bottom: RangeInclusive<[f32; 3]>,
+ wall_sides: RangeInclusive<[f32; 3]>,
+ },
+ Leveled {
+ fixed: Vec<RangeInclusive<[f32; 3]>>,
+ },
+ Connected {
+ fixed: Vec<RangeInclusive<[f32; 3]>>,
+ connect_dirs: [Vec<RangeInclusive<[f32; 3]>>; 6],
+ disconnect_dirs: [Vec<RangeInclusive<[f32; 3]>>; 6],
+ disconnect_all: Vec<RangeInclusive<[f32; 3]>>,
+ disconnect_sides: Vec<RangeInclusive<[f32; 3]>>,
+ },
+}
+
#[mt_derive(to = "clt")]
-pub struct ItemDef; // TODO
+#[mt(size = "u16")]
+pub struct NodeDef {
+ // TODO: impl Default
+ #[mt(const_before = "13u8")]
+ pub name: String,
+ pub groups: HashMap<String, u16>,
+ pub param1_type: Param1Type,
+ pub param2_type: Param2Type,
+ pub draw_type: DrawType,
+ pub mesh: String,
+ pub scale: f32,
+ #[mt(const_before = "6u8")]
+ pub tiles: [TileDef; 6],
+ pub overlay_tiles: [TileDef; 6],
+ #[mt(const_before = "6u8")]
+ pub special_tiles: [TileDef; 6],
+ pub color: Color,
+ pub palette: String,
+ pub waving: Waving,
+ pub connect_sides: u8,
+ pub connect_to: Vec<u16>,
+ pub inside_tint: Color,
+ pub level: u8, // FIXME: must be below 128
+ pub translucent: bool, // sunlight scattering
+ pub transparent: bool,
+ pub light_source: u8, // FIXME: max: 14 (?)
+ pub ground_content: bool,
+ pub collision: bool,
+ pub pointable: bool,
+ pub diggable: bool,
+ pub climbable: bool,
+ pub replaceable: bool,
+ pub has_on_right_click: bool,
+ pub damage_per_second: i32,
+ pub liquid: Liquid,
+ pub flowing_alt: String,
+ pub source_alt: String,
+ pub viscosity: u8, // FIXME: 0-7
+ pub liquid_renewable: bool,
+ pub flow_range: u8,
+ pub drown_damage: u8,
+ pub floodable: bool,
+ pub draw_box: NodeBox,
+ pub collision_box: NodeBox,
+ pub selection_box: NodeBox,
+ pub footstep_sound: SoundDef,
+ pub digging_sound: SoundDef,
+ pub dug_sound: SoundDef,
+ pub legacy_face_dir: bool,
+ pub legacy_mounted: bool,
+ pub dig_predict: String,
+ pub max_level: u8,
+ pub alpha: Alpha,
+ pub move_resistance: u8,
+ pub liquid_move_physics: bool,
+}
+
+#[mt_derive(to = "clt", custom)]
+pub struct NodeDefs(pub HashMap<u16, NodeDef>);
+
+// stupid bullshit ahead
+
+#[cfg(feature = "server")]
+impl MtSerialize for NodeDefs {
+ fn mt_serialize<C: MtCfg>(
+ &self,
+ writer: &mut impl std::io::Write,
+ ) -> Result<(), mt_ser::SerializeError> {
+ DefCfg::write_len(self.0.len(), writer)?;
+
+ let mut buf = Vec::new();
+ self.0.mt_serialize::<()>(&mut buf)?;
+ buf.mt_serialize::<u32>(writer)?;
+
+ Ok(())
+ }
+}
+
+#[cfg(feature = "client")]
+impl MtDeserialize for NodeDefs {
+ fn mt_deserialize<C: MtCfg>(
+ reader: &mut impl std::io::Read,
+ ) -> Result<Self, mt_ser::DeserializeError> {
+ use mt_ser::MtLen;
+
+ let len = DefCfg::read_len(reader)?;
+ let mut reader = u32::read_len(reader)?.take(mt_ser::WrapRead(reader));
+ let inner =
+ mt_ser::mt_deserialize_sized_seq::<DefCfg, _>(&len, &mut reader)?.try_collect()?;
+
+ Ok(Self(inner))
+ }
+}
+
+/* TODO: Rustify this
+
+func BuiltinNodeDefs(n int) map[Content]NodeDef {
+ defs := make(map[Content]NodeDef, 3+n)
+ defs[Unknown] = NodeDef{
+ Name: "unknown",
+ }
+ defs[Air] = NodeDef{
+ Name: "air",
+ DrawType: DrawNothing,
+ P1Type: P1Light,
+ Translucent: true,
+ Transparent: true,
+ Replaceable: true,
+ Floodable: true,
+ GndContent: true,
+ }
+ defs[Ignore] = NodeDef{
+ Name: "ignore",
+ DrawType: DrawNothing,
+ Replaceable: true,
+ GndContent: true,
+ }
+ return defs
+}
+*/
+
+#[mt_derive(to = "clt")]
+pub struct ToolGroupCap {
+ pub uses: i16, // 32to16
+ pub max_level: i16,
+ #[mt(len = "u32")]
+ pub times: HashMap<i16, f32>,
+}
#[mt_derive(to = "clt")]
-pub struct NodeDef; // TODO
+pub struct ToolCaps {
+ #[mt(const_before = "5u8")]
+ pub attack_cooldown: f32,
+ pub max_drop_level: i16,
+ #[mt(len = "u32")]
+ pub group_caps: HashMap<String, ToolGroupCap>,
+ #[mt(len = "u32")]
+ pub dmg_groups: HashMap<String, u16>,
+ pub punch_uses: u16, // 32tou16
+}
#[mt_derive(to = "clt", repr = "u8")]
-pub enum SoundSrcType {
+pub enum ItemType {
+ Node = 1,
+ Craft,
+ Tool,
+}
+
+#[mt_derive(to = "clt", repr = "u8")]
+pub enum SoundSource {
Nowhere = 0,
Pos,
Obj,
}
+
+#[mt_derive(to = "clt")]
+pub struct SoundDef {
+ pub name: String,
+ pub gain: f32,
+ pub pitch: f32,
+ pub fade: f32,
+}
+
+#[mt_derive(to = "clt")]
+#[mt(size = "u16")]
+pub struct ItemDef {
+ #[mt(const_before = "6u8")]
+ #[serde(rename = "type")]
+ pub item_type: ItemType,
+ pub name: String,
+ pub description: String,
+ pub inventory_image: String,
+ pub wield_image: String,
+ pub wield_scale: [f32; 3],
+ pub stack_max: u16,
+ pub usable: bool,
+ pub can_point_liquids: bool,
+ #[mt(size = "u16")]
+ pub tool_caps: Option<ToolCaps>,
+ pub groups: HashMap<String, u16>,
+ pub place_predict: String,
+ pub place_sound: SoundDef,
+ pub place_fail_sound: SoundDef,
+ pub point_range: f32,
+ pub palette: String,
+ pub color: Color,
+ pub inventory_overlay: String,
+ pub wield_overlay: String,
+ pub short_description: String,
+ pub place_param2: u8,
+}
diff --git a/src/to_clt/obj.rs b/src/to_clt/obj.rs
index 9e88fff..1b605cc 100644
--- a/src/to_clt/obj.rs
+++ b/src/to_clt/obj.rs
@@ -16,8 +16,8 @@ pub struct ObjProps {
pub max_hp: u16, // player only
pub collide_with_nodes: bool,
pub weight: f32, // deprecated
- pub collision_box: ([f32; 3], [f32; 3]),
- pub selection_box: ([f32; 3], [f32; 3]),
+ pub collision_box: RangeInclusive<[f32; 3]>,
+ pub selection_box: RangeInclusive<[f32; 3]>,
pub pointable: bool,
pub visual: ObjVisual,
pub visual_size: [f32; 3],