Index: C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/config/telnet.properties===================================================================--- C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/config/telnet.properties (revision 0)+++ C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/config/telnet.properties (revision 0)@@ -0,0 +1,15 @@+#Telnet is disabled by default.+EnableTelnet = false++#This is the port telnet server will bind to+StatusPort = 12345++#If the following is not set, a random password is generated on server startup.+#StatusPW = somePass++#This list can contain IPs or Hosts of clients you wish to allow.+#Hosts must be resolvable to an IP.+#The format is as follows:+#ListOfHosts = 0.0.0.0,host,0.0.0.1,host2,host3,host4,0.0.0.3+#Make sure there are no spaces between hosts/ips+ListOfHosts = 127.0.0.1,localhostIndex: C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java===================================================================--- C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java (revision 0)+++ C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/status/Status.java (revision 0)@@ -0,0 +1,107 @@+package net.sf.l2j.status;++import java.io.IOException;+import java.io.InputStream;+import java.net.ServerSocket;+import java.net.Socket;+import java.util.Properties;+import java.util.Random;++import net.sf.l2j.Config;+++public class Status extends Thread+{++ private ServerSocket statusServerSocket;++ private int _uptime;+ private int _StatusPort;+ private String _StatusPW; ++ public void run()+ {+ while (true)+ {+ try+ {+ Socket connection = statusServerSocket.accept();++ new StatusThread(connection, _uptime, _StatusPW);+ if (this.isInterrupted())+ {+ try+ {+ statusServerSocket.close();+ }+ catch (IOException io) { io.printStackTrace(); }+ break;+ }+ }+ catch (IOException e)+ {+ if (this.isInterrupted())+ {+ try+ {+ statusServerSocket.close();+ }+ catch (IOException io) { io.printStackTrace(); }+ break;+ }+ }+ }+ }++ public Status() throws IOException+ {+ super("Status");+ Properties telnetSettings = new Properties();+ InputStream is = getClass().getResourceAsStream(Config.TELNET_FILE);+ telnetSettings.load(is);+ is.close();++ _StatusPort = Integer.parseInt(telnetSettings.getProperty("StatusPort", "25650"));+ _StatusPW = telnetSettings.getProperty("StatusPW");++ if (_StatusPW == null)+ {+ System.out.println("Server's Telnet Function Has No Password Defined!");+ System.out.println("A Password Has Been Automaticly Created!");+ _StatusPW = RndPW(10);+ System.out.println("Password Has Been Set To: " + _StatusPW);+ }+ statusServerSocket = new ServerSocket(_StatusPort);+ _uptime = (int) System.currentTimeMillis();+ System.out.println("StatusServer Started! - Listening on Port: " + _StatusPort);+ System.out.println("Password Has Been Set To: " + _StatusPW);+ }++++ private String RndPW(int length)+ {+ StringBuffer password = new StringBuffer();+ String lowerChar= "qwertyuiopasdfghjklzxcvbnm";+ String upperChar = "QWERTYUIOPASDFGHJKLZXCVBNM";+ String digits = "1234567890";+ Random randInt = new Random();+ for (int i = 0; i < length; i++)+ {+ int charSet = randInt.nextInt(3);+ switch (charSet)+ {+ case 0:+ password.append(lowerChar.charAt(randInt.nextInt(lowerChar.length()-1)));+ break;+ case 1:+ password.append(upperChar.charAt(randInt.nextInt(upperChar.length()-1)));+ break;+ case 2:+ password.append(digits.charAt(randInt.nextInt(digits.length()-1)));+ break;+ }+ }+ return password.toString();+ }+}Index: C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/status/StatusThread.java===================================================================--- C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/status/StatusThread.java (revision 0)+++ C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/status/StatusThread.java (revision 0)@@ -0,0 +1,345 @@+package net.sf.l2j.status;+++import java.io.IOException;++import java.io.InputStream;+import java.io.PrintWriter;+import java.io.BufferedReader;+import java.io.InputStreamReader;+++import java.net.InetAddress;+import java.net.Socket;+import java.text.SimpleDateFormat;+import java.util.Calendar;+import java.util.Hashtable;+import java.util.Properties;+import java.util.StringTokenizer;+++import net.sf.l2j.Config;+import net.sf.l2j.gameserver.Announcements;++import net.sf.l2j.gameserver.GmListTable;+import net.sf.l2j.gameserver.GameTimeController;+import net.sf.l2j.gameserver.Shutdown;+import net.sf.l2j.gameserver.serverpackets.CreatureSay;+import net.sf.l2j.gameserver.clientpackets.Say2;+import net.sf.l2j.gameserver.model.L2PcInstance;+import net.sf.l2j.gameserver.model.L2World;+import net.sf.l2j.loginserver.LoginController;+++public class StatusThread extends Thread+{++ private Socket _csocket;++ private PrintWriter _print;+ private BufferedReader _read;++ private int _uptime;++ private void telnetOutput(int type, String text) {+ if ( type == 1 ) System.out.println("TELNET | "+text);+ else if ( type == 2 ) System.out.print("TELNET | "+text);+ else if ( type == 3 ) System.out.print(text);+ else if ( type == 4 ) System.out.println(text);+ else System.out.println("TELNET | "+text);+ }++ private boolean isValidIP(Socket client) {+ boolean result = false; + InetAddress ClientIP = client.getInetAddress();++ // convert IP to String, and compare with list+ String clientStringIP = ClientIP.getHostAddress();++ telnetOutput(1, "Connection from: "+clientStringIP);++ // read and loop thru list of IPs, compare with newIP+ if ( Config.DEVELOPER ) telnetOutput(2, ""); ++ try {+ Properties telnetSettings = new Properties();+ InputStream telnetIS = getClass().getResourceAsStream(Config.TELNET_FILE);+ telnetSettings.load(telnetIS);+ telnetIS.close();++ String HostList = telnetSettings.getProperty("ListOfHosts", "127.0.0.1,localhost");++ if ( Config.DEVELOPER ) telnetOutput(3, "Comparing ip to list...");++ // compare+ String ipToCompare = null;+ for (String ip:HostList.split(",")) {+ if ( !result ) {+ ipToCompare = InetAddress.getByName(ip).getHostAddress();+ if ( clientStringIP.equals(ipToCompare) ) result = true;+ if ( Config.DEVELOPER ) telnetOutput(3, clientStringIP + " = " + ipToCompare + "("+ip+") = " + result);+ }+ } + }+ catch ( IOException e) {+ if ( Config.DEVELOPER ) telnetOutput(4, "");+ telnetOutput(1, "Error: "+e);+ }++ if ( Config.DEVELOPER ) telnetOutput(4, "Allow IP: "+result);+ return result;+ }++ public StatusThread(Socket client, int uptime, String StatusPW) throws IOException+ {+ _csocket = client;+ this._uptime = uptime;++ _print = new PrintWriter(_csocket.getOutputStream());+ _read = new BufferedReader(new InputStreamReader(_csocket.getInputStream()));++ if ( isValidIP(client) ) { + telnetOutput(1, client.getInetAddress().getHostAddress()+" accepted.");+ _print.println("Welcome To The L2J Telnet Session.");+ _print.println("Please Insert Your Password!");+ _print.print("Password: ");+ _print.flush();+ String tmpLine = _read.readLine();+ if ( tmpLine == null ) {+ _print.println("Error.");+ _print.println("Disconnected...");+ _print.flush();+ _csocket.close();+ }+ else {+ if (tmpLine.compareTo(StatusPW) != 0)+ {+ _print.println("Incorrect Password!");+ _print.println("Disconnected...");+ _print.flush();+ _csocket.close();+ }+ else+ {+ _print.println("Password Correct!");+ _print.println("[L2J]");+ _print.print("");+ _print.flush();+ start();+ }+ }+ }+ else {+ telnetOutput(1, "Connection attempt from "+ client.getInetAddress().getHostAddress() +" rejected.");+ _csocket.close();+ }+ }++ public void run()+ {+ String _usrCommand = "";+ try+ {+ while (_usrCommand.compareTo("quit") != 0)+ {+ _usrCommand = _read.readLine();+ if (_usrCommand.equals("help")) {+ _print.println("The following is a list of all available commands: ");+ _print.println("help - shows this help.");+ _print.println("status - displays basic server statistics.");+ _print.println("announce <text> - announces <text> in game.");+ _print.println("msg <nick> <text> - Sends a whisper to char <nick> with <text>.");+ _print.println("gmchat <text> - Sends a message to all GMs with <text>.");+ _print.println("gmlist - lists all gms online.");+ _print.println("shutdown <time> - shuts down server in <time> seconds.");+ _print.println("restart <time> - restarts down server in <time> seconds.");+ _print.println("abort - aborts shutdown/restart.");+ _print.println("quit - closes telnet session.");+ }+ else if (_usrCommand.equals("status"))+ {+ String _output = null;+ int playerCount = 0;+ int max = LoginController.getInstance().getMaxAllowedOnlinePlayers();++ L2PcInstance[] players = L2World.getInstance().getAllPlayers().toArray(new L2PcInstance[0]);+ for (int i = 0; i < players.length; i++) {+ L2PcInstance player = players[i];+ if (player.isOnline() == 1) playerCount++;+ }++ _print.println("Server Status: ");+ _print.println(" --> Player Count: " + playerCount + "/" + max); + _print.println(" --> Ingame Time: " + GameTime());+ _print.println(" --> Server Uptime: " + GetUptime(_uptime));+ _print.println(" --> GM Count: " + GetOnlineGMS());++ _print.println(_output);+ _print.flush();+ }+ else if (_usrCommand.startsWith("announce"))+ {+ try+ {+ _usrCommand = _usrCommand.substring(9);+ Announcements.getInstance().announceToAll(_usrCommand);+ _print.println("Announcement Sent!");+ }+ catch (StringIndexOutOfBoundsException e)+ {+ _print.println("Please Enter Some Text To Announce!");+ }+ }+ else if (_usrCommand.startsWith("msg"))+ {+ try+ {+ String val = _usrCommand.substring(4);+ StringTokenizer st = new StringTokenizer(val);+ String name = st.nextToken();+ String message = val.substring(name.length()+1);+ L2PcInstance reciever = L2World.getInstance().getPlayer(name);+ CreatureSay cs = new CreatureSay(0, Say2.TELL, "Telnet Priv", message);+ if(reciever != null)+ {+ reciever.sendPacket(cs);+ _print.println("Telnet Priv->" + name + ": " + message);+ _print.println("Message Sent!");+ }+ else+ {+ _print.println("Unable To Find Username: " + name);+ }+ }+ catch (StringIndexOutOfBoundsException e)+ {+ _print.println("Please Enter Some Text!");+ }+ }+ else if (_usrCommand.startsWith("gmchat"))+ {+ try+ {+ _usrCommand = _usrCommand.substring(7);+ CreatureSay cs = new CreatureSay(0, 9, "Telnet GM Broadcast from " + _csocket.getInetAddress().getHostAddress(), _usrCommand);+ GmListTable.getInstance().broadcastToGMs(cs);+ _print.println("Your Message Has Been Sent To " + GetOnlineGMS() + " GM(s).");+ }+ catch (StringIndexOutOfBoundsException e)+ {+ _print.println("Please Enter Some Text To Announce!");+ }+ }+ else if (_usrCommand.equals("gmlist"))+ {+ int igm = 0;+ String gmList = "";+ L2PcInstance[] players = L2World.getInstance().getAllPlayers().toArray(new L2PcInstance[0]);+ for (int i = 0; i < players.length; i++)+ {+ L2PcInstance player = players[i];+ if (player.isGM())+ {+ gmList = gmList + ", " + player.getName();+ igm++;+ }+ }+ _print.println("There are currently " + igm +" GM(s) online...");+ if ( gmList != "" ) _print.println(gmList);+ }+ else if (_usrCommand.startsWith("shutdown"))+ {+ try+ {+ int val = Integer.parseInt(_usrCommand.substring(9)); + Shutdown.getInstance().startTelnetShutdown(_csocket.getInetAddress().getHostAddress(), val, false);+ _print.println("Server Will Shutdown In " + val + " Seconds!");+ _print.println("Type \"abort\" To Abort Shutdown!");+ }+ catch (StringIndexOutOfBoundsException e)+ {+ _print.println("Please Enter * amount of seconds to shutdown!");+ }+ catch (Exception NumberFormatException) {+ _print.println("Numbers Only!");+ }+ }+ else if (_usrCommand.startsWith("restart"))+ {+ try+ {+ int val = Integer.parseInt(_usrCommand.substring(8)); + Shutdown.getInstance().startTelnetShutdown(_csocket.getInetAddress().getHostAddress(), val, true);+ _print.println("Server Will Restart In " + val + " Seconds!");+ _print.println("Type \"abort\" To Abort Restart!");+ }+ catch (StringIndexOutOfBoundsException e)+ {+ _print.println("Please Enter * amount of seconds to restart!");+ }+ catch (Exception NumberFormatException) {+ _print.println("Numbers Only!");+ }+ }+ else if (_usrCommand.startsWith("abort"))+ {+ Shutdown.getInstance().Telnetabort(_csocket.getInetAddress().getHostAddress());+ _print.println("OK! - Shutdown/Restart Aborted.");+ }+ else if (_usrCommand.equals("quit")) { /* Do Nothing :p - Just here to save us from the "Command Not Understood" Text */ }+ else if (_usrCommand.length() == 0) { /* Do Nothing Again - Same reason as the quit part */ }+ else+ {+ _print.println("Command Not Understood!");+ }+ _print.print("");+ _print.flush();+ }+ _print.println("Bye Bye!");+ _print.flush();+ _csocket.close();+ telnetOutput(1, "Connection from "+_csocket.getInetAddress().getHostAddress()+" was closed by client.");+ }+ catch (IOException e)+ {+ e.printStackTrace();+ }+ }++ private int GetOnlineGMS()+ {+ int igm = 0;+ L2PcInstance[] players = L2World.getInstance().getAllPlayers().toArray(new L2PcInstance[0]);+ for (int i = 0; i < players.length; i++)+ {+ L2PcInstance player = players[i];+ if (player.isGM())+ {+ igm++;+ }+ }+ return igm;+ }++ private String GetUptime(int _uptime)+ {+ int uptime = (int)System.currentTimeMillis()-_uptime;+ uptime = uptime/1000;+ int h = uptime/3600;+ int m = (uptime-(h*3600))/60;+ int s = ((uptime-(h*3600))-(m*60));+ return h + "hrs " + m + "mins " + s + "secs";+ }++ private String GameTime()+ {+ int t = GameTimeController.getInstance().getGameTime();+ int h = t/60;+ int m = t%60;+ SimpleDateFormat format = new SimpleDateFormat("H:mm");+ Calendar cal = Calendar.getInstance();+ cal.set(Calendar.HOUR_OF_DAY, h);+ cal.set(Calendar.MINUTE, m);+ return format.format(cal.getTime());+ }+}Index: C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/Config.java===================================================================--- C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/Config.java (revision 892)+++ C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/Config.java (working copy)@@ -187,6 +187,7 @@ public static final boolean USE_3D_MAP; public static final boolean SHOW_LEVEL_COMMUNITYBOARD;+ public static final String TELNET_FILE = "/config/telnet.properties"; public static final String CONFIGURATION_FILE = "/config/server.properties"; public static final String VERSION_FILE = "/config/l2j-version.properties"; public static final String SIEGE_CONFIGURATION_FILE = "/config/siege.properties";@@ -288,6 +289,9 @@ /** Deep Blue Mobs' Drop Rules Enabled */ public static final boolean DEEPBLUE_DROP_RULES;+ // telnet enabled+ public static final boolean IS_TELNET_ENABLED;+ static { try { Properties serverSettings = new Properties();@@ -511,6 +515,20 @@ SERVER_BUILD_DATE = "Undefined Date."; }+ // telnet+ try+ {+ Properties telnetSettings = new Properties();+ is = Config.class.getResourceAsStream(TELNET_FILE); + telnetSettings.load(is);+ is.close();++ IS_TELNET_ENABLED = Boolean.valueOf(telnetSettings.getProperty("EnableTelnet", "false"));+ }+ catch (Exception e) {+ e.printStackTrace();+ throw new Error("Failed to load telnet configuration");+ } } catch (Exception e) { e.printStackTrace();Index: C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/Server.java===================================================================--- C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/Server.java (revision 892)+++ C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/Server.java (working copy)@@ -20,10 +20,12 @@ import java.io.File; import java.io.InputStream;+import java.util.Properties; import java.util.logging.LogManager; import net.sf.l2j.gameserver.GameServer; import net.sf.l2j.loginserver.LoginServer;+import net.sf.l2j.status.Status; /** * This class ...@@ -41,6 +43,7 @@ // Global class instantiations. Used to actually ready the classes public static GameServer gameServer; public static LoginServer loginServer;+ public static Status statusServer; // Main Method public static void main(String[] args) throws Exception@@ -50,12 +53,7 @@ final String LOG_NAME = "/log.cfg"; // Name of log file final String CONF_LOC = "net.sf.l2j.Config"; // Location of configuration data- - /*** Main ***/--- // Create log folder File logFolder = new File(Config.DATAPACK_ROOT, LOG_FOLDER); logFolder.mkdir();@@ -73,6 +71,14 @@ gameServer = new GameServer(); loginServer = new LoginServer(); loginServer.start();-++ // run telnet server if enabled+ if ( Config.IS_TELNET_ENABLED ) {+ statusServer = new Status();+ statusServer.start();+ }+ else {+ System.out.println("Telnet server is currently disabled.");+ } } }Index: C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Shutdown.java===================================================================--- C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Shutdown.java (revision 892)+++ C:/Documents and Settings/Administrator/Desktop/eclipse/workspace/L2_GameServer/java/net/sf/l2j/gameserver/Shutdown.java (working copy)@@ -51,7 +51,43 @@ public static final int GM_RESTART = 2; public static final int ABORT = 3; private static String[] _modeText = {"SIGTERM", "shuting down", "restarting", "aborting"};++ /**+ * This function starts a shutdown countdown from Telnet (Copied from Function startShutdown())+ * + * @param ip IP Which Issued shutdown command+ * @param seconds seconds untill shutdown+ * @param restart true if the server will restart after shutdown+ */++ public void startTelnetShutdown(String IP, int seconds, boolean restart)+ {+ Announcements _an = Announcements.getInstance();+ _log.warning("IP: " + IP + " issued shutdown command. " + _modeText[shutdownMode] + " in "+seconds+ " seconds!");+ _an.announceToAll("Server is " + _modeText[shutdownMode] + " in "+seconds+ " seconds!");+ if (_counterInstance != null) {+ _counterInstance._abort();+ }+ _counterInstance = new Shutdown(seconds, restart);+ _counterInstance.start();+ }++ /**+ * This function aborts a running countdown+ * + * @param IP IP Which Issued shutdown command+ */+ public void Telnetabort(String IP) {+ Announcements _an = Announcements.getInstance();+ _log.warning("IP: " + IP + " issued shutdown ABORT. " + _modeText[shutdownMode] + " has been stopped!");+ _an.announceToAll("Server aborts " + _modeText[shutdownMode] + " and continues normal operation!");++ if (_counterInstance != null) {+ _counterInstance._abort();+ }+ }+ /** * Default constucter is only used internal to create the shutdown-hook instance *