diff options
Diffstat (limited to 'patches/server/0912-Properly-handle-BlockBreakEvent-isDropItems.patch')
-rw-r--r-- | patches/server/0912-Properly-handle-BlockBreakEvent-isDropItems.patch | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/patches/server/0912-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/server/0912-Properly-handle-BlockBreakEvent-isDropItems.patch new file mode 100644 index 0000000000..025a223021 --- /dev/null +++ b/patches/server/0912-Properly-handle-BlockBreakEvent-isDropItems.patch @@ -0,0 +1,161 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic <[email protected]> +Date: Sat, 4 Mar 2023 10:52:52 -0800 +Subject: [PATCH] Properly handle BlockBreakEvent#isDropItems + +Setting whether a block break dropped items controlled +far more than just whether blocks dropped, like stat increases +food consumption, turtle egg count decreases, ice to water +conversions and beehive releases + +diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +index 3621770701c6fb1da75c69a41297684493380e37..4747b05619f37009a5a236678aceec6cfc1c0b79 100644 +--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java ++++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +@@ -431,8 +431,8 @@ public class ServerPlayerGameMode { + isCorrectTool = flag1; // Paper - Trigger bee_nest_destroyed trigger in the correct place + + itemstack.mineBlock(this.level, iblockdata1, pos, this.player); +- if (flag && flag1 && event.isDropItems()) { // CraftBukkit - Check if block should drop items +- block.playerDestroy(this.level, this.player, pos, iblockdata1, tileentity, itemstack1); ++ if (flag && flag1/* && event.isDropItems() */) { // CraftBukkit - Check if block should drop items // Paper - fix drops not preventing stats/food exhaustion ++ block.playerDestroy(this.level, this.player, pos, iblockdata1, tileentity, itemstack1, event.isDropItems(), false); // Paper - fix drops not preventing stats/food exhaustion + } + + // return true; // CraftBukkit +diff --git a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +index 799e44ae5a7c3d6994653d43d455c39f3e30b012..25e8d6066fb94d0b9a244ab1fec5139b9266d86d 100644 +--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java +@@ -84,8 +84,8 @@ public class BeehiveBlock extends BaseEntityBlock { + } + + @Override +- public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { +- super.playerDestroy(world, player, pos, state, blockEntity, tool); ++ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion ++ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion + if (!world.isClientSide && blockEntity instanceof BeehiveBlockEntity) { + BeehiveBlockEntity tileentitybeehive = (BeehiveBlockEntity) blockEntity; + +diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java +index 57d92c1785586dfab2b3934733d8ba253e042e2e..c4bf01177b2dfcc88f6992dc85de216d448a79f8 100644 +--- a/src/main/java/net/minecraft/world/level/block/Block.java ++++ b/src/main/java/net/minecraft/world/level/block/Block.java +@@ -411,10 +411,18 @@ public class Block extends BlockBehaviour implements ItemLike { + return this.defaultBlockState(); + } + ++ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - fix drops not preventing stats/food exhaustion + public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { ++ // Paper start - fix drops not preventing stats/food exhaustion ++ this.playerDestroy(world, player, pos, state, blockEntity, tool, true, true); ++ } ++ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { ++ // Paper end - fix drops not preventing stats/food exhaustion + player.awardStat(Stats.BLOCK_MINED.get(this)); + player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent ++ if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion + Block.dropResources(state, world, pos, blockEntity, player, tool); ++ } // Paper - fix drops not preventing stats/food exhaustion + } + + public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {} +diff --git a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java +index 0f0750f8c790d0db72a0e6b277449a1461674890..03b5ab8251497c0c94467f90e6663a0dc766babb 100644 +--- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java +@@ -96,8 +96,8 @@ public class DoublePlantBlock extends BushBlock { + } + + @Override +- public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { +- super.playerDestroy(world, player, pos, Blocks.AIR.defaultBlockState(), blockEntity, tool); ++ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion ++ super.playerDestroy(world, player, pos, Blocks.AIR.defaultBlockState(), blockEntity, tool, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion + } + + protected static void preventDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) { +diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java +index 52c6c26a300cfd19c478afba411a17c8d5ea0c3c..9c8c1df5187daefb1c8098b4d4a0976c71a7bbfd 100644 +--- a/src/main/java/net/minecraft/world/level/block/IceBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java +@@ -33,8 +33,8 @@ public class IceBlock extends HalfTransparentBlock { + } + + @Override +- public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { +- super.playerDestroy(world, player, pos, state, blockEntity, tool); ++ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion ++ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion + // Paper start - Improve Block#breakNaturally API + this.afterDestroy(world, pos, tool); + } +diff --git a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java +index c79f3a8885a5ffc9ebac51992e63df14929d9f24..b4646e26965e0f1f26c5019e7c6a13fdf22bdb47 100644 +--- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java +@@ -173,8 +173,8 @@ public class TurtleEggBlock extends Block { + } + + @Override +- public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { +- super.playerDestroy(world, player, pos, state, blockEntity, tool); ++ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion ++ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion + this.decreaseEggs(world, pos, state); + } + +diff --git a/src/test/java/io/papermc/paper/world/block/BlockPlayerDestroyOverrideTest.java b/src/test/java/io/papermc/paper/world/block/BlockPlayerDestroyOverrideTest.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7c435f7079b429873f33d7bade82eca0c6b45842 +--- /dev/null ++++ b/src/test/java/io/papermc/paper/world/block/BlockPlayerDestroyOverrideTest.java +@@ -0,0 +1,47 @@ ++package io.papermc.paper.world.block; ++ ++import io.github.classgraph.ClassGraph; ++import io.github.classgraph.ClassInfo; ++import io.github.classgraph.MethodInfo; ++import io.github.classgraph.MethodInfoList; ++import io.github.classgraph.MethodParameterInfo; ++import io.github.classgraph.ScanResult; ++import java.util.ArrayList; ++import java.util.List; ++import java.util.stream.Stream; ++import org.bukkit.support.AbstractTestingBase; ++import org.junit.jupiter.params.ParameterizedTest; ++import org.junit.jupiter.params.provider.MethodSource; ++ ++import static org.junit.jupiter.api.Assertions.assertEquals; ++ ++public class BlockPlayerDestroyOverrideTest extends AbstractTestingBase { ++ ++ public static Stream<ClassInfo> parameters() { ++ final List<ClassInfo> classInfo = new ArrayList<>(); ++ try (ScanResult scanResult = new ClassGraph() ++ .enableClassInfo() ++ .enableMethodInfo() ++ .whitelistPackages("net.minecraft") ++ .scan() ++ ) { ++ for (final ClassInfo subclass : scanResult.getSubclasses("net.minecraft.world.level.block.Block")) { ++ final MethodInfoList playerDestroy = subclass.getDeclaredMethodInfo("playerDestroy"); ++ if (!playerDestroy.isEmpty()) { ++ classInfo.add(subclass); ++ } ++ } ++ } ++ return classInfo.stream(); ++ } ++ ++ @ParameterizedTest ++ @MethodSource("parameters") ++ public void checkPlayerDestroyOverrides(ClassInfo overridesPlayerDestroy) { ++ final MethodInfoList playerDestroy = overridesPlayerDestroy.getDeclaredMethodInfo("playerDestroy"); ++ assertEquals(1, playerDestroy.size(), overridesPlayerDestroy.getName() + " has multiple playerDestroy methods"); ++ final MethodInfo next = playerDestroy.iterator().next(); ++ final MethodParameterInfo[] parameterInfo = next.getParameterInfo(); ++ assertEquals("boolean", parameterInfo[parameterInfo.length - 1].getTypeDescriptor().toStringWithSimpleNames(), overridesPlayerDestroy.getName() + " needs to change its override of playerDestroy"); ++ } ++} |