diff --git a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java index db2da9330..2339047dc 100644 --- a/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java +++ b/src/main/java/dan200/computercraft/client/proxy/ComputerCraftProxyClient.java @@ -383,6 +383,7 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon switch( packet.m_packetType ) { case ComputerCraftPacket.ComputerChanged: + case ComputerCraftPacket.ComputerTerminalChanged: case ComputerCraftPacket.ComputerDeleted: { // Packet from Server to Client @@ -417,6 +418,7 @@ public class ComputerCraftProxyClient extends ComputerCraftProxyCommon // Packets from Server to Client // /////////////////////////////////// case ComputerCraftPacket.ComputerChanged: + case ComputerCraftPacket.ComputerTerminalChanged: { int instanceID = packet.m_dataInt[ 0 ]; if( !ComputerCraft.clientComputerRegistry.contains( instanceID ) ) diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ClientComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/ClientComputer.java index 6f1c345c5..811ad83a1 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ClientComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ClientComputer.java @@ -153,11 +153,8 @@ public class ClientComputer extends ClientTerminal ComputerCraft.sendToServer( packet ); } - @Override - public void readDescription( NBTTagCompound nbttagcompound ) + private void readComputerDescription( NBTTagCompound nbttagcompound ) { - super.readDescription( nbttagcompound ); - int oldID = m_computerID; String oldLabel = m_label; boolean oldOn = m_on; @@ -189,10 +186,11 @@ public class ClientComputer extends ClientTerminal switch( packet.m_packetType ) { case ComputerCraftPacket.ComputerChanged: - { + readComputerDescription( packet.m_dataNBT ); + break; + case ComputerCraftPacket.ComputerTerminalChanged: readDescription( packet.m_dataNBT ); break; - } } } } 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 4d7c3ed55..a9950c454 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java @@ -20,10 +20,13 @@ import dan200.computercraft.shared.network.ComputerCraftPacket; import dan200.computercraft.shared.network.INetworkedThing; import dan200.computercraft.shared.util.NBTUtil; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.inventory.Container; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Loader; import java.io.InputStream; @@ -131,27 +134,62 @@ public class ServerComputer extends ServerTerminal { m_changed = true; } - - public void broadcastState() - { - // Send state to client + + private ComputerCraftPacket createComputerPacket() { ComputerCraftPacket packet = new ComputerCraftPacket(); packet.m_packetType = ComputerCraftPacket.ComputerChanged; packet.m_dataInt = new int[] { getInstanceID() }; packet.m_dataNBT = new NBTTagCompound(); - writeDescription( packet.m_dataNBT ); - ComputerCraft.sendToAllPlayers( packet ); + writeComputerDescription( packet.m_dataNBT ); + return packet; } - public void sendState( EntityPlayer player ) - { - // Send state to client + private ComputerCraftPacket createTerminalPacket() { ComputerCraftPacket packet = new ComputerCraftPacket(); - packet.m_packetType = ComputerCraftPacket.ComputerChanged; + packet.m_packetType = ComputerCraftPacket.ComputerTerminalChanged; packet.m_dataInt = new int[] { getInstanceID() }; packet.m_dataNBT = new NBTTagCompound(); writeDescription( packet.m_dataNBT ); - ComputerCraft.sendToPlayer( player, packet ); + return packet; + } + + public void broadcastState(boolean force) + { + if(hasOutputChanged() || force) + { + // Send computer state to all clients + ComputerCraft.sendToAllPlayers( createComputerPacket() ); + } + + if( hasTerminalChanged() || force ) + { + // Send terminal state to clients who are currently interacting with the computer. + FMLCommonHandler handler = FMLCommonHandler.instance(); + if( handler != null ) + { + ComputerCraftPacket packet = createTerminalPacket(); + MinecraftServer server = handler.getMinecraftServerInstance(); + for( EntityPlayerMP player : server.getPlayerList().getPlayers() ) + { + if( isInteracting( player ) ) + { + ComputerCraft.sendToPlayer( player, packet ); + } + } + } + } + } + + public void sendComputerState( EntityPlayer player ) + { + // Send state to client + ComputerCraft.sendToPlayer( player, createComputerPacket() ); + } + + public void sendTerminalState( EntityPlayer player ) + { + // Send terminal state to client + ComputerCraft.sendToPlayer( player, createTerminalPacket() ); } public void broadcastDelete() @@ -336,12 +374,8 @@ public class ServerComputer extends ServerTerminal } // Networking stuff - - @Override - public void writeDescription( NBTTagCompound nbttagcompound ) + public void writeComputerDescription( NBTTagCompound nbttagcompound ) { - super.writeDescription( nbttagcompound ); - nbttagcompound.setInteger( "id", m_computer.getID() ); String label = m_computer.getLabel(); if( label != null ) @@ -362,14 +396,9 @@ public class ServerComputer extends ServerTerminal 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; + if( packet.requiresContainer() && !isInteracting( sender ) ) + { + return; } // Receive packets sent from the client to the server @@ -415,9 +444,20 @@ public class ServerComputer extends ServerTerminal case ComputerCraftPacket.RequestComputerUpdate: { // A player asked for an update on the state of the terminal - sendState( sender ); + sendComputerState( sender ); break; } } } + + private boolean isInteracting( EntityPlayer player ) + { + if( player == null ) return false; + + Container container = player.openContainer; + if( !(container instanceof IContainerComputer) ) return false; + + IComputer computer = ((IContainerComputer) container).getComputer(); + return computer == this; + } } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java index e0ee7e690..6bca7ec9b 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputerRegistry.java @@ -33,7 +33,7 @@ public class ServerComputerRegistry extends ComputerRegistry<ServerComputer> computer.update(); if( computer.hasTerminalChanged() || computer.hasOutputChanged() ) { - computer.broadcastState(); + computer.broadcastState(false); } } } @@ -44,7 +44,7 @@ public class ServerComputerRegistry extends ComputerRegistry<ServerComputer> { //System.out.println( "ADD SERVER COMPUTER " + instanceID ); super.add( instanceID, computer ); - computer.broadcastState(); + computer.broadcastState(true); //System.out.println( getComputers().size() + " SERVER COMPUTERS" ); } diff --git a/src/main/java/dan200/computercraft/shared/network/ComputerCraftPacket.java b/src/main/java/dan200/computercraft/shared/network/ComputerCraftPacket.java index a6ac9b709..b9515aa0a 100644 --- a/src/main/java/dan200/computercraft/shared/network/ComputerCraftPacket.java +++ b/src/main/java/dan200/computercraft/shared/network/ComputerCraftPacket.java @@ -30,7 +30,8 @@ public class ComputerCraftPacket // To client public static final byte ComputerChanged = 7; - public static final byte ComputerDeleted = 8; + public static final byte ComputerTerminalChanged = 8; + public static final byte ComputerDeleted = 9; // Packet class public byte m_packetType; diff --git a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java index 53656b22d..f4bbf0d8c 100644 --- a/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java +++ b/src/main/java/dan200/computercraft/shared/proxy/ComputerCraftProxyCommon.java @@ -18,6 +18,8 @@ import dan200.computercraft.shared.computer.blocks.BlockComputer; import dan200.computercraft.shared.computer.blocks.TileCommandComputer; import dan200.computercraft.shared.computer.blocks.TileComputer; import dan200.computercraft.shared.computer.core.ComputerFamily; +import dan200.computercraft.shared.computer.core.IComputer; +import dan200.computercraft.shared.computer.core.IContainerComputer; import dan200.computercraft.shared.computer.core.ServerComputer; import dan200.computercraft.shared.computer.inventory.ContainerComputer; import dan200.computercraft.shared.computer.items.ItemCommandComputer; @@ -58,6 +60,7 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Items; +import net.minecraft.inventory.Container; import net.minecraft.item.Item; import net.minecraft.item.ItemRecord; import net.minecraft.item.ItemStack; @@ -70,6 +73,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.event.entity.player.PlayerContainerEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -646,5 +650,20 @@ public abstract class ComputerCraftProxyCommon implements IComputerCraftProxy ComputerCraft.syncConfig(); } } + + @SubscribeEvent + public void onContainerOpen( PlayerContainerEvent.Open event ) + { + // If we're opening a computer container then broadcast the terminal state + Container container = event.getContainer(); + if( container instanceof IContainerComputer ) + { + IComputer computer = ((IContainerComputer) container).getComputer(); + if( computer instanceof ServerComputer ) + { + ((ServerComputer) computer).sendTerminalState( event.getEntityPlayer() ); + } + } + } } }