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