aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2025-12-16 09:42:54 -0200
committermat <git@matdoes.dev>2025-12-16 09:42:54 -0200
commit6f2fe2c9e5af1f2fa2c1b99c3d4ea0a7e90ae16c (patch)
treeb01afabf10b51e3024dfdc139803b590a36b08c2
parent9bd529277f5025805da95f081657c180972e487e (diff)
downloadazalea-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.rs29
-rw-r--r--azalea-buf/azalea-buf-macros/src/read.rs20
-rw-r--r--azalea-buf/azalea-buf-macros/src/write.rs22
-rw-r--r--azalea-client/src/plugins/movement.rs31
-rw-r--r--azalea-client/src/plugins/packet/game/mod.rs17
-rw-r--r--azalea-protocol/src/packets/game/c_explode.rs11
-rw-r--r--azalea-protocol/src/packets/game/c_update_advancements.rs4
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)?;