Dont resend blocks on interactions (#9413)

In general, the client now has an acknowledgment system that will cause block changes made by the client to be reverted correctly.

Essentially:

The client enters a "prediction" stage, where any block changes made will have its old blockstate captured (this is referred to as "server state").
If you update blocks during this stage, the client will update this captured server state as long as they're still currently predicting.
After prediction is done (via an ack packet) all captured blockstates are reverted to their captured server state.
This means that if the server actually updated a block and send a block update packet, it's correctly set, while if a block wasn't updated on the server but WAS updated on the client (server state wasn't updated), that change will be reverted.

It should be noted that this system does not yet support block entities, so those still need to be resynced when needed.

I discovered this when noticing that blocks broken outside of the player's valid interaction distance are still properly reverted, even though the server doesn't send any block updates, only an ack packet.
This commit is contained in:
Owen1212055
2023-12-02 22:41:35 -05:00
parent 727bda93be
commit 1fa2b7d2f5
6 changed files with 173 additions and 27 deletions

View File

@@ -16,18 +16,6 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, pos, direction, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND);
if (event.isCancelled()) {
// Let the client know the block still exists
+ // Paper start - brute force neighbor blocks for any attached blocks
+ for (Direction dir : Direction.values()) {
+ this.player.connection.send(new ClientboundBlockUpdatePacket(level, pos.relative(dir)));
+ }
+ // Paper end
this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
// Update any tile entity data for this block
BlockEntity tileentity = this.level.getBlockEntity(pos);
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
// send a correcting update to the client for the block above as well, this because of replaceable blocks (such as grass, sea grass etc)