001package net.minecraft.network;
002
003import cpw.mods.fml.common.network.FMLNetworkHandler;
004import cpw.mods.fml.relauncher.Side;
005import cpw.mods.fml.relauncher.SideOnly;
006import java.io.IOException;
007import java.net.InetSocketAddress;
008import java.net.SocketAddress;
009import java.util.ArrayList;
010import java.util.Collections;
011import java.util.List;
012import net.minecraft.network.packet.NetHandler;
013import net.minecraft.network.packet.Packet;
014
015public 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}