geforkt von Mirrors/Paper
aa52bf9e33
Mojang made some changes to priorities in 1.17 and it seems that these changes conflict with the changes made in this patch, which in some cases appears to cause excessive rescheduling of tasks. This, however, is not confirmed as such but seems to be the behavior that we're seeing to cause this issue, if mojang has adopted the changes we suggested, then a good chunk of this patch may be unneeded, but, this needs a much better look than I'm currently able to do
71 Zeilen
4.0 KiB
Diff
71 Zeilen
4.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Alphaesia <creepashadowz@gmail.com>
|
|
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 4a49c06bdae9f2dd684743f434d96817d472de06..3ea6ec6cd8a081fd427319bb01ea23e4670e8507 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
|
@@ -685,6 +685,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 {
|
|
@@ -726,7 +733,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
|