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    }