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