    001package net.minecraft.server;
    002
    003import cpw.mods.fml.common.FMLLog;
    004import cpw.mods.fml.relauncher.Side;
    005import cpw.mods.fml.relauncher.SideOnly;
    006import java.io.IOException;
    007import java.net.InetAddress;
    008import java.net.ServerSocket;
    009import java.net.Socket;
    010import java.util.ArrayList;
    011import java.util.Collections;
    012import java.util.HashMap;
    013import java.util.List;
    014import java.util.logging.Level;
    015
    016import net.minecraft.network.NetLoginHandler;
    017import net.minecraft.network.NetworkListenThread;
    018
    019public class ServerListenThread extends Thread
    020{
    021    private final List pendingConnections = Collections.synchronizedList(new ArrayList());
    022
    023    /**
    024     * This map stores a list of InetAddresses and the last time which they connected at
    025     */
    026    private final HashMap recentConnections = new HashMap();
    027    private int connectionCounter = 0;
    028    private final ServerSocket myServerSocket;
    029    private NetworkListenThread myNetworkListenThread;
    030    private final InetAddress myServerAddress;
    031    private final int myPort;
    032
    033    public ServerListenThread(NetworkListenThread par1NetworkListenThread, InetAddress par2InetAddress, int par3) throws IOException
    034    {
    035        super("Listen thread");
    036        this.myNetworkListenThread = par1NetworkListenThread;
    037        this.myPort = par3;
    038        this.myServerSocket = new ServerSocket(par3, 0, par2InetAddress);
    039        this.myServerAddress = par2InetAddress == null ? this.myServerSocket.getInetAddress() : par2InetAddress;
    040        this.myServerSocket.setPerformancePreferences(0, 2, 1);
    041    }
    042
    043    public void processPendingConnections()
    044    {
    045        List list = this.pendingConnections;
    046
    047        synchronized (this.pendingConnections)
    048        {
    049            for (int i = 0; i < this.pendingConnections.size(); ++i)
    050            {
    051                NetLoginHandler netloginhandler = (NetLoginHandler)this.pendingConnections.get(i);
    052
    053                try
    054                {
    055                    netloginhandler.tryLogin();
    056                }
    057                catch (Exception exception)
    058                {
    059                    netloginhandler.raiseErrorAndDisconnect("Internal server error");
    060                    FMLLog.log(Level.SEVERE, exception, "Error handling login related packet - connection from %s refused", netloginhandler.getUsernameAndAddress());
    061                    this.myNetworkListenThread.getServer().func_98033_al().func_98235_b("Failed to handle packet for " + netloginhandler.getUsernameAndAddress() + ": " + exception, exception);
    062                }
    063
    064                if (netloginhandler.connectionComplete)
    065                {
    066                    this.pendingConnections.remove(i--);
    067                }
    068
    069                netloginhandler.myTCPConnection.wakeThreads();
    070            }
    071        }
    072    }
    073
    074    public void run()
    075    {
    076        while (this.myNetworkListenThread.isListening)
    077        {
    078            try
    079            {
    080                Socket socket = this.myServerSocket.accept();
    081                InetAddress inetaddress = socket.getInetAddress();
    082                long i = System.currentTimeMillis();
    083                HashMap hashmap = this.recentConnections;
    084
    085                synchronized (this.recentConnections)
    086                {
    087                    if (this.recentConnections.containsKey(inetaddress) && !isLocalHost(inetaddress) && i - ((Long)this.recentConnections.get(inetaddress)).longValue() < 4000L)
    088                    {
    089                        this.recentConnections.put(inetaddress, Long.valueOf(i));
    090                        socket.close();
    091                        continue;
    092                    }
    093
    094                    this.recentConnections.put(inetaddress, Long.valueOf(i));
    095                }
    096
    097                NetLoginHandler netloginhandler = new NetLoginHandler(this.myNetworkListenThread.getServer(), socket, "Connection #" + this.connectionCounter++);
    098                this.addPendingConnection(netloginhandler);
    099            }
    100            catch (IOException ioexception)
    101            {
    102                ioexception.printStackTrace();
    103            }
    104        }
    105
    106        this.myNetworkListenThread.getServer().func_98033_al().func_98233_a("Closing listening thread");
    107    }
    108
    109    private void addPendingConnection(NetLoginHandler par1NetLoginHandler)
    110    {
    111        if (par1NetLoginHandler == null)
    112        {
    113            throw new IllegalArgumentException("Got null pendingconnection!");
    114        }
    115        else
    116        {
    117            List list = this.pendingConnections;
    118
    119            synchronized (this.pendingConnections)
    120            {
    121                this.pendingConnections.add(par1NetLoginHandler);
    122            }
    123        }
    124    }
    125
    126    private static boolean isLocalHost(InetAddress par0InetAddress)
    127    {
    128        return "127.0.0.1".equals(par0InetAddress.getHostAddress());
    129    }
    130
    131    public void func_71769_a(InetAddress par1InetAddress)
    132    {
    133        if (par1InetAddress != null)
    134        {
    135            HashMap hashmap = this.recentConnections;
    136
    137            synchronized (this.recentConnections)
    138            {
    139                this.recentConnections.remove(par1InetAddress);
    140            }
    141        }
    142    }
    143
    144    public void func_71768_b()
    145    {
    146        try
    147        {
    148            this.myServerSocket.close();
    149        }
    150        catch (Throwable throwable)
    151        {
    152            ;
    153        }
    154    }
    155
    156    @SideOnly(Side.CLIENT)
    157    public InetAddress getInetAddress()
    158    {
    159        return this.myServerAddress;
    160    }
    161
    162    @SideOnly(Side.CLIENT)
    163    public int getMyPort()
    164    {
    165        return this.myPort;
    166    }
    167}