aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2025-06-25 15:14:39 -1245
committermat <git@matdoes.dev>2025-06-25 15:14:39 -1245
commit08c409d04896e7057c31250f2d6f99c75b8af5b5 (patch)
tree78c839b5d88f18df88dd1c562050f63d18814e41 /azalea-client/src
parentf9e4b65713bbacabcd54416a388a92b90f56ab47 (diff)
downloadazalea-drasl-08c409d04896e7057c31250f2d6f99c75b8af5b5.tar.xz
improve packet_order test, add BlockUpdatePlugin, fix packet order for sprinting
Diffstat (limited to 'azalea-client/src')
-rw-r--r--azalea-client/src/client.rs4
-rw-r--r--azalea-client/src/plugins/block_update.rs49
-rw-r--r--azalea-client/src/plugins/chunks.rs4
-rw-r--r--azalea-client/src/plugins/disconnect.rs3
-rw-r--r--azalea-client/src/plugins/mod.rs2
-rw-r--r--azalea-client/src/plugins/movement.rs2
-rw-r--r--azalea-client/src/plugins/packet/game/mod.rs36
7 files changed, 71 insertions, 29 deletions
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index c9cc5259..9481ba2d 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -47,6 +47,7 @@ use uuid::Uuid;
use crate::{
Account, DefaultPlugins,
attack::{self},
+ block_update::QueuedServerBlockUpdates,
chunks::ChunkBatchInfo,
connection::RawConnection,
disconnect::DisconnectEvent,
@@ -586,7 +587,8 @@ pub struct JoinedClientBundle {
pub physics_state: PhysicsState,
pub inventory: Inventory,
pub tab_list: TabList,
- pub current_sequence_number: BlockStatePredictionHandler,
+ pub block_state_prediction_handler: BlockStatePredictionHandler,
+ pub queued_server_block_updates: QueuedServerBlockUpdates,
pub last_sent_direction: LastSentLookDirection,
pub abilities: PlayerAbilities,
pub permission_level: PermissionLevel,
diff --git a/azalea-client/src/plugins/block_update.rs b/azalea-client/src/plugins/block_update.rs
new file mode 100644
index 00000000..15e885b6
--- /dev/null
+++ b/azalea-client/src/plugins/block_update.rs
@@ -0,0 +1,49 @@
+use azalea_block::BlockState;
+use azalea_core::position::BlockPos;
+use bevy_app::{App, Plugin, Update};
+use bevy_ecs::prelude::*;
+
+use crate::{
+ chunks::handle_receive_chunk_event, interact::BlockStatePredictionHandler,
+ local_player::InstanceHolder,
+};
+
+pub struct BlockUpdatePlugin;
+impl Plugin for BlockUpdatePlugin {
+ fn build(&self, app: &mut App) {
+ app.add_systems(
+ Update,
+ // has to be after ReceiveChunkEvent is handled so if we get chunk+blockupdate in one
+ // Update then the block update actually gets applied
+ handle_block_update_event.after(handle_receive_chunk_event),
+ );
+ }
+}
+
+/// A component that holds the list of block updates that need to be handled.
+///
+/// This is updated by `read_packets` (in `PreUpdate`) and handled/cleared by
+/// [`handle_block_update_event`] (`Update`).
+///
+/// This is a component instead of an ECS event for performance reasons.
+#[derive(Component, Debug, Clone, Default)]
+pub struct QueuedServerBlockUpdates {
+ pub list: Vec<(BlockPos, BlockState)>,
+}
+
+pub fn handle_block_update_event(
+ mut query: Query<(
+ &mut QueuedServerBlockUpdates,
+ &InstanceHolder,
+ &mut BlockStatePredictionHandler,
+ )>,
+) {
+ for (mut queued, instance_holder, mut prediction_handler) in query.iter_mut() {
+ let world = instance_holder.instance.read();
+ for (pos, block_state) in queued.list.drain(..) {
+ if !prediction_handler.update_known_server_state(pos, block_state) {
+ world.chunks.set_block_state(pos, block_state);
+ }
+ }
+ }
+}
diff --git a/azalea-client/src/plugins/chunks.rs b/azalea-client/src/plugins/chunks.rs
index 7a99c16c..a4e19f7f 100644
--- a/azalea-client/src/plugins/chunks.rs
+++ b/azalea-client/src/plugins/chunks.rs
@@ -28,7 +28,7 @@ impl Plugin for ChunksPlugin {
Update,
(
handle_chunk_batch_start_event,
- handle_receive_chunk_events,
+ handle_receive_chunk_event,
handle_chunk_batch_finished_event,
)
.chain()
@@ -65,7 +65,7 @@ pub struct ChunkBatchFinishedEvent {
pub batch_size: u32,
}
-pub fn handle_receive_chunk_events(
+pub fn handle_receive_chunk_event(
mut events: EventReader<ReceiveChunkEvent>,
mut query: Query<&InstanceHolder>,
) {
diff --git a/azalea-client/src/plugins/disconnect.rs b/azalea-client/src/plugins/disconnect.rs
index 8dddff09..80993476 100644
--- a/azalea-client/src/plugins/disconnect.rs
+++ b/azalea-client/src/plugins/disconnect.rs
@@ -56,6 +56,7 @@ pub struct DisconnectEvent {
#[derive(Bundle)]
pub struct RemoveOnDisconnectBundle {
pub joined_client: JoinedClientBundle,
+
pub entity: EntityBundle,
pub minecraft_entity_id: MinecraftEntityId,
pub instance_holder: InstanceHolder,
@@ -69,7 +70,7 @@ pub struct RemoveOnDisconnectBundle {
pub chat_signing_session: chat_signing::ChatSigningSession,
/// They're not authenticated anymore if they disconnected.
pub is_authenticated: IsAuthenticated,
- // send ServerboundPlayerLoaded next time we join
+ // send ServerboundPlayerLoaded next time we join.
pub has_client_loaded: HasClientLoaded,
}
diff --git a/azalea-client/src/plugins/mod.rs b/azalea-client/src/plugins/mod.rs
index 6f003b01..7c5cd3a3 100644
--- a/azalea-client/src/plugins/mod.rs
+++ b/azalea-client/src/plugins/mod.rs
@@ -2,6 +2,7 @@ use bevy_app::{PluginGroup, PluginGroupBuilder};
pub mod attack;
pub mod auto_reconnect;
+pub mod block_update;
pub mod brand;
pub mod chat;
pub mod chat_signing;
@@ -48,6 +49,7 @@ impl PluginGroup for DefaultPlugins {
.add(mining::MiningPlugin)
.add(attack::AttackPlugin)
.add(chunks::ChunksPlugin)
+ .add(block_update::BlockUpdatePlugin)
.add(tick_end::TickEndPlugin)
.add(loading::PlayerLoadedPlugin)
.add(brand::BrandPlugin)
diff --git a/azalea-client/src/plugins/movement.rs b/azalea-client/src/plugins/movement.rs
index 5d43261f..e97d9ec1 100644
--- a/azalea-client/src/plugins/movement.rs
+++ b/azalea-client/src/plugins/movement.rs
@@ -65,8 +65,8 @@ impl Plugin for MovementPlugin {
.in_set(PhysicsSet)
.before(ai_step)
.before(azalea_physics::fluids::update_in_water_state_and_do_fluid_pushing),
- send_sprinting_if_needed.after(azalea_entity::update_in_loaded_chunk),
send_player_input_packet,
+ send_sprinting_if_needed.after(azalea_entity::update_in_loaded_chunk),
send_position.after(PhysicsSet),
)
.chain(),
diff --git a/azalea-client/src/plugins/packet/game/mod.rs b/azalea-client/src/plugins/packet/game/mod.rs
index d9940937..fd6b712c 100644
--- a/azalea-client/src/plugins/packet/game/mod.rs
+++ b/azalea-client/src/plugins/packet/game/mod.rs
@@ -23,6 +23,7 @@ use tracing::{debug, error, trace, warn};
use crate::{
ClientInformation,
+ block_update::QueuedServerBlockUpdates,
chat::{ChatPacket, ChatReceivedEvent},
chunks,
connection::RawConnection,
@@ -1058,17 +1059,10 @@ impl GamePacketHandler<'_> {
pub fn block_update(&mut self, p: &ClientboundBlockUpdate) {
debug!("Got block update packet {p:?}");
- as_system::<Query<(&InstanceHolder, &mut BlockStatePredictionHandler)>>(
- self.ecs,
- |mut query| {
- let (local_player, mut prediction_handler) = query.get_mut(self.player).unwrap();
-
- let world = local_player.instance.read();
- if !prediction_handler.update_known_server_state(p.pos, p.block_state) {
- world.chunks.set_block_state(p.pos, p.block_state);
- }
- },
- );
+ as_system::<Query<&mut QueuedServerBlockUpdates>>(self.ecs, |mut query| {
+ let mut queued = query.get_mut(self.player).unwrap();
+ queued.list.push((p.pos, p.block_state));
+ });
}
pub fn animate(&mut self, p: &ClientboundAnimate) {
@@ -1078,19 +1072,13 @@ impl GamePacketHandler<'_> {
pub fn section_blocks_update(&mut self, p: &ClientboundSectionBlocksUpdate) {
debug!("Got section blocks update packet {p:?}");
- as_system::<Query<(&InstanceHolder, &mut BlockStatePredictionHandler)>>(
- self.ecs,
- |mut query| {
- let (local_player, mut prediction_handler) = query.get_mut(self.player).unwrap();
- let world = local_player.instance.read();
- for new_state in &p.states {
- let pos = p.section_pos + new_state.pos;
- if !prediction_handler.update_known_server_state(pos, new_state.state) {
- world.chunks.set_block_state(pos, new_state.state);
- }
- }
- },
- );
+ as_system::<Query<&mut QueuedServerBlockUpdates>>(self.ecs, |mut query| {
+ let mut queued = query.get_mut(self.player).unwrap();
+ for new_state in &p.states {
+ let pos = p.section_pos + new_state.pos;
+ queued.list.push((pos, new_state.state));
+ }
+ });
}
pub fn game_event(&mut self, p: &ClientboundGameEvent) {