PaperMC/nms-patches/Container.patch

137 lines
7.2 KiB
Diff
Raw Normal View History

2015-05-25 12:37:24 +02:00
--- a/net/minecraft/server/Container.java
+++ b/net/minecraft/server/Container.java
2016-11-17 02:41:03 +01:00
@@ -7,6 +7,17 @@
import java.util.Set;
2016-05-10 13:47:39 +02:00
import javax.annotation.Nullable;
+// CraftBukkit start
+import java.util.HashMap;
+import java.util.Map;
+import org.bukkit.craftbukkit.inventory.CraftInventory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.Event.Result;
+import org.bukkit.event.inventory.InventoryDragEvent;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.inventory.InventoryView;
+// CraftBukkit end
+
public abstract class Container {
2016-11-17 02:41:03 +01:00
public NonNullList<ItemStack> b = NonNullList.a();
@@ -18,6 +29,18 @@
2015-02-26 23:41:06 +01:00
protected List<ICrafting> listeners = Lists.newArrayList();
2016-06-09 03:43:49 +02:00
private final Set<EntityHuman> i = Sets.newHashSet();
2015-02-26 23:41:06 +01:00
+ // CraftBukkit start
+ public boolean checkReachable = true;
+ public abstract InventoryView getBukkitView();
+ public void transferTo(Container other, org.bukkit.craftbukkit.entity.CraftHumanEntity player) {
+ InventoryView source = this.getBukkitView(), destination = other.getBukkitView();
+ ((CraftInventory) source.getTopInventory()).getInventory().onClose(player);
+ ((CraftInventory) source.getBottomInventory()).getInventory().onClose(player);
+ ((CraftInventory) destination.getTopInventory()).getInventory().onOpen(player);
+ ((CraftInventory) destination.getBottomInventory()).getInventory().onOpen(player);
+ }
2015-02-26 23:41:06 +01:00
+ // CraftBukkit end
+
public Container() {}
2015-02-26 23:41:06 +01:00
protected Slot a(Slot slot) {
2016-05-10 13:47:39 +02:00
@@ -128,6 +151,7 @@
2016-11-17 02:41:03 +01:00
l = playerinventory.getCarried().getCount();
Iterator iterator = this.h.iterator();
+ Map<Integer, ItemStack> draggedSlots = new HashMap<Integer, ItemStack>(); // CraftBukkit - Store slots from drag in map (raw slot id -> new stack)
while (iterator.hasNext()) {
Slot slot1 = (Slot) iterator.next();
2016-11-17 02:41:03 +01:00
ItemStack itemstack3 = playerinventory.getCarried();
@@ -143,12 +167,48 @@
}
2016-11-17 02:41:03 +01:00
l -= itemstack4.getCount() - j1;
- slot1.set(itemstack4);
+ // slot1.set(itemstack4);
+ draggedSlots.put(slot1.rawSlotIndex, itemstack4); // CraftBukkit - Put in map instead of setting
2017-05-14 04:00:00 +02:00
}
}
- itemstack2.setCount(l);
- playerinventory.setCarried(itemstack2);
+ // CraftBukkit start - InventoryDragEvent
+ InventoryView view = getBukkitView();
2016-11-17 02:41:03 +01:00
+ org.bukkit.inventory.ItemStack newcursor = CraftItemStack.asCraftMirror(itemstack2);
+ newcursor.setAmount(l);
+ Map<Integer, org.bukkit.inventory.ItemStack> eventmap = new HashMap<Integer, org.bukkit.inventory.ItemStack>();
+ for (Map.Entry<Integer, ItemStack> ditem : draggedSlots.entrySet()) {
+ eventmap.put(ditem.getKey(), CraftItemStack.asBukkitCopy(ditem.getValue()));
+ }
2015-02-26 23:41:06 +01:00
+
+ // It's essential that we set the cursor to the new value here to prevent item duplication if a plugin closes the inventory.
+ ItemStack oldCursor = playerinventory.getCarried();
+ playerinventory.setCarried(CraftItemStack.asNMSCopy(newcursor));
+
+ InventoryDragEvent event = new InventoryDragEvent(view, (newcursor.getType() != org.bukkit.Material.AIR ? newcursor : null), CraftItemStack.asBukkitCopy(oldCursor), this.dragType == 1, eventmap);
+ entityhuman.world.getServer().getPluginManager().callEvent(event);
+
+ // Whether or not a change was made to the inventory that requires an update.
+ boolean needsUpdate = event.getResult() != Result.DEFAULT;
+
+ if (event.getResult() != Result.DENY) {
+ for (Map.Entry<Integer, ItemStack> dslot : draggedSlots.entrySet()) {
+ view.setItem(dslot.getKey(), CraftItemStack.asBukkitCopy(dslot.getValue()));
+ }
+ // The only time the carried item will be set to null is if the inventory is closed by the server.
+ // If the inventory is closed by the server, then the cursor items are dropped. This is why we change the cursor early.
+ if (playerinventory.getCarried() != null) {
+ playerinventory.setCarried(CraftItemStack.asNMSCopy(event.getCursor()));
+ needsUpdate = true;
2017-05-14 04:00:00 +02:00
+ }
+ } else {
+ playerinventory.setCarried(oldCursor);
2017-05-14 04:00:00 +02:00
+ }
+
+ if (needsUpdate && entityhuman instanceof EntityPlayer) {
+ ((EntityPlayer) entityhuman).updateInventory(this);
+ }
+ // CraftBukkit end
}
this.d();
@@ -165,8 +225,11 @@
if (i == -999) {
if (!playerinventory.getCarried().isEmpty()) {
if (j == 0) {
- entityhuman.drop(playerinventory.getCarried(), true);
+ // CraftBukkit start
+ ItemStack carried = playerinventory.getCarried();
playerinventory.setCarried(ItemStack.a);
+ entityhuman.drop(carried, true);
+ // CraftBukkit start
}
if (j == 1) {
2017-05-14 04:00:00 +02:00
@@ -254,6 +317,15 @@
}
slot2.f();
+ // CraftBukkit start - Make sure the client has the right slot contents
+ if (entityhuman instanceof EntityPlayer && slot2.getMaxStackSize() != 64) {
+ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, slot2.rawSlotIndex, slot2.getItem()));
+ // Updating a crafting inventory makes the client reset the result slot, have to send it again
+ if (this.getBukkitView().getType() == InventoryType.WORKBENCH || this.getBukkitView().getType() == InventoryType.CRAFTING) {
+ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, 0, this.getSlot(0).getItem()));
+ }
+ }
2015-02-26 23:41:06 +01:00
+ // CraftBukkit end
}
}
2016-02-29 22:32:46 +01:00
} else if (inventoryclicktype == InventoryClickType.SWAP && j >= 0 && j < 9) {
2017-05-14 04:00:00 +02:00
@@ -575,6 +647,7 @@
inventorycraftresult.a(irecipe);
itemstack = irecipe.craftItem(inventorycrafting);
}
+ itemstack = org.bukkit.craftbukkit.event.CraftEventFactory.callPreCraftEvent(inventorycrafting, itemstack, getBukkitView(), false); // CraftBukkit
inventorycraftresult.setItem(0, itemstack);
entityplayer.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, 0, itemstack));