From 93fca02b0eb149c824c2177cda1126629d7266a6 Mon Sep 17 00:00:00 2001 From: Brave <43207174+BraveDevelopment@users.noreply.github.com> Date: Sat, 21 Feb 2026 20:58:44 +0100 Subject: [PATCH] fix: block-break flickering again (#1683) * Fix block-break flickering Move CAcknowledgeBlockChange sending out of immediate per-player send into the world flush path so acknowledgements are enqueued and sent during world flush. world/mod.rs now iterates players to swap and enqueue CAcknowledgeBlockChange for any pending sequence. Also call update_sequence(...) in Java play handlers to update the player's packet sequence when handling player actions. * thats better * fix: typo * Update play.rs --------- Co-authored-by: Alexander Medvedev --- pumpkin/src/net/java/play.rs | 38 +++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/pumpkin/src/net/java/play.rs b/pumpkin/src/net/java/play.rs index 658e06a54..165bc7473 100644 --- a/pumpkin/src/net/java/play.rs +++ b/pumpkin/src/net/java/play.rs @@ -1393,17 +1393,20 @@ impl JavaClient { // TODO: Config if player.gamemode.load() == GameMode::Creative { // Block break & play sound - world + let new_state = world .break_block( &position, Some(player.clone()), BlockFlags::NOTIFY_NEIGHBORS | BlockFlags::SKIP_DROPS, ) .await; - server - .block_registry - .broken(&world, block, player, &position, server, state) - .await; + if new_state.is_some() { + server + .block_registry + .broken(&world, block, player, &position, server, state) + .await; + } + self.sync_block_state_to_client(&world, position).await; self.update_sequence(player, player_action.sequence.0); return; } @@ -1416,18 +1419,21 @@ impl JavaClient { // Instant break if speed >= 1.0 { let broken_state = world.get_block_state(&position).await; - world + let new_state = world .break_block( &position, Some(player.clone()), BlockFlags::NOTIFY_NEIGHBORS, ) .await; - server - .block_registry - .broken(&world, block, player, &position, server, broken_state) - .await; - player.apply_tool_damage_for_block_break(broken_state).await; + if new_state.is_some() { + server + .block_registry + .broken(&world, block, player, &position, server, broken_state) + .await; + player.apply_tool_damage_for_block_break(broken_state).await; + } + self.sync_block_state_to_client(&world, position).await; } else { player.mining.store(true, Ordering::Relaxed); *player.mining_pos.lock().await = position; @@ -1499,6 +1505,7 @@ impl JavaClient { .await; player.apply_tool_damage_for_block_break(state).await; } + self.sync_block_state_to_client(&world, location).await; self.update_sequence(player, player_action.sequence.0); } @@ -1551,6 +1558,15 @@ impl JavaClient { ); } + async fn sync_block_state_to_client(&self, world: &World, position: BlockPos) { + let synced_state_id = world.get_block_state_id(&position).await; + self.send_packet_now(&CBlockUpdate::new( + position, + VarInt(i32::from(synced_state_id)), + )) + .await; + } + pub async fn handle_player_abilities( &self, player: &Player,