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}