diff options
| author | mat <git@matdoes.dev> | 2026-03-18 11:07:31 +0330 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2026-03-18 11:07:31 +0330 |
| commit | 9fa09259aa9daa9119d95f4b5634d017c0262596 (patch) | |
| tree | 4443e0454aedd41ce2f8fb3a941ad3730626e1a4 | |
| parent | 8b2a9d512bad11be2ea40899e2d834f643fdc2e8 (diff) | |
| download | azalea-drasl-9fa09259aa9daa9119d95f4b5634d017c0262596.tar.xz | |
merge logic for the three move_entity packets
| -rw-r--r-- | azalea-client/src/lib.rs | 1 | ||||
| -rw-r--r-- | azalea-client/src/plugins/packet/game/mod.rs | 233 | ||||
| -rw-r--r-- | azalea-client/tests/simulation/move_despawned_entity.rs | 8 | ||||
| -rw-r--r-- | azalea-core/src/delta.rs | 2 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs | 20 | ||||
| -rw-r--r-- | azalea-protocol/src/packets/game/c_move_entity_rot.rs | 7 | ||||
| -rw-r--r-- | azalea-world/src/lib.rs | 1 | ||||
| -rw-r--r-- | azalea/src/lib.rs | 1 |
8 files changed, 143 insertions, 130 deletions
diff --git a/azalea-client/src/lib.rs b/azalea-client/src/lib.rs index 59730bf6..fbe88bf7 100644 --- a/azalea-client/src/lib.rs +++ b/azalea-client/src/lib.rs @@ -1,6 +1,5 @@ #![doc = include_str!("../README.md")] #![feature(error_generic_member_access)] -#![feature(never_type)] pub mod account; mod client; diff --git a/azalea-client/src/plugins/packet/game/mod.rs b/azalea-client/src/plugins/packet/game/mod.rs index 8c573ade..16d81eae 100644 --- a/azalea-client/src/plugins/packet/game/mod.rs +++ b/azalea-client/src/plugins/packet/game/mod.rs @@ -3,6 +3,7 @@ mod events; use std::{collections::HashSet, sync::Arc}; use azalea_core::{ + delta::PositionDelta8, entity_id::MinecraftEntityId, game_type::GameMode, position::{ChunkPos, Vec3}, @@ -16,13 +17,16 @@ use azalea_entity::{ }; use azalea_protocol::{ common::movements::MoveFlags, - packets::{ConnectionProtocol, game::*}, + packets::{ + ConnectionProtocol, + game::{c_move_entity_pos_rot::CompactLookDirection, *}, + }, }; use azalea_registry::builtin::EntityKind; use azalea_world::{PartialWorld, WorldName, Worlds}; use bevy_ecs::{prelude::*, system::SystemState}; pub use events::*; -use tracing::{debug, error, trace, warn}; +use tracing::{debug, error, warn}; use crate::{ ClientInformation, @@ -845,142 +849,78 @@ impl GamePacketHandler<'_> { as_system::<( Commands, Query<(&EntityIdIndex, &WorldHolder)>, - Query<(&mut Physics, &mut Position)>, + MoveEntityQuery, EntityUpdateQuery, )>( self.ecs, - |(mut commands, player_query, mut entity_query, entity_update_query)| { - let (entity_id_index, world_holder) = player_query.get(self.player).unwrap(); - - debug!("Got move entity pos packet {p:?}"); - - let entity_id = p.entity_id; - let Some(entity) = entity_id_index.get_by_minecraft_entity(entity_id) else { - debug!("Got move entity pos packet for unknown entity id {entity_id}"); - return; - }; - - let new_delta = p.delta.clone(); - let new_on_ground = p.on_ground; - - let (mut physics, mut position) = entity_query.get_mut(entity).unwrap(); - - if !should_apply_entity_update( - &mut commands, - &mut world_holder.partial.write(), - entity, + |(commands, player_query, entity_query, entity_update_query)| { + move_entity( + self.player, + commands, + MoveEntity { + entity_id: p.entity_id, + delta: Some(p.delta), + look_direction: None, + on_ground: p.on_ground, + }, + player_query, + entity_query, entity_update_query, - ) { - return; - } - - let new_pos = physics.vec_delta_codec.decode(&new_delta); - physics.vec_delta_codec.set_base(new_pos); - physics.set_on_ground(new_on_ground); - - if new_pos != **position { - **position = new_pos; - } - - trace!("Applied movement update for {entity_id} / {entity}"); + ); }, ); } - pub fn move_entity_pos_rot(&mut self, p: &ClientboundMoveEntityPosRot) { as_system::<( Commands, Query<(&EntityIdIndex, &WorldHolder)>, - Query<(&mut Physics, &mut Position, &mut LookDirection)>, + MoveEntityQuery, EntityUpdateQuery, )>( self.ecs, - |(mut commands, player_query, mut entity_query, entity_update_query)| { - let (entity_id_index, world_holder) = player_query.get(self.player).unwrap(); - - debug!("Got move entity pos rot packet {p:?}"); - - let entity = entity_id_index.get_by_minecraft_entity(p.entity_id); - - let Some(entity) = entity else { - // often triggered by hypixel :( - debug!( - "Got move entity pos rot packet for unknown entity id {}", - p.entity_id - ); - return; - }; - - let new_delta = p.delta.clone(); - let new_look_direction = LookDirection::new( - (p.y_rot as i32 * 360) as f32 / 256., - (p.x_rot as i32 * 360) as f32 / 256., - ); - - let new_on_ground = p.on_ground; - - let (mut physics, mut position, mut look_direction) = - entity_query.get_mut(entity).unwrap(); - - if !should_apply_entity_update( - &mut commands, - &mut world_holder.partial.write(), - entity, + |(commands, player_query, entity_query, entity_update_query)| { + move_entity( + self.player, + commands, + MoveEntity { + entity_id: p.entity_id, + delta: Some(p.delta), + look_direction: Some(p.look_direction), + on_ground: p.on_ground, + }, + player_query, + entity_query, entity_update_query, - ) { - return; - } - - let new_position = physics.vec_delta_codec.decode(&new_delta); - physics.vec_delta_codec.set_base(new_position); - physics.set_on_ground(new_on_ground); - - if new_position != **position { - **position = new_position; - } - - if new_look_direction != *look_direction { - *look_direction = new_look_direction; - } + ); }, ); } - pub fn move_entity_rot(&mut self, p: &ClientboundMoveEntityRot) { - as_system::<(Commands, Query<(&EntityIdIndex, &WorldHolder)>)>( + as_system::<( + Commands, + Query<(&EntityIdIndex, &WorldHolder)>, + MoveEntityQuery, + EntityUpdateQuery, + )>( self.ecs, - |(mut commands, query)| { - let (entity_id_index, world_holder) = query.get(self.player).unwrap(); - - let entity = entity_id_index.get_by_minecraft_entity(p.entity_id); - if let Some(entity) = entity { - let new_look_direction = LookDirection::new( - (p.y_rot as i32 * 360) as f32 / 256., - (p.x_rot as i32 * 360) as f32 / 256., - ); - let new_on_ground = p.on_ground; - - commands.entity(entity).queue(RelativeEntityUpdate::new( - world_holder.partial.clone(), - move |entity_mut| { - let mut physics = entity_mut.get_mut::<Physics>().unwrap(); - physics.set_on_ground(new_on_ground); - - let mut look_direction = entity_mut.get_mut::<LookDirection>().unwrap(); - if new_look_direction != *look_direction { - *look_direction = new_look_direction; - } - }, - )); - } else { - warn!( - "Got move entity rot packet for unknown entity id {}", - p.entity_id - ); - } + |(commands, player_query, entity_query, entity_update_query)| { + move_entity( + self.player, + commands, + MoveEntity { + entity_id: p.entity_id, + delta: None, + look_direction: Some(p.look_direction), + on_ground: p.on_ground, + }, + player_query, + entity_query, + entity_update_query, + ); }, ); } + pub fn keep_alive(&mut self, p: &ClientboundKeepAlive) { debug!("Got keep alive packet {p:?} for {:?}", self.player); @@ -1585,11 +1525,11 @@ impl GamePacketHandler<'_> { else { return; }; - let is_local_entity = local_entity.is_some(); physics.vec_delta_codec.set_base(new_position); - if is_local_entity { + let is_client_authoritative = local_entity.is_some(); + if is_client_authoritative { debug!("Ignoring entity position sync packet for local player"); return; } @@ -1706,3 +1646,62 @@ impl GamePacketHandler<'_> { debug!("Got game test highlight pos packet {p:?}"); } } + +struct MoveEntity { + pub entity_id: MinecraftEntityId, + pub delta: Option<PositionDelta8>, + pub look_direction: Option<CompactLookDirection>, + pub on_ground: bool, +} + +type MoveEntityQuery<'world, 'state, 'a> = + Query<'world, 'state, (&'a mut Physics, &'a mut Position, &'a mut LookDirection)>; + +fn move_entity( + player_entity: Entity, + mut commands: Commands, + p: MoveEntity, + player_query: Query<(&EntityIdIndex, &WorldHolder)>, + mut entity_query: MoveEntityQuery, + entity_update_query: EntityUpdateQuery, +) { + let (entity_id_index, world_holder) = player_query.get(player_entity).unwrap(); + + let entity_id = p.entity_id; + let entity = entity_id_index.get_by_minecraft_entity(entity_id); + + let Some(entity) = entity else { + // often triggered by hypixel :( + debug!("Got move move entity packet for unknown entity id {entity_id}"); + return; + }; + + let (mut physics, mut position, mut look_direction) = entity_query.get_mut(entity).unwrap(); + + if !should_apply_entity_update( + &mut commands, + &mut world_holder.partial.write(), + entity, + entity_update_query, + ) { + return; + } + + if let Some(new_delta) = p.delta { + let new_position = physics.vec_delta_codec.decode(&new_delta); + physics.vec_delta_codec.set_base(new_position); + + if new_position != **position { + **position = new_position; + } + } + + if let Some(new_look_direction) = p.look_direction { + let new_look_direction = new_look_direction.into(); + if new_look_direction != *look_direction { + *look_direction = new_look_direction; + } + } + + physics.set_on_ground(p.on_ground); +} diff --git a/azalea-client/tests/simulation/move_despawned_entity.rs b/azalea-client/tests/simulation/move_despawned_entity.rs index 57ee3e37..30b326f6 100644 --- a/azalea-client/tests/simulation/move_despawned_entity.rs +++ b/azalea-client/tests/simulation/move_despawned_entity.rs @@ -1,7 +1,10 @@ use azalea_client::test_utils::prelude::*; use azalea_core::{entity_id::MinecraftEntityId, position::ChunkPos}; use azalea_entity::metadata::Cow; -use azalea_protocol::packets::{ConnectionProtocol, game::ClientboundMoveEntityRot}; +use azalea_protocol::packets::{ + ConnectionProtocol, + game::{ClientboundMoveEntityRot, c_move_entity_pos_rot::CompactLookDirection}, +}; use azalea_registry::builtin::EntityKind; use bevy_ecs::query::With; use tracing::Level; @@ -36,8 +39,7 @@ fn test_move_despawned_entity() { // send a move_entity_rot simulation.receive_packet(ClientboundMoveEntityRot { entity_id: MinecraftEntityId(123), - y_rot: 0, - x_rot: 0, + look_direction: CompactLookDirection::default(), on_ground: false, }); simulation.tick(); diff --git a/azalea-core/src/delta.rs b/azalea-core/src/delta.rs index c45900d8..b1410e81 100644 --- a/azalea-core/src/delta.rs +++ b/azalea-core/src/delta.rs @@ -12,7 +12,7 @@ pub trait PositionDeltaTrait { } /// Only works for up to 8 blocks -#[derive(AzBuf, Clone, Debug, Default, PartialEq)] +#[derive(AzBuf, Clone, Copy, Debug, Default, PartialEq)] pub struct PositionDelta8 { pub xa: i16, pub ya: i16, diff --git a/azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs b/azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs index 047eb638..dffa16c7 100644 --- a/azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs +++ b/azalea-protocol/src/packets/game/c_move_entity_pos_rot.rs @@ -1,7 +1,7 @@ use azalea_buf::AzBuf; -use azalea_core::delta::PositionDelta8; +use azalea_core::{delta::PositionDelta8, entity_id::MinecraftEntityId}; +use azalea_entity::LookDirection; use azalea_protocol_macros::ClientboundGamePacket; -use azalea_core::entity_id::MinecraftEntityId; /// This packet is sent by the server when an entity moves less then 8 blocks. #[derive(AzBuf, ClientboundGamePacket, Clone, Debug, PartialEq)] @@ -9,7 +9,21 @@ pub struct ClientboundMoveEntityPosRot { #[var] pub entity_id: MinecraftEntityId, pub delta: PositionDelta8, + pub look_direction: CompactLookDirection, + pub on_ground: bool, +} + +#[derive(AzBuf, Clone, Copy, Debug, PartialEq, Default)] +pub struct CompactLookDirection { pub y_rot: i8, pub x_rot: i8, - pub on_ground: bool, +} + +impl From<CompactLookDirection> for LookDirection { + fn from(l: CompactLookDirection) -> Self { + LookDirection::new( + (l.y_rot as i32 * 360) as f32 / 256., + (l.x_rot as i32 * 360) as f32 / 256., + ) + } } diff --git a/azalea-protocol/src/packets/game/c_move_entity_rot.rs b/azalea-protocol/src/packets/game/c_move_entity_rot.rs index 4d0645b3..90ce41bc 100644 --- a/azalea-protocol/src/packets/game/c_move_entity_rot.rs +++ b/azalea-protocol/src/packets/game/c_move_entity_rot.rs @@ -1,12 +1,13 @@ use azalea_buf::AzBuf; -use azalea_protocol_macros::ClientboundGamePacket; use azalea_core::entity_id::MinecraftEntityId; +use azalea_protocol_macros::ClientboundGamePacket; + +use crate::packets::game::c_move_entity_pos_rot::CompactLookDirection; #[derive(AzBuf, ClientboundGamePacket, Clone, Debug, PartialEq)] pub struct ClientboundMoveEntityRot { #[var] pub entity_id: MinecraftEntityId, - pub y_rot: i8, - pub x_rot: i8, + pub look_direction: CompactLookDirection, pub on_ground: bool, } diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 8bb23071..4f9307c4 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -1,5 +1,4 @@ #![doc = include_str!("../README.md")] -#![feature(error_generic_member_access)] mod bit_storage; pub mod chunk_storage; diff --git a/azalea/src/lib.rs b/azalea/src/lib.rs index 3eefe316..332dc565 100644 --- a/azalea/src/lib.rs +++ b/azalea/src/lib.rs @@ -1,6 +1,5 @@ #![doc = include_str!("../README.md")] #![feature(type_changing_struct_update)] -#![feature(float_algebraic)] pub mod accept_resource_packs; pub mod auto_reconnect; |
