    001    package net.minecraft.network.rcon;
    002
    003    import java.io.IOException;
    004    import java.net.InetAddress;
    005    import java.net.ServerSocket;
    006    import java.net.Socket;
    007    import java.net.SocketTimeoutException;
    008    import java.util.HashMap;
    009    import java.util.Iterator;
    010    import java.util.Map;
    011    import java.util.Map.Entry;
    012
    013    public 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.getSettingsFilePath() + "\', 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.getSettingsFilePath() + "\', rcon disabled!");
    151            }
    152        }
    153    }