more read+write stuff

This commit is contained in:
MeexReay 2025-05-11 22:17:43 +03:00
parent 94b8cee580
commit 0d6752b880
3 changed files with 257 additions and 1 deletions

View File

@ -58,6 +58,45 @@ pub enum IdOr<T> {
Or(T),
}
pub trait ReadWriteIdOr<T: Sized> {
fn read_id_or(
&mut self,
func: impl Fn(&mut Self) -> Result<T, ServerError>,
) -> Result<IdOr<T>, ServerError>;
fn write_id_or(
&mut self,
val: &IdOr<T>,
func: impl Fn(&mut Self, &T) -> Result<(), ServerError>,
) -> Result<(), ServerError>;
}
impl<T: DataReader + DataWriter, S> ReadWriteIdOr<S> for T {
fn read_id_or(
&mut self,
func: impl Fn(&mut Self) -> Result<S, ServerError>,
) -> Result<IdOr<S>, 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<S>,
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),

View File

@ -105,6 +105,49 @@ pub enum ConsumeEffect {
PlaySound(SoundEvent),
}
impl ReadWriteAny<ConsumeEffect> for Packet {
fn read_any(&mut self) -> Result<ConsumeEffect, ServerError> {
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<TrimMaterial> for Packet {
fn read_any(&mut self) -> Result<TrimMaterial, ServerError> {
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<TrimPattern> for Packet {
fn read_any(&mut self) -> Result<TrimPattern, ServerError> {
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<Box<PotionEffectDetail>>,
}
impl<T: DataReader + DataWriter> ReadWriteAny<PotionEffectDetail> for T {
fn read_any(&mut self) -> Result<PotionEffectDetail, ServerError> {
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<T: DataReader + DataWriter> ReadWriteAny<PotionEffect> for T {
fn read_any(&mut self) -> Result<PotionEffect, ServerError> {
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<T: DataReader + DataWriter> ReadWriteAny<FireworkExplosion> for T {
fn read_any(&mut self) -> Result<FireworkExplosion, ServerError> {
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<HiveBee> for Packet {
fn read_any(&mut self) -> Result<HiveBee, ServerError> {
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 {

View File

@ -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<f32>,
}
impl<T: DataReader + DataWriter> ReadWriteAny<SoundEvent> for T {
fn read_any(&mut self) -> Result<SoundEvent, ServerError> {
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(())
}
}