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