From bda6e81b933a596c65d72523587c712d45721939 Mon Sep 17 00:00:00 2001 From: JavierFlores09 Date: Thu, 9 Jul 2026 00:18:37 -0300 Subject: [PATCH 1/2] Fix BlockBreakEvent misfire in Adventure mode Move the blockActionRestricted check to be made before the event itself is called. --- .../server/level/ServerPlayerGameMode.java.patch | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index ccaaccec7059..8627f27fe806 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -191,7 +191,7 @@ } } } -@@ -261,13 +_,53 @@ +@@ -261,21 +_,69 @@ public boolean destroyBlock(final BlockPos pos) { BlockState state = this.level.getBlockState(pos); @@ -200,6 +200,10 @@ + org.bukkit.block.Block bblock = org.bukkit.craftbukkit.block.CraftBlock.at(this.level, pos); + org.bukkit.event.block.BlockBreakEvent event = null; + if (this.player instanceof ServerPlayer) { ++ // Paper - moved up from below - Ensure BlockBreakEvent only fires for valid adventure breaks ++ if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { ++ return false; ++ } + // Sword + Creative mode pre-cancel + boolean canAttackBlock = !this.player.getMainHandItem().canDestroyBlock(state, this.level, pos, this.player); + event = new org.bukkit.event.block.BlockBreakEvent(bblock, this.player.getBukkitEntity()); @@ -215,7 +219,7 @@ + ItemStack itemInHand = this.player.getItemBySlot(EquipmentSlot.MAINHAND); + event.setExpToDrop(block.getExpDrop(updatedBlockState, this.level, pos, itemInHand, true)); + } -+ ++ + if (!event.callEvent()) { + if (canAttackBlock) { + return false; @@ -248,7 +252,9 @@ this.level.sendBlockUpdated(pos, state, state, Block.UPDATE_ALL); return false; } -@@ -276,6 +_,10 @@ + +- if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { ++ if (false && this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { // Paper - moved up - Ensure BlockBreakEvent only fires for valid adventure breaks return false; } From 379d98dbb3156616bda3e88a81dc9a72f2da37c9 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 12 Jul 2026 19:27:04 +0200 Subject: [PATCH 2/2] Comments & diff --- .../server/level/ServerPlayerGameMode.java.patch | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index 8627f27fe806..0fbfbb7f20e6 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -191,7 +191,7 @@ } } } -@@ -261,21 +_,69 @@ +@@ -261,21 +_,70 @@ public boolean destroyBlock(final BlockPos pos) { BlockState state = this.level.getBlockState(pos); @@ -200,10 +200,11 @@ + org.bukkit.block.Block bblock = org.bukkit.craftbukkit.block.CraftBlock.at(this.level, pos); + org.bukkit.event.block.BlockBreakEvent event = null; + if (this.player instanceof ServerPlayer) { -+ // Paper - moved up from below - Ensure BlockBreakEvent only fires for valid adventure breaks ++ // Paper start - Ensure BlockBreakEvent only fires for valid adventure breaks - moved up from below + if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { + return false; + } ++ // Paper end - Ensure BlockBreakEvent only fires for valid adventure breaks + // Sword + Creative mode pre-cancel + boolean canAttackBlock = !this.player.getMainHandItem().canDestroyBlock(state, this.level, pos, this.player); + event = new org.bukkit.event.block.BlockBreakEvent(bblock, this.player.getBukkitEntity()); @@ -219,7 +220,7 @@ + ItemStack itemInHand = this.player.getItemBySlot(EquipmentSlot.MAINHAND); + event.setExpToDrop(block.getExpDrop(updatedBlockState, this.level, pos, itemInHand, true)); + } -+ ++ + if (!event.callEvent()) { + if (canAttackBlock) { + return false; @@ -254,7 +255,7 @@ } - if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { -+ if (false && this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { // Paper - moved up - Ensure BlockBreakEvent only fires for valid adventure breaks ++ if (false && this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) { // Paper - Ensure BlockBreakEvent only fires for valid adventure breaks - moved up return false; }