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