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.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    }