Skip to content

Commit c7a138b

Browse files
authored
Remove ItemStack mutation on drop methods (#11831)
This caused drop methods to no longer cause mutation of the underlying ItemStack being dropped (turning it into air). This caused a large amount of unintended behavior changes and broke stuff.
1 parent 889c661 commit c7a138b

File tree

7 files changed

+26
-51
lines changed

7 files changed

+26
-51
lines changed

paper-server/patches/features/0001-Moonrise-optimisation-patches.patch

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28126,7 +28126,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896
2812628126
+ // Paper end - block counting
2812728127
}
2812828128
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
28129-
index 262ac42b02b2809439aec5b9e8f4bc3fba04e7fe..9cd31bf05ef7e5b14696cb33bbf995a9405481e3 100644
28129+
index f88ac0961d2474ed0d3c18ff77e789c0ad1c3b50..c272211766d931a5ee3524567781dd41e9dbca20 100644
2813028130
--- a/net/minecraft/world/entity/Entity.java
2813128131
+++ b/net/minecraft/world/entity/Entity.java
2813228132
@@ -152,7 +152,7 @@ import org.jetbrains.annotations.Contract;
@@ -28479,7 +28479,7 @@ index 262ac42b02b2809439aec5b9e8f4bc3fba04e7fe..9cd31bf05ef7e5b14696cb33bbf995a9
2847928479
}
2848028480

2848128481
private static float[] collectCandidateStepUpHeights(AABB box, List<VoxelShape> colliders, float deltaY, float maxUpStep) {
28482-
@@ -2709,21 +2857,110 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
28482+
@@ -2707,21 +2855,110 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
2848328483
}
2848428484

2848528485
public boolean isInWall() {
@@ -28601,7 +28601,7 @@ index 262ac42b02b2809439aec5b9e8f4bc3fba04e7fe..9cd31bf05ef7e5b14696cb33bbf995a9
2860128601
}
2860228602

2860328603
public InteractionResult interact(Player player, InteractionHand hand) {
28604-
@@ -4314,15 +4551,17 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
28604+
@@ -4312,15 +4549,17 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
2860528605
}
2860628606

2860728607
public Iterable<Entity> getIndirectPassengers() {
@@ -28627,7 +28627,7 @@ index 262ac42b02b2809439aec5b9e8f4bc3fba04e7fe..9cd31bf05ef7e5b14696cb33bbf995a9
2862728627
}
2862828628

2862928629
public int countPlayerPassengers() {
28630-
@@ -4471,77 +4710,126 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
28630+
@@ -4469,77 +4708,126 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
2863128631
return Mth.lerp(partialTick, this.yRotO, this.yRot);
2863228632
}
2863328633

@@ -28812,7 +28812,7 @@ index 262ac42b02b2809439aec5b9e8f4bc3fba04e7fe..9cd31bf05ef7e5b14696cb33bbf995a9
2881228812

2881328813
public boolean touchingUnloadedChunk() {
2881428814
AABB aabb = this.getBoundingBox().inflate(1.0);
28815-
@@ -4701,6 +4989,15 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
28815+
@@ -4699,6 +4987,15 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
2881628816
}
2881728817

2881828818
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
@@ -28828,7 +28828,7 @@ index 262ac42b02b2809439aec5b9e8f4bc3fba04e7fe..9cd31bf05ef7e5b14696cb33bbf995a9
2882828828
if (!checkPosition(this, x, y, z)) {
2882928829
return;
2883028830
}
28831-
@@ -4850,6 +5147,12 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
28831+
@@ -4848,6 +5145,12 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
2883228832

2883328833
@Override
2883428834
public final void setRemoved(Entity.RemovalReason removalReason, org.bukkit.event.entity.EntityRemoveEvent.@Nullable Cause cause) { // CraftBukkit - add Bukkit remove cause
@@ -28841,7 +28841,7 @@ index 262ac42b02b2809439aec5b9e8f4bc3fba04e7fe..9cd31bf05ef7e5b14696cb33bbf995a9
2884128841
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit
2884228842
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
2884328843
if (this.removalReason == null) {
28844-
@@ -4860,7 +5163,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
28844+
@@ -4858,7 +5161,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
2884528845
this.stopRiding();
2884628846
}
2884728847

@@ -28850,7 +28850,7 @@ index 262ac42b02b2809439aec5b9e8f4bc3fba04e7fe..9cd31bf05ef7e5b14696cb33bbf995a9
2885028850
this.levelCallback.onRemove(removalReason);
2885128851
this.onRemoval(removalReason);
2885228852
// Paper start - Folia schedulers
28853-
@@ -4894,7 +5197,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
28853+
@@ -4892,7 +5195,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
2885428854
public boolean shouldBeSaved() {
2885528855
return (this.removalReason == null || this.removalReason.shouldSave())
2885628856
&& !this.isPassenger()

paper-server/patches/features/0024-Optimise-EntityScheduler-ticking.patch

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ index e7df5f105c721f2e1be1a13694275c0f03b7932b..0f56d83701ac770799970fceeb73eab5
6767
io.papermc.paper.adventure.providers.ClickCallbackProviderImpl.DIALOG_CLICK_MANAGER.handleQueue(this.tickCount); // Paper
6868
profilerFiller.push("commandFunctions");
6969
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
70-
index e491170cd817b5f2a6951456d36b4ca1bf45c15f..81b860d18f54d5007b12a2a723bde931456211c4 100644
70+
index c830385dd64ee67fd89d912d5d2c8aa2ff35b83b..80526e1e61d38736f4f86fcad282df093121fe49 100644
7171
--- a/net/minecraft/world/entity/Entity.java
7272
+++ b/net/minecraft/world/entity/Entity.java
73-
@@ -5214,6 +5214,11 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
73+
@@ -5212,6 +5212,11 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
7474
this.getBukkitEntity().taskScheduler.retire();
7575
}
7676
// Paper end - Folia schedulers
Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
--- a/net/minecraft/server/commands/GiveCommand.java
22
+++ b/net/minecraft/server/commands/GiveCommand.java
3-
@@ -54,6 +_,7 @@
4-
5-
private static int giveItem(CommandSourceStack source, ItemInput item, Collection<ServerPlayer> targets, int count) throws CommandSyntaxException {
6-
ItemStack itemStack = item.createItemStack(1, false);
7-
+ final Component displayName = itemStack.getDisplayName(); // Paper - get display name early
8-
int maxStackSize = itemStack.getMaxStackSize();
9-
int i = maxStackSize * 100;
10-
if (count > i) {
113
@@ -69,7 +_,7 @@
124
ItemStack itemStack1 = item.createItemStack(min, false);
135
boolean flag = serverPlayer.getInventory().add(itemStack1);
@@ -26,17 +18,3 @@
2618
if (itemEntity != null) {
2719
itemEntity.setNoPickUpDelay();
2820
itemEntity.setTarget(serverPlayer.getUUID());
29-
@@ -98,11 +_,11 @@
30-
31-
if (targets.size() == 1) {
32-
source.sendSuccess(
33-
- () -> Component.translatable("commands.give.success.single", count, itemStack.getDisplayName(), targets.iterator().next().getDisplayName()),
34-
+ () -> Component.translatable("commands.give.success.single", count, displayName, targets.iterator().next().getDisplayName()), // Paper - use cached display name
35-
true
36-
);
37-
} else {
38-
- source.sendSuccess(() -> Component.translatable("commands.give.success.single", count, itemStack.getDisplayName(), targets.size()), true);
39-
+ source.sendSuccess(() -> Component.translatable("commands.give.success.single", count, displayName, targets.size()), true); // Paper - use cached display name
40-
}
41-
42-
return targets.size();

paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@
943943
protected abstract void addAdditionalSaveData(ValueOutput output);
944944

945945
public @Nullable ItemEntity spawnAtLocation(ServerLevel level, ItemLike item) {
946-
@@ -2106,11 +_,60 @@
946+
@@ -2106,11 +_,58 @@
947947
}
948948

949949
public @Nullable ItemEntity spawnAtLocation(ServerLevel level, ItemStack stack, Vec3 offset) {
@@ -970,8 +970,6 @@
970970
if (stack.isEmpty()) {
971971
return null;
972972
} else {
973-
- ItemEntity itemEntity = new ItemEntity(level, this.getX() + offset.x, this.getY() + offset.y, this.getZ() + offset.z, stack);
974-
- itemEntity.setDefaultPickUpDelay();
975973
+ // CraftBukkit start - Capture drops for death event
976974
+ if (this instanceof net.minecraft.world.entity.LivingEntity && !this.forceDrops) {
977975
+ // Paper start - Restore vanilla drops behavior
@@ -985,9 +983,8 @@
985983
+ return null;
986984
+ }
987985
+ // CraftBukkit end
988-
+ ItemEntity itemEntity = new ItemEntity(level, this.getX() + offset.x, this.getY() + offset.y, this.getZ() + offset.z, stack.copy()); // Paper - copy so we can destroy original
989-
+ stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
990-
+
986+
ItemEntity itemEntity = new ItemEntity(level, this.getX() + offset.x, this.getY() + offset.y, this.getZ() + offset.z, stack);
987+
- itemEntity.setDefaultPickUpDelay();
991988
+ itemEntity.setDefaultPickUpDelay(); // Paper - diff on change (in dropConsumer)
992989
+ // Paper start - Call EntityDropItemEvent
993990
+ return this.spawnAtLocation(level, itemEntity);

paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,18 +1682,6 @@
16821682
private void updatingUsingItem() {
16831683
if (this.isUsingItem()) {
16841684
if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) {
1685-
@@ -3297,6 +_,11 @@
1686-
return null;
1687-
} else {
1688-
double d = this.getEyeY() - 0.3F;
1689-
+ // Paper start
1690-
+ final ItemStack tmp = stack.copy();
1691-
+ stack.setCount(0);
1692-
+ stack = tmp;
1693-
+ // Paper end
1694-
ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), d, this.getZ(), stack);
1695-
itemEntity.setPickUpDelay(40);
1696-
if (includeThrower) {
16971685
@@ -3328,7 +_,12 @@
16981686

16991687
protected void updateUsingItem(ItemStack usingItem) {

paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,19 @@
192192
ItemStack item = inventory.getItem(button);
193193
Slot slot = this.slots.get(slotIndex);
194194
ItemStack carried = slot.getItem();
195+
@@ -528,7 +_,11 @@
196+
}
197+
198+
carried = slot2.safeTake(i1, Integer.MAX_VALUE, player);
199+
- player.drop(carried, true);
200+
+ // CraftBukkit start - SPIGOT-8010: break loop
201+
+ if (player.drop(carried, true) == null) {
202+
+ break;
203+
+ }
204+
+ // CraftBukkit end - SPIGOT-8010: break loop
205+
player.handleCreativeModeItemDrop(carried);
206+
}
207+
}
195208
@@ -588,8 +_,9 @@
196209
if (player instanceof ServerPlayer) {
197210
ItemStack carried = this.getCarried();

paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,6 @@ public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.L
10011001
if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;
10021002

10031003
drop.runConsumer(s -> world.dropItem(entity.getLocation(), s)); // Paper - Restore vanilla drops behavior
1004-
if (stack instanceof CraftItemStack) stack.setAmount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe, but don't nuke bukkit stacks of manually added items
10051004
}
10061005

10071006
return event;

0 commit comments

Comments
 (0)