    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}