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 be25ea71cb3a3bd324935754604c9f7473a88d0a..75967b3526f3f946ffc6784b87b787396ab15368 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 @@ -387,10 +383,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 4d1fcd2d1ec8080144ded7ceffd8fa0e4bea95bb..c9b0a0489386fde907adb35f0291416e39c350a5 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1697,8 +1697,28 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl return; } // Paper end - Don't allow digging into 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");