From: Lizzy Fleckenstein Date: Fri, 10 Feb 2023 12:50:58 +0000 (+0100) Subject: Implement UTF-8 decode and move packets to different crate X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=3ed5bfd5ac9f12f323bcdb36f8fb840855d02634;p=mt_ser.git Implement UTF-8 decode and move packets to different crate --- diff --git a/Cargo.toml b/Cargo.toml index 6451008..c6c80f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,23 +1,12 @@ [package] -name = "mt_data" +name = "mt_ser" version = "0.1.0" edition = "2021" -[features] -all = ["client", "server", "random", "serde"] -client = [] -random = ["dep:generate-random", "dep:rand"] -serde = ["dep:serde", "dep:serde_arrays", "enumset/serde"] -server = [] - [dependencies] byteorder = "1.4.3" enumset = { git = "https://github.com/Lymia/enumset" } flate2 = { version = "1.0.25", features = ["zlib"], default-features = false } -generate-random = { git = "https://github.com/minetest-rust/generate-random", features = ["enumset"], optional = true } -mt_data_derive = { path = "derive" } +mt_ser_derive = { path = "derive" } paste = "1.0.11" -rand = { version = "0.8.5", optional = true } -serde = { version = "1.0.152", features = ["derive"], optional = true } -serde_arrays = { version = "0.1.0", optional = true } thiserror = "1.0.38" diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 18b97c3..d4a7702 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "mt_data_derive" +name = "mt_ser_derive" version = "0.1.0" edition = "2021" diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 75bc693..dd82c23 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -24,19 +24,16 @@ struct MacroArgs { } fn wrap_attr(attr: &mut syn::Attribute) { + let path = attr.path.clone(); + let tokens = attr.tokens.clone(); + match attr.path.get_ident().map(|i| i.to_string()).as_deref() { Some("mt") => { - let path = attr.path.clone(); - let tokens = attr.tokens.clone(); - *attr = parse_quote! { #[cfg_attr(any(feature = "client", feature = "server"), #path #tokens)] }; } Some("serde") => { - let path = attr.path.clone(); - let tokens = attr.tokens.clone(); - *attr = parse_quote! { #[cfg_attr(feature = "serde", #path #tokens)] }; @@ -176,15 +173,15 @@ struct MtArgs { len64: bool, utf16: bool, zlib: bool, - zstd: bool, + zstd: bool, // TODO default: bool, } fn get_cfg(args: &MtArgs) -> syn::Type { - let mut ty: syn::Type = parse_quote! { mt_data::DefCfg }; + let mut ty: syn::Type = parse_quote! { mt_ser::DefCfg }; if args.len0 { - ty = parse_quote! { mt_data::NoLen }; + ty = parse_quote! { () }; } macro_rules! impl_len { @@ -201,38 +198,12 @@ fn get_cfg(args: &MtArgs) -> syn::Type { impl_len!(len64, u64); if args.utf16 { - ty = parse_quote! { mt_data::Utf16<#ty> }; + ty = parse_quote! { mt_ser::Utf16<#ty> }; } ty } -/* -fn is_ident(path: &syn::Path, ident: &str) -> bool { - matches!(path.segments.first().map(|p| &p.ident), Some(idt) if idt == ident) -} - -fn get_type_generics(path: &syn::Path) -> Option<[&syn::Type; N]> { - use syn::{AngleBracketedGenericArguments as Args, PathArguments::AngleBracketed}; - - path.segments - .first() - .map(|seg| match &seg.arguments { - AngleBracketed(Args { args, .. }) => args - .iter() - .flat_map(|arg| match arg { - syn::GenericArgument::Type(t) => Some(t), - _ => None, - }) - .collect::>() - .try_into() - .ok(), - _ => None, - }) - .flatten() -} -*/ - type Fields<'a> = Vec<(TokStr, &'a syn::Field)>; fn get_fields(fields: &syn::Fields, ident: impl Fn(TokStr) -> TokStr) -> Fields { @@ -261,7 +232,7 @@ fn serialize_args(res: darling::Result, body: impl FnOnce(&MtArgs) -> To ($name:ident) => { if let Some(x) = args.$name { code.extend(quote! { - #x.mt_serialize::(__writer)?; + #x.mt_serialize::(__writer)?; }); } }; @@ -277,7 +248,10 @@ fn serialize_args(res: darling::Result, body: impl FnOnce(&MtArgs) -> To if args.zlib { code = quote! { let mut __writer = { - let mut __stream = mt_data::flate2::write::ZlibEncoder::new(__writer, flate2::Compression::default()); + let mut __stream = mt_ser::flate2::write::ZlibEncoder::new( + __writer, + mt_ser::flate2::Compression::default(), + ); let __writer = &mut __stream; #code __stream.finish()? @@ -289,7 +263,7 @@ fn serialize_args(res: darling::Result, body: impl FnOnce(&MtArgs) -> To ($name:ident, $T:ty) => { if args.$name { code = quote! { - mt_data::MtSerialize::mt_serialize::<$T>(&{ + mt_ser::MtSerialize::mt_serialize::<$T>(&{ let mut __buf = Vec::new(); let __writer = &mut __buf; #code @@ -317,7 +291,7 @@ fn serialize_fields(fields: &Fields) -> TokStr { .map(|(ident, field)| { serialize_args(MtArgs::from_field(field), |args| { let cfg = get_cfg(args); - quote! { mt_data::MtSerialize::mt_serialize::<#cfg>(#ident, __writer)?; } + quote! { mt_ser::MtSerialize::mt_serialize::<#cfg>(#ident, __writer)?; } }) }) .collect() @@ -345,7 +319,7 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream { let ident_fn = match &v.fields { syn::Fields::Unnamed(_) => |f| quote! { - mt_data::paste::paste! { [] } + mt_ser::paste::paste! { [] } }, _ => |f| quote! { #f }, }; @@ -369,7 +343,7 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream { quote! { #before #typename::#variant #destruct => { - mt_data::MtSerialize::mt_serialize::(&((#discr) as #repr), __writer)?; + mt_ser::MtSerialize::mt_serialize::(&((#discr) as #repr), __writer)?; #code } } @@ -390,8 +364,8 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream { quote! { #[automatically_derived] - impl mt_data::MtSerialize for #typename { - fn mt_serialize(&self, __writer: &mut impl std::io::Write) -> Result<(), mt_data::SerializeError> { + impl mt_ser::MtSerialize for #typename { + fn mt_serialize(&self, __writer: &mut impl std::io::Write) -> Result<(), mt_ser::SerializeError> { #code Ok(()) @@ -407,9 +381,9 @@ pub fn derive_deserialize(input: TokenStream) -> TokenStream { } = parse_macro_input!(input); quote! { #[automatically_derived] - impl mt_data::MtDeserialize for #typename { - fn mt_deserialize(__reader: &mut impl std::io::Read) -> Result { - Err(mt_data::DeserializeError::Unimplemented) + impl mt_ser::MtDeserialize for #typename { + fn mt_deserialize(__reader: &mut impl std::io::Read) -> Result { + Err(mt_ser::DeserializeError::Unimplemented) } } }.into() diff --git a/src/lib.rs b/src/lib.rs index c3e5cee..0019d1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,42 +2,24 @@ #![feature(associated_type_bounds)] #![feature(iterator_try_collect)] -pub use enumset; pub use flate2; +pub use mt_ser_derive::{mt_derive, MtDeserialize, MtSerialize}; pub use paste; -#[cfg(feature = "random")] -pub use generate_random; - -#[cfg(feature = "random")] -pub use rand; - -#[cfg(feature = "serde")] -pub use serde; - use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use enumset::{EnumSet, EnumSetType, EnumSetTypeWithRepr}; -use mt_data_derive::mt_derive; -pub use mt_data_derive::{MtDeserialize, MtSerialize}; +use enumset::{EnumSet, EnumSetTypeWithRepr}; use paste::paste as paste_macro; use std::{ collections::{HashMap, HashSet}, convert::Infallible, - fmt, io::{self, Read, Write}, num::TryFromIntError, ops::Deref, }; use thiserror::Error; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; - -#[cfg(feature = "random")] -use generate_random::GenerateRandom; - -#[cfg(any(feature = "client", feature = "server"))] -use crate as mt_data; +#[cfg(test)] +mod tests; #[derive(Error, Debug)] pub enum SerializeError { @@ -87,6 +69,49 @@ pub trait OrDefault { fn or_default(self) -> Self; } +pub struct WrapRead<'a, R: Read>(pub &'a mut R); +impl<'a, R: Read> Read for WrapRead<'a, R> { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.0.read(buf) + } + + fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { + self.0.read_vectored(bufs) + } + + /* + + fn is_read_vectored(&self) -> bool { + self.0.is_read_vectored() + } + + */ + + fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { + self.0.read_to_end(buf) + } + + fn read_to_string(&mut self, buf: &mut String) -> io::Result { + self.0.read_to_string(buf) + } + + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + self.0.read_exact(buf) + } + + /* + + fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf(buf) + } + + fn read_buf_exact(&mut self, cursor: io::BorrowedCursor<'_>) -> io::Result<()> { + self.0.read_buf_exact(cursor) + } + + */ +} + impl OrDefault for Result { fn or_default(self) -> Self { match self { @@ -96,24 +121,49 @@ impl OrDefault for Result { } } -pub trait MtCfg: - Sized + MtSerialize + MtDeserialize + TryFrom> -{ +pub trait MtLen { + fn option(&self) -> Option; + type Range: Iterator + 'static; + fn range(&self) -> Self::Range; + + type Take: Read; + fn take(&self, reader: R) -> Self::Take; +} + +pub trait MtCfg { + type Len: MtLen; fn utf16() -> bool { false } - fn var_len() -> bool; + fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError>; + fn read_len(reader: &mut impl Read) -> Result; +} - fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> { - Self::try_from(len) - .map_err(Into::into)? - .mt_serialize::(writer) +pub trait MtSerialize { + fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError>; +} + +pub trait MtDeserialize: Sized { + fn mt_deserialize(reader: &mut impl Read) -> Result; +} + +impl MtLen for usize { + fn option(&self) -> Option { + Some(*self) } - fn read_len(reader: &mut impl Read) -> Result; + type Range = std::ops::Range; + fn range(&self) -> Self::Range { + 0..*self + } + + type Take = io::Take; + fn take(&self, reader: R) -> Self::Take { + reader.take(*self as u64) + } } trait MtCfgLen: @@ -126,105 +176,70 @@ trait MtCfgLen: } impl MtCfg for T { - type Range = std::ops::Range; + type Len = usize; - fn var_len() -> bool { - false + fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> { + Self::try_from(len) + .map_err(Into::into)? + .mt_serialize::(writer) } - fn read_len(reader: &mut impl Read) -> Result { - let len = Self::mt_deserialize::(reader)? + fn read_len(reader: &mut impl Read) -> Result { + Ok(Self::mt_deserialize::(reader)? .try_into() - .map_err(Into::into)?; - - Ok(0..len) + .map_err(Into::into)?) } } -pub type DefCfg = u16; - -pub trait MtSerialize: Sized { - fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError>; -} - -pub trait MtDeserialize: Sized { - fn mt_deserialize(reader: &mut impl Read) -> Result; -} - impl MtCfgLen for u8 {} impl MtCfgLen for u16 {} impl MtCfgLen for u32 {} impl MtCfgLen for u64 {} -#[derive(Debug)] -pub struct NoLen; +pub type DefCfg = u16; -impl MtSerialize for NoLen { - fn mt_serialize(&self, _writer: &mut impl Write) -> Result<(), SerializeError> { - Ok(()) - } -} +impl MtCfg for () { + type Len = (); -impl MtDeserialize for NoLen { - fn mt_deserialize(_reader: &mut impl Read) -> Result { - Ok(Self) + fn write_len(_len: usize, _writer: &mut impl Write) -> Result<(), SerializeError> { + Ok(()) } -} -impl TryFrom for NoLen { - type Error = Infallible; - - fn try_from(_x: usize) -> Result { - Ok(Self) + fn read_len(_writer: &mut impl Read) -> Result { + Ok(()) } } -impl MtCfg for NoLen { - fn var_len() -> bool { - true +impl MtLen for () { + fn option(&self) -> Option { + None } type Range = std::ops::RangeFrom; - - fn read_len(_reader: &mut impl Read) -> Result { - Ok(0..) - } -} - -pub struct Utf16(pub B); - -impl MtSerialize for Utf16 { - fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { - self.0.mt_serialize::(writer) + fn range(&self) -> Self::Range { + 0.. } -} -impl MtDeserialize for Utf16 { - fn mt_deserialize(reader: &mut impl Read) -> Result { - Ok(Self(B::mt_deserialize::(reader)?)) + type Take = R; + fn take(&self, reader: R) -> Self::Take { + reader } } -impl TryFrom for Utf16 { - type Error = >::Error; - - fn try_from(x: usize) -> Result { - Ok(Self(x.try_into()?)) - } -} +pub struct Utf16(pub B); impl MtCfg for Utf16 { - type Range = B::Range; + type Len = B::Len; fn utf16() -> bool { true } - fn var_len() -> bool { - B::var_len() + fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> { + B::write_len(len, writer) } - fn read_len(reader: &mut impl Read) -> Result { + fn read_len(reader: &mut impl Read) -> Result { B::read_len(reader) } } @@ -320,7 +335,7 @@ impl MtSerialize for &T { } } -fn mt_serialize_seq( +pub fn mt_serialize_seq( writer: &mut impl Write, iter: impl ExactSizeIterator + IntoIterator, ) -> Result<(), SerializeError> { @@ -330,20 +345,30 @@ fn mt_serialize_seq( .try_for_each(|item| item.mt_serialize::(writer)) } -fn mt_deserialize_seq<'a, C: MtCfg, T: MtDeserialize>( +pub fn mt_deserialize_seq<'a, C: MtCfg, T: MtDeserialize>( + reader: &'a mut impl Read, +) -> Result> + 'a, DeserializeError> { + let len = C::read_len(reader)?; + mt_deserialize_sized_seq(&len, reader) +} + +pub fn mt_deserialize_sized_seq<'a, L: MtLen, T: MtDeserialize>( + len: &L, reader: &'a mut impl Read, ) -> Result> + 'a, DeserializeError> { - Ok(C::read_len(reader)? - .into_iter() - .map_while(|_| match T::mt_deserialize::(reader) { - Err(DeserializeError::UnexpectedEof) if C::var_len() => None, + let variable = len.option().is_none(); + + Ok(len + .range() + .map_while(move |_| match T::mt_deserialize::(reader) { + Err(DeserializeError::UnexpectedEof) if variable => None, x => Some(x), })) } impl MtSerialize for [T; N] { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { - mt_serialize_seq::(writer, self.iter()) + mt_serialize_seq::<(), _>(writer, self.iter()) } } @@ -406,6 +431,7 @@ impl MtDeserialize for HashSe } } +// TODO: support more tuples impl MtSerialize for (A, B) { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { self.0.mt_serialize::(writer)?; @@ -476,8 +502,17 @@ impl MtDeserialize for String { Some(e) => Err(e), } } else { - // TODO: UTF-8 decode - Ok("".into()) + let len = C::read_len(reader)?; + + // use capacity if available + let mut st = match len.option() { + Some(x) => String::with_capacity(x), + None => String::new(), + }; + + len.take(WrapRead(reader)).read_to_string(&mut st)?; + + Ok(st) } } } @@ -493,9 +528,3 @@ impl MtDeserialize for Box { Ok(Self::new(T::mt_deserialize::(reader)?)) } } - -mod to_clt; -mod to_srv; - -pub use to_clt::*; -pub use to_srv::*; diff --git a/src/tests.rs b/src/tests.rs new file mode 100644 index 0000000..b013643 --- /dev/null +++ b/src/tests.rs @@ -0,0 +1,30 @@ +use super::*; + +fn reserialize(item: &T) -> T { + let mut writer = Vec::new(); + item.mt_serialize::(&mut writer).unwrap(); + + let mut reader = std::io::Cursor::new(writer); + T::mt_deserialize::(&mut reader).unwrap() +} + +#[test] +fn test_reserialize() { + let vec = vec![1, 2, 3]; + // encoded with 8-bit length + assert_eq!(vec, reserialize::(&vec)); + + let vec2 = vec![1, 2, 3]; + // encoded without length - drains the Reader + assert_eq!(vec2, reserialize::<(), _>(&vec2)); + + let st: String = "µ ß 私 😀\n".into(); + // encoded as UTF-16 with 32-bit length (also works with () or other types) + assert_eq!(st, reserialize::, _>(&st)); + + let long: Vec<_> = (0..=256).collect(); + assert!(matches!( + long.mt_serialize::(&mut Vec::new()), + Err(SerializeError::TooBig(_)) + )); +} diff --git a/src/to_clt.rs b/src/to_clt.rs deleted file mode 100644 index b93f7ee..0000000 --- a/src/to_clt.rs +++ /dev/null @@ -1,326 +0,0 @@ -use crate::*; - -#[mt_derive(to = "clt")] -pub struct ArgbColor { - pub a: u8, - pub r: u8, - pub g: u8, - pub b: u8, -} - -#[mt_derive(to = "clt", repr = "u8")] -pub enum ModChanSig { - JoinOk = 0, - JoinFail, - LeaveOk, - LeaveFail, - NotRegistered, - SetState, -} - -mod chat; -mod env; -mod hud; -mod media; -mod status; - -pub use chat::*; -pub use env::*; -pub use hud::*; -pub use media::*; -pub use status::*; - -#[mt_derive(to = "clt", repr = "u8", tag = "type", content = "data")] -pub enum ToCltPkt { - Hello { - serialize_version: u8, - #[mt(const16 = 1)] // compression - proto_version: u16, - auth_methods: EnumSet, - username: String, - } = 2, - AcceptAuth { - player_pos: [f32; 3], - map_seed: u64, - send_interval: f32, - sudo_auth_methods: EnumSet, - } = 3, - AcceptSudoMode { - sudo_auth_methods: EnumSet, - } = 4, - DenySudoMode = 5, - Kick(KickReason) = 10, - BlockData { - pos: [i16; 3], - #[mt(zstd)] - block: Box, - } = 32, - AddNode { - pos: [i16; 3], - param0: u16, - param1: u8, - param2: u8, - keep_meta: bool, - } = 33, - RemoveNode { - pos: [i16; 3], - } = 34, - Inv { - inv: String, - } = 39, - TimeOfDay { - time: u16, - speed: f32, - } = 41, - CsmRestrictionFlags { - flags: EnumSet, - map_range: u32, - } = 42, - AddPlayerVelocity { - vel: [f32; 3], - } = 43, - MediaPush { - no_len_hash: String, - filename: String, - callback_token: u32, - should_cache: bool, - } = 44, - ChatMsg { - #[mt(const8 = 1)] - msg_type: ChatMsgType, - #[mt(utf16)] - sender: String, - #[mt(utf16)] - text: String, - timestamp: i64, // unix time - } = 47, - ObjRemoveAdd { - remove: Vec, - add: Vec, - } = 49, - ObjMsgs { - msgs: Vec, - } = 50, - Hp { - hp: u16, - #[mt(default)] - damage_effect: bool, - } = 51, - MovePlayer { - pos: [f32; 3], - pitch: f32, - yaw: f32, - } = 52, - LegacyKick { - #[mt(utf16)] - reason: String, - } = 53, - Fov { - fov: f32, - multiplier: bool, - transition_time: f32, - } = 54, - DeathScreen { - point_cam: bool, - point_at: [f32; 3], - } = 55, - Media { - n: u16, - i: u16, - files: Vec, // FIXME: can we use a HashMap for this? - } = 56, - NodeDefs { - defs: Vec, - } = 58, - AnnounceMedia { - files: Vec, // FIXME: can we use a HashMap for this? - url: String, - } = 60, - #[mt(size32, zlib)] - ItemDefs { - #[mt(const8 = 0)] // version - defs: Vec, - aliases: HashMap, - } = 61, - PlaySound { - id: u32, - name: String, - gain: f32, - src_type: SoundSrcType, - pos: [f32; 3], - src_obj_id: u16, - #[serde(rename = "loop")] - sound_loop: bool, - fade: f32, - pitch: f32, - ephermeral: bool, - } = 63, - StopSound { - id: u32, - } = 64, - Privs { - privs: HashSet, - } = 65, - InvFormspec { - #[mt(size32)] - formspec: String, - } = 66, - DetachedInv { - name: String, - keep: bool, - len: u16, - #[mt(len0)] - inv: String, - } = 67, - ShowFormspec { - #[mt(len32)] - formspec: String, - formname: String, - } = 68, - Movement { - default_accel: f32, - air_accel: f32, - fast_accel: f32, - walk_speed: f32, - crouch_speed: f32, - fast_speed: f32, - climb_speed: f32, - jump_speed: f32, - gravity: f32, - } = 69, - SpawnParticle { - pos: [f32; 3], - vel: [f32; 3], - acc: [f32; 3], - expiration_time: f32, - size: f32, - collide: bool, - #[mt(len32)] - texture: String, - vertical: bool, - collision_rm: bool, - anim_params: TileAnim, - glow: u8, - obj_collision: bool, - node_param0: u16, - node_param2: u8, - node_tile: u8, - } = 70, - AddParticleSpawner { - amount: u16, - duration: f32, - pos: [[f32; 3]; 2], - vel: [[f32; 3]; 2], - acc: [[f32; 3]; 2], - expiration_time: [f32; 2], - size: [f32; 2], - collide: bool, - #[mt(len32)] - texture: String, - id: u32, - vertical: bool, - collision_rm: bool, - attached_obj_id: u16, - anim_params: TileAnim, - glow: u8, - obj_collision: bool, - node_param0: u16, - node_param2: u8, - node_tile: u8, - } = 71, - AddHud { - id: u32, - hud: HudElement, - } = 73, - RemoveHud { - id: u32, - } = 74, - ChangeHud { - id: u32, - change: HudChange, - } = 75, - HudFlags { - flags: EnumSet, - mask: EnumSet, - } = 76, - SetHotbarParam(HotbarParam) = 77, - Breath { - breath: u16, - } = 78, - // TODO - SkyParams = 79, - OverrideDayNightRatio { - #[serde(rename = "override")] - ratio_override: bool, - ratio: u16, - } = 80, - LocalPlayerAnim { - idle: [i32; 2], - walk: [i32; 2], - dig: [i32; 2], - walk_dig: [i32; 2], - speed: f32, - } = 81, - EyeOffset { - first: [f32; 3], - third: [f32; 3], - } = 82, - RemoveParticleSpawner { - id: u32, - } = 83, - CloudParams { - density: f32, - diffuse_color: ArgbColor, - ambient_color: ArgbColor, - height: f32, - thickness: f32, - speed: [f32; 2], - } = 84, - FadeSound { - id: u32, - step: f32, - gain: f32, - } = 85, - UpdatePlayerList { - update_type: PlayerListUpdateType, - players: HashSet, - } = 86, - ModChanMsg { - channel: String, - sender: String, - msg: String, - } = 87, - ModChanSig { - signal: ModChanSig, - channel: String, - } = 88, - NodeMetasChanged(#[mt(size32)] HashMap<[i16; 3], NodeMeta>) = 89, - SunParams { - visible: bool, - texture: String, - tone_map: String, - rise: String, - rising: bool, - size: f32, - } = 90, - MoonParams { - visible: bool, - texture: String, - tone_map: String, - size: f32, - } = 91, - StarParams { - visible: bool, - texture: String, - tone_map: String, - size: f32, - } = 92, - SrpBytesSaltB { - salt: Vec, - b: Vec, - } = 96, - FormspecPrepend { - prepend: String, - } = 97, - MinimapModes(MinimapModePkt) = 98, -} diff --git a/src/to_clt/chat.rs b/src/to_clt/chat.rs deleted file mode 100644 index 4d99853..0000000 --- a/src/to_clt/chat.rs +++ /dev/null @@ -1,16 +0,0 @@ -use super::*; - -#[mt_derive(to = "clt", repr = "u8")] -pub enum ChatMsgType { - Raw = 0, - Normal, - Announce, - System, -} - -#[mt_derive(to = "clt", repr = "u8")] -pub enum PlayerListUpdateType { - Init = 0, - Add, - Remove, -} diff --git a/src/to_clt/env.rs b/src/to_clt/env.rs deleted file mode 100644 index f242298..0000000 --- a/src/to_clt/env.rs +++ /dev/null @@ -1,44 +0,0 @@ -use super::*; - -#[mt_derive(to = "clt")] -pub struct ObjAdd; // TODO - -#[mt_derive(to = "clt")] -pub struct ObjMsg; // TODO - -#[mt_derive(to = "clt", repr = "u8", enumset)] -pub enum MapBlockFlag { - IsUnderground = 0, - DayNightDiff, - LightExpired, - NotGenerated, -} - -pub const ALWAYS_LIT_FROM: u16 = 0xf000; - -#[mt_derive(to = "clt")] -pub struct MapBlock { - pub flags: EnumSet, - pub lit_from: u16, - - #[mt(const8 = 2)] - #[serde(skip)] - pub param0_size: (), - - #[mt(const8 = 2)] - #[serde(skip)] - pub param12_size: (), - - #[serde(with = "serde_arrays")] - pub param_0: [u16; 4096], - #[serde(with = "serde_arrays")] - pub param_1: [u8; 4096], - #[serde(with = "serde_arrays")] - pub param_2: [u8; 4096], - - pub node_metas: HashMap, - - #[mt(const8 = 2)] - #[serde(skip)] - pub version: (), -} diff --git a/src/to_clt/hud.rs b/src/to_clt/hud.rs deleted file mode 100644 index 3a29d7b..0000000 --- a/src/to_clt/hud.rs +++ /dev/null @@ -1,154 +0,0 @@ -use super::*; - -#[mt_derive(to = "clt", repr = "u32", enumset)] -pub enum HudStyleFlag { - Bold, - Italic, - Mono, -} - -#[mt_derive(to = "clt", repr = "u8", tag = "attribute", content = "value")] -pub enum HudChange { - Pos([f32; 2]) = 0, - Name(String), - Scale([f32; 2]), - Text(String), - Number(u32), - Item(u32), - Dir(u32), - Align([f32; 2]), - Offset([f32; 2]), - WorldPos([f32; 3]), - ZIndex(i32), - Text2(String), - Style(EnumSet), -} - -#[mt_derive(to = "clt", repr = "u8")] -pub enum HudType { - Image = 0, - Text, - Statbar, - Inv, - Waypoint, - ImageWaypoint, -} - -#[mt_derive(to = "clt")] -pub struct HudElement { - pub hud_type: HudType, - pub pos: [f32; 2], - pub name: String, - pub scale: [f32; 2], - pub text: String, - pub number: u32, - pub item: u32, - pub dir: u32, - pub align: [f32; 2], - pub offset: [f32; 2], - pub world_pos: [f32; 3], - pub z_index: i32, - pub text_2: String, - pub style: EnumSet, -} - -impl HudElement { - pub fn apply_change(&mut self, change: HudChange) { - use HudChange::*; - - match change { - Pos(v) => self.pos = v, - Name(v) => self.name = v, - Scale(v) => self.scale = v, - Text(v) => self.text = v, - Number(v) => self.number = v, - Item(v) => self.item = v, - Dir(v) => self.dir = v, - Align(v) => self.align = v, - Offset(v) => self.offset = v, - WorldPos(v) => self.world_pos = v, - ZIndex(v) => self.z_index = v, - Text2(v) => self.text_2 = v, - Style(v) => self.style = v, - } - } -} - -#[mt_derive(to = "clt", repr = "u32", enumset)] -pub enum HudFlag { - Hotbar, - HealthBar, - Crosshair, - WieldedItem, - BreathBar, - Minimap, - RadarMinimap, -} - -#[mt_derive(to = "clt", repr = "u16", tag = "attribute", content = "value")] -pub enum HotbarParam { - Size(#[mt(const16 = 4)] u32) = 0, - Image(String), - SelectionImage(String), -} - -#[mt_derive(to = "clt", repr = "u16")] -pub enum MinimapType { - None = 0, - Surface, - Radar, - Texture, -} - -#[mt_derive(to = "clt")] -pub struct MinimapMode { - pub minimap_type: MinimapType, - pub label: String, - pub size: u16, - pub texture: String, - pub scale: u16, -} - -#[mt_derive(to = "clt", custom)] -pub struct MinimapModePkt { - current: u16, - modes: Vec, -} - -#[cfg(feature = "server")] -impl MtSerialize for MinimapModePkt { - fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { - DefCfg::write_len(self.modes.len(), writer)?; - self.current.mt_serialize::(writer)?; - self.modes.mt_serialize::(writer)?; - - Ok(()) - } -} - -#[cfg(feature = "client")] -impl MtDeserialize for MinimapModePkt { - fn mt_deserialize(reader: &mut impl Read) -> Result { - let range = DefCfg::read_len(reader)?; - let current = MtDeserialize::mt_deserialize::(reader)?; - let modes = range - .map(|_| MtDeserialize::mt_deserialize::(reader)) - .try_collect()?; - - Ok(Self { current, modes }) - } -} - -/* -TODO: rustify this - -var DefaultMinimap = []MinimapMode{ - {Type: NoMinimap}, - {Type: SurfaceMinimap, Size: 256}, - {Type: SurfaceMinimap, Size: 128}, - {Type: SurfaceMinimap, Size: 64}, - {Type: RadarMinimap, Size: 512}, - {Type: RadarMinimap, Size: 256}, - {Type: RadarMinimap, Size: 128}, -} -*/ diff --git a/src/to_clt/media.rs b/src/to_clt/media.rs deleted file mode 100644 index 0dd1f3d..0000000 --- a/src/to_clt/media.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::*; - -#[mt_derive(to = "clt")] -pub struct MediaAnnounce { - pub name: String, - pub base64_sha1: String, -} - -#[mt_derive(to = "clt")] -pub struct MediaPayload { - pub name: String, - #[mt(len32)] - pub data: Vec, -} - -#[mt_derive(to = "clt")] -pub struct TileAnim; // TODO - -#[mt_derive(to = "clt")] -pub struct ItemDef; // TODO - -#[mt_derive(to = "clt")] -pub struct NodeDef; // TODO - -#[mt_derive(to = "clt")] -pub struct NodeMeta; // TODO - -#[mt_derive(to = "clt", repr = "u16")] -pub enum SoundSrcType { - Nowhere = 0, - Pos, - Obj, -} diff --git a/src/to_clt/status.rs b/src/to_clt/status.rs deleted file mode 100644 index 54adb45..0000000 --- a/src/to_clt/status.rs +++ /dev/null @@ -1,80 +0,0 @@ -use super::*; - -#[mt_derive(to = "clt", repr = "u8", tag = "reason")] -pub enum KickReason { - WrongPasswd, - UnexpectedData, - SrvIsSingleplayer, - UnsupportedVersion, - BadNameChars, - BadName, - TooManyClts, - EmptyPasswd, - AlreadyConnected, - SrvErr, - Custom { custom: String }, - Shutdown { custom: String, reconnect: bool }, - Crash { custom: String, reconnect: bool }, -} - -impl KickReason { - pub fn reconnect(&self) -> bool { - use KickReason::*; - - match self { - Shutdown { reconnect, .. } | Crash { reconnect, .. } => *reconnect, - _ => false, - } - } -} - -impl fmt::Display for KickReason { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use KickReason::*; - - match self { - WrongPasswd => write!(f, "wrong password"), - UnexpectedData => write!(f, "unexpected data"), - SrvIsSingleplayer => write!(f, "server is singleplayer"), - UnsupportedVersion => write!(f, "unsupported client version"), - BadNameChars => write!(f, "disallowed character(s) in player name"), - BadName => write!(f, "disallowed player name"), - TooManyClts => write!(f, "too many clients"), - EmptyPasswd => write!(f, "empty password"), - AlreadyConnected => write!(f, "another client is already connected with the same name"), - SrvErr => write!(f, "unsupported client version"), - Custom { custom } => write!(f, "{custom}"), - Shutdown { custom, .. } => { - if custom.is_empty() { - write!(f, "server shutdown") - } else { - write!(f, "server shutdown: {custom}") - } - } - Crash { custom, .. } => { - if custom.is_empty() { - write!(f, "server crash") - } else { - write!(f, "server crash: {custom}") - } - } - } - } -} - -#[mt_derive(to = "clt", repr = "u32", enumset)] -pub enum AuthMethod { - LegacyPasswd, - Srp, - FirstSrp, -} - -#[mt_derive(to = "clt", repr = "u64", enumset)] -pub enum CsmRestrictionFlag { - NoCsms, - NoChatMsgs, - NoItemDefs, - NoNodeDefs, - LimitMapRange, - NoPlayerList, -} diff --git a/src/to_srv.rs b/src/to_srv.rs deleted file mode 100644 index e83a8b8..0000000 --- a/src/to_srv.rs +++ /dev/null @@ -1,133 +0,0 @@ -use crate::*; - -#[mt_derive(to = "srv", repr = "u32", enumset)] -pub enum Key { - Forward, - Backward, - Left, - Right, - Jump, - Special, - Sneak, - Dig, - Place, - Zoom, -} - -#[mt_derive(to = "srv")] -pub struct PlayerPos { - pub pos_100: [i32; 3], - pub vel_100: [i32; 3], - pub pitch_100: i32, - pub yaw_100: i32, - pub keys: EnumSet, - pub fov_80: u8, - pub wanted_range: u8, -} - -#[mt_derive(to = "srv", repr = "u8")] -pub enum Interaction { - Dig = 0, - StopDigging, - Dug, - Place, - Use, - Activate, -} - -#[mt_derive(to = "srv")] -pub struct PointedThing; // TODO - -#[mt_derive(to = "srv", repr = "u16", tag = "type", content = "data")] -pub enum ToSrvPkt { - Nil = 0, - Init { - serialize_version: u8, - #[mt(const16 = 1)] // supported compression - min_proto_version: u16, - max_proto_version: u16, - player_name: String, - #[mt(default)] - send_full_item_meta: bool, - } = 2, - Init2 { - lang: String, - } = 17, - JoinModChan { - channel: String, - } = 23, - LeaveModChan { - channel: String, - } = 24, - MsgModChan { - channel: String, - msg: String, - } = 25, - PlayerPos(PlayerPos) = 35, - GotBlocks { - #[mt(len8)] - blocks: Vec<[i16; 3]>, - } = 36, - DeletedBlocks { - #[mt(len8)] - blocks: Vec<[i16; 3]>, - } = 37, - InvAction { - #[mt(len0)] - action: String, - } = 49, - ChatMsg { - #[mt(utf16)] - msg: String, - } = 50, - FallDmg { - amount: u16, - } = 53, - SelectItem { - select_item: u16, - } = 55, - Respawn = 56, - Interact { - action: Interaction, - item_slot: u16, - #[mt(size32)] - pointed: PointedThing, - pos: PlayerPos, - } = 57, - RemovedSounds { - ids: Vec, - } = 58, - NodeMetaFields { - pos: [i16; 3], - formname: String, - fields: HashMap, - } = 59, - InvFields { - formname: String, - fields: HashMap, - } = 60, - ReqMedia { - filenames: Vec, - } = 64, - CltReady { - major: u8, - minor: u8, - patch: u8, - reserved: u8, - version: String, - formspec: u16, - } = 67, - FirstSrp { - salt: Vec, - verifier: Vec, - empty_passwd: bool, - } = 80, - SrpBytesA { - a: Vec, - no_sha1: bool, - } = 81, - SrpBytesM { - m: Vec, - } = 82, - Disco = 0xffff, -}