    001    package net.minecraft.server;
    002
    003    import cpw.mods.fml.common.FMLLog;
    004    import cpw.mods.fml.relauncher.Side;
    005    import cpw.mods.fml.relauncher.SideOnly;
    006    import java.io.IOException;
    007    import java.net.InetAddress;
    008    import java.net.ServerSocket;
    009    import java.net.Socket;
    010    import java.util.ArrayList;
    011    import java.util.Collections;
    012    import java.util.HashMap;
    013    import java.util.List;
    014    import java.util.logging.Level;
    015    import java.util.logging.Logger;
    016    import net.minecraft.network.NetLoginHandler;
    017    import net.minecraft.network.NetworkListenThread;
    018
    019    public 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    }