aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2025-02-21 17:22:00 +0000
committermat <git@matdoes.dev>2025-02-21 17:22:00 +0000
commit63b1036a96c45b0fefc6ca2501f1cc479acc95de (patch)
treea0a06a5b1111d335c4e3c92695a3673f534a7769
parentc285fadd34df2a43a5cfe1d3c02a3cc47bf69e9e (diff)
downloadazalea-drasl-63b1036a96c45b0fefc6ca2501f1cc479acc95de.tar.xz
fix CustomModelData and WrittenBookContent datacomponents
-rw-r--r--Cargo.lock1
-rwxr-xr-xazalea-buf/src/read.rs31
-rw-r--r--azalea-core/src/filterable.rs55
-rwxr-xr-xazalea-core/src/lib.rs1
-rw-r--r--azalea-inventory/Cargo.toml1
-rw-r--r--azalea-inventory/src/components.rs19
-rwxr-xr-xazalea-protocol/src/packets/game/c_container_set_slot.rs24
7 files changed, 126 insertions, 6 deletions
diff --git a/Cargo.lock b/Cargo.lock
index eb279897..f4a6adce 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -432,6 +432,7 @@ dependencies = [
"azalea-registry",
"indexmap",
"simdnbt",
+ "tracing",
"uuid",
]
diff --git a/azalea-buf/src/read.rs b/azalea-buf/src/read.rs
index d7a55716..71c96c34 100755
--- a/azalea-buf/src/read.rs
+++ b/azalea-buf/src/read.rs
@@ -21,6 +21,8 @@ pub enum BufReadError {
CouldNotReadBytes,
#[error("The received encoded string buffer length is longer than maximum allowed ({length} > {max_length})")]
StringLengthTooLong { length: u32, max_length: u32 },
+ #[error("The received Vec length is longer than maximum allowed ({length} > {max_length})")]
+ VecLengthTooLong { length: u32, max_length: u32 },
#[error("{source}")]
Io {
#[from]
@@ -183,7 +185,7 @@ impl AzaleaRead for UnsizedByteArray {
}
}
-impl<T: AzaleaRead + Send> AzaleaRead for Vec<T> {
+impl<T: AzaleaRead> AzaleaRead for Vec<T> {
default fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let length = u32::azalea_read_var(buf)? as usize;
// we limit the capacity to not get exploited into allocating a bunch
@@ -194,6 +196,23 @@ impl<T: AzaleaRead + Send> AzaleaRead for Vec<T> {
Ok(contents)
}
}
+impl<T: AzaleaRead> AzaleaReadLimited for Vec<T> {
+ fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
+ let length = u32::azalea_read_var(buf)? as usize;
+ if length > limit {
+ return Err(BufReadError::VecLengthTooLong {
+ length: length as u32,
+ max_length: limit as u32,
+ });
+ }
+
+ let mut contents = Vec::with_capacity(usize::min(length, 65536));
+ for _ in 0..length {
+ contents.push(T::azalea_read(buf)?);
+ }
+ Ok(contents)
+ }
+}
impl<K: AzaleaRead + Send + Eq + Hash, V: AzaleaRead + Send> AzaleaRead for HashMap<K, V> {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
@@ -343,6 +362,16 @@ impl<T: AzaleaReadVar> AzaleaReadVar for Option<T> {
})
}
}
+impl<T: AzaleaReadLimited> AzaleaReadLimited for Option<T> {
+ fn azalea_read_limited(buf: &mut Cursor<&[u8]>, limit: usize) -> Result<Self, BufReadError> {
+ let present = bool::azalea_read(buf)?;
+ Ok(if present {
+ Some(T::azalea_read_limited(buf, limit)?)
+ } else {
+ None
+ })
+ }
+}
// [String; 4]
impl<T: AzaleaRead, const N: usize> AzaleaRead for [T; N] {
diff --git a/azalea-core/src/filterable.rs b/azalea-core/src/filterable.rs
new file mode 100644
index 00000000..70b0d6f7
--- /dev/null
+++ b/azalea-core/src/filterable.rs
@@ -0,0 +1,55 @@
+use std::io::Cursor;
+
+use azalea_buf::{AzaleaRead, AzaleaReadLimited, AzaleaReadVar, AzaleaWrite};
+
+/// Used for written books.
+pub struct Filterable<T> {
+ pub raw: T,
+ pub filtered: Option<T>,
+}
+
+impl<T: AzaleaWrite> azalea_buf::AzaleaWrite for Filterable<T> {
+ fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> {
+ self.raw.azalea_write(buf)?;
+ self.filtered.azalea_write(buf)?;
+ Ok(())
+ }
+}
+impl<T: AzaleaRead> azalea_buf::AzaleaRead for Filterable<T> {
+ fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
+ let raw = AzaleaRead::azalea_read(buf)?;
+ let filtered = AzaleaRead::azalea_read(buf)?;
+ Ok(Self { raw, filtered })
+ }
+}
+impl<T: AzaleaReadLimited> azalea_buf::AzaleaReadLimited for Filterable<T> {
+ fn azalea_read_limited(
+ buf: &mut Cursor<&[u8]>,
+ limit: usize,
+ ) -> Result<Self, azalea_buf::BufReadError> {
+ let raw = AzaleaReadLimited::azalea_read_limited(buf, limit)?;
+ let filtered = AzaleaReadLimited::azalea_read_limited(buf, limit)?;
+ Ok(Self { raw, filtered })
+ }
+}
+impl<T: AzaleaReadVar> azalea_buf::AzaleaReadVar for Filterable<T> {
+ fn azalea_read_var(buf: &mut Cursor<&[u8]>) -> Result<Self, azalea_buf::BufReadError> {
+ let raw = AzaleaReadVar::azalea_read_var(buf)?;
+ let filtered = AzaleaReadVar::azalea_read_var(buf)?;
+ Ok(Self { raw, filtered })
+ }
+}
+
+impl<T: Clone> Clone for Filterable<T> {
+ fn clone(&self) -> Self {
+ Self {
+ raw: self.raw.clone(),
+ filtered: self.filtered.clone(),
+ }
+ }
+}
+impl<T: PartialEq> PartialEq for Filterable<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.raw == other.raw && self.filtered == other.filtered
+ }
+}
diff --git a/azalea-core/src/lib.rs b/azalea-core/src/lib.rs
index 81dbf684..ba6d61ef 100755
--- a/azalea-core/src/lib.rs
+++ b/azalea-core/src/lib.rs
@@ -9,6 +9,7 @@ pub mod data_registry;
pub mod delta;
pub mod difficulty;
pub mod direction;
+pub mod filterable;
pub mod game_type;
pub mod math;
pub mod objectives;
diff --git a/azalea-inventory/Cargo.toml b/azalea-inventory/Cargo.toml
index 4d4830db..e56392b1 100644
--- a/azalea-inventory/Cargo.toml
+++ b/azalea-inventory/Cargo.toml
@@ -17,4 +17,5 @@ azalea-registry = { path = "../azalea-registry", version = "0.11.0" }
indexmap.workspace = true
simdnbt.workspace = true
+tracing.workspace = true
uuid.workspace = true
diff --git a/azalea-inventory/src/components.rs b/azalea-inventory/src/components.rs
index 262cf215..6dd60819 100644
--- a/azalea-inventory/src/components.rs
+++ b/azalea-inventory/src/components.rs
@@ -3,12 +3,15 @@ use std::{any::Any, collections::HashMap, io::Cursor};
use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite, BufReadError};
use azalea_chat::FormattedText;
-use azalea_core::{position::GlobalPos, resource_location::ResourceLocation};
+use azalea_core::{
+ filterable::Filterable, position::GlobalPos, resource_location::ResourceLocation,
+};
use azalea_registry::{
Attribute, Block, ConsumeEffectKind, DataComponentKind, Enchantment, EntityKind, HolderSet,
Item, MobEffect, Potion, SoundEvent, TrimMaterial, TrimPattern,
};
use simdnbt::owned::{Nbt, NbtCompound};
+use tracing::trace;
use uuid::Uuid;
use crate::ItemStack;
@@ -54,6 +57,8 @@ pub fn from_kind(
// if this is causing a compile-time error, look at DataComponents.java in the
// decompiled vanilla code to see how to implement new components
+ trace!("Reading data component {kind}");
+
// note that this match statement is updated by genitemcomponents.py
Ok(match kind {
DataComponentKind::CustomData => Box::new(CustomData::azalea_read(buf)?),
@@ -328,8 +333,10 @@ impl DataComponent for AttributeModifiers {
#[derive(Clone, PartialEq, AzBuf)]
pub struct CustomModelData {
- #[var]
- pub value: i32,
+ pub floats: Vec<f32>,
+ pub flags: Vec<bool>,
+ pub strings: Vec<String>,
+ pub colors: Vec<i32>,
}
impl DataComponent for CustomModelData {
const KIND: DataComponentKind = DataComponentKind::CustomModelData;
@@ -535,13 +542,15 @@ impl DataComponent for WritableBookContent {
#[derive(Clone, PartialEq, AzBuf)]
pub struct WrittenBookContent {
- pub title: String,
+ #[limit(32)]
+ pub title: Filterable<String>,
pub author: String,
#[var]
pub generation: i32,
- pub pages: Vec<FormattedText>,
+ pub pages: Vec<Filterable<FormattedText>>,
pub resolved: bool,
}
+
impl DataComponent for WrittenBookContent {
const KIND: DataComponentKind = DataComponentKind::WrittenBookContent;
}
diff --git a/azalea-protocol/src/packets/game/c_container_set_slot.rs b/azalea-protocol/src/packets/game/c_container_set_slot.rs
index 20df5b06..d150fc60 100755
--- a/azalea-protocol/src/packets/game/c_container_set_slot.rs
+++ b/azalea-protocol/src/packets/game/c_container_set_slot.rs
@@ -11,3 +11,27 @@ pub struct ClientboundContainerSetSlot {
pub slot: u16,
pub item_stack: ItemStack,
}
+
+#[cfg(test)]
+mod test {
+ use std::io::Cursor;
+
+ use azalea_buf::AzaleaRead;
+
+ use crate::packets::game::ClientboundContainerSetSlot;
+
+ #[test]
+ fn test_read_container_set_slot() {
+ tracing_subscriber::fmt::try_init().ok();
+
+ #[rustfmt::skip]
+ let contents = [
+ 0, 2, 0, 39, 1, 246, 8, 3, 0, 8, 1, 10, 9, 0, 5, 101, 120, 116, 114, 97, 8, 0, 0, 0, 1, 0, 47, 89, 111, 117, 114, 32, 106, 111, 117, 114, 110, 97, 108, 44, 32, 99, 111, 110, 116, 97, 105, 110, 105, 110, 103, 32, 97, 108, 108, 32, 113, 117, 101, 115, 116, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 115, 8, 0, 4, 116, 101, 120, 116, 0, 0, 0, 14, 1, 191, 128, 0, 0, 0, 0, 0, 44, 7, 74, 111, 117, 114, 110, 97, 108, 0, 12, 65, 115, 116, 114, 97, 108, 99, 104, 114, 111, 109, 97, 0, 2, 10, 9, 0, 5, 101, 120, 116, 114, 97, 10, 0, 0, 0, 20, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 1, 0, 10, 117, 110, 100, 101, 114, 108, 105, 110, 101, 100, 0, 1, 0, 4, 98, 111, 108, 100, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 98, 108, 117, 101, 1, 0, 10, 111, 98, 102, 117, 115, 99, 97, 116, 101, 100, 0, 1, 0, 13, 115, 116, 114, 105, 107, 101, 116, 104, 114, 111, 117, 103, 104, 0, 8, 0, 4, 116, 101, 120, 116, 0, 1, 45, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 12, 81, 117, 101, 115, 116, 32, 83, 116, 97, 116, 117, 115, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 1, 45, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 5, 98, 108, 97, 99, 107, 8, 0, 4, 116, 101, 120, 116, 0, 3, 10, 32, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 114, 97, 121, 8, 0, 4, 116, 101, 120, 116, 0, 9, 76, 111, 99, 107, 101, 100, 10, 32, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 10, 100, 97, 114, 107, 95, 103, 114, 101, 101, 110, 8, 0, 4, 116, 101, 120, 116, 0, 17, 67, 97, 110, 32, 98, 101, 32, 83, 116, 97, 114, 116, 101, 100, 10, 32, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 111, 108, 100, 8, 0, 4, 116, 101, 120, 116, 0, 10, 83, 116, 97, 114, 116, 101, 100, 10, 32, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 103, 114, 97, 121, 8, 0, 4, 116, 101, 120, 116, 0, 19, 70, 105, 110, 105, 115, 104, 101, 100, 47, 67, 111, 111, 108, 100, 111, 119, 110, 10, 10, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 1, 45, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 10, 81, 117, 101, 115, 116, 32, 76, 105, 115, 116, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 1, 45, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 8, 100, 97, 114, 107, 95, 114, 101, 100, 8, 0, 4, 116, 101, 120, 116, 0, 3, 10, 32, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 103, 114, 97, 121, 8, 0, 4, 116, 101, 120, 116, 0, 15, 67, 104, 101, 116, 104, 32, 67, 111, 108, 108, 101, 99, 116, 111, 114, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 8, 100, 97, 114, 107, 95, 114, 101, 100, 8, 0, 4, 116, 101, 120, 116, 0, 1, 10, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 1, 45, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 17, 82, 101, 112, 101, 97, 116, 97, 98, 108, 101, 32, 81, 117, 101, 115, 116, 115, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 1, 45, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 8, 100, 97, 114, 107, 95, 114, 101, 100, 8, 0, 4, 116, 101, 120, 116, 0, 3, 10, 32, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 10, 100, 97, 114, 107, 95, 103, 114, 101, 101, 110, 8, 0, 4, 116, 101, 120, 116, 0, 16, 68, 97, 105, 108, 121, 32, 67, 111, 109, 109, 105, 115, 115, 105, 111, 110, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 8, 100, 97, 114, 107, 95, 114, 101, 100, 8, 0, 4, 116, 101, 120, 116, 0, 1, 10, 0, 8, 0, 4, 116, 101, 120, 116, 0, 0, 0, 0, 10, 9, 0, 5, 101, 120, 116, 114, 97, 10, 0, 0, 0, 12, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 11, 49, 48, 46, 48, 50, 46, 50, 48, 50, 53, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 103, 111, 108, 100, 8, 0, 4, 116, 101, 120, 116, 0, 6, 49, 55, 58, 48, 48, 10, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 1, 45, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 4, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 16, 68, 97, 105, 108, 121, 32, 67, 111, 109, 109, 105, 115, 115, 105, 111, 110, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 9, 100, 97, 114, 107, 95, 98, 108, 117, 101, 8, 0, 4, 116, 101, 120, 116, 0, 1, 45, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 5, 98, 108, 97, 99, 107, 8, 0, 4, 116, 101, 120, 116, 0, 11, 10, 32, 32, 84, 97, 108, 107, 32, 116, 111, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 10, 100, 97, 114, 107, 95, 103, 114, 101, 101, 110, 8, 0, 4, 116, 101, 120, 116, 0, 11, 65, 113, 117, 97, 10, 75, 121, 114, 101, 108, 108, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 5, 98, 108, 97, 99, 107, 8, 0, 4, 116, 101, 120, 116, 0, 4, 32, 97, 116, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 10, 100, 97, 114, 107, 95, 103, 114, 101, 101, 110, 8, 0, 4, 116, 101, 120, 116, 0, 22, 91, 75, 114, 105, 111, 58, 10, 52, 52, 56, 57, 44, 32, 51, 54, 44, 32, 49, 51, 49, 52, 93, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 5, 98, 108, 97, 99, 107, 8, 0, 4, 116, 101, 120, 116, 0, 7, 46, 10, 32, 32, 10, 32, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 10, 100, 97, 114, 107, 95, 103, 114, 101, 101, 110, 8, 0, 4, 116, 101, 120, 116, 0, 9, 82, 101, 119, 97, 114, 100, 115, 58, 32, 0, 1, 0, 6, 105, 116, 97, 108, 105, 99, 0, 8, 0, 5, 99, 111, 108, 111, 114, 0, 5, 98, 108, 97, 99, 107, 8, 0, 4, 116, 101, 120, 116, 0, 6, 36, 53, 48, 48, 48, 10, 0, 8, 0, 4, 116, 101, 120, 116, 0, 0, 0, 0, 0
+ ];
+ let mut buf = Cursor::new(contents.as_slice());
+ let packet = ClientboundContainerSetSlot::azalea_read(&mut buf).unwrap();
+ println!("{:?}", packet);
+
+ assert_eq!(buf.position(), contents.len() as u64);
+ }
+}