]> git.lizzy.rs Git - mt_ser.git/commitdiff
Implement UTF-8 decode and move packets to different crate
authorLizzy Fleckenstein <eliasfleckenstein@web.de>
Fri, 10 Feb 2023 12:50:58 +0000 (13:50 +0100)
committerLizzy Fleckenstein <eliasfleckenstein@web.de>
Fri, 10 Feb 2023 12:50:58 +0000 (13:50 +0100)
12 files changed:
Cargo.toml
derive/Cargo.toml
derive/src/lib.rs
src/lib.rs
src/tests.rs [new file with mode: 0644]
src/to_clt.rs [deleted file]
src/to_clt/chat.rs [deleted file]
src/to_clt/env.rs [deleted file]
src/to_clt/hud.rs [deleted file]
src/to_clt/media.rs [deleted file]
src/to_clt/status.rs [deleted file]
src/to_srv.rs [deleted file]

index 645100867b82c9dd66205607eabb02678deb9934..c6c80f4e9d85bb62b7a12851210bd113fd4881a0 100644 (file)
@@ -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"
index 18b97c394b77ee8c3680dd74694d9cb9186fad5e..d4a770211f17de16cf20a7f3f77a006da52c1554 100644 (file)
@@ -1,5 +1,5 @@
 [package]
-name = "mt_data_derive"
+name = "mt_ser_derive"
 version = "0.1.0"
 edition = "2021"
 
index 75bc693b5515a3198219749ef7b2611dac046500..dd82c23cf3e60e47a8ad066b4f71a212ff7831c3 100644 (file)
@@ -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<const N: usize>(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::<Vec<_>>()
-                               .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<MtArgs>, body: impl FnOnce(&MtArgs) -> To
                                ($name:ident) => {
                                        if let Some(x) = args.$name {
                                                code.extend(quote! {
-                                                       #x.mt_serialize::<mt_data::DefCfg>(__writer)?;
+                                                       #x.mt_serialize::<mt_ser::DefCfg>(__writer)?;
                                                });
                                        }
                                };
@@ -277,7 +248,10 @@ fn serialize_args(res: darling::Result<MtArgs>, 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<MtArgs>, 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! { [<field_ #f>] }
+                                                       mt_ser::paste::paste! { [<field_ #f>] }
                                                },
                                                _ => |f| quote! { #f },
                                        };
@@ -369,7 +343,7 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream {
                                                quote! {
                                                        #before
                                                        #typename::#variant #destruct => {
-                                                               mt_data::MtSerialize::mt_serialize::<mt_data::DefCfg>(&((#discr) as #repr), __writer)?;
+                                                               mt_ser::MtSerialize::mt_serialize::<mt_ser::DefCfg>(&((#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<C: MtCfg>(&self, __writer: &mut impl std::io::Write) -> Result<(), mt_data::SerializeError> {
+               impl mt_ser::MtSerialize for #typename {
+                       fn mt_serialize<C: mt_ser::MtCfg>(&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<C: MtCfg>(__reader: &mut impl std::io::Read) -> Result<Self, mt_data::DeserializeError> {
-                               Err(mt_data::DeserializeError::Unimplemented)
+               impl mt_ser::MtDeserialize for #typename {
+                       fn mt_deserialize<C: mt_ser::MtCfg>(__reader: &mut impl std::io::Read) -> Result<Self, mt_ser::DeserializeError> {
+                               Err(mt_ser::DeserializeError::Unimplemented)
                        }
                }
        }.into()
index c3e5cee2dd9b4c67642a663968539596bca918c0..0019d1c0b63e023abc5befa8b21e824a8e972d6b 100644 (file)
@@ -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<T> {
     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<usize> {
+        self.0.read(buf)
+    }
+
+    fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
+        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<u8>) -> io::Result<usize> {
+        self.0.read_to_end(buf)
+    }
+
+    fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
+        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<T: MtDeserialize + Default> OrDefault<T> for Result<T, DeserializeError> {
     fn or_default(self) -> Self {
         match self {
@@ -96,24 +121,49 @@ impl<T: MtDeserialize + Default> OrDefault<T> for Result<T, DeserializeError> {
     }
 }
 
-pub trait MtCfg:
-    Sized + MtSerialize + MtDeserialize + TryFrom<usize, Error: Into<SerializeError>>
-{
+pub trait MtLen {
+    fn option(&self) -> Option<usize>;
+
     type Range: Iterator<Item = usize> + 'static;
+    fn range(&self) -> Self::Range;
+
+    type Take<R: Read>: Read;
+    fn take<R: Read>(&self, reader: R) -> Self::Take<R>;
+}
+
+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<Self::Len, DeserializeError>;
+}
 
-    fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> {
-        Self::try_from(len)
-            .map_err(Into::into)?
-            .mt_serialize::<DefCfg>(writer)
+pub trait MtSerialize {
+    fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError>;
+}
+
+pub trait MtDeserialize: Sized {
+    fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError>;
+}
+
+impl MtLen for usize {
+    fn option(&self) -> Option<usize> {
+        Some(*self)
     }
 
-    fn read_len(reader: &mut impl Read) -> Result<Self::Range, DeserializeError>;
+    type Range = std::ops::Range<usize>;
+    fn range(&self) -> Self::Range {
+        0..*self
+    }
+
+    type Take<R: Read> = io::Take<R>;
+    fn take<R: Read>(&self, reader: R) -> Self::Take<R> {
+        reader.take(*self as u64)
+    }
 }
 
 trait MtCfgLen:
@@ -126,105 +176,70 @@ trait MtCfgLen:
 }
 
 impl<T: MtCfgLen> MtCfg for T {
-    type Range = std::ops::Range<usize>;
+    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::<DefCfg>(writer)
     }
 
-    fn read_len(reader: &mut impl Read) -> Result<Self::Range, DeserializeError> {
-        let len = Self::mt_deserialize::<DefCfg>(reader)?
+    fn read_len(reader: &mut impl Read) -> Result<Self::Len, DeserializeError> {
+        Ok(Self::mt_deserialize::<DefCfg>(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<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError>;
-}
-
-pub trait MtDeserialize: Sized {
-    fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError>;
-}
-
 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<C: MtCfg>(&self, _writer: &mut impl Write) -> Result<(), SerializeError> {
-        Ok(())
-    }
-}
+impl MtCfg for () {
+    type Len = ();
 
-impl MtDeserialize for NoLen {
-    fn mt_deserialize<C: MtCfg>(_reader: &mut impl Read) -> Result<Self, DeserializeError> {
-        Ok(Self)
+    fn write_len(_len: usize, _writer: &mut impl Write) -> Result<(), SerializeError> {
+        Ok(())
     }
-}
 
-impl TryFrom<usize> for NoLen {
-    type Error = Infallible;
-
-    fn try_from(_x: usize) -> Result<Self, Self::Error> {
-        Ok(Self)
+    fn read_len(_writer: &mut impl Read) -> Result<Self::Len, DeserializeError> {
+        Ok(())
     }
 }
 
-impl MtCfg for NoLen {
-    fn var_len() -> bool {
-        true
+impl MtLen for () {
+    fn option(&self) -> Option<usize> {
+        None
     }
 
     type Range = std::ops::RangeFrom<usize>;
-
-    fn read_len(_reader: &mut impl Read) -> Result<Self::Range, DeserializeError> {
-        Ok(0..)
-    }
-}
-
-pub struct Utf16<B: MtCfg>(pub B);
-
-impl<B: MtCfg> MtSerialize for Utf16<B> {
-    fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
-        self.0.mt_serialize::<DefCfg>(writer)
+    fn range(&self) -> Self::Range {
+        0..
     }
-}
 
-impl<B: MtCfg> MtDeserialize for Utf16<B> {
-    fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError> {
-        Ok(Self(B::mt_deserialize::<DefCfg>(reader)?))
+    type Take<R: Read> = R;
+    fn take<R: Read>(&self, reader: R) -> Self::Take<R> {
+        reader
     }
 }
 
-impl<B: MtCfg> TryFrom<usize> for Utf16<B> {
-    type Error = <usize as TryInto<B>>::Error;
-
-    fn try_from(x: usize) -> Result<Self, Self::Error> {
-        Ok(Self(x.try_into()?))
-    }
-}
+pub struct Utf16<B: MtCfg>(pub B);
 
 impl<B: MtCfg> MtCfg for Utf16<B> {
-    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<Self::Range, DeserializeError> {
+    fn read_len(reader: &mut impl Read) -> Result<Self::Len, DeserializeError> {
         B::read_len(reader)
     }
 }
@@ -320,7 +335,7 @@ impl<T: MtSerialize> MtSerialize for &T {
     }
 }
 
-fn mt_serialize_seq<C: MtCfg, T: MtSerialize>(
+pub fn mt_serialize_seq<C: MtCfg, T: MtSerialize>(
     writer: &mut impl Write,
     iter: impl ExactSizeIterator + IntoIterator<Item = T>,
 ) -> Result<(), SerializeError> {
@@ -330,20 +345,30 @@ fn mt_serialize_seq<C: MtCfg, T: MtSerialize>(
         .try_for_each(|item| item.mt_serialize::<DefCfg>(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<impl Iterator<Item = Result<T, DeserializeError>> + '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<impl Iterator<Item = Result<T, DeserializeError>> + 'a, DeserializeError> {
-    Ok(C::read_len(reader)?
-        .into_iter()
-        .map_while(|_| match T::mt_deserialize::<DefCfg>(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::<DefCfg>(reader) {
+            Err(DeserializeError::UnexpectedEof) if variable => None,
             x => Some(x),
         }))
 }
 
 impl<T: MtSerialize, const N: usize> MtSerialize for [T; N] {
     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
-        mt_serialize_seq::<NoLen, _>(writer, self.iter())
+        mt_serialize_seq::<(), _>(writer, self.iter())
     }
 }
 
@@ -406,6 +431,7 @@ impl<T: MtDeserialize + std::cmp::Eq + std::hash::Hash> MtDeserialize for HashSe
     }
 }
 
+// TODO: support more tuples
 impl<A: MtSerialize, B: MtSerialize> MtSerialize for (A, B) {
     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
         self.0.mt_serialize::<DefCfg>(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<T: MtDeserialize> MtDeserialize for Box<T> {
         Ok(Self::new(T::mt_deserialize::<C>(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 (file)
index 0000000..b013643
--- /dev/null
@@ -0,0 +1,30 @@
+use super::*;
+
+fn reserialize<C: MtCfg, T: MtSerialize + MtDeserialize>(item: &T) -> T {
+    let mut writer = Vec::new();
+    item.mt_serialize::<C>(&mut writer).unwrap();
+
+    let mut reader = std::io::Cursor::new(writer);
+    T::mt_deserialize::<C>(&mut reader).unwrap()
+}
+
+#[test]
+fn test_reserialize() {
+    let vec = vec![1, 2, 3];
+    // encoded with 8-bit length
+    assert_eq!(vec, reserialize::<u8, _>(&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::<Utf16<u32>, _>(&st));
+
+    let long: Vec<_> = (0..=256).collect();
+    assert!(matches!(
+        long.mt_serialize::<u8>(&mut Vec::new()),
+        Err(SerializeError::TooBig(_))
+    ));
+}
diff --git a/src/to_clt.rs b/src/to_clt.rs
deleted file mode 100644 (file)
index b93f7ee..0000000
+++ /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<AuthMethod>,
-        username: String,
-    } = 2,
-    AcceptAuth {
-        player_pos: [f32; 3],
-        map_seed: u64,
-        send_interval: f32,
-        sudo_auth_methods: EnumSet<AuthMethod>,
-    } = 3,
-    AcceptSudoMode {
-        sudo_auth_methods: EnumSet<AuthMethod>,
-    } = 4,
-    DenySudoMode = 5,
-    Kick(KickReason) = 10,
-    BlockData {
-        pos: [i16; 3],
-        #[mt(zstd)]
-        block: Box<MapBlock>,
-    } = 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<CsmRestrictionFlag>,
-        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<u16>,
-        add: Vec<ObjAdd>,
-    } = 49,
-    ObjMsgs {
-        msgs: Vec<ObjMsg>,
-    } = 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<MediaPayload>, // FIXME: can we use a HashMap for this?
-    } = 56,
-    NodeDefs {
-        defs: Vec<NodeDef>,
-    } = 58,
-    AnnounceMedia {
-        files: Vec<MediaAnnounce>, // FIXME: can we use a HashMap for this?
-        url: String,
-    } = 60,
-    #[mt(size32, zlib)]
-    ItemDefs {
-        #[mt(const8 = 0)] // version
-        defs: Vec<ItemDef>,
-        aliases: HashMap<String, String>,
-    } = 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<String>,
-    } = 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<HudFlag>,
-        mask: EnumSet<HudFlag>,
-    } = 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<String>,
-    } = 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<u8>,
-        b: Vec<u8>,
-    } = 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 (file)
index 4d99853..0000000
+++ /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 (file)
index f242298..0000000
+++ /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<MapBlockFlag>,
-    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<u16, NodeMeta>,
-
-    #[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 (file)
index 3a29d7b..0000000
+++ /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<HudStyleFlag>),
-}
-
-#[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<HudStyleFlag>,
-}
-
-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<MinimapMode>,
-}
-
-#[cfg(feature = "server")]
-impl MtSerialize for MinimapModePkt {
-    fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
-        DefCfg::write_len(self.modes.len(), writer)?;
-        self.current.mt_serialize::<DefCfg>(writer)?;
-        self.modes.mt_serialize::<NoLen>(writer)?;
-
-        Ok(())
-    }
-}
-
-#[cfg(feature = "client")]
-impl MtDeserialize for MinimapModePkt {
-    fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError> {
-        let range = DefCfg::read_len(reader)?;
-        let current = MtDeserialize::mt_deserialize::<DefCfg>(reader)?;
-        let modes = range
-            .map(|_| MtDeserialize::mt_deserialize::<DefCfg>(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 (file)
index 0dd1f3d..0000000
+++ /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<u8>,
-}
-
-#[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 (file)
index 54adb45..0000000
+++ /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 (file)
index e83a8b8..0000000
+++ /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<Key>,
-    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<i32>,
-    } = 58,
-    NodeMetaFields {
-        pos: [i16; 3],
-        formname: String,
-        fields: HashMap<String, String>,
-    } = 59,
-    InvFields {
-        formname: String,
-        fields: HashMap<String, String>,
-    } = 60,
-    ReqMedia {
-        filenames: Vec<String>,
-    } = 64,
-    CltReady {
-        major: u8,
-        minor: u8,
-        patch: u8,
-        reserved: u8,
-        version: String,
-        formspec: u16,
-    } = 67,
-    FirstSrp {
-        salt: Vec<u8>,
-        verifier: Vec<u8>,
-        empty_passwd: bool,
-    } = 80,
-    SrpBytesA {
-        a: Vec<u8>,
-        no_sha1: bool,
-    } = 81,
-    SrpBytesM {
-        m: Vec<u8>,
-    } = 82,
-    Disco = 0xffff,
-}