/* * 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 <http://www.gnu.org/licenses/>. */ package silentium.authserver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import silentium.authserver.configs.MainConfig; import silentium.commons.ServerType; import silentium.commons.configuration.PropertiesParser; import silentium.commons.database.DatabaseFactory; import silentium.commons.database.DatabaseTuning; import silentium.commons.network.mmocore.SelectorConfig; import silentium.commons.network.mmocore.SelectorThread; import silentium.commons.utils.Util; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; import java.net.InetAddress; import java.net.UnknownHostException; /** * @author KenM */ public class L2LoginServer { public static final int PROTOCOL_REV = 0x0102; private static L2LoginServer loginServer; private final Logger _log = LoggerFactory.getLogger(L2LoginServer.class.getName()); private GameServerListener _gameServerListener; private SelectorThread<L2LoginClient> _selectorThread; public static void main(final String... args) throws Exception { loginServer = new L2LoginServer(); } public static L2LoginServer getInstance() { return loginServer; } public L2LoginServer() throws Exception { ServerType.SERVER_TYPE = ServerType.AUTHSERVER; // Create log folder final File logFolder = new File("./log"); logFolder.mkdir(); Util.printSection("Main"); _log.info("Developers: Silentium"); _log.info("https://silentium.by"); Util.printSection("Configuration"); PropertiesParser.parse(); Util.printSection("Database"); DatabaseFactory.init(); DatabaseTuning.start(); Util.printSection("LoginController"); LoginController.load(); GameServerTable.getInstance(); Util.printSection("Ban List"); loadBanFile(); Util.printSection("IP, Ports & Socket infos"); InetAddress bindAddress = null; if (!"*".equals(MainConfig.LOGIN_BIND_ADDRESS)) { try { bindAddress = InetAddress.getByName(MainConfig.LOGIN_BIND_ADDRESS); } catch (UnknownHostException e1) { _log.error("WARNING: The LoginServer bind address is invalid, using all available IPs. Reason: " + e1.getMessage()); if (MainConfig.DEVELOPER) e1.printStackTrace(); } } final SelectorConfig sc = new SelectorConfig(); sc.MAX_READ_PER_PASS = MainConfig.MMO_MAX_READ_PER_PASS; sc.MAX_SEND_PER_PASS = MainConfig.MMO_MAX_SEND_PER_PASS; sc.SLEEP_TIME = MainConfig.MMO_SELECTOR_SLEEP_TIME; sc.HELPER_BUFFER_COUNT = MainConfig.MMO_HELPER_BUFFER_COUNT; final L2LoginPacketHandler lph = new L2LoginPacketHandler(); final SelectorHelper sh = new SelectorHelper(); try { _selectorThread = new SelectorThread<>(sc, sh, lph, sh, sh); } catch (IOException e) { _log.error("FATAL: Failed to open selector. Reason: " + e.getMessage()); if (MainConfig.DEVELOPER) e.printStackTrace(); System.exit(1); } try { _gameServerListener = new GameServerListener(); _gameServerListener.start(); _log.info("Listening for gameservers on " + MainConfig.GAME_SERVER_LOGIN_HOST + ":" + MainConfig.GAME_SERVER_LOGIN_PORT); } catch (IOException e) { _log.error("FATAL: Failed to start the gameserver listener. Reason: " + e.getMessage()); if (MainConfig.DEVELOPER) e.printStackTrace(); System.exit(1); } try { _selectorThread.openServerSocket(bindAddress, MainConfig.PORT_LOGIN); } catch (IOException e) { _log.error("FATAL: Failed to open server socket. Reason: " + e.getMessage()); if (MainConfig.DEVELOPER) e.printStackTrace(); System.exit(1); } _selectorThread.start(); _log.info("Loginserver ready on " + (bindAddress == null ? "*" : bindAddress.getHostAddress()) + ":" + MainConfig.PORT_LOGIN); Util.printSection("Waiting for gameserver answer"); } public GameServerListener getGameServerListener() { return _gameServerListener; } private void loadBanFile() { final File banFile = new File("config/banned_ip.cfg"); if (banFile.exists() && banFile.isFile()) { LineNumberReader reader = null; try { String line; String[] parts; reader = new LineNumberReader(new FileReader(banFile)); while ((line = reader.readLine()) != null) { line = line.trim(); // check if this line isnt a comment line if (!line.isEmpty() && line.charAt(0) != '#') { // split comments if any parts = line.split("#"); // discard comments in the line, if any line = parts[0]; parts = line.split(" "); final String address = parts[0]; long duration = 0; if (parts.length > 1) { try { duration = Long.parseLong(parts[1]); } catch (NumberFormatException e) { _log.warn("Skipped: Incorrect ban duration (" + parts[1] + ") on banned_ip.cfg. Line: " + reader.getLineNumber()); continue; } } try { LoginController.getInstance().addBanForAddress(address, duration); } catch (UnknownHostException e) { _log.warn("Skipped: Invalid address (" + parts[0] + ") on banned_ip.cfg. Line: " + reader.getLineNumber()); } } } } catch (IOException e) { _log.warn("Error while reading banned_ip.cfg. Details: " + e.getMessage()); if (MainConfig.DEVELOPER) e.printStackTrace(); } _log.info("Loaded " + LoginController.getInstance().getBannedIps().size() + " IP(s) from banned_ip.cfg."); } else _log.warn("banned_ip.cfg is missing. Ban listing is skipped."); } public void shutdown(final boolean restart) { Runtime.getRuntime().exit(restart ? 2 : 0); } }