diff --git a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java index 58ce252e5..f6a438eb5 100644 --- a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java +++ b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java @@ -20,6 +20,7 @@ import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive; import dan200.computercraft.shared.peripheral.monitor.TileMonitor; import dan200.computercraft.shared.peripheral.printer.TilePrinter; +import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.proxy.ComputerCraftProxyCommon; import dan200.computercraft.shared.turtle.blocks.TileTurtle; @@ -325,7 +326,7 @@ public Object getPrintoutGUI( EntityPlayer player, EnumHand hand ) @Override public Object getPocketComputerGUI( EntityPlayer player, EnumHand hand ) { - ContainerHeldItem container = new ContainerHeldItem( player, hand ); + ContainerPocketComputer container = new ContainerPocketComputer( player, hand ); if( container.getStack() != null && container.getStack().getItem() instanceof ItemPocketComputer ) { return new GuiPocketComputer( container ); diff --git a/src/main/java/dan200/computercraft/shared/computer/core/IContainerComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/IContainerComputer.java new file mode 100644 index 000000000..67f13f7d9 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/computer/core/IContainerComputer.java @@ -0,0 +1,20 @@ +package dan200.computercraft.shared.computer.core; + +import javax.annotation.Nullable; + +/** + * An instance of {@link net.minecraft.inventory.Container} which provides a computer. You should implement this + * if you provide custom computers/GUIs to interact with them. + */ +public interface IContainerComputer +{ + /** + * Get the computer you are interacting with. + * + * This will only be called on the server. + * + * @return The computer you are interacting with. + */ + @Nullable + IComputer getComputer(); +} diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java index 5f1c0ba17..4161afb7d 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java @@ -20,6 +20,7 @@ import dan200.computercraft.shared.network.INetworkedThing; import dan200.computercraft.shared.util.NBTUtil; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -351,6 +352,17 @@ public void writeDescription( NBTTagCompound nbttagcompound ) @Override public void handlePacket( ComputerCraftPacket packet, EntityPlayer sender ) { + // Allow Computer/Tile updates as they may happen at any time. + if (packet.requiresContainer()) { + if (sender == null) return; + + Container container = sender.openContainer; + if (!(container instanceof IContainerComputer)) return; + + IComputer computer = ((IContainerComputer) container).getComputer(); + if (computer != this) return; + } + // Receive packets sent from the client to the server switch( packet.m_packetType ) { diff --git a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputer.java b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputer.java index 4ff378a1c..d99c4ca8a 100644 --- a/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/inventory/ContainerComputer.java @@ -7,10 +7,15 @@ package dan200.computercraft.shared.computer.inventory; import dan200.computercraft.shared.computer.blocks.TileComputer; +import dan200.computercraft.shared.computer.core.IComputer; +import dan200.computercraft.shared.computer.core.IContainerComputer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; +import javax.annotation.Nullable; + public class ContainerComputer extends Container + implements IContainerComputer { private TileComputer m_computer; @@ -24,4 +29,11 @@ public boolean canInteractWith( EntityPlayer player ) { return m_computer.isUseableByPlayer( player ); } + + @Nullable + @Override + public IComputer getComputer() + { + return m_computer.getServerComputer(); + } } diff --git a/src/main/java/dan200/computercraft/shared/network/ComputerCraftPacket.java b/src/main/java/dan200/computercraft/shared/network/ComputerCraftPacket.java index 9b3ca1693..fdb16f8d9 100644 --- a/src/main/java/dan200/computercraft/shared/network/ComputerCraftPacket.java +++ b/src/main/java/dan200/computercraft/shared/network/ComputerCraftPacket.java @@ -224,4 +224,12 @@ public void fromBytes( ByteBuf buffer ) } } } + + /** + * Determine whether this packet requires the player to be interacting with the + * target. + */ + public boolean requiresContainer() { + return m_packetType != RequestComputerUpdate && m_packetType != RequestTileEntityUpdate; + } } diff --git a/src/main/java/dan200/computercraft/shared/pocket/inventory/ContainerPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/inventory/ContainerPocketComputer.java new file mode 100644 index 000000000..2ec110ef3 --- /dev/null +++ b/src/main/java/dan200/computercraft/shared/pocket/inventory/ContainerPocketComputer.java @@ -0,0 +1,35 @@ +package dan200.computercraft.shared.pocket.inventory; + +import dan200.computercraft.shared.computer.core.IComputer; +import dan200.computercraft.shared.computer.core.IContainerComputer; +import dan200.computercraft.shared.media.inventory.ContainerHeldItem; +import dan200.computercraft.shared.pocket.items.ItemPocketComputer; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumHand; + +import javax.annotation.Nullable; + +public class ContainerPocketComputer extends ContainerHeldItem + implements IContainerComputer +{ + public ContainerPocketComputer( EntityPlayer player, EnumHand hand ) + { + super( player, hand ); + } + + @Nullable + @Override + public IComputer getComputer() + { + ItemStack stack = getStack(); + if( stack != null && stack.getItem() instanceof ItemPocketComputer ) + { + return ((ItemPocketComputer) stack.getItem()).getServerComputer( stack ); + } + else + { + return null; + } + } +} diff --git a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java index 484c9ecdc..1e9371667 100644 --- a/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java +++ b/src/main/java/dan200/computercraft/shared/pocket/items/ItemPocketComputer.java @@ -279,6 +279,16 @@ private ServerComputer createServerComputer( final World world, IInventory inven return computer; } + public ServerComputer getServerComputer( ItemStack stack ) + { + int instanceID = getInstanceID( stack ); + if( instanceID >= 0 ) + { + return ComputerCraft.serverComputerRegistry.get( instanceID ); + } + return null; + } + public ClientComputer createClientComputer( ItemStack stack ) { int instanceID = getInstanceID( stack ); diff --git a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java index 4bafb6f5d..d51ac0393 100644 --- a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java +++ b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java @@ -42,6 +42,7 @@ import dan200.computercraft.shared.peripheral.monitor.TileMonitor; import dan200.computercraft.shared.peripheral.printer.ContainerPrinter; import dan200.computercraft.shared.peripheral.printer.TilePrinter; +import dan200.computercraft.shared.pocket.inventory.ContainerPocketComputer; import dan200.computercraft.shared.pocket.items.ItemPocketComputer; import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory; import dan200.computercraft.shared.pocket.recipes.PocketComputerUpgradeRecipe; @@ -540,7 +541,7 @@ public Object getServerGuiElement( int id, EntityPlayer player, World world, int if (tile != null && tile instanceof TileTurtle) { TileTurtle turtle = (TileTurtle) tile; - return new ContainerTurtle( player.inventory, turtle.getAccess() ); + return new ContainerTurtle( player.inventory, turtle.getAccess(), turtle.getServerComputer() ); } break; } @@ -550,7 +551,7 @@ public Object getServerGuiElement( int id, EntityPlayer player, World world, int } case ComputerCraft.pocketComputerGUIID: { - return new ContainerHeldItem( player, x == 0 ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND ); + return new ContainerPocketComputer( player, x == 0 ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND ); } } return null; diff --git a/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java b/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java index 7c869215c..780144989 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java +++ b/src/main/java/dan200/computercraft/shared/turtle/inventory/ContainerTurtle.java @@ -7,6 +7,8 @@ package dan200.computercraft.shared.turtle.inventory; import dan200.computercraft.api.turtle.ITurtleAccess; +import dan200.computercraft.shared.computer.core.IComputer; +import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.turtle.blocks.TileTurtle; import dan200.computercraft.shared.turtle.core.TurtleBrain; import net.minecraft.entity.player.EntityPlayer; @@ -16,7 +18,10 @@ import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; +import javax.annotation.Nullable; + public class ContainerTurtle extends Container + implements IContainerComputer { private static final int PROGRESS_ID_SELECTED_SLOT = 0; @@ -24,6 +29,7 @@ public class ContainerTurtle extends Container public final int m_turtleInvStartX; protected ITurtleAccess m_turtle; + private IComputer m_computer; private int m_selectedSlot; protected ContainerTurtle( IInventory playerInventory, ITurtleAccess turtle, int playerInvStartY, int turtleInvStartX ) @@ -71,6 +77,12 @@ public ContainerTurtle( IInventory playerInventory, ITurtleAccess turtle ) this( playerInventory, turtle, 134, 175 ); } + public ContainerTurtle( IInventory playerInventory, ITurtleAccess turtle, IComputer computer ) + { + this( playerInventory, turtle ); + m_computer = computer; + } + public int getSelectedSlot() { return m_selectedSlot; @@ -178,4 +190,11 @@ else if( slotNum >= 16 ) } return null; } + + @Nullable + @Override + public IComputer getComputer() + { + return m_computer; + } }