From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Sat, 25 Jun 2022 19:45:20 -0400 Subject: [PATCH] Send block entities after destroy prediction Minecraft's prediction system does not handle block entities, so if we are manually sending block entities during block breaking we need to set it after the prediction is finished. This fixes block entities not showing when cancelling the BlockBreakEvent. diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java index 3574fe0ce7c161a13a78b66ab881463def8cc461..c14ab35c4336c025c242e8a350ac4b8d1b1d5c78 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java @@ -62,6 +62,8 @@ public class ServerPlayerGameMode { private BlockPos delayedDestroyPos; private int delayedTickStart; private int lastSentState; + public boolean captureSentBlockEntities = false; // Paper - Send block entities after destroy prediction + public boolean capturedBlockEntity = false; // Paper - Send block entities after destroy prediction public ServerPlayerGameMode(ServerPlayer player) { this.gameModeForPlayer = GameType.DEFAULT_MODE; @@ -188,10 +190,7 @@ public class ServerPlayerGameMode { this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); this.debugLogging(pos, false, sequence, "may not interact"); // Update any tile entity data for this block - BlockEntity tileentity = this.level.getBlockEntity(pos); - if (tileentity != null) { - this.player.connection.send(tileentity.getUpdatePacket()); - } + capturedBlockEntity = true; // Paper - Send block entities after destroy prediction // CraftBukkit end return; } @@ -202,10 +201,7 @@ public class ServerPlayerGameMode { // Let the client know the block still exists this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // Update any tile entity data for this block - BlockEntity tileentity = this.level.getBlockEntity(pos); - if (tileentity != null) { - this.player.connection.send(tileentity.getUpdatePacket()); - } + capturedBlockEntity = true; // Paper - Send block entities after destroy prediction return; } // CraftBukkit end @@ -389,10 +385,12 @@ public class ServerPlayerGameMode { } // Update any tile entity data for this block + if (!captureSentBlockEntities) { // Paper - Send block entities after destroy prediction BlockEntity tileentity = this.level.getBlockEntity(pos); if (tileentity != null) { this.player.connection.send(tileentity.getUpdatePacket()); } + } else {capturedBlockEntity = true;} // Paper - Send block entities after destroy prediction return false; } } diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index aa37c08c4ede225439f4c52ac7787b757461f3e1..ff7a6977166892421e3ae8348aa15a847ebde30e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1783,8 +1783,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } // Paper end - Don't allow digging in unloaded chunks + // Paper start - Send block entities after destroy prediction + this.player.gameMode.capturedBlockEntity = false; + this.player.gameMode.captureSentBlockEntities = true; + // Paper end - Send block entities after destroy prediction this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level().getMaxBuildHeight(), packet.getSequence()); this.player.connection.ackBlockChangesUpTo(packet.getSequence()); + // Paper start - Send block entities after destroy prediction + this.player.gameMode.captureSentBlockEntities = false; + // If a block entity was modified speedup the block change ack to avoid the block entity + // being overriden. + if (this.player.gameMode.capturedBlockEntity) { + // manually tick + this.send(new ClientboundBlockChangedAckPacket(this.ackBlockChangesUpTo)); + this.player.connection.ackBlockChangesUpTo = -1; + + this.player.gameMode.capturedBlockEntity = false; + BlockEntity tileentity = this.player.level().getBlockEntity(blockposition); + if (tileentity != null) { + this.player.connection.send(tileentity.getUpdatePacket()); + } + } + // Paper end - Send block entities after destroy prediction return; default: throw new IllegalArgumentException("Invalid player action");