--- a/net/minecraft/server/TileEntityHopper.java +++ b/net/minecraft/server/TileEntityHopper.java @@ -3,12 +3,46 @@ import java.util.Iterator; import java.util.List; +// CraftBukkit start +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.inventory.Inventory; +// CraftBukkit end + public class TileEntityHopper extends TileEntityContainer implements IHopper, IUpdatePlayerListBox { private ItemStack[] items = new ItemStack[5]; private String f; private int g = -1; + // CraftBukkit start - add fields and methods + public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>(); + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List<HumanEntity> getViewers() { + return transaction; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + public TileEntityHopper() {} public void a(NBTTagCompound nbttagcompound) { @@ -120,7 +154,7 @@ } public int getMaxStackSize() { - return 64; + return maxStack; // CraftBukkit } public boolean a(EntityHuman entityhuman) { @@ -216,10 +250,35 @@ for (int i = 0; i < this.getSize(); ++i) { if (this.getItem(i) != null) { ItemStack itemstack = this.getItem(i).cloneItemStack(); - ItemStack itemstack1 = addItem(iinventory, this.splitStack(i, 1), enumdirection); + // ItemStack itemstack1 = addItem(iinventory, this.splitStack(i, 1), enumdirection); + + // CraftBukkit start - Call event when pushing items into other inventories + CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, 1)); + + Inventory destinationInventory; + // Have to special case large chests as they work oddly + if (iinventory instanceof InventoryLargeChest) { + destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); + } else { + destinationInventory = iinventory.getOwner().getInventory(); + } + + InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); + this.getWorld().getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + this.setItem(i, itemstack); + this.d(8); // Delay hopper checks + return false; + } + ItemStack itemstack1 = addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), enumdirection); if (itemstack1 == null || itemstack1.count == 0) { - iinventory.update(); + if (event.getItem().equals(oitemstack)) { + iinventory.update(); + } else { + this.setItem(i, itemstack); + } + // CraftBukkit end return true; } @@ -330,10 +389,41 @@ if (itemstack != null && b(iinventory, itemstack, i, enumdirection)) { ItemStack itemstack1 = itemstack.cloneItemStack(); - ItemStack itemstack2 = addItem(ihopper, iinventory.splitStack(i, 1), (EnumDirection) null); + // ItemStack itemstack2 = addItem(ihopper, iinventory.splitStack(i, 1), (EnumDirection) null); + // CraftBukkit start - Call event on collection of items from inventories into the hopper + CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, 1)); + + Inventory sourceInventory; + // Have to special case large chests as they work oddly + if (iinventory instanceof InventoryLargeChest) { + sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); + } else { + sourceInventory = iinventory.getOwner().getInventory(); + } + + InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false); + + ihopper.getWorld().getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + iinventory.setItem(i, itemstack1); + + if (ihopper instanceof TileEntityHopper) { + ((TileEntityHopper) ihopper).d(8); // Delay hopper checks + } else if (ihopper instanceof EntityMinecartHopper) { + ((EntityMinecartHopper) ihopper).m(4); // Delay hopper minecart checks + } + + return false; + } + ItemStack itemstack2 = addItem(ihopper, CraftItemStack.asNMSCopy(event.getItem()), null); if (itemstack2 == null || itemstack2.count == 0) { - iinventory.update(); + if (event.getItem().equals(oitemstack)) { + iinventory.update(); + } else { + iinventory.setItem(i, itemstack1); + } + // CraftBukkit end return true; } @@ -349,6 +439,13 @@ if (entityitem == null) { return false; } else { + // CraftBukkit start + InventoryPickupItemEvent event = new InventoryPickupItemEvent(iinventory.getOwner().getInventory(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); + entityitem.world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } + // CraftBukkit end ItemStack itemstack = entityitem.getItemStack().cloneItemStack(); ItemStack itemstack1 = addItem(iinventory, itemstack, (EnumDirection) null);