diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/commons/util/Util.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/commons/util/Util.java index b26d9d32be..9acfa8d77e 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/commons/util/Util.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/commons/util/Util.java @@ -152,4 +152,25 @@ public class Util t.printStackTrace(new PrintWriter(sw)); return sw.toString(); } + + /** + * Method to generate a random sequence of bytes returned as byte array + * @param size number of random bytes to generate + * @return byte array with sequence of random bytes + */ + public static byte[] generateHex(int size) + { + final byte[] array = new byte[size]; + Rnd.nextBytes(array); + + // Don't allow 0s inside the array! + for (int i = 0; i < array.length; i++) + { + while (array[i] == 0) + { + array[i] = (byte) Rnd.get(Byte.MAX_VALUE); + } + } + return array; + } } diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/tools/gsregistering/BaseGameServerRegister.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/tools/gsregistering/BaseGameServerRegister.java new file mode 100644 index 0000000000..ac8c32a20e --- /dev/null +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/tools/gsregistering/BaseGameServerRegister.java @@ -0,0 +1,239 @@ +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.tools.gsregistering; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.math.BigInteger; +import java.security.GeneralSecurityException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.ResourceBundle; + +import com.l2jmobius.Config; +import com.l2jmobius.Server; +import com.l2jmobius.commons.database.DatabaseFactory; +import com.l2jmobius.commons.util.Util; +import com.l2jmobius.loginserver.GameServerTable; + +/** + * The Class BaseGameServerRegister. + * @author KenM + */ +public abstract class BaseGameServerRegister +{ + private boolean _loaded = false; + + /** + * The main method. + * @param args the arguments + */ + public static void main(String[] args) + { + final GameServerRegister cmdUi = new GameServerRegister(); + try + { + cmdUi.consoleUI(); + } + catch (IOException e) + { + cmdUi.showError("I/O exception trying to get input from keyboard.", e); + } + } + + /** + * Load. + */ + public void load() + { + Server.serverMode = Server.MODE_LOGINSERVER; + + Config.load(); + GameServerTable.getInstance(); + try + { + GameServerTable.load(); + } + catch (GeneralSecurityException e) + { + e.printStackTrace(); + } + + _loaded = true; + } + + /** + * Checks if is loaded. + * @return true, if is loaded + */ + public boolean isLoaded() + { + return _loaded; + } + + /** + * Show the error. + * @param msg the msg. + * @param t the t. + */ + public abstract void showError(String msg, Throwable t); + + /** + * Unregister the game server. + * @param id the game server id. + * @throws SQLException the SQL exception. + */ + public static void unregisterGameServer(int id) throws SQLException + { + try (Connection con = DatabaseFactory.getInstance().getConnection(); + PreparedStatement ps = con.prepareStatement("DELETE FROM gameservers WHERE server_id = ?")) + + { + ps.setInt(1, id); + ps.executeUpdate(); + } + GameServerTable.getInstance().getRegisteredGameServers().remove(id); + } + + /** + * Unregister all game servers. + * @throws SQLException the SQL exception + */ + public static void unregisterAllGameServers() throws SQLException + { + try (Connection con = DatabaseFactory.getInstance().getConnection(); + Statement s = con.createStatement()) + { + s.executeUpdate("DELETE FROM gameservers"); + } + GameServerTable.getInstance().getRegisteredGameServers().clear(); + } + + /** + * Register a game server. + * @param id the id of the game server. + * @param outDir the out dir. + * @throws IOException Signals that an I/O exception has occurred. + */ + public static void registerGameServer(int id, String outDir) throws IOException + { + final byte[] hexId = Util.generateHex(16); + GameServerTable.getInstance().registerServerOnDB(hexId, id, ""); + + final Properties hexSetting = new Properties(); + final File file = new File(outDir, "hexid.txt"); + // Create a new empty file only if it doesn't exist + file.createNewFile(); + try (OutputStream out = new FileOutputStream(file)) + { + hexSetting.setProperty("ServerID", String.valueOf(id)); + hexSetting.setProperty("HexID", new BigInteger(hexId).toString(16)); + hexSetting.store(out, "The HexId to Auth into LoginServer"); + } + } + + /** + * Register first available. + * @param outDir the out dir + * @return the int + * @throws IOException Signals that an I/O exception has occurred. + */ + public static int registerFirstAvailable(String outDir) throws IOException + { + for (Entry e : GameServerTable.getInstance().getServerNames().entrySet()) + { + if (!GameServerTable.getInstance().hasRegisteredGameServerOnId(e.getKey())) + { + BaseGameServerRegister.registerGameServer(e.getKey(), outDir); + return e.getKey(); + } + } + return -1; + } + + /** + * The Class BaseTask. + */ + protected static abstract class BaseTask implements Runnable + { + private ResourceBundle _bundle; + + /** + * Sets the bundle. + * @param bundle The bundle to set. + */ + public void setBundle(ResourceBundle bundle) + { + _bundle = bundle; + } + + /** + * Gets the bundle. + * @return Returns the bundle. + */ + public ResourceBundle getBundle() + { + return _bundle; + } + + /** + * Show the error. + * @param msg the msg + * @param t the t + */ + public void showError(String msg, Throwable t) + { + String title; + if (getBundle() != null) + { + title = getBundle().getString("error"); + msg += Config.EOL + getBundle().getString("reason") + ' ' + t.getLocalizedMessage(); + } + else + { + title = "Error"; + msg += Config.EOL + "Cause: " + t.getLocalizedMessage(); + } + System.out.println(title + ": " + msg); + } + } + + /** + * The Class UnregisterAllTask. + */ + protected static class UnregisterAllTask extends BaseTask + { + @Override + public void run() + { + try + { + BaseGameServerRegister.unregisterAllGameServers(); + } + catch (SQLException e) + { + showError(getBundle().getString("sqlErrorUnregisterAll"), e); + } + } + } +} diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/tools/gsregistering/GameServerRegister.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/tools/gsregistering/GameServerRegister.java index 0ccb2a8613..ed7e99bbf2 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/tools/gsregistering/GameServerRegister.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/tools/gsregistering/GameServerRegister.java @@ -1,152 +1,327 @@ -/* - * This file is part of the L2J Mobius project. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.l2jmobius.tools.gsregistering; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.LineNumberReader; -import java.math.BigInteger; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Map; -import java.util.logging.Logger; - -import com.l2jmobius.Config; -import com.l2jmobius.Server; -import com.l2jmobius.commons.database.DatabaseFactory; -import com.l2jmobius.gameserver.thread.LoginServerThread; -import com.l2jmobius.loginserver.GameServerTable; - -public class GameServerRegister -{ - private static final Logger LOGGER = Logger.getLogger(GameServerRegister.class.getName()); - private static String _choice; - private static boolean _choiceOk; - - public static void main(String[] args) throws IOException - { - Server.serverMode = Server.MODE_LOGINSERVER; - Config.load(); - final LineNumberReader _in = new LineNumberReader(new InputStreamReader(System.in)); - try - { - GameServerTable.load(); - } - catch (Exception e) - { - LOGGER.info("FATAL: Failed loading GameServerTable. Reason: " + e.getMessage()); - e.printStackTrace(); - System.exit(1); - } - final GameServerTable gameServerTable = GameServerTable.getInstance(); - LOGGER.info("Welcome to L2JMobius GameServer Registering"); - LOGGER.info("Enter The id of the server you want to register"); - LOGGER.info("Type 'help' to get a list of ids."); - LOGGER.info("Type 'clean' to unregister all currently registered gameservers on this LoginServer."); - while (!_choiceOk) - { - LOGGER.info("Your choice:"); - _choice = _in.readLine(); - if (_choice.equalsIgnoreCase("help")) - { - for (Map.Entry entry : gameServerTable.getServerNames().entrySet()) - { - LOGGER.info("Server: ID: " + entry.getKey() + "\t- " + entry.getValue() + " - In Use: " + (gameServerTable.hasRegisteredGameServerOnId(entry.getKey()) ? "YES" : "NO")); - } - LOGGER.info("You can also see servername.xml"); - } - else if (_choice.equalsIgnoreCase("clean")) - { - System.out.print("This is going to UNREGISTER ALL servers from this LoginServer. Are you sure? (y/n) "); - _choice = _in.readLine(); - if (_choice.equals("y")) - { - GameServerRegister.cleanRegisteredGameServersFromDB(); - gameServerTable.getRegisteredGameServers().clear(); - } - else - { - LOGGER.info("ABORTED"); - } - } - else - { - try - { - final int id = Integer.parseInt(_choice); - final int size = gameServerTable.getServerNames().size(); - if (size == 0) - { - LOGGER.info("No server names avalible, please make sure that servername.xml is in the LoginServer directory."); - System.exit(1); - } - - _choice = ""; - - while (!_choice.equalsIgnoreCase("")) - { - LOGGER.info("External Server Ip:"); - _choice = _in.readLine(); - } - - final String ip = _choice; - - final String name = gameServerTable.getServerNameById(id); - if (name == null) - { - LOGGER.info("No name for id: " + id); - continue; - } - - if (gameServerTable.hasRegisteredGameServerOnId(id)) - { - LOGGER.info("This id is not free"); - } - else - { - final byte[] hexId = LoginServerThread.generateHex(16); - gameServerTable.registerServerOnDB(hexId, id, ip); - Config.saveHexid(id, new BigInteger(hexId).toString(16), "hexid.txt"); - LOGGER.info("Server Registered hexid saved to 'hexid.txt'"); - LOGGER.info("Put this file in the /config folder of your gameserver."); - return; - } - } - catch (NumberFormatException nfe) - { - LOGGER.info("Please, type a number or 'help'"); - } - } - } - } - - public static void cleanRegisteredGameServersFromDB() - { - PreparedStatement statement = null; - try (Connection con = DatabaseFactory.getInstance().getConnection()) - { - statement = con.prepareStatement("DELETE FROM gameservers"); - statement.executeUpdate(); - statement.close(); - } - catch (SQLException e) - { - LOGGER.info("SQL error while cleaning registered servers: " + e); - } - } +/* + * This file is part of the L2J Mobius project. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.l2jmobius.tools.gsregistering; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.sql.SQLException; +import java.util.Map.Entry; + +import com.l2jmobius.Config; +import com.l2jmobius.loginserver.GameServerTable; + +public class GameServerRegister extends BaseGameServerRegister +{ + private LineNumberReader _in; + + public static void main(String[] args) + { + // Backwards compatibility, redirect to the new one + BaseGameServerRegister.main(args); + } + + public GameServerRegister() + { + super(); + load(); + + if (GameServerTable.getInstance().getServerNames().size() == 0) + { + System.out.println("No available names for GameServer, verify servername.xml file exists in the LoginServer folder."); + System.exit(1); + } + } + + public void consoleUI() throws IOException + { + _in = new LineNumberReader(new InputStreamReader(System.in)); + boolean choiceOk = false; + String choice; + + while (true) + { + hr(); + System.out.println("GSRegister"); + System.out.println(Config.EOL); + System.out.println("1 - Register GameServer"); + System.out.println("2 - List GameServers Names and IDs"); + System.out.println("3 - Remove GameServer"); + System.out.println("4 - Remove ALL GameServers"); + System.out.println("5 - Exit"); + + do + { + System.out.print("Choice: "); + choice = _in.readLine(); + try + { + final int choiceNumber = Integer.parseInt(choice); + choiceOk = true; + + switch (choiceNumber) + { + case 1: + { + registerNewGS(); + break; + } + case 2: + { + listGSNames(); + break; + } + case 3: + { + unregisterSingleGS(); + break; + } + case 4: + { + unregisterAllGS(); + break; + } + case 5: + { + System.exit(0); + break; + } + default: + { + System.out.printf("Invalid Choice: %s" + Config.EOL, choice); + choiceOk = false; + } + } + } + catch (NumberFormatException nfe) + { + System.out.printf("Invalid Choice: %s" + Config.EOL, choice); + } + } + while (!choiceOk); + } + } + + /** + * + */ + private void hr() + { + System.out.println("_____________________________________________________" + Config.EOL); + } + + /** + * + */ + private void listGSNames() + { + int idMaxLen = 0; + int nameMaxLen = 0; + for (Entry e : GameServerTable.getInstance().getServerNames().entrySet()) + { + if (e.getKey().toString().length() > idMaxLen) + { + idMaxLen = e.getKey().toString().length(); + } + if (e.getValue().length() > nameMaxLen) + { + nameMaxLen = e.getValue().length(); + } + } + idMaxLen += 2; + nameMaxLen += 2; + + String id; + boolean inUse; + final String gsInUse = "In Use"; + final String gsFree = "Free"; + final int gsStatusMaxLen = Math.max(gsInUse.length(), gsFree.length()) + 2; + for (Entry e : GameServerTable.getInstance().getServerNames().entrySet()) + { + id = e.getKey().toString(); + System.out.print(id); + + for (int i = id.length(); i < idMaxLen; i++) + { + System.out.print(' '); + } + System.out.print("| "); + + System.out.print(e.getValue()); + + for (int i = e.getValue().length(); i < nameMaxLen; i++) + { + System.out.print(' '); + } + System.out.print("| "); + + inUse = GameServerTable.getInstance().hasRegisteredGameServerOnId(e.getKey()); + final String inUseStr = inUse ? gsInUse : gsFree; + System.out.print(inUseStr); + + for (int i = inUseStr.length(); i < gsStatusMaxLen; i++) + { + System.out.print(' '); + } + System.out.println('|'); + } + } + + /** + * @throws IOException + */ + private void unregisterAllGS() throws IOException + { + if (yesNoQuestion("Are you sure you want to remove ALL GameServers?")) + { + try + { + BaseGameServerRegister.unregisterAllGameServers(); + System.out.println("All GameServers were successfully removed."); + } + catch (SQLException e) + { + showError("An SQL error occurred while trying to remove ALL GameServers.", e); + } + } + } + + private boolean yesNoQuestion(String question) throws IOException + { + do + { + hr(); + System.out.println(question); + System.out.println("1 - Yes"); + System.out.println("2 - No"); + System.out.print("Choice: "); + String choice; + choice = _in.readLine(); + if (choice != null) + { + if (choice.equals("1")) + { + return true; + } + else if (choice.equals("2")) + { + return false; + } + else + { + System.out.printf("Invalid Choice: %s" + Config.EOL, choice); + } + } + } + while (true); + } + + /** + * @throws IOException + */ + private void unregisterSingleGS() throws IOException + { + String line; + int id = Integer.MIN_VALUE; + + do + { + System.out.print("Enter desired ID: "); + line = _in.readLine(); + try + { + id = Integer.parseInt(line); + } + catch (NumberFormatException e) + { + System.out.printf("Invalid Choice: %s" + Config.EOL, line); + } + } + while (id == Integer.MIN_VALUE); + + final String name = GameServerTable.getInstance().getServerNameById(id); + if (name == null) + { + System.out.printf("No name for ID: %d" + Config.EOL, id); + } + else if (GameServerTable.getInstance().hasRegisteredGameServerOnId(id)) + { + System.out.printf("Are you sure you want to remove GameServer %d - %s?" + Config.EOL, id, name); + try + { + BaseGameServerRegister.unregisterGameServer(id); + System.out.printf("GameServer ID: %d was successfully removed from LoginServer." + Config.EOL, id); + } + catch (SQLException e) + { + showError("An SQL error occurred while trying to remove the GameServer.", e); + } + } + else + { + System.out.printf("No GameServer is registered on ID: %d" + Config.EOL, id); + } + } + + private void registerNewGS() throws IOException + { + String line; + int id = Integer.MIN_VALUE; + + do + { + System.out.println("Enter desired ID:"); + line = _in.readLine(); + try + { + id = Integer.parseInt(line); + } + catch (NumberFormatException e) + { + System.out.printf("Invalid Choice: %s" + Config.EOL, line); + } + } + while (id == Integer.MIN_VALUE); + + if (GameServerTable.getInstance().getServerNameById(id) == null) + { + System.out.printf("No name for ID: %d" + Config.EOL, id); + } + else if (GameServerTable.getInstance().hasRegisteredGameServerOnId(id)) + { + System.out.println("This ID is not available."); + } + else + { + try + { + BaseGameServerRegister.registerGameServer(id, "."); + } + catch (IOException e) + { + showError("An error saving the hexid file occurred while trying to register the GameServer.", e); + } + } + } + + @Override + public void showError(String msg, Throwable t) + { + msg += Config.EOL + "Reason: " + t.getLocalizedMessage(); + System.out.println("Error: " + msg); + } } \ No newline at end of file