/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package gcb; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.Iterator; import java.util.TimerTask; /** * * @author wizardus */ public class GCBRcon implements Runnable { public static int RCON_DEFAULTPORT = 7464; Main main; ServerSocket server; String password; boolean localOnly; public GCBRcon(Main main) throws IOException { this.main = main; localOnly = GCBConfig.configuration.getBoolean("rcon_localonly", true); password = GCBConfig.configuration.getString("rcon_password", ""); if(password.isEmpty()) { Main.println(1, "[GCBRcon] WARNING: rcon_password is empty, you won't be able to authenticate"); } new Thread(this).start(); } public void run() { String bind = GCBConfig.configuration.getString("rcon_bind", "0.0.0.0"); int port = GCBConfig.configuration.getInt("rcon_port", RCON_DEFAULTPORT); while(server == null) { try { Main.println(3, "[GCBRcon] Initializing on " + bind + ":" + port); server = new ServerSocket(); server.bind(new InetSocketAddress(bind, port)); } catch(IOException ioe) { Main.println(1, "[GCBRcon] Failed to bind; trying again in 10 seconds: " + ioe.getLocalizedMessage()); server = null; try { Thread.sleep(10000); } catch(InterruptedException ie) {} } } while(true) { try { Socket socket = server.accept(); Main.println(0, "[GCBRcon] New connection from " + socket.getInetAddress()); if(localOnly && !socket.getInetAddress().isAnyLocalAddress() && !socket.getInetAddress().isLoopbackAddress()) { Main.println(1, "[GCBRcon] Rejecting connection: not local"); socket.close(); continue; } new RconHandler(socket); } catch(IOException ioe) { Main.println(1, "[GCBRcon] Error while accepting new connection: " + ioe.getLocalizedMessage()); if(!server.isBound() || server.isClosed()) { Main.println(0, "[GCBRcon] Terminating: I am no longer bound!"); break; } try { Thread.sleep(1000); } catch(InterruptedException ie) {} } } } class RconHandler extends Thread { Socket socket; BufferedReader in; PrintWriter out; boolean authenticated; public RconHandler(Socket socket) throws IOException { this.socket = socket; in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); authenticated = false; start(); } public void run() { while(socket.isConnected()) { String str = null; try { str = in.readLine(); } catch(IOException ioe) { Main.println(1, "[GCBRcon " + socket.getInetAddress() + "] Error while reading: " + ioe.getLocalizedMessage() + "; terminating"); } if(str == null) { break; } str = str.trim(); if(str.isEmpty()) { continue; } else if(!authenticated) { if(str.equals(password)) { authenticated = true; Main.println(0, "[GCBRcon " + socket.getInetAddress() + "] authentication succeeded"); continue; } else { out.println("gtfo"); Main.println(0, "[GCBRcon " + socket.getInetAddress() + "] authentication failed"); break; } } str = str.toLowerCase(); Main.println(0, "[GCBRcon " + socket.getInetAddress() + "] received command: " + str); String[] parts = str.split(" "); String command = parts[0]; if(command.equals("exit")) { if(parts.length >= 2 && (parts[1].equals("nice") || parts[1].equals("nicely"))) { //first tell all of the connections to exit nicely synchronized(main.garenaConnections) { Iterator<GarenaInterface> it = main.garenaConnections.values().iterator(); while(it.hasNext()) { it.next().exitNicely(); } } if(main.tcpPool != null) { main.tcpPool.exitNicely(); } if(main.wc3i != null) { main.wc3i.exitNicely(); } //wait for them to actually do so, then terminate synchronized(Main.TIMER) { Main.TIMER.schedule(new ExitTask(), 1000, 5000); } try { server.close(); } catch(IOException ioe) { Main.println(1, "Failed to shut down rcon port."); } out.println("Connections set to exit nicely."); Main.println(0, "Connections set to exit nicely."); } else { out.println("Good night."); System.exit(0); } } } try { socket.close(); } catch(IOException ioe) {} } } class ExitTask extends TimerTask { public void run() { if(main.tcpPool.count() == 0) { System.exit(0); } } } }