From 6602dc655ed012b7604a315153e7e205eacf6416 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Thu, 15 Jul 2021 16:00:58 -0700 Subject: [PATCH] Catch desynced block breaks (#6193) --- .../server/Add-PlayerKickEvent-causes.patch | 9 ++++++++ ...t-allow-digging-into-unloaded-chunks.patch | 22 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/patches/server/Add-PlayerKickEvent-causes.patch b/patches/server/Add-PlayerKickEvent-causes.patch index 273a708bd1..4d855ee296 100644 --- a/patches/server/Add-PlayerKickEvent-causes.patch +++ b/patches/server/Add-PlayerKickEvent-causes.patch @@ -209,6 +209,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return; } } +@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser + double blockDistanceSquared = this.player.distanceToSqr(blockposition.getX() + 0.5D, blockposition.getY() + 0.5D + 1.5D, blockposition.getZ() + 0.5D); // Copied from ServerPlayerGameMode#handleBlockBreakAction + if (blockDistanceSquared > 40 * 40) { + LOGGER.warn("{} tried to break a block {} square blocks away from their position", this.player.getScoreboardName(), blockDistanceSquared); +- this.disconnect("Invalid block break distance"); ++ this.disconnect("Invalid block break distance", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); + return; + } + if (this.player.level.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) == null) { @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); if (packet.getAction() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) { diff --git a/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch b/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch index 49c3037f92..27d585d19f 100644 --- a/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch +++ b/patches/server/Don-t-allow-digging-into-unloaded-chunks.patch @@ -34,6 +34,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (iblockdata.isAir()) { this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); this.lastSentState = -1; +@@ -0,0 +0,0 @@ public class ServerPlayerGameMode { + double d1 = this.player.getY() - ((double) pos.getY() + 0.5D) + 1.5D; + double d2 = this.player.getZ() - ((double) pos.getZ() + 0.5D); + double d3 = d0 * d0 + d1 * d1 + d2 * d2; ++ // Paper start ++ this.handleBlockBreakAction(pos, action, direction, worldHeight, d3); ++ } ++ public void handleBlockBreakAction(BlockPos pos, ServerboundPlayerActionPacket.Action action, Direction direction, int worldHeight, double d3) { ++ // Paper end + + if (d3 > 36.0D) { + this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, false, "too far")); @@ -0,0 +0,0 @@ public class ServerPlayerGameMode { this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, true, "stopped destroying")); } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { @@ -58,11 +70,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: +- this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level.getMaxBuildHeight()); + // Paper start - Don't allow digging in unloaded chunks ++ double blockDistanceSquared = this.player.distanceToSqr(blockposition.getX() + 0.5D, blockposition.getY() + 0.5D + 1.5D, blockposition.getZ() + 0.5D); // Copied from ServerPlayerGameMode#handleBlockBreakAction ++ if (blockDistanceSquared > 40 * 40) { ++ LOGGER.warn("{} tried to break a block {} square blocks away from their position", this.player.getScoreboardName(), blockDistanceSquared); ++ this.disconnect("Invalid block break distance"); ++ return; ++ } + if (this.player.level.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) == null) { + return; + } ++ this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level.getMaxBuildHeight(), blockDistanceSquared); + // Paper end - Don't allow digging in unloaded chunks - this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level.getMaxBuildHeight()); return; default: + throw new IllegalArgumentException("Invalid player action");