geforkt von Mirrors/Paper
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
Dieser Commit ist enthalten in:
Ursprung
06ee045ab9
Commit
7e6bdb92a4
165
patches/server/Properly-handle-BlockBreakEvent-isDropItems.patch
Normale Datei
165
patches/server/Properly-handle-BlockBreakEvent-isDropItems.patch
Normale Datei
@ -0,0 +1,165 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
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 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) { // 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 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 // 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 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) { // 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 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) { // 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 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) { // 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..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 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());
|
||||||
|
+ }
|
||||||
|
+}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren