package net.minecraft.network.rcon;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class RConThreadMain extends RConThreadBase
{
/** Port RCon is running on */
private int rconPort;
/** Port the server is running on */
private int serverPort;
/** Hostname RCon is running on */
private String hostname;
/** The RCon ServerSocket. */
private ServerSocket serverSocket = null;
/** The RCon password */
private String rconPassword;
/** A map of client addresses to their running Threads */
private Map clientThreads;
public RConThreadMain(IServer par1IServer)
{
super(par1IServer);
this.rconPort = par1IServer.getIntProperty("rcon.port", 0);
this.rconPassword = par1IServer.getStringProperty("rcon.password", "");
this.hostname = par1IServer.getHostname();
this.serverPort = par1IServer.getPort();
if (0 == this.rconPort)
{
this.rconPort = this.serverPort + 10;
this.logInfo("Setting default rcon port to " + this.rconPort);
par1IServer.setProperty("rcon.port", Integer.valueOf(this.rconPort));
if (0 == this.rconPassword.length())
{
par1IServer.setProperty("rcon.password", "");
}
par1IServer.saveProperties();
}
if (0 == this.hostname.length())
{
this.hostname = "0.0.0.0";
}
this.initClientThreadList();
this.serverSocket = null;
}
private void initClientThreadList()
{
this.clientThreads = new HashMap();
}
/**
* Cleans up the clientThreads map by removing client Threads that are not running
*/
private void cleanClientThreadsMap()
{
Iterator iterator = this.clientThreads.entrySet().iterator();
while (iterator.hasNext())
{
Entry entry = (Entry)iterator.next();
if (!((RConThreadClient)entry.getValue()).isRunning())
{
iterator.remove();
}
}
}
public void run()
{
this.logInfo("RCON running on " + this.hostname + ":" + this.rconPort);
try
{
while (this.running)
{
try
{
Socket socket = this.serverSocket.accept();
socket.setSoTimeout(500);
RConThreadClient rconthreadclient = new RConThreadClient(this.server, socket);
rconthreadclient.startThread();
this.clientThreads.put(socket.getRemoteSocketAddress(), rconthreadclient);
this.cleanClientThreadsMap();
}
catch (SocketTimeoutException sockettimeoutexception)
{
this.cleanClientThreadsMap();
}
catch (IOException ioexception)
{
if (this.running)
{
this.logInfo("IO: " + ioexception.getMessage());
}
}
}
}
finally
{
this.closeServerSocket(this.serverSocket);
}
}
/**
* Creates a new Thread object from this class and starts running
*/
public void startThread()
{
if (0 == this.rconPassword.length())
{
this.logWarning("No rcon password set in \'" + this.server.getSettingsFilename() + "\', rcon disabled!");
}
else if (0 < this.rconPort && 65535 >= this.rconPort)
{
if (!this.running)
{
try
{
this.serverSocket = new ServerSocket(this.rconPort, 0, InetAddress.getByName(this.hostname));
this.serverSocket.setSoTimeout(500);
super.startThread();
}
catch (IOException ioexception)
{
this.logWarning("Unable to initialise rcon on " + this.hostname + ":" + this.rconPort + " : " + ioexception.getMessage());
}
}
}
else
{
this.logWarning("Invalid rcon port " + this.rconPort + " found in \'" + this.server.getSettingsFilename() + "\', rcon disabled!");
}
}
}