From 7120842f9d2c659a2f12d8922299c2a761bc5582 Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Sun, 10 Aug 2025 18:55:23 -0500 Subject: Send correct data component checksums (#234) * start implementing data component crc32 hashes * start doing serde impls for checksums * make more components hashable * make all data components serializable * support recursive components * fix simdnbt dep * update changelog * clippy --- CHANGELOG.md | 1 + Cargo.lock | 23 +- Cargo.toml | 2 +- azalea-buf/Cargo.toml | 1 + azalea-buf/azalea-buf-macros/src/read.rs | 10 +- azalea-buf/azalea-buf-macros/src/write.rs | 12 +- azalea-chat/src/base_component.rs | 12 +- azalea-chat/src/click_event.rs | 16 + azalea-chat/src/component.rs | 6 +- azalea-chat/src/hover_event.rs | 20 + azalea-chat/src/lib.rs | 2 + azalea-chat/src/style.rs | 132 ++- azalea-chat/src/text_component.rs | 18 +- azalea-chat/src/translatable_component.rs | 10 +- azalea-chat/tests/integration_test.rs | 2 +- azalea-client/src/plugins/inventory.rs | 25 +- azalea-core/Cargo.toml | 6 +- azalea-core/src/checksum.rs | 823 ++++++++++++++ azalea-core/src/codec_utils.rs | 83 ++ azalea-core/src/direction.rs | 8 +- azalea-core/src/filterable.rs | 3 + azalea-core/src/hit_result.rs | 19 +- azalea-core/src/lib.rs | 2 + azalea-core/src/position.rs | 39 +- azalea-core/src/resource_location.rs | 3 - azalea-core/src/sound.rs | 3 +- azalea-inventory/Cargo.toml | 4 +- azalea-inventory/src/components.rs | 1122 ++++++++++---------- .../src/default_components/generated.rs | 274 ++--- azalea-inventory/src/default_components/mod.rs | 6 +- azalea-inventory/src/item/consume_effect.rs | 10 +- azalea-inventory/src/slot.rs | 117 +- azalea-inventory/tests/components.rs | 201 ++++ azalea-protocol/Cargo.toml | 6 +- .../src/packets/game/s_container_click.rs | 34 +- azalea-registry/azalea-registry-macros/src/lib.rs | 21 +- azalea-registry/src/data.rs | 11 + azalea-registry/src/lib.rs | 59 +- azalea/Cargo.toml | 7 +- codegen/lib/code/data_components.py | 80 +- 40 files changed, 2349 insertions(+), 884 deletions(-) create mode 100644 azalea-chat/src/click_event.rs create mode 100644 azalea-chat/src/hover_event.rs create mode 100644 azalea-core/src/checksum.rs create mode 100644 azalea-core/src/codec_utils.rs create mode 100644 azalea-inventory/tests/components.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d2194a3..0484dc69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ is breaking anyways, semantic versioning is not followed. - Movement code was updated with the changes from 1.21.5, so it no longer flags Grim. - `azalea-chat` now correctly handles arrays of integers in the `with` field. (@qwqawawow) - Inventories now use the correct max stack sizes. +- Clients now send the correct data component checksums when interacting with items. ## [0.13.0+mc1.21.5] - 2025-06-15 diff --git a/Cargo.lock b/Cargo.lock index ba291f43..07ddee83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -302,6 +302,7 @@ version = "0.13.0+mc1.21.8" dependencies = [ "azalea-buf-macros", "byteorder", + "serde", "serde_json", "simdnbt", "thiserror 2.0.12", @@ -376,12 +377,15 @@ dependencies = [ "azalea-chat", "azalea-registry", "bevy_ecs", + "crc32c", "indexmap", "nohash-hasher", "num-traits", "serde", "simdnbt", + "thiserror 2.0.12", "tracing", + "uuid", ] [[package]] @@ -434,6 +438,8 @@ dependencies = [ "azalea-inventory-macros", "azalea-registry", "indexmap", + "serde", + "serde_json", "simdnbt", "tracing", "uuid", @@ -494,7 +500,6 @@ dependencies = [ "azalea-registry", "azalea-world", "bevy_ecs", - "crc32fast", "flate2", "futures", "futures-lite", @@ -1064,6 +1069,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32c" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" +dependencies = [ + "rustc_version", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -3066,10 +3080,11 @@ dependencies = [ [[package]] name = "simdnbt" version = "0.7.2" -source = "git+https://github.com/azalea-rs/simdnbt#1505d233fd277353f1dba9845360880b74ff3a71" +source = "git+https://github.com/azalea-rs/simdnbt#6c1100f38262abab2f080c454351c6c594921a95" dependencies = [ "byteorder", "flate2", + "serde", "simd_cesu8", "simdnbt-derive", "thiserror 2.0.12", @@ -3078,7 +3093,7 @@ dependencies = [ [[package]] name = "simdnbt-derive" version = "0.7.0" -source = "git+https://github.com/azalea-rs/simdnbt#1505d233fd277353f1dba9845360880b74ff3a71" +source = "git+https://github.com/azalea-rs/simdnbt#6c1100f38262abab2f080c454351c6c594921a95" dependencies = [ "proc-macro2", "quote", @@ -3798,7 +3813,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 421f8302..85a24965 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,7 +80,7 @@ num-format = "0.4.4" indexmap = "2.10.0" paste = "1.0.15" compact_str = "0.9.0" -crc32fast = "1.5.0" +crc32c = "0.6.8" async-compat = "0.2.4" azalea-block-macros = { path = "azalea-block/azalea-block-macros", version = "0.13.0" } diff --git a/azalea-buf/Cargo.toml b/azalea-buf/Cargo.toml index e5fc7f07..793332b7 100644 --- a/azalea-buf/Cargo.toml +++ b/azalea-buf/Cargo.toml @@ -9,6 +9,7 @@ repository.workspace = true [dependencies] azalea-buf-macros.workspace = true byteorder.workspace = true +serde.workspace = true serde_json = { workspace = true, optional = true } simdnbt.workspace = true thiserror.workspace = true diff --git a/azalea-buf/azalea-buf-macros/src/read.rs b/azalea-buf/azalea-buf-macros/src/read.rs index 5b4518bb..3ec6133e 100644 --- a/azalea-buf/azalea-buf-macros/src/read.rs +++ b/azalea-buf/azalea-buf-macros/src/read.rs @@ -9,7 +9,7 @@ pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenS quote! { impl azalea_buf::AzaleaRead for #ident { - fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> std::result::Result { #(#read_fields)* Ok(Self { #(#read_field_names: #read_field_names),* @@ -21,7 +21,7 @@ pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenS syn::Fields::Unit => { quote! { impl azalea_buf::AzaleaRead for #ident { - fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> std::result::Result { Ok(Self) } } @@ -32,7 +32,7 @@ pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenS quote! { impl azalea_buf::AzaleaRead for #ident { - fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> std::result::Result { Ok(Self( #(#read_fields),* )) @@ -136,14 +136,14 @@ pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenS quote! { impl azalea_buf::AzaleaRead for #ident { - fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> Result { + fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> std::result::Result { let id = azalea_buf::AzaleaReadVar::azalea_read_var(buf)?; Self::azalea_read_id(buf, id) } } impl #ident { - pub fn azalea_read_id(buf: &mut std::io::Cursor<&[u8]>, id: u32) -> Result { + pub fn azalea_read_id(buf: &mut std::io::Cursor<&[u8]>, id: u32) -> std::result::Result { match id { #match_contents // you'd THINK this throws an error, but mojang decided to make it default for some reason diff --git a/azalea-buf/azalea-buf-macros/src/write.rs b/azalea-buf/azalea-buf-macros/src/write.rs index d433d1d7..12739eb5 100644 --- a/azalea-buf/azalea-buf-macros/src/write.rs +++ b/azalea-buf/azalea-buf-macros/src/write.rs @@ -11,7 +11,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token quote! { impl azalea_buf::AzaleaWrite for #ident { - fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { #write_fields Ok(()) } @@ -21,7 +21,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token syn::Fields::Unit => { quote! { impl azalea_buf::AzaleaWrite for #ident { - fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { Ok(()) } } @@ -32,7 +32,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token quote! { impl azalea_buf::AzaleaWrite for #ident { - fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { #write_fields Ok(()) } @@ -144,7 +144,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token if is_data_enum { quote! { impl azalea_buf::AzaleaWrite for #ident { - fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { match self { #match_arms } @@ -152,7 +152,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token } } impl #ident { - pub fn write_without_id(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + pub fn write_without_id(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { match self { #match_arms_without_id } @@ -164,7 +164,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token // optimization: if it doesn't have data we can just do `as u32` quote! { impl azalea_buf::AzaleaWrite for #ident { - fn azalea_write(&self, buf: &mut impl std::io::Write) -> Result<(), std::io::Error> { + fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { azalea_buf::AzaleaWriteVar::azalea_write_var(&(*self as u32), buf) } } diff --git a/azalea-chat/src/base_component.rs b/azalea-chat/src/base_component.rs index cbc5ae8b..366904c7 100644 --- a/azalea-chat/src/base_component.rs +++ b/azalea-chat/src/base_component.rs @@ -2,20 +2,26 @@ use serde::Serialize; use crate::{FormattedText, style::Style}; -#[derive(Clone, Debug, PartialEq, Serialize, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Serialize)] pub struct BaseComponent { // implements mutablecomponent #[serde(skip_serializing_if = "Vec::is_empty")] pub siblings: Vec, #[serde(flatten)] - pub style: Style, + pub style: Box