aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAlphaesia <[email protected]>2021-04-23 21:36:34 +1200
committerGitHub <[email protected]>2021-04-23 11:36:34 +0200
commit9957f46302b558fb850e96363f5d4c61b6090263 (patch)
tree513bc0c1457b552a73d45f85b5b3443918808f6a
parentd94882043d21d3e4f00f0172bfe1657f18c73d13 (diff)
downloadPaper-9957f46302b558fb850e96363f5d4c61b6090263.tar.gz
Paper-9957f46302b558fb850e96363f5d4c61b6090263.zip
Fix duplicating /give items on item drop cancel (#5536)
-rw-r--r--Spigot-Server-Patches/0707-Fix-duplicating-give-items-on-item-drop-cancel.patch70
1 files changed, 70 insertions, 0 deletions
diff --git a/Spigot-Server-Patches/0707-Fix-duplicating-give-items-on-item-drop-cancel.patch b/Spigot-Server-Patches/0707-Fix-duplicating-give-items-on-item-drop-cancel.patch
new file mode 100644
index 0000000000..cee651ba1d
--- /dev/null
+++ b/Spigot-Server-Patches/0707-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/CommandGive.java b/src/main/java/net/minecraft/server/commands/CommandGive.java
+index 6685bf1757458d908e32d4069f7a8a22a28c28d7..a10207f7cb9455e29db7e6906cb2138ad5609a1f 100644
+--- a/src/main/java/net/minecraft/server/commands/CommandGive.java
++++ b/src/main/java/net/minecraft/server/commands/CommandGive.java
+@@ -49,7 +49,7 @@ public class CommandGive {
+
+ if (flag && itemstack.isEmpty()) {
+ itemstack.setCount(1);
+- entityitem = entityplayer.drop(itemstack, false);
++ entityitem = entityplayer.drop(itemstack, false, false, true); // Paper - Fix duplicating /give items on item drop cancel
+ if (entityitem != null) {
+ entityitem.s();
+ }
+diff --git a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
+index ec0956a98c133bcd3d4f92f696c667eab6ff98f1..3a62bde04d7fbb6c571cfef11d4f6891e11c7ac8 100644
+--- a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
++++ b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java
+@@ -642,6 +642,13 @@ public abstract class EntityHuman extends EntityLiving {
+
+ @Nullable
+ public EntityItem a(ItemStack itemstack, boolean flag, boolean flag1) {
++ // Paper start - Fix duplicating /give items on item drop cancel
++ return this.drop(itemstack, flag, flag1, false);
++ }
++
++ @Nullable
++ public EntityItem drop(ItemStack itemstack, boolean flag, boolean flag1, boolean alwaysSucceed) {
++ // Paper end
+ if (itemstack.isEmpty()) {
+ return null;
+ } else {
+@@ -683,7 +690,7 @@ public abstract class EntityHuman extends EntityLiving {
+ PlayerDropItemEvent event = new PlayerDropItemEvent(player, drop);
+ this.world.getServer().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 (flag1 && (cur == null || cur.getAmount() == 0)) {
+ // The complete stack was dropped