aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0630-Fix-duplicating-give-items-on-item-drop-cancel.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0630-Fix-duplicating-give-items-on-item-drop-cancel.patch')
-rw-r--r--patches/server/0630-Fix-duplicating-give-items-on-item-drop-cancel.patch70
1 files changed, 70 insertions, 0 deletions
diff --git a/patches/server/0630-Fix-duplicating-give-items-on-item-drop-cancel.patch b/patches/server/0630-Fix-duplicating-give-items-on-item-drop-cancel.patch
new file mode 100644
index 0000000000..1fdb5f16ee
--- /dev/null
+++ b/patches/server/0630-Fix-duplicating-give-items-on-item-drop-cancel.patch
@@ -0,0 +1,70 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Alphaesia <[email protected]>
+Date: Fri, 23 Apr 2021 09:57:56 +1200
+Subject: [PATCH] Fix duplicating /give items on item drop cancel
+
+Fixes SPIGOT-2942 (Give command fires PlayerDropItemEvent, cancelling it causes item duplication).
+
+For every stack of items to give, /give puts the item stack straight
+into the player's inventory. However, it also summons a "fake item"
+at the player's location. When the PlayerDropItemEvent for this fake
+item is cancelled, the server attempts to put the item back into the
+player's inventory. The result is that the fake item, which is never
+meant to be obtained, is combined with the real items injected directly
+into the player's inventory. This means more items than the amount
+specified in /give are given to the player - one for every stack of
+items given. (e.g. /give @s dirt 1 gives you 2 dirt).
+
+While this isn't a big issue for general building usage, it can affect
+e.g. adventure maps where the number of items the player receives is
+important (and you want to restrict the player from throwing items).
+
+If there are any overflow items that didn't make it into the inventory
+(insufficient space), those items are dropped as a real item instead
+of a fake one. While cancelling this drop would also result in the
+server attempting to put those items into the inventory, since it is
+full this has no effect.
+
+Just ignoring cancellation of the PlayerDropItemEvent seems like the
+cleanest and least intrusive way to fix it.
+
+diff --git a/src/main/java/net/minecraft/server/commands/GiveCommand.java b/src/main/java/net/minecraft/server/commands/GiveCommand.java
+index 58941830a4bd024fcdb97df47783c82062e9167f..a0dc380e90415de9068ea408d62a1605c82631df 100644
+--- a/src/main/java/net/minecraft/server/commands/GiveCommand.java
++++ b/src/main/java/net/minecraft/server/commands/GiveCommand.java
+@@ -47,7 +47,7 @@ public class GiveCommand {
+ boolean bl = serverPlayer.getInventory().add(itemStack);
+ if (bl && itemStack.isEmpty()) {
+ itemStack.setCount(1);
+- ItemEntity itemEntity2 = serverPlayer.drop(itemStack, false);
++ ItemEntity itemEntity2 = serverPlayer.drop(itemStack, false, false, true); // Paper - Fix duplicating /give items on item drop cancel
+ if (itemEntity2 != null) {
+ itemEntity2.makeFakeItem();
+ }
+diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
+index 4e604e902145ea91811e8e7769952024fcbd1a3d..0a486c8c4ad6abfdca804887e5db1487f53c1098 100644
+--- a/src/main/java/net/minecraft/world/entity/player/Player.java
++++ b/src/main/java/net/minecraft/world/entity/player/Player.java
+@@ -693,6 +693,13 @@ public abstract class Player extends LivingEntity {
+
+ @Nullable
+ public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership) {
++ // Paper start - Fix duplicating /give items on item drop cancel
++ return this.drop(stack, throwRandomly, retainOwnership, false);
++ }
++
++ @Nullable
++ public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership, boolean alwaysSucceed) {
++ // Paper end
+ if (stack.isEmpty()) {
+ return null;
+ } else {
+@@ -734,7 +741,7 @@ public abstract class Player extends LivingEntity {
+ PlayerDropItemEvent event = new PlayerDropItemEvent(player, drop);
+ this.level.getCraftServer().getPluginManager().callEvent(event);
+
+- if (event.isCancelled()) {
++ if (event.isCancelled() && !alwaysSucceed) { // Paper - Fix duplicating /give items on item drop cancel
+ org.bukkit.inventory.ItemStack cur = player.getInventory().getItemInHand();
+ if (retainOwnership && (cur == null || cur.getAmount() == 0)) {
+ // The complete stack was dropped