diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 62ac7fd..f52f60b 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1078,6 +1078,9 @@ } public static net.minecraft.inventory.Container callInventoryOpenEvent(net.minecraft.entity.player.EntityPlayerMP player, net.minecraft.inventory.Container container, boolean closeInv) { + IMixinContainer mixinContainer = (IMixinContainer) container; + if (mixinContainer.isOpened() || mixinContainer.isClosedByEventCancelling()) + return container; 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)); @@ -1088,15 +1091,18 @@ // 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 + mixinContainer.setOpened(true); + InventoryOpenEvent event = new InventoryOpenEvent(mixinContainer.getBukkitView()); + if (mixinContainer.getBukkitView() != null) server.getPluginManager().callEvent(event); // Cauldron - allow vanilla mods to bypass if (event.isCancelled()) { - ((IMixinContainer) container).transferTo(player.openContainer, craftPlayer); + mixinContainer.transferTo(player.openContainer, craftPlayer); + mixinContainer.setOpened(false); + mixinContainer.setClosedByEventCancelling(true); // 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(); + ((IMixinPlayerMP) player).closeScreenSilent(); player.openContainer = player.inventoryContainer; } // Cauldron end @@ -1235,6 +1241,7 @@ 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()); + ((IMixinContainer) human.openContainer).setOpened(false); } public static void handleEditBookEvent(net.minecraft.entity.player.EntityPlayerMP player, net.minecraft.item.ItemStack newBookItem) 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 6f655d4..4931a1c 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 @@ -52,4 +52,6 @@ void setCollidesWithEntities(boolean collidesWithEntities); int nextContainerCounter(); + + void closeScreenSilent(); } 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 index e6504d0..6ade895 100644 --- a/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinContainer.java +++ b/src/main/java/org/ultramine/mods/bukkit/interfaces/inventory/IMixinContainer.java @@ -9,5 +9,15 @@ { @Nullable InventoryView getBukkitView(); + void setBukkitView(InventoryView bukkitView); + void transferTo(Container other, org.bukkit.craftbukkit.entity.CraftHumanEntity player); + + void setOpened(boolean isOpened); + + boolean isOpened(); + + void setClosedByEventCancelling(boolean closedByEventCancelling); + + boolean isClosedByEventCancelling(); } 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 601a7fe..f1db3b2 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 @@ -12,6 +12,7 @@ import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.PacketBuffer; import net.minecraft.network.play.server.S2DPacketOpenWindow; +import net.minecraft.network.play.server.S2EPacketCloseWindow; import net.minecraft.network.play.server.S3FPacketCustomPayload; import net.minecraft.tileentity.TileEntityBeacon; import net.minecraft.tileentity.TileEntityBrewingStand; @@ -428,4 +429,12 @@ { CraftEventFactory.handleInventoryCloseEvent(this); } + + @Override + public void closeScreenSilent() + { + this.playerNetServerHandler.sendPacket(new S2EPacketCloseWindow(this.openContainer.windowId)); + this.openContainer.onContainerClosed(this); + this.openContainer = this.inventoryContainer; + } } 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 index 042ce80..8380caa 100644 --- a/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainer.java +++ b/src/main/java/org/ultramine/mods/bukkit/mixin/inventory/MixinContainer.java @@ -57,6 +57,9 @@ @Shadow public List inventorySlots; @Shadow protected List crafters; + private boolean isOpened = false; + private boolean isClosedByEventCancelling = false; + private InventoryView bukkitView; private boolean isBukkitViewCreated; @@ -74,6 +77,13 @@ return bukkitView; // nullable here } + @Override + public void setBukkitView(InventoryView bukkitView) + { + this.bukkitView = bukkitView; + isBukkitViewCreated = true; + } + private InventoryView computeBukkitView() { Container container = (Container) (Object) this; @@ -535,4 +545,28 @@ } return itemstack; } + + @Override + public void setOpened(boolean isOpened) + { + this.isOpened = isOpened; + } + + @Override + public boolean isOpened() + { + return this.isOpened; + } + + @Override + public boolean isClosedByEventCancelling() + { + return this.isClosedByEventCancelling; + } + + @Override + public void setClosedByEventCancelling(boolean closedByEventCancelling) + { + this.isClosedByEventCancelling = closedByEventCancelling; + } } 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 ebd4f2f..5087442 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 @@ -4,7 +4,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.init.Blocks; -import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.network.Packet; @@ -13,14 +13,22 @@ import net.minecraft.world.World; import net.minecraft.world.WorldSettings; import net.minecraftforge.event.ForgeEventFactory; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.entity.HumanEntity; import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryType; +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.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.ultramine.mods.bukkit.interfaces.entity.IMixinEntity; import org.ultramine.mods.bukkit.interfaces.inventory.IMixinContainer; @Mixin(net.minecraft.server.management.ItemInWorldManager.class) @@ -234,6 +242,24 @@ 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_); + if (thisPlayerMP != null) + { + if (((IMixinContainer) thisPlayerMP.openContainer).getBukkitView() == null) + { + TileEntity te = thisPlayerMP.worldObj.getTileEntity(p_73078_4_, p_73078_5_, p_73078_6_); + CraftEntity bukkitPlayer = ((IMixinEntity) thisPlayerMP).getBukkitEntity(); + if (te != null && te instanceof IInventory) + ((IMixinContainer) thisPlayerMP.openContainer).setBukkitView(new CraftInventoryView((HumanEntity) bukkitPlayer, new CraftInventory((IInventory) te), thisPlayerMP.openContainer)); + else + ((IMixinContainer) thisPlayerMP.openContainer).setBukkitView(new CraftInventoryView((HumanEntity) bukkitPlayer, Bukkit.createInventory((InventoryHolder) bukkitPlayer, InventoryType.CHEST), thisPlayerMP.openContainer)); + } + thisPlayerMP.openContainer = CraftEventFactory.callInventoryOpenEvent(thisPlayerMP, thisPlayerMP.openContainer, false); + if (thisPlayerMP.openContainer == null) + { + thisPlayerMP.openContainer = thisPlayerMP.inventoryContainer; + return false; + } + } } if(p_73078_3_ != null && !denyResult && p_73078_3_.stackSize > 0)