diff options
author | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-02-06 19:56:53 +0100 |
---|---|---|
committer | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-02-06 19:56:53 +0100 |
commit | be0db6761c344a53a13f569a934b33d01eb54147 (patch) | |
tree | 2668dbbab1b2ff9ebc12866d8af48e0bc8b771e5 /src | |
download | mt_ser-be0db6761c344a53a13f569a934b33d01eb54147.tar.xz |
Initial commit
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 52 | ||||
-rw-r--r-- | src/to_clt.rs | 330 | ||||
-rw-r--r-- | src/to_clt/chat.rs | 16 | ||||
-rw-r--r-- | src/to_clt/env.rs | 44 | ||||
-rw-r--r-- | src/to_clt/hud.rs | 124 | ||||
-rw-r--r-- | src/to_clt/media.rs | 33 | ||||
-rw-r--r-- | src/to_clt/status.rs | 80 | ||||
-rw-r--r-- | src/to_srv.rs | 119 |
8 files changed, 798 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..143b397 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,52 @@ +pub use enumset; + +#[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_data_derive::mt_derive; +pub use mt_data_derive::{MtDeserialize, MtSerialize}; +use std::{collections::HashMap, fmt, io}; +use thiserror::Error; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "random")] +use generate_random::GenerateRandom; + +#[derive(Error, Debug)] +pub enum SerializeError { + #[error("{0}")] + IoError(#[from] io::Error), + #[error("serialization is not implemented")] + Unimplemented, +} + +#[derive(Error, Debug)] +pub enum DeserializeError { + #[error("{0}")] + IoError(#[from] io::Error), + #[error("deserialization is not implemented")] + Unimplemented, +} + +pub trait MtSerialize: Sized { + fn mt_serialize<W: io::Write>(&self, writer: &mut W) -> Result<(), SerializeError>; +} + +pub trait MtDeserialize: Sized { + fn mt_deserialize<R: io::Read>(reader: &mut R) -> Result<Self, DeserializeError>; +} + +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..6a4b3c6 --- /dev/null +++ b/src/to_clt.rs @@ -0,0 +1,330 @@ +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>, + } = 56, + NodeDefs { + defs: Vec<NodeDef>, + } = 58, + AnnounceMedia { + files: Vec<MediaAnnounce>, + 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: Vec<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: Vec<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 { + #[mt(len = "modes")] + current: u16, + modes: Vec<MinimapMode>, + } = 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<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 new file mode 100644 index 0000000..c7a206a --- /dev/null +++ b/src/to_clt/hud.rs @@ -0,0 +1,124 @@ +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, +} + +/* +TODO: rustify + +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<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 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..354bbb4 --- /dev/null +++ b/src/to_srv.rs @@ -0,0 +1,119 @@ +use crate::*; + +#[mt_derive(to = "srv")] +pub struct PlayerPos { + #[mt(const_u16 = 1)] // supported compression + pub pos_100: [i32; 3], + pub vel_100: [i32; 3], + pub pitch_100: i32, + pub yaw_100: i32, + 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(const_u16 = 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(size_u32)] + 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, +} |