diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index 9e4be51..2291747 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -3,9 +3,14 @@ import net.minecraft.entity.player.EntityPlayerMP; import org.bukkit.GameMode; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftContainer; import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryType; @@ -20,6 +25,8 @@ import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; import org.ultramine.mods.bukkit.interfaces.entity.player.IMixinPlayer; +import org.ultramine.mods.bukkit.interfaces.entity.player.IMixinPlayerMP; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinContainer; import java.util.Set; @@ -205,9 +212,8 @@ } public InventoryView getOpenInventory() - { //TODO -// return getHandle().openContainer.getBukkitView(); - throw new UnsupportedOperationException(); + { + return ((IMixinContainer) getHandle().openContainer).getBukkitView(); } public InventoryView openInventory(Inventory inventory) @@ -283,103 +289,99 @@ { return null; } -// getHandle().openContainer.checkReachable = false; -// return getHandle().openContainer.getBukkitView(); - - throw new UnsupportedOperationException(); //TODO + //TODO +// getHandle().openContainer.checkReachable = false; + return ((IMixinContainer) getHandle().openContainer).getBukkitView(); } private void openCustomInventory(Inventory inventory, net.minecraft.entity.player.EntityPlayerMP player, int windowType) { -// if (player.playerNetServerHandler == null) return; -// net.minecraft.inventory.Container container = new CraftContainer(inventory, this, player.nextContainerCounter()); -// -// container = CraftEventFactory.callInventoryOpenEvent(player, container); -// if(container == null) return; -// -// String title = container.getBukkitView().getTitle(); -// int size = container.getBukkitView().getTopInventory().getSize(); -// -// player.playerNetServerHandler.sendPacket(new net.minecraft.network.play.server.S2DPacketOpenWindow(container.windowId, windowType, title, size, true)); -// getHandle().openContainer = container; -// getHandle().openContainer.addCraftingToCrafters(player); + if (player.playerNetServerHandler == null) return; + net.minecraft.inventory.Container container = new CraftContainer(inventory, this, ((IMixinPlayerMP) player).nextContainerCounter()); - throw new UnsupportedOperationException(); //TODO + container = CraftEventFactory.callInventoryOpenEvent(player, container); + if(container == null) return; + + InventoryView view = ((IMixinContainer) container).getBukkitView(); + if(view == null) return; + + String title = view.getTitle(); + int size = view.getTopInventory().getSize(); + + player.playerNetServerHandler.sendPacket(new net.minecraft.network.play.server.S2DPacketOpenWindow(container.windowId, windowType, title, size, true)); + getHandle().openContainer = container; + getHandle().openContainer.addCraftingToCrafters(player); } public InventoryView openWorkbench(Location location, boolean force) { -// if (!force) { -// Block block = location.getBlock(); -// if (block.getType() != Material.WORKBENCH) { -// return null; -// } -// } -// if (location == null) { -// location = getLocation(); -// } -// getHandle().displayGUIWorkbench(location.getBlockX(), location.getBlockY(), location.getBlockZ()); -// if (force) { -// getHandle().openContainer.checkReachable = false; -// } -// return getHandle().openContainer.getBukkitView(); - - throw new UnsupportedOperationException(); //TODO + if (!force) { + Block block = location.getBlock(); + if (block.getType() != Material.WORKBENCH) { + return null; + } + } + if (location == null) { + location = getLocation(); + } + getHandle().displayGUIWorkbench(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + if (force) { + // TODO +// getHandle().openContainer.checkReachable = false; + } + return ((IMixinContainer) getHandle().openContainer).getBukkitView(); } public InventoryView openEnchanting(Location location, boolean force) { -// if (!force) { -// Block block = location.getBlock(); -// if (block.getType() != Material.ENCHANTMENT_TABLE) { -// return null; -// } -// } -// if (location == null) { -// location = getLocation(); -// } -// getHandle().displayGUIEnchantment(location.getBlockX(), location.getBlockY(), location.getBlockZ(), null); -// if (force) { -// getHandle().openContainer.checkReachable = false; -// } -// return getHandle().openContainer.getBukkitView(); - - throw new UnsupportedOperationException(); //TODO + if (!force) { + Block block = location.getBlock(); + if (block.getType() != Material.ENCHANTMENT_TABLE) { + return null; + } + } + if (location == null) { + location = getLocation(); + } + getHandle().displayGUIEnchantment(location.getBlockX(), location.getBlockY(), location.getBlockZ(), null); + if (force) { + // TODO +// getHandle().openContainer.checkReachable = false; + } + return ((IMixinContainer) getHandle().openContainer).getBukkitView(); } public void openInventory(InventoryView inventory) { -// if (!(getHandle() instanceof net.minecraft.entity.player.EntityPlayerMP)) return; // TODO: NPC support? -// if (((net.minecraft.entity.player.EntityPlayerMP) getHandle()).playerNetServerHandler == null) return; -// if (getHandle().openContainer != getHandle().inventoryContainer) { -// // fire INVENTORY_CLOSE if one already open -// ((net.minecraft.entity.player.EntityPlayerMP)getHandle()).playerNetServerHandler.processCloseWindow(new net.minecraft.network.play.client.C0DPacketCloseWindow(getHandle().openContainer.windowId)); -// } -// net.minecraft.entity.player.EntityPlayerMP player = (net.minecraft.entity.player.EntityPlayerMP) getHandle(); -// net.minecraft.inventory.Container container; -// if (inventory instanceof CraftInventoryView) { -// container = ((CraftInventoryView) inventory).getHandle(); -// } else { -// player.getNextWindowId(); -// container = new CraftContainer(inventory, player.currentWindowId); -// } -// -// // Trigger an INVENTORY_OPEN event -// container = CraftEventFactory.callInventoryOpenEvent(player, container); -// if (container == null) { -// return; -// } -// -// // Now open the window -// InventoryType type = inventory.getType(); -// int windowType = CraftContainer.getNotchInventoryType(type); -// String title = inventory.getTitle(); -// int size = inventory.getTopInventory().getSize(); -// player.playerNetServerHandler.sendPacket(new net.minecraft.network.play.server.S2DPacketOpenWindow(container.windowId, windowType, title, size, false)); -// player.openContainer = container; -// player.openContainer.addCraftingToCrafters(player); + if (!(getHandle() instanceof net.minecraft.entity.player.EntityPlayerMP)) return; // TODO: NPC support? + if (((net.minecraft.entity.player.EntityPlayerMP) getHandle()).playerNetServerHandler == null) return; + if (getHandle().openContainer != getHandle().inventoryContainer) { + // fire INVENTORY_CLOSE if one already open + ((net.minecraft.entity.player.EntityPlayerMP)getHandle()).playerNetServerHandler.processCloseWindow(new net.minecraft.network.play.client.C0DPacketCloseWindow(getHandle().openContainer.windowId)); + } + net.minecraft.entity.player.EntityPlayerMP player = (net.minecraft.entity.player.EntityPlayerMP) getHandle(); + net.minecraft.inventory.Container container; + if (inventory instanceof CraftInventoryView) { + container = ((CraftInventoryView) inventory).getHandle(); + } else { + player.getNextWindowId(); + container = new CraftContainer(inventory, player.currentWindowId); + } - throw new UnsupportedOperationException(); //TODO + // Trigger an INVENTORY_OPEN event + container = CraftEventFactory.callInventoryOpenEvent(player, container); + if (container == null) { + return; + } + + // Now open the window + InventoryType type = inventory.getType(); + int windowType = CraftContainer.getNotchInventoryType(type); + String title = inventory.getTitle(); + int size = inventory.getTopInventory().getSize(); + player.playerNetServerHandler.sendPacket(new net.minecraft.network.play.server.S2DPacketOpenWindow(container.windowId, windowType, title, size, false)); + player.openContainer = container; + player.openContainer.addCraftingToCrafters(player); } public void closeInventory() diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index cc1f575..62ac7fd 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -29,8 +29,10 @@ import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.craftbukkit.entity.CraftLivingEntity; import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.util.CraftDamageSource; import org.bukkit.craftbukkit.util.CraftMagicNumbers; @@ -87,6 +89,9 @@ import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.inventory.PrepareItemCraftEvent; import org.bukkit.event.player.PlayerAchievementAwardedEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerBucketFillEvent; @@ -99,12 +104,14 @@ import org.bukkit.event.player.PlayerStatisticIncrementEvent; import org.bukkit.event.player.PlayerUnleashEntityEvent; import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.meta.BookMeta; import org.ultramine.mods.bukkit.interfaces.IMixinEntityDamageSourceIndirect; import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntity; import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntityLiving; import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntityLivingBase; import org.ultramine.mods.bukkit.interfaces.entity.player.IMixinPlayerMP; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinContainer; import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; import org.ultramine.mods.bukkit.util.ArmorPropertiesUM; @@ -1066,44 +1073,39 @@ //TODO // Cauldron start - allow inventory force close to be toggled -// public static net.minecraft.inventory.Container callInventoryOpenEvent(net.minecraft.entity.player.EntityPlayerMP player, net.minecraft.inventory.Container container) { -// return callInventoryOpenEvent(player, container, true); -// } + public static net.minecraft.inventory.Container callInventoryOpenEvent(net.minecraft.entity.player.EntityPlayerMP player, net.minecraft.inventory.Container container) { + return callInventoryOpenEvent(player, container, true); + } -// public static net.minecraft.inventory.Container callInventoryOpenEvent(net.minecraft.entity.player.EntityPlayerMP player, net.minecraft.inventory.Container container, boolean closeInv) { -// if (player.openContainer != player.inventoryContainer && closeInv) { // fire INVENTORY_CLOSE if one already open -// // Cauldron end -// player.playerNetServerHandler.processCloseWindow(new net.minecraft.network.play.client.C0DPacketCloseWindow(player.openContainer.windowId)); -// } -// -// CraftServer server = ((IMixinWorld) player.worldObj).getServer(); -// CraftPlayer craftPlayer = (CraftPlayer) ((IMixinEntity) player).getBukkitEntity(); -// // Cauldron start - vanilla compatibility -// try { -// player.openContainer.transferTo(container, craftPlayer); -// } -// catch (AbstractMethodError e) { -// // do nothing -// } -// // Cauldron end -// InventoryOpenEvent event = new InventoryOpenEvent(container.getBukkitView()); -// if (container.getBukkitView() != null) server.getPluginManager().callEvent(event); // Cauldron - allow vanilla mods to bypass -// -// if (event.isCancelled()) { -// container.transferTo(player.openContainer, craftPlayer); -// // Cauldron start - handle close for modded containers -// if (!closeInv) { // fire INVENTORY_CLOSE if one already open -// player.openContainer = container; // make sure the right container is processed -// player.closeScreen(); -// player.openContainer = player.inventoryContainer; -// } -// // Cauldron end -// return null; -// } -// -// return container; -// } -// + public static net.minecraft.inventory.Container callInventoryOpenEvent(net.minecraft.entity.player.EntityPlayerMP player, net.minecraft.inventory.Container container, boolean closeInv) { + if (player.openContainer != player.inventoryContainer && closeInv) { // fire INVENTORY_CLOSE if one already open + // Cauldron end + player.playerNetServerHandler.processCloseWindow(new net.minecraft.network.play.client.C0DPacketCloseWindow(player.openContainer.windowId)); + } + + CraftServer server = ((IMixinWorld) player.worldObj).getServer(); + CraftPlayer craftPlayer = (CraftPlayer) ((IMixinEntity) player).getBukkitEntity(); + // Cauldron start - vanilla compatibility + ((IMixinContainer) player.openContainer).transferTo(container, craftPlayer); + // Cauldron end + InventoryOpenEvent event = new InventoryOpenEvent(((IMixinContainer) container).getBukkitView()); + if (((IMixinContainer) container).getBukkitView() != null) server.getPluginManager().callEvent(event); // Cauldron - allow vanilla mods to bypass + + if (event.isCancelled()) { + ((IMixinContainer) container).transferTo(player.openContainer, craftPlayer); + // Cauldron start - handle close for modded containers + if (!closeInv) { // fire INVENTORY_CLOSE if one already open + player.openContainer = container; // make sure the right container is processed + player.closeScreen(); + player.openContainer = player.inventoryContainer; + } + // Cauldron end + return null; + } + + return container; + } + // public static net.minecraft.item.ItemStack callPreCraftEvent(net.minecraft.inventory.InventoryCrafting matrix, net.minecraft.item.ItemStack result, InventoryView lastCraftView, boolean isRepair) { // CraftInventoryCrafting inventory = new CraftInventoryCrafting(matrix, matrix.resultInventory); // inventory.setResult(CraftItemStack.asCraftMirror(result)); @@ -1227,12 +1229,12 @@ return event; } - //TODO !!! public static void handleInventoryCloseEvent(net.minecraft.entity.player.EntityPlayer human) - { //TODO !!! -// InventoryCloseEvent event = new InventoryCloseEvent(human.openContainer.getBukkitView()); -// if (human.openContainer.getBukkitView() != null) ((IMixinWorld) human.worldObj).getServer().getPluginManager().callEvent(event); // Cauldron - allow vanilla mods to bypass -// human.openContainer.transferTo(human.inventoryContainer, (HumanEntity) ((IMixinEntity) human).getBukkitEntity()); + { + InventoryView view = ((IMixinContainer) human.openContainer).getBukkitView(); + if(view != null) + ((IMixinWorld) human.worldObj).getServer().getPluginManager().callEvent(new InventoryCloseEvent(view)); // Cauldron - allow vanilla mods to bypass + ((IMixinContainer) human.openContainer).transferTo(human.inventoryContainer, (CraftHumanEntity) ((IMixinEntity) human).getBukkitEntity()); } public static void handleEditBookEvent(net.minecraft.entity.player.EntityPlayerMP player, net.minecraft.item.ItemStack newBookItem) diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java index e93e9c9..5180554 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java @@ -575,7 +575,7 @@ public InventoryHolder getHolder() { - return BukkitUtil.getBukkitOwner(getInventory()); + return BukkitUtil.getInventoryOwner(getInventory()); } public int getMaxStackSize() diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java index da2ffa7..e69cd54 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java @@ -1,9 +1,16 @@ package org.bukkit.craftbukkit.inventory; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.ShapelessRecipes; import org.bukkit.inventory.CraftingInventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; +import org.bukkit.inventory.ShapedRecipe; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryCrafting; +import org.ultramine.mods.bukkit.interfaces.item.crafting.IMixinShapedRecipes; +import org.ultramine.mods.bukkit.interfaces.item.crafting.IMixinShapelessRecipes; import org.ultramine.mods.bukkit.util.BukkitUtil; +import org.ultramine.mods.bukkit.util.CustomModRecipe; import java.util.Arrays; @@ -166,9 +173,14 @@ public Recipe getRecipe() { -// net.minecraft.item.crafting.IRecipe recipe = ((net.minecraft.inventory.InventoryCrafting)getInventory()).currentRecipe; -// return BukkitInventoryUtil.toBukkitRecipe(recipe); - - throw new UnsupportedOperationException(); // TODO + IRecipe recipe = ((IMixinInventoryCrafting) this).getCurrentRecipe(); + if (recipe != null) + { + if (recipe instanceof ShapelessRecipes) + return ((IMixinShapelessRecipes) recipe).toBukkitRecipe(); + else if(recipe instanceof ShapedRecipe) + return ((IMixinShapedRecipes) recipe).toBukkitRecipe(); + } + return new CustomModRecipe(recipe); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryEnchanting.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryEnchanting.java index 9b5f6c8..bc51354 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryEnchanting.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryEnchanting.java @@ -1,22 +1,24 @@ package org.bukkit.craftbukkit.inventory; -// TODO +import org.bukkit.inventory.EnchantingInventory; +import org.bukkit.inventory.ItemStack; -//public class CraftInventoryEnchanting extends CraftInventory implements EnchantingInventory { -// public CraftInventoryEnchanting(net.minecraft.inventory.ContainerEnchantTableInventory inventory) { -// super(inventory); -// } -// -// public void setItem(ItemStack item) { -// setItem(0,item); -// } -// -// public ItemStack getItem() { -// return getItem(0); -// } -// +public class CraftInventoryEnchanting extends CraftInventory implements EnchantingInventory +{ + public CraftInventoryEnchanting(net.minecraft.inventory.IInventory inventory) { + super(inventory); + } + + public void setItem(ItemStack item) { + setItem(0, item); + } + + public ItemStack getItem() { + return getItem(0); + } + // @Override // public net.minecraft.inventory.ContainerEnchantTableInventory getInventory() { // return (net.minecraft.inventory.ContainerEnchantTableInventory)inventory; // } -//} +} diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java index 14ad1d4..e5a1513 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java @@ -46,6 +46,6 @@ @Override public Furnace getHolder() { - return (Furnace) BukkitUtil.getBukkitOwner(inventory); + return (Furnace) BukkitUtil.getInventoryOwner(inventory); } } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java index 6a1b32f..7b15157 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java @@ -1,7 +1,11 @@ package org.bukkit.craftbukkit.inventory; import org.bukkit.inventory.Recipe; -import org.ultramine.mods.bukkit.util.BukkitUtil; +import org.bukkit.inventory.ShapedRecipe; +import org.bukkit.inventory.ShapelessRecipe; +import org.ultramine.mods.bukkit.interfaces.item.crafting.IMixinShapedRecipes; +import org.ultramine.mods.bukkit.interfaces.item.crafting.IMixinShapelessRecipes; +import org.ultramine.mods.bukkit.util.CustomModRecipe; import java.util.Collections; import java.util.Iterator; @@ -33,7 +37,11 @@ if(recipes.hasNext()) { removeFrom = recipes; - return BukkitUtil.toBukkitRecipe(recipes.next()); + if (recipes.next() instanceof ShapelessRecipe) + return ((IMixinShapelessRecipes) recipes.next()).toBukkitRecipe(); + else if (recipes.next() instanceof ShapedRecipe) + return ((IMixinShapedRecipes) recipes.next()).toBukkitRecipe(); + return new CustomModRecipe(recipes.next()); } else { diff --git a/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java b/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java index 485c342..41467d8 100644 --- a/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java +++ b/src/main/java/org/ultramine/mods/bukkit/EventImplProgress.java @@ -126,15 +126,15 @@ reg(true, org.bukkit.event.inventory.FurnaceBurnEvent.class); reg(false, org.bukkit.event.inventory.FurnaceExtractEvent.class); reg(true, org.bukkit.event.inventory.FurnaceSmeltEvent.class); - reg(false, org.bukkit.event.inventory.InventoryClickEvent.class); - reg(false, org.bukkit.event.inventory.InventoryCloseEvent.class); - reg(false, org.bukkit.event.inventory.InventoryCreativeEvent.class); - reg(false, org.bukkit.event.inventory.InventoryDragEvent.class); - reg(false, org.bukkit.event.inventory.InventoryEvent.class); - reg(false, org.bukkit.event.inventory.InventoryInteractEvent.class); - reg(false, org.bukkit.event.inventory.InventoryMoveItemEvent.class); - reg(false, org.bukkit.event.inventory.InventoryOpenEvent.class); - reg(false, org.bukkit.event.inventory.InventoryPickupItemEvent.class); + reg(true, org.bukkit.event.inventory.InventoryClickEvent.class); + reg(true, org.bukkit.event.inventory.InventoryCloseEvent.class); + reg(true, org.bukkit.event.inventory.InventoryCreativeEvent.class); + reg(true, org.bukkit.event.inventory.InventoryDragEvent.class); + reg(true, org.bukkit.event.inventory.InventoryEvent.class); + reg(true, org.bukkit.event.inventory.InventoryInteractEvent.class); + reg(true, org.bukkit.event.inventory.InventoryMoveItemEvent.class); + reg(true, org.bukkit.event.inventory.InventoryOpenEvent.class); + reg(true, org.bukkit.event.inventory.InventoryPickupItemEvent.class); reg(false, org.bukkit.event.inventory.PrepareItemCraftEvent.class); reg(false, org.bukkit.event.painting.PaintingBreakByEntityEvent.class); reg(false, org.bukkit.event.painting.PaintingBreakEvent.class); diff --git a/src/main/java/org/ultramine/mods/bukkit/interfaces/entity/player/IMixinPlayerMP.java b/src/main/java/org/ultramine/mods/bukkit/interfaces/entity/player/IMixinPlayerMP.java index 8b51e05..6f655d4 100644 --- a/src/main/java/org/ultramine/mods/bukkit/interfaces/entity/player/IMixinPlayerMP.java +++ b/src/main/java/org/ultramine/mods/bukkit/interfaces/entity/player/IMixinPlayerMP.java @@ -50,4 +50,6 @@ boolean isCollidesWithEntities(); void setCollidesWithEntities(boolean collidesWithEntities); + + int nextContainerCounter(); } diff --git a/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinContainer.java b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinContainer.java new file mode 100644 index 0000000..e6504d0 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinContainer.java @@ -0,0 +1,13 @@ +package org.ultramine.mods.bukkit.interfaces.inventory; + +import net.minecraft.inventory.Container; +import org.bukkit.inventory.InventoryView; + +import javax.annotation.Nullable; + +public interface IMixinContainer +{ + @Nullable InventoryView getBukkitView(); + + void transferTo(Container other, org.bukkit.craftbukkit.entity.CraftHumanEntity player); +} diff --git a/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryCrafting.java b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryCrafting.java new file mode 100644 index 0000000..707de0d --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryCrafting.java @@ -0,0 +1,15 @@ +package org.ultramine.mods.bukkit.interfaces.inventory; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.crafting.IRecipe; + +public interface IMixinInventoryCrafting +{ + void setOwner(EntityPlayer inventoryOwner); + + void setCurrentRecipe(IRecipe recipe); + + IRecipe getCurrentRecipe(); + + EntityPlayer getOwner(); +} diff --git a/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryEnderChest.java b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryEnderChest.java new file mode 100644 index 0000000..eb613d2 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryEnderChest.java @@ -0,0 +1,10 @@ +package org.ultramine.mods.bukkit.interfaces.inventory; + +import jline.internal.Nullable; +import org.bukkit.inventory.InventoryHolder; + +public interface IMixinInventoryEnderChest +{ + @Nullable + InventoryHolder getOwner(); +} diff --git a/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryMerchant.java b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryMerchant.java new file mode 100644 index 0000000..1862aa5 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinInventoryMerchant.java @@ -0,0 +1,8 @@ +package org.ultramine.mods.bukkit.interfaces.inventory; + +import net.minecraft.entity.player.EntityPlayer; + +public interface IMixinInventoryMerchant +{ + EntityPlayer getPlayer(); +} diff --git a/src/main/java/org/ultramine/mods/bukkit/interfaces/item/crafting/IMixinShapedRecipes.java b/src/main/java/org/ultramine/mods/bukkit/interfaces/item/crafting/IMixinShapedRecipes.java new file mode 100644 index 0000000..38ad918 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/interfaces/item/crafting/IMixinShapedRecipes.java @@ -0,0 +1,8 @@ +package org.ultramine.mods.bukkit.interfaces.item.crafting; + +import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; + +public interface IMixinShapedRecipes +{ + CraftShapedRecipe toBukkitRecipe(); +} diff --git a/src/main/java/org/ultramine/mods/bukkit/interfaces/item/crafting/IMixinShapelessRecipes.java b/src/main/java/org/ultramine/mods/bukkit/interfaces/item/crafting/IMixinShapelessRecipes.java new file mode 100644 index 0000000..d5c3fce --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/interfaces/item/crafting/IMixinShapelessRecipes.java @@ -0,0 +1,8 @@ +package org.ultramine.mods.bukkit.interfaces.item.crafting; + +import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; + +public interface IMixinShapelessRecipes +{ + CraftShapelessRecipe toBukkitRecipe(); +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockDropper.java b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockDropper.java new file mode 100644 index 0000000..b42d675 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/block/MixinBlockDropper.java @@ -0,0 +1,78 @@ +package org.ultramine.mods.bukkit.mixin.block; + +import net.minecraft.block.BlockDropper; +import net.minecraft.block.BlockSourceImpl; +import net.minecraft.dispenser.BehaviorDefaultDispenseItem; +import net.minecraft.dispenser.IBehaviorDispenseItem; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryLargeChest; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntityDispenser; +import net.minecraft.tileentity.TileEntityHopper; +import net.minecraft.util.Facing; +import net.minecraft.world.World; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; +import org.ultramine.mods.bukkit.util.BukkitUtil; + +@Mixin(BlockDropper.class) +public class MixinBlockDropper +{ + private final IBehaviorDispenseItem behaviorDispenseItem = new BehaviorDefaultDispenseItem(); + + @Overwrite + protected void func_149941_e(World world, int x, int y, int z) + { + BlockSourceImpl blocksourceimpl = new BlockSourceImpl(world, x, y, z); + TileEntityDispenser tileentitydispenser = (TileEntityDispenser) blocksourceimpl.getBlockTileEntity(); + if (tileentitydispenser != null) + { + int l = tileentitydispenser.func_146017_i(); + if (l < 0) + { + world.playAuxSFX(1001, x, y, z, 0); + } + else + { + ItemStack itemstack = tileentitydispenser.getStackInSlot(l); + int i1 = world.getBlockMetadata(x, y, z) & 7; + IInventory iinventory = TileEntityHopper.func_145893_b(world, x + Facing.offsetsXForSide[i1], y + Facing.offsetsYForSide[i1], z + Facing.offsetsZForSide[i1]); + ItemStack itemstack1; + if (iinventory != null) + { + CraftItemStack oitemstack = CraftItemStack.asCraftMirror(itemstack.copy().splitStack(1)); + org.bukkit.inventory.Inventory destinationInventory; + if (iinventory instanceof InventoryLargeChest) + destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); + else + destinationInventory = BukkitUtil.getInventoryOwner(iinventory).getInventory(); + InventoryMoveItemEvent event = new InventoryMoveItemEvent(BukkitUtil.getInventoryOwner(tileentitydispenser).getInventory(), oitemstack.clone(), destinationInventory, true); + ((IMixinWorld) world).getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) + return; + itemstack1 = TileEntityHopper.func_145889_a(iinventory, CraftItemStack.asNMSCopy(event.getItem()), Facing.oppositeSide[i1]); + if (event.getItem().equals(oitemstack) && itemstack1 == null) + { + itemstack1 = itemstack.copy(); + if (--itemstack1.stackSize == 0) + itemstack1 = null; + } + else + { + itemstack1 = itemstack.copy(); + } + } + else + { + itemstack1 = this.behaviorDispenseItem.dispense(blocksourceimpl, itemstack); + if (itemstack1 != null && itemstack1.stackSize == 0) + itemstack1 = null; + } + tileentitydispenser.setInventorySlotContents(l, itemstack1); + } + } + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/entity/player/MixinPlayer.java b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/player/MixinPlayer.java index f88eee5..b986597 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/entity/player/MixinPlayer.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/player/MixinPlayer.java @@ -11,6 +11,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.entity.CraftItem; import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.player.PlayerBedEnterEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.spongepowered.asm.mixin.Mixin; @@ -20,12 +21,14 @@ import org.spongepowered.asm.mixin.injection.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntity; import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntityLivingBase; import org.ultramine.mods.bukkit.interfaces.entity.player.IMixinPlayer; import org.ultramine.mods.bukkit.interfaces.entity.player.IMixinPlayerMP; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinContainer; import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; import org.ultramine.mods.bukkit.mixin.entity.MixinEntityLivingBase; @@ -165,4 +168,10 @@ } } } + + @Inject(method = "setDead", at = @At(value = "INVOKE", target = "Lnet/minecraft/inventory/Container;onContainerClosed(Lnet/minecraft/entity/player/EntityPlayer;)V", ordinal = 1, shift = Shift.BEFORE)) + public void setDeadInject(CallbackInfo ci) { + InventoryCloseEvent event = new InventoryCloseEvent(((IMixinContainer)((EntityPlayer)(Object)this).openContainer).getBukkitView()); + if (((IMixinContainer)((EntityPlayer)(Object)this).openContainer).getBukkitView() != null) Bukkit.getServer().getPluginManager().callEvent(event); // Cauldron - allow vanilla mods to bypass + } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/entity/player/MixinPlayerMP.java b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/player/MixinPlayerMP.java index a5e4529..601a7fe 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/entity/player/MixinPlayerMP.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/entity/player/MixinPlayerMP.java @@ -1,8 +1,32 @@ package org.ultramine.mods.bukkit.mixin.entity.player; +import com.mojang.authlib.GameProfile; +import io.netty.buffer.Unpooled; +import net.minecraft.entity.IMerchant; +import net.minecraft.entity.item.EntityMinecartHopper; +import net.minecraft.entity.passive.EntityHorse; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.inventory.*; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.S2DPacketOpenWindow; +import net.minecraft.network.play.server.S3FPacketCustomPayload; +import net.minecraft.tileentity.TileEntityBeacon; +import net.minecraft.tileentity.TileEntityBrewingStand; +import net.minecraft.tileentity.TileEntityDispenser; +import net.minecraft.tileentity.TileEntityDropper; +import net.minecraft.tileentity.TileEntityFurnace; +import net.minecraft.tileentity.TileEntityHopper; +import net.minecraft.village.MerchantRecipeList; +import net.minecraft.world.World; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -10,7 +34,7 @@ import org.ultramine.mods.bukkit.interfaces.entity.player.IMixinPlayerMP; @Mixin(net.minecraft.entity.player.EntityPlayerMP.class) -public abstract class MixinPlayerMP implements IMixinPlayerMP +public abstract class MixinPlayerMP extends EntityPlayer implements IMixinPlayerMP { @Shadow private String translator; @@ -18,6 +42,10 @@ private int lastExperience; @Shadow private int field_147101_bU; + @Shadow public int currentWindowId; + + @Shadow public NetHandlerPlayServer playerNetServerHandler; + private static final Logger logger = LogManager.getLogger(); // CraftBukkit start public String displayName; @@ -32,6 +60,11 @@ // Spigot start public boolean collidesWithEntities = true; + public MixinPlayerMP(World p_i45324_1_, GameProfile p_i45324_2_) + { + super(p_i45324_1_, p_i45324_2_); + } + @Override public String getTranslator() { @@ -170,6 +203,12 @@ this.collidesWithEntities = collidesWithEntities; } + public int nextContainerCounter() + { + this.currentWindowId = this.currentWindowId % 100 + 1; + return this.currentWindowId; + } + @Inject(method = "readEntityFromNBT", at = @At("RETURN")) public void onReadEntityFromNBT(NBTTagCompound nbt, CallbackInfo ci) { @@ -181,4 +220,212 @@ { ((CraftPlayer) getBukkitEntity()).setExtraData(nbt); } + + @Overwrite + public void displayGUIEnchantment(int p_71002_1_, int p_71002_2_, int p_71002_3_, String p_71002_4_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerEnchantment(this.inventory, this.worldObj, p_71002_1_, p_71002_2_, p_71002_3_)); + if (container == null) + return; + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 4, p_71002_4_ == null ? "" : p_71002_4_, 9, p_71002_4_ != null)); + this.openContainer = container; + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void displayGUIWorkbench(int p_71058_1_, int p_71058_2_, int p_71058_3_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerWorkbench(this.inventory, this.worldObj, p_71058_1_, p_71058_2_, p_71058_3_)); + if (container == null) + return; + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 1, "Crafting", 9, true)); + this.openContainer = container; + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void displayGUIAnvil(int p_82244_1_, int p_82244_2_, int p_82244_3_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerRepair(this.inventory, this.worldObj, p_82244_1_, p_82244_2_, p_82244_3_, this)); + if (container == null) + return; + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 8, "Repairing", 9, true)); + this.openContainer = container; + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void displayGUIChest(IInventory p_71007_1_) + { + if (this.openContainer != this.inventoryContainer) + this.closeScreen(); + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerChest(this.inventory, p_71007_1_)); + if (container == null) + { + p_71007_1_.closeInventory(); // Cauldron - prevent chest from being stuck in open state on clients + return; + } + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 0, p_71007_1_.getInventoryName(), p_71007_1_.getSizeInventory(), p_71007_1_.hasCustomInventoryName())); + this.openContainer = container; + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void func_146093_a(TileEntityHopper p_146093_1_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerHopper(this.inventory, p_146093_1_)); + if (container == null) + { + p_146093_1_.closeInventory(); // Cauldron - prevent chest from being stuck in open state on clients + return; + } + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 9, p_146093_1_.getInventoryName(), p_146093_1_.getSizeInventory(), p_146093_1_.hasCustomInventoryName())); + this.openContainer = container; + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void displayGUIHopperMinecart(EntityMinecartHopper p_96125_1_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerHopper(this.inventory, p_96125_1_)); + if (container == null) + { + p_96125_1_.closeInventory(); // Cauldron - prevent chest from being stuck in open state on clients + return; + } + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 9, p_96125_1_.getInventoryName(), p_96125_1_.getSizeInventory(), p_96125_1_.hasCustomInventoryName())); + this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void func_146101_a(TileEntityFurnace p_146101_1_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerFurnace(this.inventory, p_146101_1_)); + if (container == null) + { + p_146101_1_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients + return; + } + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 2, p_146101_1_.getInventoryName(), p_146101_1_.getSizeInventory(), p_146101_1_.hasCustomInventoryName())); + this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void func_146102_a(TileEntityDispenser p_146102_1_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerDispenser(this.inventory, p_146102_1_)); + if (container == null) + { + p_146102_1_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients + return; + } + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, p_146102_1_ instanceof TileEntityDropper ? 10 : 3, p_146102_1_.getInventoryName(), p_146102_1_.getSizeInventory(), p_146102_1_.hasCustomInventoryName())); + this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void func_146098_a(TileEntityBrewingStand p_146098_1_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerBrewingStand(this.inventory, p_146098_1_)); + if (container == null) + { + p_146098_1_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients + return; + } + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 5, p_146098_1_.getInventoryName(), p_146098_1_.getSizeInventory(), p_146098_1_.hasCustomInventoryName())); + this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void func_146104_a(TileEntityBeacon p_146104_1_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerBeacon(this.inventory, p_146104_1_)); + if (container == null) + { + p_146104_1_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients + return; + } + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 7, p_146104_1_.getInventoryName(), p_146104_1_.getSizeInventory(), p_146104_1_.hasCustomInventoryName())); + this.openContainer = container; + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Overwrite + public void displayGUIMerchant(IMerchant p_71030_1_, String p_71030_2_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerMerchant(this.inventory, p_71030_1_, this.worldObj)); + if (container == null) + return; + this.nextContainerCounter(); + this.openContainer = container; + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + InventoryMerchant inventorymerchant = ((ContainerMerchant) this.openContainer).getMerchantInventory(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 6, p_71030_2_ == null ? "" : p_71030_2_, inventorymerchant.getSizeInventory(), p_71030_2_ != null)); + MerchantRecipeList merchantrecipelist = p_71030_1_.getRecipes(this); + if (merchantrecipelist != null) + { + PacketBuffer packetbuffer = new PacketBuffer(Unpooled.buffer()); + try + { + packetbuffer.writeInt(this.currentWindowId); + merchantrecipelist.func_151391_a(packetbuffer); + this.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload("MC|TrList", packetbuffer)); + } catch (Exception var10) + { + logger.error("Couldn't send trade list", var10); + } finally + { + packetbuffer.release(); + } + } + } + + @Overwrite + public void displayGUIHorse(EntityHorse p_110298_1_, IInventory p_110298_2_) + { + Container container = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP) (Object) this, new ContainerHorseInventory(this.inventory, p_110298_2_, p_110298_1_)); + if (container == null) + { + p_110298_2_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients + return; + } + if (this.openContainer != this.inventoryContainer) + this.closeScreen(); + this.nextContainerCounter(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 11, p_110298_2_.getInventoryName(), p_110298_2_.getSizeInventory(), p_110298_2_.hasCustomInventoryName(), p_110298_1_.getEntityId())); + this.openContainer = container; + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters((EntityPlayerMP) (Object) this); + } + + @Inject(method = "closeScreen", at = @At(value = "HEAD")) + public void closeScreenInject(CallbackInfo ci) + { + CraftEventFactory.handleInventoryCloseEvent(this); + } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainer.java b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainer.java new file mode 100644 index 0000000..042ce80 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainer.java @@ -0,0 +1,538 @@ +package org.ultramine.mods.bukkit.mixin.inventory; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.ContainerEnchantment; +import net.minecraft.inventory.ICrafting; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryBasic; +import net.minecraft.inventory.InventoryCraftResult; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.inventory.InventoryLargeChest; +import net.minecraft.inventory.Slot; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntityBeacon; +import net.minecraft.tileentity.TileEntityBrewingStand; +import net.minecraft.tileentity.TileEntityFurnace; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +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.Inventory; +import org.bukkit.inventory.InventoryView; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.ultramine.mods.bukkit.interfaces.entity.player.IMixinPlayer; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinContainer; +import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static net.minecraft.inventory.Container.func_94525_a; +import static net.minecraft.inventory.Container.func_94527_a; +import static net.minecraft.inventory.Container.func_94528_d; +import static net.minecraft.inventory.Container.func_94529_b; +import static net.minecraft.inventory.Container.func_94532_c; + +@Mixin(Container.class) +public abstract class MixinContainer implements IMixinContainer +{ + @Shadow public List inventorySlots; + @Shadow protected List crafters; + + private InventoryView bukkitView; + private boolean isBukkitViewCreated; + + @Override + @Nullable + public InventoryView getBukkitView() + { + if(!isBukkitViewCreated) + { + isBukkitViewCreated = true; + bukkitView = computeBukkitView(); + return bukkitView; + } + + return bukkitView; // nullable here + } + + private InventoryView computeBukkitView() + { + Container container = (Container) (Object) this; + + Set uniqueInventorySet = new HashSet(); + for(Object o : inventorySlots) + uniqueInventorySet.add(((Slot) o).inventory); + List invs = new ArrayList(uniqueInventorySet); + + InventoryPlayer playerInv = null; + + for(Iterator it = invs.iterator(); it.hasNext();) + { + IInventory inv = it.next(); + if(inv instanceof InventoryPlayer) + { + InventoryPlayer foundPlayerInv = (InventoryPlayer) inv; + //noinspection SuspiciousMethodCalls +// if(crafters.contains(foundPlayerInv.player)) + { + playerInv = foundPlayerInv; + it.remove(); + break; + } + } + } + + if(playerInv == null) + return null; + + Inventory craftInv = null; + if(invs.size() == 1) + { + IInventory firstInv = invs.get(0); + if(container instanceof ContainerEnchantment) + craftInv = new org.bukkit.craftbukkit.inventory.CraftInventoryEnchanting(firstInv); + else if (firstInv instanceof InventoryPlayer) + craftInv = new org.bukkit.craftbukkit.inventory.CraftInventoryPlayer((CraftHumanEntity) ((IMixinPlayer) ((InventoryPlayer) firstInv).player).getBukkitEntity()); + else if (firstInv instanceof InventoryLargeChest) + craftInv = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) firstInv); + else if(firstInv instanceof TileEntityBeacon) + craftInv = new org.bukkit.craftbukkit.inventory.CraftInventoryBeacon((TileEntityBeacon) firstInv); + else if(firstInv instanceof TileEntityBrewingStand) + craftInv = new org.bukkit.craftbukkit.inventory.CraftInventoryBrewer((TileEntityBrewingStand) firstInv); + else if(firstInv instanceof TileEntityFurnace) + craftInv = new org.bukkit.craftbukkit.inventory.CraftInventoryFurnace((TileEntityFurnace) firstInv); + } + else if(invs.size() == 2) + { + InventoryCraftResult result = findInstance(invs, InventoryCraftResult.class); + if(result != null) + { + InventoryCrafting crafting = findInstance(invs, InventoryCrafting.class); + if(crafting != null) + { + craftInv = new org.bukkit.craftbukkit.inventory.CraftInventoryCrafting(crafting, result); + } + else + { + InventoryBasic basic = findInstance(invs, InventoryBasic.class); + if(basic != null && "Repair".equals(basic.getInventoryName())) + craftInv = new org.bukkit.craftbukkit.inventory.CraftInventoryAnvil(basic, result); + } + } + } + + CraftPlayer bukkitPlayer = (CraftPlayer) ((IMixinPlayer) playerInv.player).getBukkitEntity(); + + if(craftInv == null) + { + if(invs.size() != 1) + craftInv = Bukkit.getServer().createInventory(bukkitPlayer, InventoryType.CHEST); + else + craftInv = new CraftInventory(invs.get(0)); + } + + return new CraftInventoryView(bukkitPlayer, craftInv, container); + } + + @Nullable + private static T findInstance(List list, Class type) + { + for(Object o : list) + if(type.isInstance(o)) + return type.cast(o); + return null; + } + + @Override + public void transferTo(Container other, CraftHumanEntity player) + { + + } + + @Final + @Shadow private Set field_94537_h; + @Shadow private int field_94535_f = -1; + @Shadow private int field_94536_g; + @Shadow protected abstract void func_94533_d(); + @Shadow public abstract ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int p_82846_2_); + @Shadow protected abstract void retrySlotClick(int p_75133_1_, int p_75133_2_, boolean p_75133_3_, EntityPlayer p_75133_4_); + @Shadow public abstract boolean canDragIntoSlot(Slot p_94531_1_); + @Shadow public abstract boolean func_94530_a(ItemStack p_94530_1_, Slot p_94530_2_); + @Shadow public abstract void detectAndSendChanges(); + + @Overwrite + public ItemStack slotClick(int index, int p_75144_2_, int p_75144_3_, EntityPlayer player) + { + ItemStack itemstack = null; + InventoryPlayer inventoryplayer = player.inventory; + int i1; + ItemStack itemstack3; + ItemStack itemstack4; + int j1; + if (p_75144_3_ == 5) + { + int l = this.field_94536_g; + this.field_94536_g = func_94532_c(p_75144_2_); + if ((l != 1 || this.field_94536_g != 2) && l != this.field_94536_g) + { + this.func_94533_d(); + } + else if (inventoryplayer.getItemStack() == null) + { + this.func_94533_d(); + } + else if (this.field_94536_g == 0) + { + this.field_94535_f = func_94529_b(p_75144_2_); + if (func_94528_d(this.field_94535_f)) + { + this.field_94536_g = 1; + this.field_94537_h.clear(); + } else + { + this.func_94533_d(); + } + } + else if (this.field_94536_g == 1) + { + Slot slot = this.inventorySlots.get(index); + if (slot != null && func_94527_a(slot, inventoryplayer.getItemStack(), true) && slot.isItemValid(inventoryplayer.getItemStack()) && inventoryplayer.getItemStack().stackSize > this.field_94537_h.size() && this.canDragIntoSlot(slot)) + this.field_94537_h.add(slot); + } + else if (this.field_94536_g == 2) + { + if (!this.field_94537_h.isEmpty()) + { + itemstack3 = inventoryplayer.getItemStack().copy(); + i1 = inventoryplayer.getItemStack().stackSize; + Map draggedSlots = new HashMap(); // CraftBukkit - Store slots from drag in map (raw slot id -> new stack) + for (Object aField_94537_h : this.field_94537_h) + { + Slot slot1 = (Slot) aField_94537_h; + if (slot1 != null && func_94527_a(slot1, inventoryplayer.getItemStack(), true) && slot1.isItemValid(inventoryplayer.getItemStack()) && inventoryplayer.getItemStack().stackSize >= this.field_94537_h.size() && this.canDragIntoSlot(slot1)) + { + itemstack4 = itemstack3.copy(); + j1 = slot1.getHasStack() ? slot1.getStack().stackSize : 0; + func_94525_a(this.field_94537_h, this.field_94535_f, itemstack4, j1); + if (itemstack4.stackSize > itemstack4.getMaxStackSize()) + { + itemstack4.stackSize = itemstack4.getMaxStackSize(); + } + + if (itemstack4.stackSize > slot1.getSlotStackLimit()) + { + itemstack4.stackSize = slot1.getSlotStackLimit(); + } + + i1 -= itemstack4.stackSize - j1; + draggedSlots.put(slot1.slotNumber, itemstack4); // CraftBukkit - Put in map instead of setting + } + } + + // CraftBukkit start - InventoryDragEvent + InventoryView view = getBukkitView(); + org.bukkit.inventory.ItemStack newcursor = CraftItemStack.asCraftMirror(itemstack3); + newcursor.setAmount(i1); + Map eventmap = new HashMap(); + for (Map.Entry ditem : draggedSlots.entrySet()) + { + eventmap.put(ditem.getKey(), CraftItemStack.asBukkitCopy(ditem.getValue())); + } + + // 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 = inventoryplayer.getItemStack(); + inventoryplayer.setItemStack(CraftItemStack.asNMSCopy(newcursor)); + InventoryDragEvent event = new InventoryDragEvent(view, (newcursor.getType() != org.bukkit.Material.AIR ? newcursor : null), CraftItemStack.asBukkitCopy(oldCursor), this.field_94535_f == i1, eventmap); // Should be dragButton + Bukkit.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 dslot : draggedSlots.entrySet()) + if (view != null) + 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 (inventoryplayer.getItemStack() != null) + { + inventoryplayer.setItemStack(CraftItemStack.asNMSCopy(event.getCursor())); + needsUpdate = true; + } + } + else + { + inventoryplayer.setItemStack(oldCursor); + } + if (needsUpdate && player instanceof EntityPlayerMP) + ((EntityPlayerMP) player).sendContainerToPlayer((Container) (Object) this); + // CraftBukkit end + } + this.func_94533_d(); + } + else + { + this.func_94533_d(); + } + } + else if (this.field_94536_g != 0) + { + this.func_94533_d(); + } + else + { + Slot slot2; + int l1; + ItemStack itemstack5; + if ((p_75144_3_ == 0 || p_75144_3_ == 1) && (p_75144_2_ == 0 || p_75144_2_ == 1)) + { + if (index == -999) + { + if (inventoryplayer.getItemStack() != null) + { + if (p_75144_2_ == 0) + { + player.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack(), true); + inventoryplayer.setItemStack(null); + } + + if (p_75144_2_ == 1) + { + player.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack().splitStack(1), true); + if (inventoryplayer.getItemStack().stackSize == 0) + inventoryplayer.setItemStack(null); + } + } + } + else if (p_75144_3_ == 1) + { + if (index < 0) + return null; + slot2 = this.inventorySlots.get(index); + if (slot2 != null && slot2.canTakeStack(player)) + { + itemstack3 = this.transferStackInSlot(player, index); + if (itemstack3 != null) + { + Item item = itemstack3.getItem(); + itemstack = itemstack3.copy(); + if (slot2.getStack() != null && slot2.getStack().getItem() == item) + this.retrySlotClick(index, p_75144_2_, true, player); + } + } + } + else + { + if (index < 0) + { + return null; + } + + slot2 = this.inventorySlots.get(index); + if (slot2 != null) + { + itemstack3 = slot2.getStack(); + itemstack4 = inventoryplayer.getItemStack(); + if (itemstack3 != null) + { + itemstack = itemstack3.copy(); + } + + if (itemstack3 == null) + { + if (itemstack4 != null && slot2.isItemValid(itemstack4)) + { + l1 = p_75144_2_ == 0 ? itemstack4.stackSize : 1; + if (l1 > slot2.getSlotStackLimit()) + { + l1 = slot2.getSlotStackLimit(); + } + + if (itemstack4.stackSize >= l1) + { + slot2.putStack(itemstack4.splitStack(l1)); + } + + if (itemstack4.stackSize == 0) + { + inventoryplayer.setItemStack(null); + } + } + } + else if (slot2.canTakeStack(player)) + { + if (itemstack4 == null) + { + l1 = p_75144_2_ == 0 ? itemstack3.stackSize : (itemstack3.stackSize + 1) / 2; + itemstack5 = slot2.decrStackSize(l1); + inventoryplayer.setItemStack(itemstack5); + if (itemstack3.stackSize == 0) + { + slot2.putStack(null); + } + + slot2.onPickupFromSlot(player, inventoryplayer.getItemStack()); + } + else if (slot2.isItemValid(itemstack4)) + { + if (itemstack3.getItem() == itemstack4.getItem() && itemstack3.getItemDamage() == itemstack4.getItemDamage() && ItemStack.areItemStackTagsEqual(itemstack3, itemstack4)) + { + l1 = p_75144_2_ == 0 ? itemstack4.stackSize : 1; + if (l1 > slot2.getSlotStackLimit() - itemstack3.stackSize) + { + l1 = slot2.getSlotStackLimit() - itemstack3.stackSize; + } + + if (l1 > itemstack4.getMaxStackSize() - itemstack3.stackSize) + { + l1 = itemstack4.getMaxStackSize() - itemstack3.stackSize; + } + + itemstack4.splitStack(l1); + if (itemstack4.stackSize == 0) + { + inventoryplayer.setItemStack(null); + } + + itemstack3.stackSize += l1; + } + else if (itemstack4.stackSize <= slot2.getSlotStackLimit()) + { + slot2.putStack(itemstack4); + inventoryplayer.setItemStack(itemstack3); + } + } + else if (itemstack3.getItem() == itemstack4.getItem() && itemstack4.getMaxStackSize() > 1 && (!itemstack3.getHasSubtypes() || itemstack3.getItemDamage() == itemstack4.getItemDamage()) && ItemStack.areItemStackTagsEqual(itemstack3, itemstack4)) + { + l1 = itemstack3.stackSize; + if (l1 > 0 && l1 + itemstack4.stackSize <= itemstack4.getMaxStackSize()) + { + itemstack4.stackSize += l1; + itemstack3 = slot2.decrStackSize(l1); + if (itemstack3.stackSize == 0) + { + slot2.putStack(null); + } + + slot2.onPickupFromSlot(player, inventoryplayer.getItemStack()); + } + } + } + + slot2.onSlotChanged(); + } + } + } + else if (p_75144_3_ == 2 && p_75144_2_ >= 0 && p_75144_2_ < 9) + { + slot2 = this.inventorySlots.get(index); + if (slot2.canTakeStack(player)) + { + itemstack3 = inventoryplayer.getStackInSlot(p_75144_2_); + boolean flag = itemstack3 == null || slot2.inventory == inventoryplayer && slot2.isItemValid(itemstack3); + l1 = -1; + if (!flag) + { + l1 = inventoryplayer.getFirstEmptyStack(); + flag |= l1 > -1; + } + + if (slot2.getHasStack() && flag) + { + itemstack5 = slot2.getStack(); + inventoryplayer.setInventorySlotContents(p_75144_2_, itemstack5.copy()); + if ((slot2.inventory != inventoryplayer || !slot2.isItemValid(itemstack3)) && itemstack3 != null) + { + if (l1 > -1) + { + inventoryplayer.addItemStackToInventory(itemstack3); + slot2.decrStackSize(itemstack5.stackSize); + slot2.putStack(null); + slot2.onPickupFromSlot(player, itemstack5); + } + } + else + { + slot2.decrStackSize(itemstack5.stackSize); + slot2.putStack(itemstack3); + slot2.onPickupFromSlot(player, itemstack5); + } + } + else if (!slot2.getHasStack() && itemstack3 != null && slot2.isItemValid(itemstack3)) + { + inventoryplayer.setInventorySlotContents(p_75144_2_, null); + slot2.putStack(itemstack3); + } + } + } + else if (p_75144_3_ == 3 && player.capabilities.isCreativeMode && inventoryplayer.getItemStack() == null && index >= 0) + { + slot2 = this.inventorySlots.get(index); + if (slot2 != null && slot2.getHasStack()) + { + itemstack3 = slot2.getStack().copy(); + itemstack3.stackSize = itemstack3.getMaxStackSize(); + inventoryplayer.setItemStack(itemstack3); + } + } + else if (p_75144_3_ == 4 && inventoryplayer.getItemStack() == null && index >= 0) + { + slot2 = this.inventorySlots.get(index); + if (slot2 != null && slot2.getHasStack() && slot2.canTakeStack(player)) + { + itemstack3 = slot2.decrStackSize(p_75144_2_ == 0 ? 1 : slot2.getStack().stackSize); + slot2.onPickupFromSlot(player, itemstack3); + player.dropPlayerItemWithRandomChoice(itemstack3, true); + } + } + else if (p_75144_3_ == 6 && index >= 0) + { + slot2 = this.inventorySlots.get(index); + itemstack3 = inventoryplayer.getItemStack(); + if (itemstack3 != null && (slot2 == null || !slot2.getHasStack() || !slot2.canTakeStack(player))) + { + i1 = p_75144_2_ == 0 ? 0 : this.inventorySlots.size() - 1; + l1 = p_75144_2_ == 0 ? 1 : -1; + + for (int i2 = 0; i2 < 2; ++i2) + { + for (j1 = i1; j1 >= 0 && j1 < this.inventorySlots.size() && itemstack3.stackSize < itemstack3.getMaxStackSize(); j1 += l1) + { + Slot slot3 = this.inventorySlots.get(j1); + if (slot3.getHasStack() && func_94527_a(slot3, itemstack3, true) && slot3.canTakeStack(player) && this.func_94530_a(itemstack3, slot3) && (i2 != 0 || slot3.getStack().stackSize != slot3.getStack().getMaxStackSize())) + { + int k1 = Math.min(itemstack3.getMaxStackSize() - itemstack3.stackSize, slot3.getStack().stackSize); + ItemStack itemstack2 = slot3.decrStackSize(k1); + itemstack3.stackSize += k1; + if (itemstack2.stackSize <= 0) + slot3.putStack(null); + slot3.onPickupFromSlot(player, itemstack2); + } + } + } + } + this.detectAndSendChanges(); + } + } + return itemstack; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainerPlayer.java b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainerPlayer.java new file mode 100644 index 0000000..873175f --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainerPlayer.java @@ -0,0 +1,30 @@ +package org.ultramine.mods.bukkit.mixin.inventory; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryCraftResult; +import net.minecraft.inventory.InventoryCrafting; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryCrafting; + +@Mixin(ContainerPlayer.class) +public class MixinContainerPlayer +{ + @Shadow public InventoryCrafting craftMatrix; + @Shadow public IInventory craftResult; + + @Inject(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/inventory/ContainerPlayer;addSlotToContainer(Lnet/minecraft/inventory/Slot;)Lnet/minecraft/inventory/Slot;", ordinal = 0, shift = Shift.BEFORE)) + public void ContainerPlayerInject(InventoryPlayer p_i1819_1_, boolean p_i1819_2_, EntityPlayer p_i1819_3_, CallbackInfo ci) + { + this.craftResult = new InventoryCraftResult(); // CraftBukkit - moved to before InventoryCrafting construction + this.craftMatrix = new InventoryCrafting((ContainerPlayer) (Object) this, 2, 2); + ((IMixinInventoryCrafting) this.craftMatrix).setOwner(p_i1819_1_.player); + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainerWorkbench.java b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainerWorkbench.java new file mode 100644 index 0000000..f47d9f3 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainerWorkbench.java @@ -0,0 +1,31 @@ +package org.ultramine.mods.bukkit.mixin.inventory; + +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.inventory.ContainerWorkbench; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryCraftResult; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryCrafting; + +@Mixin(ContainerWorkbench.class) +public class MixinContainerWorkbench +{ + @Shadow public InventoryCrafting craftMatrix; + @Shadow public IInventory craftResult; + + @Inject(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/inventory/ContainerPlayer;addSlotToContainer(Lnet/minecraft/inventory/Slot;)Lnet/minecraft/inventory/Slot;", ordinal = 0, shift = Shift.BEFORE)) + public void ContainerWorkbenchInject(InventoryPlayer p_i1808_1_, World p_i1808_2_, int p_i1808_3_, int p_i1808_4_, int p_i1808_5_, CallbackInfo ci) + { + this.craftResult = new InventoryCraftResult(); // CraftBukkit - moved to before InventoryCrafting construction + this.craftMatrix = new InventoryCrafting((ContainerPlayer) (Object) this, 3, 3); + ((IMixinInventoryCrafting) this.craftMatrix).setOwner(p_i1808_1_.player); + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryCrafting.java b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryCrafting.java new file mode 100644 index 0000000..282f25f --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryCrafting.java @@ -0,0 +1,38 @@ +package org.ultramine.mods.bukkit.mixin.inventory; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.crafting.IRecipe; +import org.spongepowered.asm.mixin.Mixin; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryCrafting; + +@Mixin(InventoryCrafting.class) +public class MixinInventoryCrafting implements IMixinInventoryCrafting +{ + private EntityPlayer inventoryOwner; + private IRecipe currentRecipe; + + @Override + public void setOwner(EntityPlayer inventoryOwner) + { + this.inventoryOwner = inventoryOwner; + } + + @Override + public void setCurrentRecipe(IRecipe recipe) + { + this.currentRecipe = recipe; + } + + @Override + public IRecipe getCurrentRecipe() + { + return currentRecipe; + } + + @Override + public EntityPlayer getOwner() + { + return inventoryOwner; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryEnderChest.java b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryEnderChest.java new file mode 100644 index 0000000..af555fb --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryEnderChest.java @@ -0,0 +1,27 @@ +package org.ultramine.mods.bukkit.mixin.inventory; + +import jline.internal.Nullable; +import net.minecraft.inventory.InventoryEnderChest; +import net.minecraft.tileentity.TileEntityEnderChest; +import org.bukkit.block.BlockState; +import org.bukkit.inventory.InventoryHolder; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryEnderChest; +import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; + +@Mixin(InventoryEnderChest.class) +public class MixinInventoryEnderChest implements IMixinInventoryEnderChest +{ + @Shadow private TileEntityEnderChest associatedChest; + + @Nullable + @Override + public InventoryHolder getOwner() + { + BlockState state = ((IMixinWorld) associatedChest.getWorldObj()).getWorld().getBlockAt(associatedChest.xCoord, associatedChest.yCoord, associatedChest.zCoord).getState(); + if (state instanceof InventoryHolder) + return (InventoryHolder) state; + return null; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryMerchant.java b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryMerchant.java new file mode 100644 index 0000000..519f206 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinInventoryMerchant.java @@ -0,0 +1,21 @@ +package org.ultramine.mods.bukkit.mixin.inventory; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.InventoryMerchant; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryMerchant; + +@Mixin(InventoryMerchant.class) +public class MixinInventoryMerchant implements IMixinInventoryMerchant +{ + @Final + @Shadow private EntityPlayer thePlayer; + + @Override + public EntityPlayer getPlayer() + { + return thePlayer; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/item/crafting/MixinShapedRecipes.java b/src/main/java/org/ultramine/mods/bukkit/mixin/item/crafting/MixinShapedRecipes.java new file mode 100644 index 0000000..944f0a3 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/item/crafting/MixinShapedRecipes.java @@ -0,0 +1,76 @@ +package org.ultramine.mods.bukkit.mixin.item.crafting; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.ShapedRecipes; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.ultramine.mods.bukkit.interfaces.item.crafting.IMixinShapedRecipes; + +@Mixin(ShapedRecipes.class) +public class MixinShapedRecipes implements IMixinShapedRecipes +{ + @Shadow private ItemStack recipeOutput; + + @Override + public CraftShapedRecipe toBukkitRecipe() + { + ShapedRecipes thisShapedRecipe = (ShapedRecipes)(Object) this; + CraftItemStack result = CraftItemStack.asCraftMirror(recipeOutput); + CraftShapedRecipe craftShapedRecipe = new CraftShapedRecipe(result, thisShapedRecipe); + switch (thisShapedRecipe.recipeHeight) + { + case 1: + switch (thisShapedRecipe.recipeWidth) + { + case 1: + craftShapedRecipe.shape("a"); + break; + case 2: + craftShapedRecipe.shape("ab"); + break; + case 3: + craftShapedRecipe.shape("abc"); + break; + } + break; + case 2: + switch (thisShapedRecipe.recipeWidth) + { + case 1: + craftShapedRecipe.shape("a", "b"); + break; + case 2: + craftShapedRecipe.shape("ab", "cd"); + break; + case 3: + craftShapedRecipe.shape("abc", "def"); + break; + } + break; + case 3: + switch (thisShapedRecipe.recipeWidth) + { + case 1: + craftShapedRecipe.shape("a", "b", "c"); + break; + case 2: + craftShapedRecipe.shape("ab", "cd", "ef"); + break; + case 3: + craftShapedRecipe.shape("abc", "def", "ghi"); + break; + } + break; + } + char c = 'a'; + for (ItemStack stack : thisShapedRecipe.recipeItems) + { + if (stack != null) + craftShapedRecipe.setIngredient(c, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), stack.getItemDamage()); + c++; + } + return craftShapedRecipe; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/item/crafting/MixinShapelessRecipes.java b/src/main/java/org/ultramine/mods/bukkit/mixin/item/crafting/MixinShapelessRecipes.java new file mode 100644 index 0000000..dabfe5d --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/item/crafting/MixinShapelessRecipes.java @@ -0,0 +1,32 @@ +package org.ultramine.mods.bukkit.mixin.item.crafting; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.ShapelessRecipes; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.ultramine.mods.bukkit.interfaces.item.crafting.IMixinShapelessRecipes; + +import java.util.List; + +@Mixin(ShapelessRecipes.class) +public class MixinShapelessRecipes implements IMixinShapelessRecipes +{ + @Final + @Shadow private ItemStack recipeOutput; + + @Override + @SuppressWarnings("unchecked") + public CraftShapelessRecipe toBukkitRecipe() + { + ShapelessRecipes thisShapelessRecipe = (ShapelessRecipes)(Object) this; + CraftItemStack result = CraftItemStack.asCraftMirror(recipeOutput); + CraftShapelessRecipe craftShapelessRecipe = new CraftShapelessRecipe(result, thisShapelessRecipe); + for (ItemStack stack : (List) thisShapelessRecipe.recipeItems) + if (stack != null) + craftShapelessRecipe.addIngredient(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), stack.getItemDamage()); + return craftShapelessRecipe; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/management/MixinCraftingManager.java b/src/main/java/org/ultramine/mods/bukkit/mixin/management/MixinCraftingManager.java new file mode 100644 index 0000000..f2d75b6 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/management/MixinCraftingManager.java @@ -0,0 +1,48 @@ +package org.ultramine.mods.bukkit.mixin.management; + +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.ShapelessRecipes; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryCrafting; + +import java.util.ArrayList; +import java.util.List; + +@Mixin(CraftingManager.class) +public class MixinCraftingManager +{ + @Inject(method = "findMatchingRecipe", at = @At(value = "RETURN", ordinal = 0), locals = LocalCapture.CAPTURE_FAILEXCEPTION) + public void findMatchingRecipeInject(InventoryCrafting inventoryCrafting, World world, CallbackInfoReturnable cir, int i, ItemStack itemstack, ItemStack itemstack1, int p, Item item, int j1, int k, int l, int i1) + { + ItemStack result = new ItemStack(itemstack.getItem(), 1, i1); + List ingredients = new ArrayList(); + ingredients.add(itemstack.copy()); + ingredients.add(itemstack1.copy()); + ShapelessRecipes currentRecipe = new ShapelessRecipes(result.copy(), ingredients); + ((IMixinInventoryCrafting) inventoryCrafting).setCurrentRecipe(currentRecipe); + // TODO: callPreCraftEvent + cir.setReturnValue(result); + cir.cancel(); + } + + @Inject(method = "findMatchingRecipe", at = @At(value = "INVOKE", target = "Lorg/ultramine/server/RecipeCache;findRecipe(Lnet/minecraft/inventory/InventoryCrafting;Lnet/minecraft/world/World;)Lnet/minecraft/item/crafting/IRecipe;", shift = Shift.BY, by = 3), locals = LocalCapture.CAPTURE_FAILEXCEPTION) + public void findMatchingRecipeInject(InventoryCrafting inventoryCrafting, World world, CallbackInfoReturnable cir, int i, ItemStack itemstack, ItemStack itemstack1, int p, IRecipe recipe) + { + if (recipe != null) + { + if (recipe.matches(inventoryCrafting, world)) + ((IMixinInventoryCrafting) inventoryCrafting).setCurrentRecipe(recipe); + // TODO: callPreCraftEvent + } + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/management/MixinItemInWorldManager.java b/src/main/java/org/ultramine/mods/bukkit/mixin/management/MixinItemInWorldManager.java index 162ceba..ebd4f2f 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/management/MixinItemInWorldManager.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/management/MixinItemInWorldManager.java @@ -21,6 +21,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinContainer; @Mixin(net.minecraft.server.management.ItemInWorldManager.class) public abstract class MixinItemInWorldManager @@ -233,32 +234,6 @@ else if(!p_73078_1_.isSneaking() || p_73078_3_ == null || p_73078_1_.getHeldItem().getItem().doesSneakBypassUse(p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_1_)) { denyResult |= block.onBlockActivated(p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_1_, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_); - // Cauldron start - if bukkitView is null, create one. Required for Ender Chests since they do not use NetworkRegistry.openRemoteGUI - if(thisPlayerMP != null && !(thisPlayerMP.openContainer instanceof ContainerPlayer)) - { -// if (thisPlayerMP.openContainer.getBukkitView() == null) -// { -// TileEntity te = thisPlayerMP.worldObj.getTileEntity(p_73078_4_, p_73078_5_, p_73078_6_); -// if (te != null && te instanceof IInventory) -// { -// IInventory teInv = (IInventory)te; -// CraftInventory inventory = new CraftInventory(teInv); -// thisPlayerMP.openContainer.bukkitView = new CraftInventoryView(thisPlayerMP.getBukkitEntity(), inventory, thisPlayerMP.openContainer); -// } -// else -// { -// thisPlayerMP.openContainer.bukkitView = new CraftInventoryView(thisPlayerMP.getBukkitEntity(), MinecraftServer.getServer().server.createInventory(thisPlayerMP.getBukkitEntity(), InventoryType.CHEST), thisPlayerMP.openContainer); -// } -// -// thisPlayerMP.openContainer = CraftEventFactory.callInventoryOpenEvent(thisPlayerMP, thisPlayerMP.openContainer, false); -// if (thisPlayerMP.openContainer == null) -// { -// thisPlayerMP.openContainer = thisPlayerMP.inventoryContainer; -// return false; -// } -// } - } - // Cauldron end } if(p_73078_3_ != null && !denyResult && p_73078_3_.stackSize > 0) diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/network/MixinNetHPlayS.java b/src/main/java/org/ultramine/mods/bukkit/mixin/network/MixinNetHPlayS.java index e238d0b..297ff4d 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/network/MixinNetHPlayS.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/network/MixinNetHPlayS.java @@ -1,33 +1,63 @@ package org.ultramine.mods.bukkit.mixin.network; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.Slot; import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement; import net.minecraft.network.play.client.C09PacketHeldItemChange; +import net.minecraft.network.play.client.C0DPacketCloseWindow; +import net.minecraft.network.play.client.C0EPacketClickWindow; +import net.minecraft.network.play.client.C10PacketCreativeInventoryAction; import net.minecraft.network.play.client.C12PacketUpdateSign; import net.minecraft.network.play.client.C17PacketCustomPayload; import net.minecraft.network.play.server.S09PacketHeldItemChange; +import net.minecraft.network.play.server.S2FPacketSetSlot; +import net.minecraft.network.play.server.S32PacketConfirmTransaction; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntitySign; +import net.minecraft.util.IntHashMap; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.CraftItemEvent; +import org.bukkit.event.inventory.InventoryAction; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCreativeEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.InventoryView; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntity; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinContainer; import org.ultramine.mods.bukkit.interfaces.network.IMixinNetHPS; import org.ultramine.mods.bukkit.interfaces.network.ITimestampedPacket; +import java.util.ArrayList; +import java.util.HashSet; + @Mixin(net.minecraft.network.NetHandlerPlayServer.class) public abstract class MixinNetHPlayS implements IMixinNetHPS { @@ -173,4 +203,412 @@ Bukkit.getServer().getMessenger().dispatchIncomingMessage(getPlayerB(), p_147349_1_.func_149559_c(), p_147349_1_.func_149558_e()); // CraftBukkit end } + + private final static HashSet invalidItems = new HashSet(java.util.Arrays.asList(8, 9, 10, 11, 26, 34, + 36, 43, 51, 52, 55, 59, 60, 62, 63, 64, 68, 71, 74, 75, 83, 90, 92, 93, 94, 104, 105, 115, 117, 118, 119, + 125, 127, 132, 140, 141, 142, 144)); + + @Shadow private int field_147375_m; + + @Overwrite + public void processCreativeInventoryAction(C10PacketCreativeInventoryAction creativeActionPacket) + { + if (this.playerEntity.theItemInWorldManager.isCreative()) + { + boolean flag = creativeActionPacket.func_149627_c() < 0; + ItemStack itemstack = creativeActionPacket.func_149625_d(); + boolean flag1 = creativeActionPacket.func_149627_c() >= 1 && creativeActionPacket.func_149627_c() < 36 + InventoryPlayer.getHotbarSize(); + boolean flag2 = itemstack == null || itemstack.getItem() != null && !invalidItems.contains(Item.getIdFromItem(itemstack.getItem())); + boolean flag3 = itemstack == null || itemstack.getItemDamage() >= 0 && itemstack.stackSize <= 64 && itemstack.stackSize > 0; + if (flag || (flag1 && !ItemStack.areItemStacksEqual(this.playerEntity.inventoryContainer.getSlot(creativeActionPacket.func_149627_c()).getStack(), + creativeActionPacket.func_149625_d()))) // Insist on valid slot + { + org.bukkit.entity.HumanEntity player = (HumanEntity) ((IMixinEntity) this.playerEntity).getBukkitEntity(); + InventoryView inventory = new CraftInventoryView(player, player.getInventory(), this.playerEntity.inventoryContainer); + org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(creativeActionPacket.func_149625_d()); // Should be packet107setcreativeslot.newitem + SlotType type = SlotType.QUICKBAR; + if (flag) + type = SlotType.OUTSIDE; + else if (creativeActionPacket.func_149627_c() < 36) + if (creativeActionPacket.func_149627_c() >= 5 && creativeActionPacket.func_149627_c() < 9) + type = SlotType.ARMOR; + else + type = SlotType.CONTAINER; + InventoryCreativeEvent event = new InventoryCreativeEvent(inventory, type, flag ? -999 : creativeActionPacket.func_149627_c(), item); + Bukkit.getServer().getPluginManager().callEvent(event); + itemstack = CraftItemStack.asNMSCopy(event.getCursor()); + switch (event.getResult()) + { + case ALLOW: + // Plugin cleared the id / stacksize checks + flag2 = flag3 = true; + break; + case DEFAULT: + break; + case DENY: + // Reset the slot + if (creativeActionPacket.func_149627_c() >= 0) + { + this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(this.playerEntity.inventoryContainer.windowId, creativeActionPacket + .func_149627_c(), this.playerEntity.inventoryContainer.getSlot(creativeActionPacket.func_149627_c()).getStack())); + this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(-1, -1, null)); + } + return; + } + } + if (flag1 && flag2 && flag3) + { + if (itemstack == null) + this.playerEntity.inventoryContainer.putStackInSlot(creativeActionPacket.func_149627_c(), null); + else + this.playerEntity.inventoryContainer.putStackInSlot(creativeActionPacket.func_149627_c(), itemstack); + this.playerEntity.inventoryContainer.setPlayerIsPresent(this.playerEntity, true); + } + else if (flag && flag2 && flag3 && this.field_147375_m < 200) + { + this.field_147375_m += 20; + EntityItem entityitem = this.playerEntity.dropPlayerItemWithRandomChoice(itemstack, true); + if (entityitem != null) + entityitem.setAgeToCreativeDespawnTime(); + } + } + + } + + @Inject(method = "processCloseWindow", at = @At(value = "INVOKE")) + public void processCloseWindowInject(C0DPacketCloseWindow p_147356_1_, CallbackInfo ci) + { + if (this.playerEntity.isDead) + return; + if (((IMixinContainer) this.playerEntity.openContainer).getBukkitView() != null) + CraftEventFactory.handleInventoryCloseEvent(this.playerEntity); // CraftBukkit + } + + @Shadow private IntHashMap field_147372_n; + + @Overwrite + public void processClickWindow(C0EPacketClickWindow p_147351_1_) + { + this.playerEntity.func_143004_u(); + if (this.playerEntity.openContainer.windowId == p_147351_1_.func_149548_c() && this.playerEntity.openContainer.isPlayerNotUsingContainer(this.playerEntity)) + { + // CraftBukkit start - Call InventoryClickEvent + if (p_147351_1_.func_149544_d() < -1 && p_147351_1_.func_149544_d() != -999) + return; + InventoryView inventory = ((IMixinContainer) this.playerEntity.openContainer).getBukkitView(); + SlotType type = CraftInventoryView.getSlotType(inventory, p_147351_1_.func_149544_d()); + InventoryClickEvent event; + ClickType click = ClickType.UNKNOWN; + InventoryAction action = InventoryAction.UNKNOWN; + ItemStack itemstack = null; + // Cauldron start - some containers such as NEI's Creative Container does not have a view at this point so we need to create one + if (inventory == null) + { + inventory = new CraftInventoryView((HumanEntity) ((IMixinEntity) this.playerEntity).getBukkitEntity(), Bukkit.getServer().createInventory( + (InventoryHolder) ((IMixinEntity) this.playerEntity).getBukkitEntity(), InventoryType.CHEST), this.playerEntity.openContainer); +// this.playerEntity.openContainer.bukkitView = inventory; + } + // Cauldron end + if (p_147351_1_.func_149544_d() == -1) + { + type = SlotType.OUTSIDE; // override + click = p_147351_1_.func_149543_e() == 0 ? ClickType.WINDOW_BORDER_LEFT : ClickType.WINDOW_BORDER_RIGHT; + action = InventoryAction.NOTHING; + } + else if (p_147351_1_.func_149542_h() == 0) + { + if (p_147351_1_.func_149543_e() == 0 || p_147351_1_.func_149543_e() == 1) + { + click = p_147351_1_.func_149543_e() == 0 ? ClickType.LEFT : ClickType.RIGHT; + action = InventoryAction.NOTHING; // Don't want to repeat ourselves + if (p_147351_1_.func_149544_d() == -999) + { + if (playerEntity.inventory.getItemStack() != null) + action = p_147351_1_.func_149543_e() == 0 ? InventoryAction.DROP_ALL_CURSOR : InventoryAction.DROP_ONE_CURSOR; + } + else + { + Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); + if (slot != null) + { + ItemStack clickedItem = slot.getStack(); + ItemStack cursor = playerEntity.inventory.getItemStack(); + if (clickedItem == null) + { + if (cursor != null) + action = p_147351_1_.func_149543_e() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; + } + else if (slot.canTakeStack(playerEntity)) // Should be Slot.isPlayerAllowed + { + if (cursor == null) + { + action = p_147351_1_.func_149543_e() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; + } + else if (slot.isItemValid(cursor)) // Should be Slot.isItemAllowed + { + if (clickedItem.isItemEqual(cursor) && ItemStack.areItemStackTagsEqual(clickedItem, cursor)) + { + int toPlace = p_147351_1_.func_149543_e() == 0 ? cursor.stackSize : 1; + toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.stackSize); + toPlace = Math.min(toPlace, slot.inventory.getInventoryStackLimit() - clickedItem.stackSize); + if (toPlace == 1) + action = InventoryAction.PLACE_ONE; + else if (toPlace == cursor.stackSize) + action = InventoryAction.PLACE_ALL; + else if (toPlace < 0) + action = toPlace != -1 ? InventoryAction.PICKUP_SOME : InventoryAction.PICKUP_ONE; // this happens with oversized stacks + else if (toPlace != 0) + action = InventoryAction.PLACE_SOME; + } + else if (cursor.stackSize <= slot.getSlotStackLimit()) // Should be Slot.getMaxStackSize() + { + action = InventoryAction.SWAP_WITH_CURSOR; + } + } + else if (cursor.getItem() == clickedItem.getItem() && (!cursor.getHasSubtypes() || cursor.getItemDamage() == clickedItem.getItemDamage()) && ItemStack.areItemStackTagsEqual(cursor, clickedItem)) + { + if (clickedItem.stackSize >= 0) + if (clickedItem.stackSize + cursor.stackSize <= cursor.getMaxStackSize()) + // As of 1.5, this is result slots only + action = InventoryAction.PICKUP_ALL; + } + } + } + } + } + } + else if (p_147351_1_.func_149542_h() == 1) + { + if (p_147351_1_.func_149543_e() == 0) + click = ClickType.SHIFT_LEFT; + else if (p_147351_1_.func_149543_e() == 1) + click = ClickType.SHIFT_RIGHT; + if (p_147351_1_.func_149543_e() == 0 || p_147351_1_.func_149543_e() == 1) + { + if (p_147351_1_.func_149544_d() < 0) + { + action = InventoryAction.NOTHING; + } + else + { + Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); + if (slot != null && slot.canTakeStack(this.playerEntity) && slot.getHasStack()) // Should be Slot.hasItem() + action = InventoryAction.MOVE_TO_OTHER_INVENTORY; + else + action = InventoryAction.NOTHING; + } + } + } + else if (p_147351_1_.func_149542_h() == 2) + { + if (p_147351_1_.func_149543_e() >= 0 && p_147351_1_.func_149543_e() < 9) + { + click = ClickType.NUMBER_KEY; + Slot clickedSlot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); + if (clickedSlot.canTakeStack(playerEntity)) + { + ItemStack hotbar = this.playerEntity.inventory.getStackInSlot(p_147351_1_.func_149543_e()); + boolean canCleanSwap = hotbar == null || (clickedSlot.inventory == playerEntity.inventory && clickedSlot.isItemValid(hotbar)); // the slot will accept the hotbar item + if (clickedSlot.getHasStack()) + { + if (canCleanSwap) + { + action = InventoryAction.HOTBAR_SWAP; + } + else + { + int firstEmptySlot = playerEntity.inventory.getFirstEmptyStack(); // Should be Inventory.firstEmpty() + if (firstEmptySlot > -1) + action = InventoryAction.HOTBAR_MOVE_AND_READD; + else + action = InventoryAction.NOTHING; // This is not sane! Mojang: You should test for other slots of same type + } + } + else if (!clickedSlot.getHasStack() && hotbar != null && clickedSlot.isItemValid(hotbar)) + { + action = InventoryAction.HOTBAR_SWAP; + } + else + { + action = InventoryAction.NOTHING; + } + } + else + { + action = InventoryAction.NOTHING; + } + // Special constructor for number key + event = new InventoryClickEvent(inventory, type, p_147351_1_.func_149544_d(), click, action, p_147351_1_.func_149543_e()); + } + } + else if (p_147351_1_.func_149542_h() == 3) + { + if (p_147351_1_.func_149543_e() == 2) + { + click = ClickType.MIDDLE; + if (p_147351_1_.func_149544_d() == -999) + { + action = InventoryAction.NOTHING; + } + else + { + Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); + if (slot != null && slot.getHasStack() && playerEntity.capabilities.isCreativeMode && playerEntity.inventory.getItemStack() == null) + action = InventoryAction.CLONE_STACK; + else + action = InventoryAction.NOTHING; + } + } + else + { + click = ClickType.UNKNOWN; + action = InventoryAction.UNKNOWN; + } + } + else if (p_147351_1_.func_149542_h() == 4) + { + if (p_147351_1_.func_149544_d() >= 0) + { + if (p_147351_1_.func_149543_e() == 0) + { + click = ClickType.DROP; + Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); + if (slot != null && slot.getHasStack() && slot.canTakeStack(playerEntity) && slot.getStack() != null && slot.getStack().getItem() != Item.getItemFromBlock(Blocks.air)) + action = InventoryAction.DROP_ONE_SLOT; + else + action = InventoryAction.NOTHING; + } + else if (p_147351_1_.func_149543_e() == 1) + { + click = ClickType.CONTROL_DROP; + Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); + if (slot != null && slot.getHasStack() && slot.canTakeStack(playerEntity) && slot.getStack() != null && slot.getStack().getItem() != Item.getItemFromBlock(Blocks.air)) + action = InventoryAction.DROP_ALL_SLOT; + else + action = InventoryAction.NOTHING; + } + } + else + { + // Sane default (because this happens when they are holding nothing. Don't ask why.) + click = ClickType.LEFT; + if (p_147351_1_.func_149543_e() == 1) + click = ClickType.RIGHT; + action = InventoryAction.NOTHING; + } + } + else if (p_147351_1_.func_149542_h() == 5) + { + itemstack = this.playerEntity.openContainer.slotClick(p_147351_1_.func_149544_d(), p_147351_1_.func_149543_e(), 5, this.playerEntity); + } + else if (p_147351_1_.func_149542_h() == 6) + { + click = ClickType.DOUBLE_CLICK; + action = InventoryAction.NOTHING; + if (p_147351_1_.func_149544_d() >= 0 && this.playerEntity.inventory.getItemStack() != null) + { + ItemStack cursor = this.playerEntity.inventory.getItemStack(); + action = InventoryAction.NOTHING; + // Quick check for if we have any of the item + // Cauldron start - can't call getContents() on modded IInventory; CB-added method + if (inventory.getTopInventory().contains(org.bukkit.Material.getMaterial(Item.getIdFromItem(cursor.getItem()))) + || inventory.getBottomInventory().contains(org.bukkit.Material.getMaterial(Item.getIdFromItem(cursor.getItem())))) + { + action = InventoryAction.COLLECT_TO_CURSOR; + } + // Cauldron end + } + } + // TODO check on updates + if (p_147351_1_.func_149542_h() != 5) + { + if (click == ClickType.NUMBER_KEY) + event = new InventoryClickEvent(inventory, type, p_147351_1_.func_149544_d(), click, action, p_147351_1_.func_149543_e()); + else + event = new InventoryClickEvent(inventory, type, p_147351_1_.func_149544_d(), click, action); + org.bukkit.inventory.Inventory top = inventory.getTopInventory(); + if (p_147351_1_.func_149544_d() == 0 && top instanceof CraftingInventory) + { + // Cauldron start - vanilla compatibility (mod recipes) + org.bukkit.inventory.Recipe recipe = null; + recipe = ((CraftingInventory) top).getRecipe(); + // Cauldron end + + if (recipe != null) + if (click == ClickType.NUMBER_KEY) + event = new CraftItemEvent(recipe, inventory, type, p_147351_1_.func_149544_d(), click, action, p_147351_1_.func_149543_e()); + else + event = new CraftItemEvent(recipe, inventory, type, p_147351_1_.func_149544_d(), click, action); + } + Bukkit.getServer().getPluginManager().callEvent(event); + switch (event.getResult()) + { + case ALLOW: + case DEFAULT: + itemstack = this.playerEntity.openContainer.slotClick(p_147351_1_.func_149544_d(), p_147351_1_.func_149543_e(), + p_147351_1_.func_149542_h(), this.playerEntity); + break; + case DENY: + switch (action) + { + // Modified other slots + case PICKUP_ALL: + case MOVE_TO_OTHER_INVENTORY: + case HOTBAR_MOVE_AND_READD: + case HOTBAR_SWAP: + case COLLECT_TO_CURSOR: + case UNKNOWN: + this.playerEntity.sendContainerToPlayer(this.playerEntity.openContainer); + break; + // Modified cursor and clicked + case PICKUP_SOME: + case PICKUP_HALF: + case PICKUP_ONE: + case PLACE_ALL: + case PLACE_SOME: + case PLACE_ONE: + case SWAP_WITH_CURSOR: + this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(-1, -1, this.playerEntity.inventory.getItemStack())); + this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(this.playerEntity.openContainer.windowId, p_147351_1_ + .func_149544_d(), this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()).getStack())); + break; + // Modified clicked only + case DROP_ALL_SLOT: + case DROP_ONE_SLOT: + this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(this.playerEntity.openContainer.windowId, p_147351_1_ + .func_149544_d(), this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()).getStack())); + break; + // Modified cursor only + case DROP_ALL_CURSOR: + case DROP_ONE_CURSOR: + case CLONE_STACK: + this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(-1, -1, this.playerEntity.inventory.getItemStack())); + break; + // Nothing + case NOTHING: + break; + } + return; + } + } + if (ItemStack.areItemStacksEqual(p_147351_1_.func_149546_g(), itemstack)) + { + this.playerEntity.playerNetServerHandler.sendPacket(new S32PacketConfirmTransaction(p_147351_1_.func_149548_c(), p_147351_1_.func_149547_f(), true)); + this.playerEntity.isChangingQuantityOnly = true; + this.playerEntity.openContainer.detectAndSendChanges(); + this.playerEntity.updateHeldItem(); + this.playerEntity.isChangingQuantityOnly = false; + } + else + { + this.field_147372_n.addKey(this.playerEntity.openContainer.windowId, p_147351_1_.func_149547_f()); + this.playerEntity.playerNetServerHandler.sendPacket(new S32PacketConfirmTransaction(p_147351_1_.func_149548_c(), p_147351_1_.func_149547_f(), false)); + this.playerEntity.openContainer.setPlayerIsPresent(this.playerEntity, false); + ArrayList arraylist = new ArrayList(); + for (int i = 0; i < this.playerEntity.openContainer.inventorySlots.size(); ++i) + arraylist.add(((Slot) this.playerEntity.openContainer.inventorySlots.get(i)).getStack()); + this.playerEntity.sendContainerAndContentsToPlayer(this.playerEntity.openContainer, arraylist); + } + } + } } diff --git a/src/main/java/org/ultramine/mods/bukkit/mixin/tileentity/MixinTileEntityHopper.java b/src/main/java/org/ultramine/mods/bukkit/mixin/tileentity/MixinTileEntityHopper.java new file mode 100644 index 0000000..87e12e8 --- /dev/null +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/tileentity/MixinTileEntityHopper.java @@ -0,0 +1,150 @@ +package org.ultramine.mods.bukkit.mixin.tileentity; + +import net.minecraft.block.BlockHopper; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryLargeChest; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.IHopper; +import net.minecraft.tileentity.TileEntityHopper; +import net.minecraft.util.Facing; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntity; +import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; +import org.ultramine.mods.bukkit.util.BukkitUtil; + +import static net.minecraft.tileentity.TileEntityHopper.func_145889_a; + +@Mixin(TileEntityHopper.class) +public abstract class MixinTileEntityHopper +{ + @Shadow protected abstract IInventory func_145895_l(); + + @Shadow protected abstract boolean func_152102_a(IInventory p_152102_1_, int p_152102_2_); + + @Inject(method = "func_145898_a", cancellable = true, at = @At(value = "RETURN", ordinal = 0, shift = Shift.BY, by = 2)) + private static void func_145898_aInject(IInventory p_145898_0_, EntityItem p_145898_1_, CallbackInfoReturnable cir) + { + if (BukkitUtil.getInventoryOwner(p_145898_0_) != null && ((IMixinEntity) p_145898_1_).getBukkitEntity() != null) + { + InventoryPickupItemEvent event = new InventoryPickupItemEvent(BukkitUtil.getInventoryOwner(p_145898_0_).getInventory(), (org.bukkit.entity.Item) ((IMixinEntity) p_145898_1_).getBukkitEntity()); + ((IMixinWorld) p_145898_1_.worldObj).getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) + { + cir.setReturnValue(false); + cir.cancel(); + } + } + } + + @Overwrite + private boolean func_145883_k() + { + IInventory iinventory = this.func_145895_l(); + TileEntityHopper thisObject = ((TileEntityHopper) (Object) this); + if (iinventory == null) + { + return false; + } + else + { + int i = Facing.oppositeSide[BlockHopper.getDirectionFromMetadata(thisObject.getBlockMetadata())]; + if (this.func_152102_a(iinventory, i)) + { + return false; + } + else + { + for (int j = 0; j < thisObject.getSizeInventory(); ++j) + if (thisObject.getStackInSlot(j) != null) + { + ItemStack itemstack = thisObject.getStackInSlot(j).copy(); + CraftItemStack oitemstack = CraftItemStack.asCraftMirror(thisObject.decrStackSize(j, 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 + { + InventoryHolder owner = BukkitUtil.getInventoryOwner(iinventory); + destinationInventory = owner != null ? owner.getInventory() : null; + } + InventoryMoveItemEvent event = new InventoryMoveItemEvent(BukkitUtil.getInventoryOwner(thisObject).getInventory(), oitemstack.clone(), destinationInventory, true); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) + { + thisObject.setInventorySlotContents(j, itemstack); + return false; + } + ItemStack itemstack1 = func_145889_a(iinventory, CraftItemStack.asNMSCopy(event.getItem()), i); + if (itemstack1 == null || itemstack1.stackSize == 0) + { + iinventory.markDirty(); + return true; + } + thisObject.setInventorySlotContents(j, itemstack); + } + return false; + } + } + } + + @Shadow + private static boolean func_145890_b(IInventory p_145890_0_, ItemStack p_145890_1_, int p_145890_2_, int p_145890_3_) + { + return false; + } + + @Overwrite + private static boolean func_145892_a(IHopper hopper, IInventory inventory, int slotId, int p_145892_3_) + { + ItemStack itemstack = inventory.getStackInSlot(slotId); + if (itemstack != null && func_145890_b(inventory, itemstack, slotId, p_145892_3_)) + { + ItemStack itemstack1 = itemstack.copy(); + CraftItemStack oitemstack = CraftItemStack.asCraftMirror(inventory.decrStackSize(slotId, 1)); + Inventory sourceInventory = null; + + // Have to special case large chests as they work oddly + if (inventory instanceof InventoryLargeChest) + { + sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) inventory); + } + else + { + InventoryHolder owner = BukkitUtil.getInventoryOwner(inventory); + sourceInventory = owner != null ? owner.getInventory() : null; + } + + InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), BukkitUtil.getInventoryOwner(hopper).getInventory(), false); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) + { + inventory.setInventorySlotContents(slotId, itemstack1); + return false; + } + ItemStack itemstack2 = func_145889_a(hopper, CraftItemStack.asNMSCopy(event.getItem()), -1); + if (itemstack2 == null || itemstack2.stackSize == 0) + { + inventory.markDirty(); + return true; + } + inventory.setInventorySlotContents(slotId, itemstack1); + } + return false; + } +} diff --git a/src/main/java/org/ultramine/mods/bukkit/util/BukkitUtil.java b/src/main/java/org/ultramine/mods/bukkit/util/BukkitUtil.java index 4a6d4bc..8eeebe4 100644 --- a/src/main/java/org/ultramine/mods/bukkit/util/BukkitUtil.java +++ b/src/main/java/org/ultramine/mods/bukkit/util/BukkitUtil.java @@ -1,14 +1,24 @@ package org.ultramine.mods.bukkit.util; +import jline.internal.Nullable; import net.minecraft.command.ICommandSender; import net.minecraft.command.server.CommandBlockLogic; import net.minecraft.entity.EntityMinecartCommandBlock; +import net.minecraft.entity.item.EntityMinecartContainer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.AnimalChest; import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.InventoryBasic; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.inventory.InventoryEnderChest; +import net.minecraft.inventory.InventoryMerchant; +import net.minecraft.item.crafting.IRecipe; import net.minecraft.network.rcon.RConConsoleSource; import net.minecraft.server.MinecraftServer; import net.minecraft.tileentity.TileEntity; import org.bukkit.Bukkit; +import org.bukkit.block.BlockState; import org.bukkit.command.CommandSender; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.command.CraftBlockCommandSender; @@ -19,6 +29,9 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.InventoryHolder; import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntity; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryCrafting; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryEnderChest; +import org.ultramine.mods.bukkit.interfaces.inventory.IMixinInventoryMerchant; import org.ultramine.mods.bukkit.interfaces.world.IMixinWorld; import org.ultramine.server.event.WorldEventProxy; import org.ultramine.server.event.WorldUpdateObject; @@ -52,32 +65,6 @@ return items; } - public static org.bukkit.inventory.Recipe toBukkitRecipe(net.minecraft.item.crafting.IRecipe iRecipe) - { -// try { -// return iRecipe.toBukkitRecipe(); -// } catch (AbstractMethodError ex) { -// // No Bukkit wrapper provided -// return new CustomModRecipe(iRecipe); -// } - return new CustomModRecipe(iRecipe); // TODO - } - - public static org.bukkit.inventory.InventoryHolder getBukkitOwner(IInventory inv) - { - if(inv instanceof TileEntity) // TODO - { - TileEntity te = (TileEntity) inv; - - org.bukkit.block.BlockState state = ((IMixinWorld) te.getWorldObj()).getWorld().getBlockAt(te.xCoord, te.yCoord, te.zCoord).getState(); - - if(state instanceof InventoryHolder) - return (InventoryHolder) state; - } - - return null; - } - public static CommandSender toBukkitCommandSender(ICommandSender sender) { CommandSender bukkitSender; @@ -133,4 +120,44 @@ return vanillaSender; } + + @Nullable + public static InventoryHolder getInventoryOwner(IInventory inventory) + { + if (inventory instanceof TileEntity) + { + TileEntity te = (TileEntity) inventory; + BlockState state = ((IMixinWorld) te.getWorldObj()).getWorld().getBlockAt(te.xCoord, te.yCoord, te.zCoord).getState(); + if (state instanceof InventoryHolder) + return (InventoryHolder) state; + } + else if (inventory instanceof InventoryBasic) + { + InventoryBasic inventoryBasic = (InventoryBasic) inventory; + if (inventoryBasic instanceof AnimalChest) + return (InventoryHolder) ((IMixinEntity) inventoryBasic).getBukkitEntity(); + else if (inventoryBasic instanceof InventoryEnderChest) + return ((IMixinInventoryEnderChest) inventoryBasic).getOwner(); + } + else if (inventory instanceof EntityMinecartContainer) + { + org.bukkit.entity.Entity cart = ((IMixinEntity) inventory).getBukkitEntity(); + if (cart instanceof InventoryHolder) + return (InventoryHolder) cart; + } + else if (inventory instanceof InventoryPlayer) + { + InventoryPlayer inventoryPlayer = (InventoryPlayer) inventory; + return (InventoryHolder) ((IMixinEntity) inventoryPlayer.player).getBukkitEntity(); + } + else if (inventory instanceof InventoryCrafting) + { + return (InventoryHolder) ((IMixinInventoryCrafting) inventory).getOwner(); + } + else if (inventory instanceof InventoryMerchant) + { + return (InventoryHolder) ((IMixinInventoryMerchant) inventory).getPlayer(); + } + return null; + } } diff --git a/src/main/resources/mixin.umbukkitimpl.json b/src/main/resources/mixin.umbukkitimpl.json index 82d0f38..af7a338 100644 --- a/src/main/resources/mixin.umbukkitimpl.json +++ b/src/main/resources/mixin.umbukkitimpl.json @@ -29,6 +29,7 @@ "block.MixinBlockPistonBase", "block.MixinBlockMushroom", "block.MixinBlockVine", + "block.MixinBlockDropper", "entity.MixinEntity", "entity.MixinEntityLiving", "entity.MixinEntityLivingBase", @@ -56,14 +57,23 @@ "entity.item.MixinEntityItemFrame", "entity.item.MixinEntityFireworkRocket", "entity.effect.MixinEntityLightningBolt", + "inventory.MixinContainer", "inventory.MixinInventoryLargeChest", + "inventory.MixinInventoryMerchant", + "inventory.MixinInventoryEnderChest", + "inventory.MixinInventoryCrafting", + "inventory.MixinContainerPlayer", + "inventory.MixinContainerWorkbench", "item.MixinItemFlintAndSteel", "item.MixinItemBucket", + "item.crafting.MixinShapedRecipes", + "item.crafting.MixinShapelessRecipes", "management.MixinBanEntry", "management.MixinItemInWorldManager", "management.MixinServerConfigurationManager", "management.MixinUserList", "management.MixinUserListEntry", + "management.MixinCraftingManager", "network.MixinNetHPlayS", "network.MixinNetHLoginS", "network.MixinC08PacketPlayerBlockPlacement", @@ -71,6 +81,7 @@ "tileentity.MixinTileEntityFurnace", "tileentity.MixinTileEntitySkull", "tileentity.MixinTileEntityNote", + "tileentity.MixinTileEntityHopper", "world.MixinChunk", "world.MixinWorld", "world.MixinWorldServer",