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;
015
016import net.minecraft.network.NetLoginHandler;
017import net.minecraft.network.NetworkListenThread;
018
019public class ServerListenThread extends Thread
020{
021    private final List pendingConnections = Collections.synchronizedList(new ArrayList());
022
023    /**
024     * This map stores a list of InetAddresses and the last time which they connected at
025     */
026    private final HashMap recentConnections = new HashMap();
027    private int connectionCounter = 0;
028    private final ServerSocket myServerSocket;
029    private NetworkListenThread myNetworkListenThread;
030    private final InetAddress myServerAddress;
031    private final int myPort;
032
033    public ServerListenThread(NetworkListenThread par1NetworkListenThread, InetAddress par2InetAddress, int par3) throws IOException
034    {
035        super("Listen thread");
036        this.myNetworkListenThread = par1NetworkListenThread;
037        this.myPort = par3;
038        this.myServerSocket = new ServerSocket(par3, 0, par2InetAddress);
039        this.myServerAddress = par2InetAddress == null ? this.myServerSocket.getInetAddress() : par2InetAddress;
040        this.myServerSocket.setPerformancePreferences(0, 2, 1);
041    }
042
043    public void processPendingConnections()
044    {
045        List list = this.pendingConnections;
046
047        synchronized (this.pendingConnections)
048        {
049            for (int i = 0; i < this.pendingConnections.size(); ++i)
050            {
051                NetLoginHandler netloginhandler = (NetLoginHandler)this.pendingConnections.get(i);
052
053                try
054                {
055                    netloginhandler.tryLogin();
056                }
057                catch (Exception exception)
058                {
059                    netloginhandler.raiseErrorAndDisconnect("Internal server error");
060                    FMLLog.log(Level.SEVERE, exception, "Error handling login related packet - connection from %s refused", netloginhandler.getUsernameAndAddress());
061                    this.myNetworkListenThread.getServer().getLogAgent().func_98235_b("Failed to handle packet for " + netloginhandler.getUsernameAndAddress() + ": " + exception, exception);
062                }
063
064                if (netloginhandler.connectionComplete)
065                {
066                    this.pendingConnections.remove(i--);
067                }
068
069                netloginhandler.myTCPConnection.wakeThreads();
070            }
071        }
072    }
073
074    public void run()
075    {
076        while (this.myNetworkListenThread.isListening)
077        {
078            try
079            {
080                Socket socket = this.myServerSocket.accept();
081                NetLoginHandler netloginhandler = new NetLoginHandler(this.myNetworkListenThread.getServer(), socket, "Connection #" + this.connectionCounter++);
082                this.addPendingConnection(netloginhandler);
083            }
084            catch (IOException ioexception)
085            {
086                ioexception.printStackTrace();
087            }
088        }
089
090        this.myNetworkListenThread.getServer().getLogAgent().logInfo("Closing listening thread");
091    }
092
093    private void addPendingConnection(NetLoginHandler par1NetLoginHandler)
094    {
095        if (par1NetLoginHandler == null)
096        {
097            throw new IllegalArgumentException("Got null pendingconnection!");
098        }
099        else
100        {
101            List list = this.pendingConnections;
102
103            synchronized (this.pendingConnections)
104            {
105                this.pendingConnections.add(par1NetLoginHandler);
106            }
107        }
108    }
109
110    public void func_71769_a(InetAddress par1InetAddress)
111    {
112        if (par1InetAddress != null)
113        {
114            HashMap hashmap = this.recentConnections;
115
116            synchronized (this.recentConnections)
117            {
118                this.recentConnections.remove(par1InetAddress);
119            }
120        }
121    }
122
123    public void func_71768_b()
124    {
125        try
126        {
127            this.myServerSocket.close();
128        }
129        catch (Throwable throwable)
130        {
131            ;
132        }
133    }
134
135    @SideOnly(Side.CLIENT)
136    public InetAddress getInetAddress()
137    {
138        return this.myServerAddress;
139    }
140
141    @SideOnly(Side.CLIENT)
142    public int getMyPort()
143    {
144        return this.myPort;
145    }
146}