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