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 15a2d3fb2db4abfe66392a22d9a33159a816f285..e868c434be0bf223728b439df9a0db6afeaee46e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -1704,8 +1704,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");