001package net.minecraft.network.rcon;
002
003import java.io.IOException;
004import java.net.InetAddress;
005import java.net.ServerSocket;
006import java.net.Socket;
007import java.net.SocketTimeoutException;
008import java.util.HashMap;
009import java.util.Iterator;
010import java.util.Map;
011import java.util.Map.Entry;
012
013public class RConThreadMain extends RConThreadBase
014{
015    /** Port RCon is running on */
016    private int rconPort;
017
018    /** Port the server is running on */
019    private int serverPort;
020
021    /** Hostname RCon is running on */
022    private String hostname;
023
024    /** The RCon ServerSocket. */
025    private ServerSocket serverSocket = null;
026
027    /** The RCon password */
028    private String rconPassword;
029
030    /** A map of client addresses to their running Threads */
031    private Map clientThreads;
032
033    public RConThreadMain(IServer par1IServer)
034    {
035        super(par1IServer);
036        this.rconPort = par1IServer.getIntProperty("rcon.port", 0);
037        this.rconPassword = par1IServer.getStringProperty("rcon.password", "");
038        this.hostname = par1IServer.getHostname();
039        this.serverPort = par1IServer.getPort();
040
041        if (0 == this.rconPort)
042        {
043            this.rconPort = this.serverPort + 10;
044            this.logInfo("Setting default rcon port to " + this.rconPort);
045            par1IServer.setProperty("rcon.port", Integer.valueOf(this.rconPort));
046
047            if (0 == this.rconPassword.length())
048            {
049                par1IServer.setProperty("rcon.password", "");
050            }
051
052            par1IServer.saveProperties();
053        }
054
055        if (0 == this.hostname.length())
056        {
057            this.hostname = "0.0.0.0";
058        }
059
060        this.initClientThreadList();
061        this.serverSocket = null;
062    }
063
064    private void initClientThreadList()
065    {
066        this.clientThreads = new HashMap();
067    }
068
069    /**
070     * Cleans up the clientThreads map by removing client Threads that are not running
071     */
072    private void cleanClientThreadsMap()
073    {
074        Iterator var1 = this.clientThreads.entrySet().iterator();
075
076        while (var1.hasNext())
077        {
078            Entry var2 = (Entry)var1.next();
079
080            if (!((RConThreadClient)var2.getValue()).isRunning())
081            {
082                var1.remove();
083            }
084        }
085    }
086
087    public void run()
088    {
089        this.logInfo("RCON running on " + this.hostname + ":" + this.rconPort);
090
091        try
092        {
093            while (this.running)
094            {
095                try
096                {
097                    Socket var1 = this.serverSocket.accept();
098                    var1.setSoTimeout(500);
099                    RConThreadClient var2 = new RConThreadClient(this.server, var1);
100                    var2.startThread();
101                    this.clientThreads.put(var1.getRemoteSocketAddress(), var2);
102                    this.cleanClientThreadsMap();
103                }
104                catch (SocketTimeoutException var7)
105                {
106                    this.cleanClientThreadsMap();
107                }
108                catch (IOException var8)
109                {
110                    if (this.running)
111                    {
112                        this.logInfo("IO: " + var8.getMessage());
113                    }
114                }
115            }
116        }
117        finally
118        {
119            this.closeServerSocket(this.serverSocket);
120        }
121    }
122
123    /**
124     * Creates a new Thread object from this class and starts running
125     */
126    public void startThread()
127    {
128        if (0 == this.rconPassword.length())
129        {
130            this.logWarning("No rcon password set in \'" + this.server.getSettingsFilename() + "\', rcon disabled!");
131        }
132        else if (0 < this.rconPort && 65535 >= this.rconPort)
133        {
134            if (!this.running)
135            {
136                try
137                {
138                    this.serverSocket = new ServerSocket(this.rconPort, 0, InetAddress.getByName(this.hostname));
139                    this.serverSocket.setSoTimeout(500);
140                    super.startThread();
141                }
142                catch (IOException var2)
143                {
144                    this.logWarning("Unable to initialise rcon on " + this.hostname + ":" + this.rconPort + " : " + var2.getMessage());
145                }
146            }
147        }
148        else
149        {
150            this.logWarning("Invalid rcon port " + this.rconPort + " found in \'" + this.server.getSettingsFilename() + "\', rcon disabled!");
151        }
152    }
153}