From 6c875082474431a39596b1547b436a9bec1f5533 Mon Sep 17 00:00:00 2001 From: Lizzy Fleckenstein Date: Fri, 10 Feb 2023 15:53:15 +0100 Subject: [PATCH] Initial commit --- .gitignore | 2 + Cargo.toml | 28 +++ src/lib.rs | 32 ++++ src/to_clt.rs | 326 +++++++++++++++++++++++++++++++++++ src/to_clt/chat.rs | 16 ++ src/to_clt/env.rs | 44 +++++ src/to_clt/hud.rs | 155 +++++++++++++++++ src/to_clt/media.rs | 33 ++++ src/to_clt/status.rs | 80 +++++++++ src/to_srv.rs | 133 ++++++++++++++ tests/.gitignore | 2 + tests/random.rs | 49 ++++++ tests/reserialize/.gitignore | 1 + tests/reserialize/go.mod | 10 ++ tests/reserialize/go.sum | 6 + tests/reserialize/main.go | 16 ++ 16 files changed, 933 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs create mode 100644 src/to_clt.rs create mode 100644 src/to_clt/chat.rs create mode 100644 src/to_clt/env.rs create mode 100644 src/to_clt/hud.rs create mode 100644 src/to_clt/media.rs create mode 100644 src/to_clt/status.rs create mode 100644 src/to_srv.rs create mode 100644 tests/.gitignore create mode 100644 tests/random.rs create mode 100644 tests/reserialize/.gitignore create mode 100644 tests/reserialize/go.mod create mode 100644 tests/reserialize/go.sum create mode 100644 tests/reserialize/main.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..7b8e51d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "mt_net" +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] +mt_ser = { path = "../mt_ser" } +enumset = { git = "https://github.com/Lymia/enumset" } +generate-random = { git = "https://github.com/minetest-rust/generate-random", features = ["enumset"], optional = true } +rand = { version = "0.8.5", optional = true } +serde = { version = "1.0.152", features = ["derive"], optional = true } +serde_arrays = { version = "0.1.0", optional = true } + +[dev-dependencies] +libtest-mimic = "0.6.0" +serde_json = "1.0.93" + +[[test]] +name = "random" +path = "tests/random.rs" +harness = false diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..a1b8469 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,32 @@ +#![feature(iterator_try_collect)] + +#[cfg(feature = "random")] +pub use generate_random; + +#[cfg(feature = "random")] +pub use rand; + +#[cfg(feature = "serde")] +pub use serde; + +use enumset::{EnumSet, EnumSetType}; +use mt_ser::mt_derive; +use std::{ + collections::{HashMap, HashSet}, + fmt, +}; + +#[cfg(any(feature = "client", feature = "server"))] +use mt_ser::{DefCfg, DeserializeError, MtCfg, MtDeserialize, MtSerialize, SerializeError}; + +#[cfg(feature = "random")] +use generate_random::GenerateRandom; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +mod to_clt; +mod to_srv; + +pub use to_clt::*; +pub use to_srv::*; diff --git a/src/to_clt.rs b/src/to_clt.rs new file mode 100644 index 0000000..fff0ff7 --- /dev/null +++ b/src/to_clt.rs @@ -0,0 +1,326 @@ +use super::*; + +#[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 new file mode 100644 index 0000000..4d99853 --- /dev/null +++ b/src/to_clt/chat.rs @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000..f242298 --- /dev/null +++ b/src/to_clt/env.rs @@ -0,0 +1,44 @@ +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 new file mode 100644 index 0000000..f45d735 --- /dev/null +++ b/src/to_clt/hud.rs @@ -0,0 +1,155 @@ +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 std::io::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 std::io::Read) -> Result { + let len = DefCfg::read_len(reader)?; + let current = MtDeserialize::mt_deserialize::(reader)?; + let modes = mt_ser::mt_deserialize_sized_seq(&len, 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 new file mode 100644 index 0000000..0dd1f3d --- /dev/null +++ b/src/to_clt/media.rs @@ -0,0 +1,33 @@ +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 new file mode 100644 index 0000000..54adb45 --- /dev/null +++ b/src/to_clt/status.rs @@ -0,0 +1,80 @@ +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 new file mode 100644 index 0000000..03cb5a4 --- /dev/null +++ b/src/to_srv.rs @@ -0,0 +1,133 @@ +use super::*; + +#[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, +} diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/tests/random.rs b/tests/random.rs new file mode 100644 index 0000000..4d2ad42 --- /dev/null +++ b/tests/random.rs @@ -0,0 +1,49 @@ +use libtest_mimic::{Arguments, Failed, Trial}; + +use mt_net::{generate_random::GenerateRandomVariant, rand, ToCltPkt, ToSrvPkt}; +use mt_ser::{DefCfg, MtDeserialize, MtSerialize}; +use std::{error::Error, fmt::Debug}; + +fn test_reserialize(type_name: &'static str) -> impl Iterator +where + T: MtSerialize + MtDeserialize + GenerateRandomVariant + PartialEq + Debug, +{ + (0..T::num_variants()).map(move |i| { + Trial::test(format!("{type_name}::{}", T::variant_name(i)), move || { + let mut rng = rand::thread_rng(); + + for _ in 0..100 { + let input = T::generate_random_variant(&mut rng, i); + + let mut writer = Vec::new(); + input + .mt_serialize::(&mut writer) + .map_err(|e| format!("serialize error: {e}\ninput: {input:?}"))?; + + let mut reader = std::io::Cursor::new(writer); + let output = T::mt_deserialize::(&mut reader) + .map_err(|e| format!("deserialize error: {e}\ninput: {input:?}"))?; + + if input != output { + return Err(format!( + "output did not match input\n\ + input: {input:?}\n\ + output: {output:?}", + ) + .into()); + } + } + + Ok(()) + }) + .with_kind("random") + }) +} + +fn main() -> Result<(), Box> { + let args = Arguments::from_args(); + let tests = test_reserialize::("ToSrvPkt") + .chain(test_reserialize::("ToCltPkt")) + .collect(); + libtest_mimic::run(&args, tests).exit(); +} diff --git a/tests/reserialize/.gitignore b/tests/reserialize/.gitignore new file mode 100644 index 0000000..49a0751 --- /dev/null +++ b/tests/reserialize/.gitignore @@ -0,0 +1 @@ +validate diff --git a/tests/reserialize/go.mod b/tests/reserialize/go.mod new file mode 100644 index 0000000..414ffb6 --- /dev/null +++ b/tests/reserialize/go.mod @@ -0,0 +1,10 @@ +module github.com/minetest-rust/mt_net/tests/reserialize + +go 1.20 + +replace github.com/dragonfireclient/mt => /home/fleckenstein/src/mt + +require ( + github.com/dragonfireclient/mt v0.0.1 // indirect + github.com/klauspost/compress v1.15.15 // indirect +) diff --git a/tests/reserialize/go.sum b/tests/reserialize/go.sum new file mode 100644 index 0000000..c92cbb7 --- /dev/null +++ b/tests/reserialize/go.sum @@ -0,0 +1,6 @@ +github.com/dragonfireclient/mt v0.0.2-0.20220709120709-173ad6e339cf h1:0CY1XyRPpNTgPQJjgsqvBzBgXdf6NN6deKw81G0qeHQ= +github.com/dragonfireclient/mt v0.0.2-0.20220709120709-173ad6e339cf/go.mod h1:3oHbcSQytW21mTF7ozw3Il3UzdOAG30gPzO2XUAqvGs= +github.com/klauspost/compress v1.15.5 h1:qyCLMz2JCrKADihKOh9FxnW3houKeNsp2h5OEz0QSEA= +github.com/klauspost/compress v1.15.5/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= diff --git a/tests/reserialize/main.go b/tests/reserialize/main.go new file mode 100644 index 0000000..101f3bf --- /dev/null +++ b/tests/reserialize/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/dragonfireclient/mt" + "os" +) + +// WIP: test against the Go mt package +func main() { + pkt, err := mt.DeserializePkt(os.Stdin, false) + if err != nil { + panic(err) + } + + mt.SerializePkt(*pkt, os.Stdout, false) +} -- 2.44.0