diff options
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.patch | 70 |
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 |