aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server
diff options
context:
space:
mode:
authorJake Potrebic <[email protected]>2023-08-20 20:49:20 -0700
committerGitHub <[email protected]>2023-08-20 20:49:20 -0700
commitd12916255ac3e1b6e963d4ff69ae61b7a3ecff03 (patch)
tree409d606af13204680b20f72512ff72ee2fb59116 /patches/server
parent666a2147a7f4de7f718fffb72fcfe0827304fa14 (diff)
downloadPaper-d12916255ac3e1b6e963d4ff69ae61b7a3ecff03.tar.gz
Paper-d12916255ac3e1b6e963d4ff69ae61b7a3ecff03.zip
Properly handle BlockBreakEvent#isDropItems (#8936)
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
Diffstat (limited to 'patches/server')
-rw-r--r--patches/server/1006-Properly-handle-BlockBreakEvent-isDropItems.patch165
1 files changed, 165 insertions, 0 deletions
diff --git a/patches/server/1006-Properly-handle-BlockBreakEvent-isDropItems.patch b/patches/server/1006-Properly-handle-BlockBreakEvent-isDropItems.patch
new file mode 100644
index 0000000000..5816480722
--- /dev/null
+++ b/patches/server/1006-Properly-handle-BlockBreakEvent-isDropItems.patch
@@ -0,0 +1,165 @@
+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 baf3e79489e310f443788bc917c553ae7ea86c89..9a17193c9fe26c9c0390906b4c1f9d619ccba249 100644
+--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
++++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+@@ -438,8 +438,8 @@ public class ServerPlayerGameMode {
+ isCorrectTool = flag1; // Paper
+
+ itemstack.mineBlock(this.level, iblockdata, pos, this.player);
+- if (flag && flag1 && event.isDropItems()) { // CraftBukkit - Check if block should drop items
+- block.playerDestroy(this.level, this.player, pos, iblockdata, 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, iblockdata, tileentity, itemstack1, event.isDropItems()); // Paper
+ }
+
+ // 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 8b715a750a0406d1d7b25c2f023dc2fb4d8b70fa..2abb05c5d4de9ebd0764c4aab444adc914173cdc 100644
+--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
++++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
+@@ -77,8 +77,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) { // Paper
++ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops); // Paper
+ 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 9522e646529f3d849471931b4b3c0d133e7fcfc5..fdd9c61b7248e92dbcbec91cd6fe4c6310bba237 100644
+--- a/src/main/java/net/minecraft/world/level/block/Block.java
++++ b/src/main/java/net/minecraft/world/level/block/Block.java
+@@ -416,10 +416,18 @@ public class Block extends BlockBehaviour implements ItemLike {
+ return this.defaultBlockState();
+ }
+
++ @io.papermc.paper.annotation.DoNotUse // Paper - method below allows better control of item drops
+ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
++ // Paper start
++ this.playerDestroy(world, player, pos, state, blockEntity, tool, true);
++ }
++ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops) {
++ // Paper end
+ player.awardStat(Stats.BLOCK_MINED.get(this));
+ player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
++ if (includeDrops) { // Paper
+ Block.dropResources(state, world, pos, blockEntity, player, tool);
++ } // Paper
+ }
+
+ 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 9db66b393e057d93a8025b803ae0ad2a1bca61f6..030b38d5d5d2578d6ef482a239ef58787efa3b08 100644
+--- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
++++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
+@@ -89,8 +89,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) { // Paper
++ super.playerDestroy(world, player, pos, Blocks.AIR.defaultBlockState(), blockEntity, tool, includeDrops); // Paper
+ }
+
+ protected static void preventCreativeDropFromBottomPart(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 5fbdc96f29e29dfc092b9e84a988032db0fa36ab..04089e6f7d6e3d532b00585870283922b6be5246 100644
+--- a/src/main/java/net/minecraft/world/level/block/IceBlock.java
++++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java
+@@ -25,8 +25,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) { // Paper
++ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops); // Paper
+ // Paper start
+ 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 6c1a0e6f961e46a1a89850746a71e97b32514adf..181e99e3f29c70568b6f28f8a5d3bb692f7abad8 100644
+--- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
++++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
+@@ -164,8 +164,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) { // Paper
++ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops); // Paper
+ 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..934b4b5b0d36e84fed6c2754b513395a22b86eb5
+--- /dev/null
++++ b/src/test/java/io/papermc/paper/world/block/BlockPlayerDestroyOverrideTest.java
+@@ -0,0 +1,51 @@
++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 org.bukkit.support.AbstractTestingBase;
++import org.junit.Test;
++import org.junit.runner.RunWith;
++import org.junit.runners.Parameterized;
++
++import static org.junit.Assert.assertEquals;
++
++@RunWith(Parameterized.class)
++public class BlockPlayerDestroyOverrideTest extends AbstractTestingBase {
++
++ @Parameterized.Parameter
++ public ClassInfo overridesPlayerDestroy;
++
++ @Parameterized.Parameters
++ public static Iterable<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;
++ }
++
++ @Test
++ public void checkPlayerDestroyOverrides() {
++ final MethodInfoList playerDestroy = this.overridesPlayerDestroy.getDeclaredMethodInfo("playerDestroy");
++ assertEquals(this.overridesPlayerDestroy.getName() + " has multiple playerDestroy methods", 1, playerDestroy.size());
++ final MethodInfo next = playerDestroy.iterator().next();
++ final MethodParameterInfo[] parameterInfo = next.getParameterInfo();
++ assertEquals(this.overridesPlayerDestroy.getName() + " needs to change it's override of playerDestroy", "boolean", parameterInfo[parameterInfo.length - 1].getTypeDescriptor().toStringWithSimpleNames());
++ }
++}