diff options
| author | mat <git@matdoes.dev> | 2025-12-16 09:42:54 -0200 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2025-12-16 09:42:54 -0200 |
| commit | 6f2fe2c9e5af1f2fa2c1b99c3d4ea0a7e90ae16c (patch) | |
| tree | b01afabf10b51e3024dfdc139803b590a36b08c2 | |
| parent | 9bd529277f5025805da95f081657c180972e487e (diff) | |
| download | azalea-drasl-6f2fe2c9e5af1f2fa2c1b99c3d4ea0a7e90ae16c.tar.xz | |
change KnockbackEvent to an EntityEvent and fix ClientboundExplode representation
ty mahtog for pointing out the latter issue <3
| -rw-r--r-- | azalea-buf/azalea-buf-macros/src/lib.rs | 29 | ||||
| -rw-r--r-- | azalea-buf/azalea-buf-macros/src/read.rs | 20 | ||||
| -rw-r--r-- | azalea-buf/azalea-buf-macros/src/write.rs | 22 | ||||
| -rw-r--r-- | azalea-client/src/plugins/movement.rs | 31 | ||||
| -rw-r--r-- | azalea-client/src/plugins/packet/game/mod.rs | 17 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/c_explode.rs | 11 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/c_update_advancements.rs | 4 |
7 files changed, 83 insertions, 51 deletions
diff --git a/azalea-buf/azalea-buf-macros/src/lib.rs b/azalea-buf/azalea-buf-macros/src/lib.rs index c4938f89..965e19c9 100644 --- a/azalea-buf/azalea-buf-macros/src/lib.rs +++ b/azalea-buf/azalea-buf-macros/src/lib.rs @@ -7,24 +7,39 @@ use syn::{DeriveInput, parse_macro_input}; #[proc_macro_derive(AzaleaRead, attributes(var))] pub fn derive_azalearead(input: TokenStream) -> TokenStream { - let DeriveInput { ident, data, .. } = parse_macro_input!(input); + let DeriveInput { + ident, + generics, + data, + .. + } = parse_macro_input!(input); - read::create_impl_azalearead(&ident, &data).into() + read::create_impl_azalearead(&ident, &generics, &data).into() } #[proc_macro_derive(AzaleaWrite, attributes(var))] pub fn derive_azaleawrite(input: TokenStream) -> TokenStream { - let DeriveInput { ident, data, .. } = parse_macro_input!(input); + let DeriveInput { + ident, + generics, + data, + .. + } = parse_macro_input!(input); - write::create_impl_azaleawrite(&ident, &data).into() + write::create_impl_azaleawrite(&ident, &generics, &data).into() } #[proc_macro_derive(AzBuf, attributes(var, limit))] pub fn derive_azbuf(input: TokenStream) -> TokenStream { - let DeriveInput { ident, data, .. } = parse_macro_input!(input); + let DeriveInput { + ident, + generics, + data, + .. + } = parse_macro_input!(input); - let writable = write::create_impl_azaleawrite(&ident, &data); - let readable = read::create_impl_azalearead(&ident, &data); + let writable = write::create_impl_azaleawrite(&ident, &generics, &data); + let readable = read::create_impl_azalearead(&ident, &generics, &data); quote! { #writable #readable diff --git a/azalea-buf/azalea-buf-macros/src/read.rs b/azalea-buf/azalea-buf-macros/src/read.rs index 3ec6133e..9f4fa78a 100644 --- a/azalea-buf/azalea-buf-macros/src/read.rs +++ b/azalea-buf/azalea-buf-macros/src/read.rs @@ -1,14 +1,20 @@ use quote::{ToTokens, quote}; -use syn::{Data, Field, FieldsNamed, Ident, punctuated::Punctuated, token::Comma}; +use syn::{Data, Field, FieldsNamed, Generics, Ident, punctuated::Punctuated, token::Comma}; + +pub fn create_impl_azalearead( + ident: &Ident, + generics: &Generics, + data: &Data, +) -> proc_macro2::TokenStream { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); -pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { match data { syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { syn::Fields::Named(FieldsNamed { named, .. }) => { let (read_fields, read_field_names) = read_named_fields(named); quote! { - impl azalea_buf::AzaleaRead for #ident { + impl #impl_generics azalea_buf::AzaleaRead for #ident #ty_generics #where_clause { fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> std::result::Result<Self, azalea_buf::BufReadError> { #(#read_fields)* Ok(Self { @@ -20,7 +26,7 @@ pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenS } syn::Fields::Unit => { quote! { - impl azalea_buf::AzaleaRead for #ident { + impl #impl_generics azalea_buf::AzaleaRead for #ident #ty_generics #where_clause { fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> std::result::Result<Self, azalea_buf::BufReadError> { Ok(Self) } @@ -31,7 +37,7 @@ pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenS let read_fields = read_unnamed_fields(&fields.unnamed); quote! { - impl azalea_buf::AzaleaRead for #ident { + impl #impl_generics azalea_buf::AzaleaRead for #ident #ty_generics #where_clause { fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> std::result::Result<Self, azalea_buf::BufReadError> { Ok(Self( #(#read_fields),* @@ -135,14 +141,14 @@ pub fn create_impl_azalearead(ident: &Ident, data: &Data) -> proc_macro2::TokenS let first_reader = first_reader.expect("There should be at least one variant"); quote! { - impl azalea_buf::AzaleaRead for #ident { + impl #impl_generics azalea_buf::AzaleaRead for #ident #ty_generics #where_clause { fn azalea_read(buf: &mut std::io::Cursor<&[u8]>) -> std::result::Result<Self, azalea_buf::BufReadError> { let id = azalea_buf::AzaleaReadVar::azalea_read_var(buf)?; Self::azalea_read_id(buf, id) } } - impl #ident { + impl #impl_generics #ident #ty_generics #where_clause { pub fn azalea_read_id(buf: &mut std::io::Cursor<&[u8]>, id: u32) -> std::result::Result<Self, azalea_buf::BufReadError> { match id { #match_contents diff --git a/azalea-buf/azalea-buf-macros/src/write.rs b/azalea-buf/azalea-buf-macros/src/write.rs index 12739eb5..7bd58d29 100644 --- a/azalea-buf/azalea-buf-macros/src/write.rs +++ b/azalea-buf/azalea-buf-macros/src/write.rs @@ -1,8 +1,14 @@ use proc_macro2::Span; use quote::{ToTokens, quote}; -use syn::{Data, Field, FieldsNamed, Ident, punctuated::Punctuated, token::Comma}; +use syn::{Data, Field, FieldsNamed, Generics, Ident, punctuated::Punctuated, token::Comma}; + +pub fn create_impl_azaleawrite( + ident: &Ident, + generics: &Generics, + data: &Data, +) -> proc_macro2::TokenStream { + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); -pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::TokenStream { match data { syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { syn::Fields::Named(FieldsNamed { named, .. }) => { @@ -10,7 +16,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token write_named_fields(named, Some(&Ident::new("self", Span::call_site()))); quote! { - impl azalea_buf::AzaleaWrite for #ident { + impl #impl_generics azalea_buf::AzaleaWrite for #ident #ty_generics #where_clause { fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { #write_fields Ok(()) @@ -20,7 +26,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token } syn::Fields::Unit => { quote! { - impl azalea_buf::AzaleaWrite for #ident { + impl #impl_generics azalea_buf::AzaleaWrite for #ident #ty_generics #where_clause { fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { Ok(()) } @@ -31,7 +37,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token let write_fields = write_unnamed_fields(&fields.unnamed); quote! { - impl azalea_buf::AzaleaWrite for #ident { + impl #impl_generics azalea_buf::AzaleaWrite for #ident #ty_generics #where_clause { fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { #write_fields Ok(()) @@ -143,7 +149,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token } if is_data_enum { quote! { - impl azalea_buf::AzaleaWrite for #ident { + impl #impl_generics azalea_buf::AzaleaWrite for #ident #ty_generics #where_clause { fn azalea_write(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { match self { #match_arms @@ -151,7 +157,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token Ok(()) } } - impl #ident { + impl #impl_generics #ident #ty_generics #where_clause { pub fn write_without_id(&self, buf: &mut impl std::io::Write) -> std::result::Result<(), std::io::Error> { match self { #match_arms_without_id @@ -163,7 +169,7 @@ pub fn create_impl_azaleawrite(ident: &Ident, data: &Data) -> proc_macro2::Token } else { // optimization: if it doesn't have data we can just do `as u32` quote! { - impl azalea_buf::AzaleaWrite for #ident { + impl #impl_generics azalea_buf::AzaleaWrite for #ident #ty_generics #where_clause { 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-client/src/plugins/movement.rs b/azalea-client/src/plugins/movement.rs index fd85de2d..c4409722 100644 --- a/azalea-client/src/plugins/movement.rs +++ b/azalea-client/src/plugins/movement.rs @@ -46,10 +46,9 @@ impl Plugin for MovementPlugin { fn build(&self, app: &mut App) { app.add_message::<StartWalkEvent>() .add_message::<StartSprintEvent>() - .add_message::<KnockbackEvent>() .add_systems( Update, - (handle_sprint, handle_walk, handle_knockback) + (handle_sprint, handle_walk) .chain() .in_set(MoveEventsSystems) .after(update_bounding_box) @@ -70,7 +69,8 @@ impl Plugin for MovementPlugin { send_position.after(PhysicsSystems), ) .chain(), - ); + ) + .add_observer(handle_knockback); } } @@ -655,27 +655,26 @@ fn has_enough_impulse_to_start_sprinting(physics_state: &PhysicsState) -> bool { /// Usually `KnockbackKind::Set` is used for normal knockback and /// `KnockbackKind::Add` is used for explosions, but some servers (notably /// Hypixel) use explosions for knockback. -#[derive(Message)] +#[derive(EntityEvent, Debug, Clone)] pub struct KnockbackEvent { pub entity: Entity, - pub knockback: KnockbackType, + pub data: KnockbackData, } -pub enum KnockbackType { +#[derive(Debug, Clone)] +pub enum KnockbackData { Set(Vec3), Add(Vec3), } -pub fn handle_knockback(mut query: Query<&mut Physics>, mut events: MessageReader<KnockbackEvent>) { - for event in events.read() { - if let Ok(mut physics) = query.get_mut(event.entity) { - match event.knockback { - KnockbackType::Set(velocity) => { - physics.velocity = velocity; - } - KnockbackType::Add(velocity) => { - physics.velocity += velocity; - } +pub fn handle_knockback(knockback: On<KnockbackEvent>, mut query: Query<&mut Physics>) { + if let Ok(mut physics) = query.get_mut(knockback.entity) { + match knockback.data { + KnockbackData::Set(velocity) => { + physics.velocity = velocity; + } + KnockbackData::Add(velocity) => { + physics.velocity += velocity; } } } diff --git a/azalea-client/src/plugins/packet/game/mod.rs b/azalea-client/src/plugins/packet/game/mod.rs index f39a9f8f..edb755c9 100644 --- a/azalea-client/src/plugins/packet/game/mod.rs +++ b/azalea-client/src/plugins/packet/game/mod.rs @@ -34,7 +34,7 @@ use crate::{ interact::BlockStatePredictionHandler, inventory::{ClientsideCloseContainerEvent, MenuOpenedEvent, SetContainerContentEvent}, local_player::{Hunger, InstanceHolder, LocalGameMode, TabList}, - movement::{KnockbackEvent, KnockbackType}, + movement::{KnockbackData, KnockbackEvent}, packet::{as_system, declare_packet_handlers}, player::{GameProfileComponent, PlayerInfo}, tick_counter::TicksConnected, @@ -738,14 +738,13 @@ impl GamePacketHandler<'_> { // this is to make sure the same entity velocity update doesn't get sent // multiple times when in swarms - let knockback = KnockbackType::Set(p.delta.to_vec3()); + let data = KnockbackData::Set(p.delta.to_vec3()); commands.entity(entity).queue(RelativeEntityUpdate::new( instance_holder.partial_instance.clone(), move |entity_mut| { - entity_mut.world_scope(|world| { - world.write_message(KnockbackEvent { entity, knockback }) - }); + entity_mut + .world_scope(|world| world.trigger(KnockbackEvent { entity, data })); }, )); }, @@ -1262,13 +1261,13 @@ impl GamePacketHandler<'_> { pub fn delete_chat(&mut self, _p: &ClientboundDeleteChat) {} pub fn explode(&mut self, p: &ClientboundExplode) { - trace!("Got explode packet {p:?}"); + println!("Got explode packet {p:?}"); - as_system::<MessageWriter<_>>(self.ecs, |mut knockback_events| { + as_system::<Commands>(self.ecs, |mut knockback_events| { if let Some(knockback) = p.player_knockback { - knockback_events.write(KnockbackEvent { + knockback_events.trigger(KnockbackEvent { entity: self.player, - knockback: KnockbackType::Set(knockback), + data: KnockbackData::Set(knockback), }); } }); diff --git a/azalea-protocol/src/packets/game/c_explode.rs b/azalea-protocol/src/packets/game/c_explode.rs index 2c934c31..be86abb6 100644 --- a/azalea-protocol/src/packets/game/c_explode.rs +++ b/azalea-protocol/src/packets/game/c_explode.rs @@ -1,4 +1,4 @@ -use azalea_buf::AzBuf; +use azalea_buf::{AzBuf, AzaleaRead, AzaleaWrite}; use azalea_core::position::Vec3; use azalea_entity::particle::Particle; use azalea_protocol_macros::ClientboundGamePacket; @@ -12,7 +12,14 @@ pub struct ClientboundExplode { pub player_knockback: Option<Vec3>, pub explosion_particle: Particle, pub explosion_sound: SoundEvent, - pub block_particles: Vec<ExplosionParticleInfo>, + pub block_particles: Vec<Weighted<ExplosionParticleInfo>>, +} + +#[derive(AzBuf, Clone, Debug, PartialEq)] +pub struct Weighted<T: AzaleaRead + AzaleaWrite> { + pub value: T, + #[var] + pub weight: i32, } #[derive(AzBuf, Clone, Debug, PartialEq)] diff --git a/azalea-protocol/src/packets/game/c_update_advancements.rs b/azalea-protocol/src/packets/game/c_update_advancements.rs index 07479656..62881b9d 100644 --- a/azalea-protocol/src/packets/game/c_update_advancements.rs +++ b/azalea-protocol/src/packets/game/c_update_advancements.rs @@ -3,7 +3,7 @@ use std::{ io::{self, Cursor, Write}, }; -use azalea_buf::AzBuf; +use azalea_buf::{AzBuf, AzaleaWrite}; use azalea_chat::FormattedText; use azalea_inventory::ItemStack; use azalea_protocol_macros::ClientboundGamePacket; @@ -40,7 +40,7 @@ pub struct DisplayInfo { pub y: f32, } -impl azalea_buf::AzaleaWrite for DisplayInfo { +impl AzaleaWrite for DisplayInfo { fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> { self.title.azalea_write(buf)?; self.description.azalea_write(buf)?; |
