diff options
| author | mat <git@matdoes.dev> | 2025-01-13 04:52:40 +0000 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2025-01-13 04:52:40 +0000 |
| commit | 5721eaf193977ce0d7c2fee9504b8ad057d1c1a2 (patch) | |
| tree | f789d0707e46885e1da454b81740f2f4c20a2d6f | |
| parent | 862dec529bf7619401fd0ae021fc55cbbe27c697 (diff) | |
| download | azalea-drasl-5721eaf193977ce0d7c2fee9504b8ad057d1c1a2.tar.xz | |
fix ClientboundSound and implement az_registry::Holder
| -rwxr-xr-x | azalea-protocol/src/packets/game/c_sound.rs | 37 | ||||
| -rwxr-xr-x | azalea-registry/src/lib.rs | 50 |
2 files changed, 85 insertions, 2 deletions
diff --git a/azalea-protocol/src/packets/game/c_sound.rs b/azalea-protocol/src/packets/game/c_sound.rs index 77161769..8ec028a7 100755 --- a/azalea-protocol/src/packets/game/c_sound.rs +++ b/azalea-protocol/src/packets/game/c_sound.rs @@ -1,11 +1,13 @@ use azalea_buf::AzBuf; +use azalea_core::resource_location::ResourceLocation; use azalea_protocol_macros::ClientboundGamePacket; use azalea_registry::SoundEvent; #[derive(Clone, Debug, AzBuf, ClientboundGamePacket)] pub struct ClientboundSound { - pub sound: SoundEvent, + pub sound: azalea_registry::Holder<SoundEvent, CustomSound>, pub source: SoundSource, + // this can't be a BlockPos because it serializes differently :( pub x: i32, pub y: i32, pub z: i32, @@ -14,6 +16,12 @@ pub struct ClientboundSound { pub seed: u64, } +#[derive(Clone, Debug, AzBuf)] +pub struct CustomSound { + pub location: ResourceLocation, + pub fixed_range: Option<f32>, +} + #[derive(AzBuf, Clone, Copy, Debug)] pub enum SoundSource { Master = 0, @@ -27,3 +35,30 @@ pub enum SoundSource { Ambient = 8, Voice = 9, } + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use azalea_buf::AzaleaRead; + + use crate::packets::game::ClientboundSound; + + #[test] + fn test_read_write_custom_sound() { + let contents = [ + 0, 21, 109, 105, 110, 101, 99, 114, 97, 102, 116, 58, 97, 115, 102, 97, 115, 100, 102, + 115, 100, 102, 103, 0, 8, 0, 0, 0, 63, 255, 255, 254, 32, 0, 0, 0, 82, 66, 200, 0, 0, + 63, 128, 0, 0, 71, 94, 219, 133, 200, 13, 150, 31, + ]; + let mut buf = Cursor::new(contents.as_slice()); + let packet = ClientboundSound::azalea_read(&mut buf).unwrap(); + println!("{:?}", packet); + + assert_eq!(buf.position(), contents.len() as u64); + + let mut buf = Vec::new(); + packet.write(&mut buf).unwrap(); + assert_eq!(buf, contents); + } +} diff --git a/azalea-registry/src/lib.rs b/azalea-registry/src/lib.rs index ffead5b4..4a6df6aa 100755 --- a/azalea-registry/src/lib.rs +++ b/azalea-registry/src/lib.rs @@ -90,7 +90,6 @@ pub enum HolderSet<D: Registry, ResourceLocation: AzaleaRead + AzaleaWrite> { contents: Vec<ResourceLocation>, }, } - impl<D: Registry, ResourceLocation: AzaleaRead + AzaleaWrite> AzaleaRead for HolderSet<D, ResourceLocation> { @@ -145,6 +144,55 @@ impl<D: Registry + Debug, ResourceLocation: AzaleaRead + AzaleaWrite + Debug> De } } +/// A reference to either a registry or a custom value (usually something with a +/// ResourceLocation). +pub enum Holder<R: Registry, Direct: AzaleaRead + AzaleaWrite> { + Reference(R), + Direct(Direct), +} +impl<R: Registry, Direct: AzaleaRead + AzaleaWrite> AzaleaRead for Holder<R, Direct> { + fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + let id = u32::azalea_read_var(buf)?; + if id == 0 { + Ok(Self::Direct(Direct::azalea_read(buf)?)) + } else { + let Some(value) = R::from_u32(id - 1) else { + return Err(BufReadError::UnexpectedEnumVariant { + id: (id - 1) as i32, + }); + }; + Ok(Self::Reference(value)) + } + } +} +impl<R: Registry, Direct: AzaleaRead + AzaleaWrite> AzaleaWrite for Holder<R, Direct> { + fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + match self { + Self::Reference(value) => (value.to_u32() + 1).azalea_write_var(buf), + Self::Direct(value) => { + 0u32.azalea_write_var(buf)?; + value.azalea_write(buf) + } + } + } +} +impl<R: Registry + Debug, Direct: AzaleaRead + AzaleaWrite + Debug> Debug for Holder<R, Direct> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Reference(value) => f.debug_tuple("Reference").field(value).finish(), + Self::Direct(value) => f.debug_tuple("Direct").field(value).finish(), + } + } +} +impl<R: Registry + Clone, Direct: AzaleaRead + AzaleaWrite + Clone> Clone for Holder<R, Direct> { + fn clone(&self) -> Self { + match self { + Self::Reference(value) => Self::Reference(value.clone()), + Self::Direct(value) => Self::Direct(value.clone()), + } + } +} + registry! { /// The AI code that's currently being executed for the entity. enum Activity { |
