2023-08-21 05:49:20 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
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
2024-01-21 12:53:04 +01:00
index 7c781820b31864999f8057ec1484f1353eb4f1ff..14d8cab88eb40560635fc51c00db225dd209dc88 100644
2023-08-21 05:49:20 +02:00
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
2023-12-03 04:41:35 +01:00
@@ -433,8 +433,8 @@ public class ServerPlayerGameMode {
2024-01-18 18:52:00 +01:00
isCorrectTool = flag1; // Paper - Trigger bee_nest_destroyed trigger in the correct place
2023-08-21 05:49:20 +02:00
2023-12-06 17:34:54 +01:00
itemstack.mineBlock(this.level, iblockdata1, pos, this.player);
2023-08-21 05:49:20 +02:00
- if (flag && flag1 && event.isDropItems()) { // CraftBukkit - Check if block should drop items
2023-12-06 17:34:54 +01:00
- block.playerDestroy(this.level, this.player, pos, iblockdata1, tileentity, itemstack1);
2024-01-05 10:07:43 +01:00
+ if (flag && flag1/* && event.isDropItems() */) { // CraftBukkit - Check if block should drop items // Paper - fix drops not preventing stats/food exhaustion
2024-01-14 16:31:39 +01:00
+ block.playerDestroy(this.level, this.player, pos, iblockdata1, tileentity, itemstack1, event.isDropItems(), false); // Paper - fix drops not preventing stats/food exhaustion
2023-08-21 05:49:20 +02:00
}
// 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
2024-01-21 12:53:04 +01:00
index a0ab721a01faccf216259c46e6d6f638426732c2..2d4a770ec7c0737eee6f06b32958716d50d230a1 100644
2023-08-21 05:49:20 +02:00
--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
2023-12-06 17:34:54 +01:00
@@ -84,8 +84,8 @@ public class BeehiveBlock extends BaseEntityBlock {
2023-08-21 05:49:20 +02:00
}
@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);
2024-01-14 16:31:39 +01:00
+ 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
2023-08-21 05:49:20 +02:00
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
2024-01-19 13:22:30 +01:00
index 6c4fd56956982eee743b4dea4e8b925891dd3b6f..5379c4a8c89cbbe73c3ab741d609cecdc81d928c 100644
2023-08-21 05:49:20 +02:00
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
2023-12-06 17:34:54 +01:00
@@ -423,10 +423,18 @@ public class Block extends BlockBehaviour implements ItemLike {
2023-08-21 05:49:20 +02:00
return this.defaultBlockState();
}
2024-01-14 16:31:39 +01:00
+ @io.papermc.paper.annotation.DoNotUse // Paper - fix drops not preventing stats/food exhaustion
2023-08-21 05:49:20 +02:00
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
2024-01-14 16:31:39 +01:00
+ // Paper start - fix drops not preventing stats/food exhaustion
2024-01-04 21:18:59 +01:00
+ this.playerDestroy(world, player, pos, state, blockEntity, tool, true, true);
2023-08-21 05:49:20 +02:00
+ }
2024-01-04 21:18:59 +01:00
+ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) {
2024-01-14 16:31:39 +01:00
+ // Paper end - fix drops not preventing stats/food exhaustion
2023-08-21 05:49:20 +02:00
player.awardStat(Stats.BLOCK_MINED.get(this));
player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
2024-01-14 16:31:39 +01:00
+ if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion
2023-08-21 05:49:20 +02:00
Block.dropResources(state, world, pos, blockEntity, player, tool);
2024-01-14 16:31:39 +01:00
+ } // Paper - fix drops not preventing stats/food exhaustion
2023-08-21 05:49:20 +02:00
}
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
2024-01-14 16:31:39 +01:00
index 0f0750f8c790d0db72a0e6b277449a1461674890..03b5ab8251497c0c94467f90e6663a0dc766babb 100644
2023-08-21 05:49:20 +02:00
--- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
2023-12-06 17:34:54 +01:00
@@ -96,8 +96,8 @@ public class DoublePlantBlock extends BushBlock {
2023-08-21 05:49:20 +02:00
}
@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);
2024-01-14 16:31:39 +01:00
+ 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
2023-08-21 05:49:20 +02:00
}
2023-12-06 17:34:54 +01:00
protected static void preventDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) {
2023-08-21 05:49:20 +02:00
diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java
2024-01-21 12:53:04 +01:00
index 52c6c26a300cfd19c478afba411a17c8d5ea0c3c..9c8c1df5187daefb1c8098b4d4a0976c71a7bbfd 100644
2023-08-21 05:49:20 +02:00
--- a/src/main/java/net/minecraft/world/level/block/IceBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java
2023-12-06 17:34:54 +01:00
@@ -33,8 +33,8 @@ public class IceBlock extends HalfTransparentBlock {
2023-08-21 05:49:20 +02:00
}
@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);
2024-01-14 16:31:39 +01:00
+ 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
2024-01-21 12:53:04 +01:00
// Paper start - Improve Block#breakNaturally API
2023-08-21 05:49:20 +02:00
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
2024-01-14 16:31:39 +01:00
index c79f3a8885a5ffc9ebac51992e63df14929d9f24..b4646e26965e0f1f26c5019e7c6a13fdf22bdb47 100644
2023-08-21 05:49:20 +02:00
--- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
2023-12-06 17:34:54 +01:00
@@ -173,8 +173,8 @@ public class TurtleEggBlock extends Block {
2023-08-21 05:49:20 +02:00
}
@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);
2024-01-14 16:31:39 +01:00
+ 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
2023-08-21 05:49:20 +02:00
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
2023-09-25 01:05:05 +02:00
index 0000000000000000000000000000000000000000..7c435f7079b429873f33d7bade82eca0c6b45842
2023-08-21 05:49:20 +02:00
--- /dev/null
+++ b/src/test/java/io/papermc/paper/world/block/BlockPlayerDestroyOverrideTest.java
2023-09-25 01:05:05 +02:00
@@ -0,0 +1,47 @@
2023-08-21 05:49:20 +02:00
+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;
2023-09-24 09:16:58 +02:00
+import java.util.stream.Stream;
2023-08-21 05:49:20 +02:00
+import org.bukkit.support.AbstractTestingBase;
2023-09-24 09:16:58 +02:00
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
2023-08-21 05:49:20 +02:00
+
2023-09-24 09:16:58 +02:00
+import static org.junit.jupiter.api.Assertions.assertEquals;
2023-08-21 05:49:20 +02:00
+
+public class BlockPlayerDestroyOverrideTest extends AbstractTestingBase {
+
2023-09-24 09:16:58 +02:00
+ public static Stream<ClassInfo> parameters() {
2023-08-21 05:49:20 +02:00
+ 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);
+ }
+ }
+ }
2023-09-24 09:16:58 +02:00
+ return classInfo.stream();
2023-08-21 05:49:20 +02:00
+ }
+
2023-09-24 09:16:58 +02:00
+ @ParameterizedTest
+ @MethodSource("parameters")
+ public void checkPlayerDestroyOverrides(ClassInfo overridesPlayerDestroy) {
+ final MethodInfoList playerDestroy = overridesPlayerDestroy.getDeclaredMethodInfo("playerDestroy");
+ assertEquals(1, playerDestroy.size(), overridesPlayerDestroy.getName() + " has multiple playerDestroy methods");
2023-08-21 05:49:20 +02:00
+ final MethodInfo next = playerDestroy.iterator().next();
+ final MethodParameterInfo[] parameterInfo = next.getParameterInfo();
2023-09-25 01:05:05 +02:00
+ assertEquals("boolean", parameterInfo[parameterInfo.length - 1].getTypeDescriptor().toStringWithSimpleNames(), overridesPlayerDestroy.getName() + " needs to change its override of playerDestroy");
2023-08-21 05:49:20 +02:00
+ }
+}