mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-29 15:49:00 +01:00
161 lines
11 KiB
Diff
161 lines
11 KiB
Diff
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
|
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/BeehiveBlock.java
|
|
@@ -0,0 +0,0 @@ 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 tileentitybeehive) {
|
|
if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) == 0) {
|
|
tileentitybeehive.emptyAllLivingFromHive(player, state, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
|
|
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/IceBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java
|
|
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/TurtleEggBlock.java
|
|
@@ -0,0 +0,0 @@ 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..0000000000000000000000000000000000000000
|
|
--- /dev/null
|
|
+++ b/src/test/java/io/papermc/paper/world/block/BlockPlayerDestroyOverrideTest.java
|
|
@@ -0,0 +0,0 @@
|
|
+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");
|
|
+ }
|
|
+}
|