001    package net.minecraft.network;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    import cpw.mods.fml.common.network.FMLNetworkHandler;
006    
007    import java.io.IOException;
008    import java.net.InetSocketAddress;
009    import java.net.SocketAddress;
010    import java.util.ArrayList;
011    import java.util.Collections;
012    import java.util.List;
013    import net.minecraft.network.packet.NetHandler;
014    import net.minecraft.network.packet.Packet;
015    
016    public class MemoryConnection implements INetworkManager
017    {
018        private static final SocketAddress mySocketAddress = new InetSocketAddress("127.0.0.1", 0);
019        private final List readPacketCache = Collections.synchronizedList(new ArrayList());
020        private MemoryConnection pairedConnection;
021        private NetHandler myNetHandler;
022    
023        /** set to true by {server,network}Shutdown */
024        private boolean shuttingDown = false;
025        private String shutdownReason = "";
026        private Object[] field_74439_g;
027        private boolean gamePaused = false;
028    
029        public MemoryConnection(NetHandler par1NetHandler) throws IOException
030        {
031            this.myNetHandler = par1NetHandler;
032        }
033    
034        /**
035         * Sets the NetHandler for this NetworkManager. Server-only.
036         */
037        public void setNetHandler(NetHandler par1NetHandler)
038        {
039            this.myNetHandler = par1NetHandler;
040        }
041    
042        /**
043         * Adds the packet to the correct send queue (chunk data packets go to a separate queue).
044         */
045        public void addToSendQueue(Packet par1Packet)
046        {
047            if (!this.shuttingDown)
048            {
049                this.pairedConnection.processOrCachePacket(par1Packet);
050            }
051        }
052    
053        /**
054         * Wakes reader and writer threads
055         */
056        public void wakeThreads() {}
057    
058        @SideOnly(Side.CLIENT)
059        public void closeConnections()
060        {
061            this.pairedConnection = null;
062            this.myNetHandler = null;
063        }
064    
065        @SideOnly(Side.CLIENT)
066        public boolean isConnectionActive()
067        {
068            return !this.shuttingDown && this.pairedConnection != null;
069        }
070    
071        /**
072         * Checks timeouts and processes all pending read packets.
073         */
074        public void processReadPackets()
075        {
076            int var1 = 2500;
077    
078            while (var1-- >= 0 && !this.readPacketCache.isEmpty())
079            {
080                Packet var2 = (Packet)this.readPacketCache.remove(0);
081                var2.processPacket(this.myNetHandler);
082            }
083    
084            if (this.readPacketCache.size() > var1)
085            {
086                System.out.println("Memory connection overburdened; after processing 2500 packets, we still have " + this.readPacketCache.size() + " to go!");
087            }
088    
089            if (this.shuttingDown && this.readPacketCache.isEmpty())
090            {
091                this.myNetHandler.handleErrorMessage(this.shutdownReason, this.field_74439_g);
092                FMLNetworkHandler.onConnectionClosed(this, this.myNetHandler.getPlayer());
093            }
094        }
095    
096        /**
097         * Return the InetSocketAddress of the remote endpoint
098         */
099        public SocketAddress getSocketAddress()
100        {
101            return mySocketAddress;
102        }
103    
104        /**
105         * Shuts down the server. (Only actually used on the server)
106         */
107        public void serverShutdown()
108        {
109            this.shuttingDown = true;
110        }
111    
112        /**
113         * Shuts down the network with the specified reason. Closes all streams and sockets, spawns NetworkMasterThread to
114         * stop reading and writing threads.
115         */
116        public void networkShutdown(String par1Str, Object ... par2ArrayOfObj)
117        {
118            this.shuttingDown = true;
119            this.shutdownReason = par1Str;
120            this.field_74439_g = par2ArrayOfObj;
121        }
122    
123        /**
124         * returns 0 for memoryConnections
125         */
126        public int packetSize()
127        {
128            return 0;
129        }
130    
131        @SideOnly(Side.CLIENT)
132        public void pairWith(MemoryConnection par1MemoryConnection)
133        {
134            this.pairedConnection = par1MemoryConnection;
135            par1MemoryConnection.pairedConnection = this;
136        }
137    
138        @SideOnly(Side.CLIENT)
139        public boolean isGamePaused()
140        {
141            return this.gamePaused;
142        }
143    
144        @SideOnly(Side.CLIENT)
145        public void setGamePaused(boolean par1)
146        {
147            this.gamePaused = par1;
148        }
149    
150        @SideOnly(Side.CLIENT)
151        public MemoryConnection getPairedConnection()
152        {
153            return this.pairedConnection;
154        }
155    
156        /**
157         * acts immiditally if isWritePacket, otherwise adds it to the readCache to be processed next tick
158         */
159        public void processOrCachePacket(Packet par1Packet)
160        {
161            String var2 = this.myNetHandler.isServerHandler() ? ">" : "<";
162    
163            if (par1Packet.isWritePacket() && this.myNetHandler.canProcessPackets())
164            {
165                par1Packet.processPacket(this.myNetHandler);
166            }
167            else
168            {
169                this.readPacketCache.add(par1Packet);
170            }
171        }
172    }