From 0d6752b8805735468fcfb4a8059755b93e88d829 Mon Sep 17 00:00:00 2001 From: MeexReay Date: Sun, 11 May 2025 22:17:43 +0300 Subject: [PATCH] more read+write stuff --- src/data/mod.rs | 39 ++++++++++ src/data/slot.rs | 187 ++++++++++++++++++++++++++++++++++++++++++++++ src/data/sound.rs | 32 +++++++- 3 files changed, 257 insertions(+), 1 deletion(-) diff --git a/src/data/mod.rs b/src/data/mod.rs index 0fb8f3b..1bce4b6 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -58,6 +58,45 @@ pub enum IdOr { Or(T), } +pub trait ReadWriteIdOr { + fn read_id_or( + &mut self, + func: impl Fn(&mut Self) -> Result, + ) -> Result, ServerError>; + fn write_id_or( + &mut self, + val: &IdOr, + func: impl Fn(&mut Self, &T) -> Result<(), ServerError>, + ) -> Result<(), ServerError>; +} + +impl ReadWriteIdOr for T { + fn read_id_or( + &mut self, + func: impl Fn(&mut Self) -> Result, + ) -> Result, ServerError> { + let id = self.read_varint()?; + + if id == 0 { + Ok(IdOr::Or(func(self)?)) + } else { + Ok(IdOr::Id(id - 1)) + } + } + + fn write_id_or( + &mut self, + val: &IdOr, + func: impl Fn(&mut Self, &S) -> Result<(), ServerError>, + ) -> Result<(), ServerError> { + match val { + IdOr::Id(id) => self.write_varint(id + 1)?, + IdOr::Or(val) => func(self, val)?, + } + Ok(()) + } +} + #[derive(Clone)] pub enum IdSet { Tag(String), diff --git a/src/data/slot.rs b/src/data/slot.rs index 6f936cb..a1b088e 100644 --- a/src/data/slot.rs +++ b/src/data/slot.rs @@ -105,6 +105,49 @@ pub enum ConsumeEffect { PlaySound(SoundEvent), } +impl ReadWriteAny for Packet { + fn read_any(&mut self) -> Result { + match self.read_varint()? { + 0 => { + let len = self.read_usize_varint()?; + let mut effects = Vec::new(); + for _ in 0..len { + effects.push(self.read_any()?); + } + let probability = self.read_float()?; + Ok(ConsumeEffect::ApplyEffects(effects, probability)) + } + 1 => Ok(ConsumeEffect::RemoveEffects(self.read_any()?)), + 2 => Ok(ConsumeEffect::ClearAllEffects), + 3 => Ok(ConsumeEffect::TeleportRandomly(self.read_float()?)), + 4 => Ok(ConsumeEffect::PlaySound(self.read_any()?)), + _ => Err(ServerError::WrongPacket), + } + } + fn write_any(&mut self, val: &ConsumeEffect) -> Result<(), ServerError> { + match val { + ConsumeEffect::ApplyEffects(effects, probability) => { + self.write_usize_varint(effects.len())?; + for effect in effects { + self.write_any(effect)?; + } + self.write_float(*probability)?; + } + ConsumeEffect::RemoveEffects(set) => { + self.write_any(set)?; + } + ConsumeEffect::ClearAllEffects => {} + ConsumeEffect::TeleportRandomly(diameter) => { + self.write_float(*diameter)?; + } + ConsumeEffect::PlaySound(sound) => { + self.write_any(sound)?; + } + } + Ok(()) + } +} + #[derive(Clone)] pub struct TrimMaterial { pub suffix: String, @@ -114,6 +157,33 @@ pub struct TrimMaterial { pub description: TextComponent, } +impl ReadWriteAny for Packet { + fn read_any(&mut self) -> Result { + Ok(TrimMaterial { + suffix: self.read_string()?, + overrides: { + let len = self.read_usize_varint()?; + let mut overrides = Vec::new(); + for _ in 0..len { + overrides.push((self.read_string()?, self.read_string()?)); + } + overrides + }, + description: self.read_any()?, + }) + } + fn write_any(&mut self, val: &TrimMaterial) -> Result<(), ServerError> { + self.write_string(&val.suffix)?; + self.write_usize_varint(val.overrides.len())?; + for ele in &val.overrides { + self.write_string(&ele.0)?; + self.write_string(&ele.1)?; + } + self.write_any(&val.description)?; + Ok(()) + } +} + #[derive(Clone)] pub struct TrimPattern { pub asset_name: String, @@ -122,6 +192,24 @@ pub struct TrimPattern { pub decal: bool, } +impl ReadWriteAny for Packet { + fn read_any(&mut self) -> Result { + Ok(TrimPattern { + asset_name: self.read_string()?, + template_item: self.read_varint()?, + description: self.read_any()?, + decal: self.read_boolean()?, + }) + } + fn write_any(&mut self, val: &TrimPattern) -> Result<(), ServerError> { + self.write_string(&val.asset_name)?; + self.write_varint(val.template_item)?; + self.write_any(&val.description)?; + self.write_boolean(val.decal)?; + Ok(()) + } +} + #[derive(Clone)] pub struct PotionEffectDetail { pub amplifier: i32, @@ -133,12 +221,55 @@ pub struct PotionEffectDetail { pub hidden_effect: Option>, } +impl ReadWriteAny for T { + fn read_any(&mut self) -> Result { + Ok(PotionEffectDetail { + amplifier: self.read_varint()?, + duration: self.read_varint()?, + ambient: self.read_boolean()?, + show_particles: self.read_boolean()?, + show_icon: self.read_boolean()?, + hidden_effect: if self.read_boolean()? { + Some(Box::new(self.read_any()?)) + } else { + None + }, + }) + } + fn write_any(&mut self, val: &PotionEffectDetail) -> Result<(), ServerError> { + self.write_varint(val.amplifier)?; + self.write_varint(val.duration)?; + self.write_boolean(val.ambient)?; + self.write_boolean(val.show_particles)?; + self.write_boolean(val.show_icon)?; + self.write_boolean(val.hidden_effect.is_some())?; + if let Some(val) = &val.hidden_effect { + self.write_any(&val.as_ref().clone())?; + } + Ok(()) + } +} + #[derive(Clone)] pub struct PotionEffect { pub type_id: u32, pub detail: PotionEffectDetail, } +impl ReadWriteAny for T { + fn read_any(&mut self) -> Result { + Ok(PotionEffect { + type_id: self.read_u32_varint()?, + detail: self.read_any()?, + }) + } + fn write_any(&mut self, val: &PotionEffect) -> Result<(), ServerError> { + self.write_u32_varint(val.type_id)?; + self.write_any(&val.detail)?; + Ok(()) + } +} + #[derive(Clone)] pub struct FireworkExplosion { /// Can be one of the following: @@ -154,6 +285,46 @@ pub struct FireworkExplosion { pub has_twinkle: bool, } +impl ReadWriteAny for T { + fn read_any(&mut self) -> Result { + Ok(FireworkExplosion { + shape: self.read_u8_varint()?, + colors: { + let len = self.read_usize_varint()?; + let mut colors = Vec::new(); + for _ in 0..len { + colors.push(self.read_int()?); + } + colors + }, + fade_colors: { + let len = self.read_usize_varint()?; + let mut colors = Vec::new(); + for _ in 0..len { + colors.push(self.read_int()?); + } + colors + }, + has_trail: self.read_boolean()?, + has_twinkle: self.read_boolean()?, + }) + } + fn write_any(&mut self, val: &FireworkExplosion) -> Result<(), ServerError> { + self.write_u8_varint(val.shape)?; + self.write_usize_varint(val.colors.len())?; + for color in val.colors.clone() { + self.write_int(color)?; + } + self.write_usize_varint(val.fade_colors.len())?; + for color in val.fade_colors.clone() { + self.write_int(color)?; + } + self.write_boolean(val.has_trail)?; + self.write_boolean(val.has_twinkle)?; + Ok(()) + } +} + #[derive(Clone)] pub struct HiveBee { pub entity_data: DynNBT, @@ -161,6 +332,22 @@ pub struct HiveBee { pub min_ticks_in_hive: i32, } +impl ReadWriteAny for Packet { + fn read_any(&mut self) -> Result { + Ok(HiveBee { + entity_data: self.read_any()?, + ticks_in_hive: self.read_varint()?, + min_ticks_in_hive: self.read_varint()?, + }) + } + fn write_any(&mut self, val: &HiveBee) -> Result<(), ServerError> { + self.write_any(&val.entity_data)?; + self.write_varint(val.ticks_in_hive)?; + self.write_varint(val.min_ticks_in_hive)?; + Ok(()) + } +} + #[derive(Clone)] pub enum BannerLayer { Direct { diff --git a/src/data/sound.rs b/src/data/sound.rs index 3467693..c4e1f0d 100644 --- a/src/data/sound.rs +++ b/src/data/sound.rs @@ -1,2 +1,32 @@ +use rust_mc_proto::{DataReader, DataWriter}; + +use crate::ServerError; + +use super::ReadWriteAny; + #[derive(Clone)] -pub struct SoundEvent; +pub struct SoundEvent { + pub name: String, + pub fixed_range: Option, +} + +impl ReadWriteAny for T { + fn read_any(&mut self) -> Result { + Ok(SoundEvent { + name: self.read_string()?, + fixed_range: if self.read_boolean()? { + Some(self.read_float()?) + } else { + None + }, + }) + } + fn write_any(&mut self, val: &SoundEvent) -> Result<(), ServerError> { + self.write_string(&val.name)?; + self.write_boolean(val.fixed_range.is_some())?; + if let Some(val) = val.fixed_range { + self.write_float(val)?; + } + Ok(()) + } +}