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