/* * 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.l2jserver.gameserver; import java.awt.Toolkit; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Calendar; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; import org.mmocore.network.SelectorConfig; import org.mmocore.network.SelectorThread; import com.l2jserver.Config; import com.l2jserver.L2DatabaseFactory; import com.l2jserver.Server; import com.l2jserver.gameserver.cache.CrestCache; import com.l2jserver.gameserver.cache.HtmCache; import com.l2jserver.gameserver.datatables.AdminTable; import com.l2jserver.gameserver.datatables.ArmorSetsData; import com.l2jserver.gameserver.datatables.AugmentationData; import com.l2jserver.gameserver.datatables.CharNameTable; import com.l2jserver.gameserver.datatables.CharSummonTable; import com.l2jserver.gameserver.datatables.CharTemplateTable; import com.l2jserver.gameserver.datatables.ClanTable; import com.l2jserver.gameserver.datatables.ClassListData; import com.l2jserver.gameserver.datatables.DoorTable; import com.l2jserver.gameserver.datatables.EnchantGroupsData; import com.l2jserver.gameserver.datatables.EnchantHPBonusData; import com.l2jserver.gameserver.datatables.EnchantItemData; import com.l2jserver.gameserver.datatables.EnchantOptionsData; import com.l2jserver.gameserver.datatables.EventDroplist; import com.l2jserver.gameserver.datatables.ExperienceTable; import com.l2jserver.gameserver.datatables.FishData; import com.l2jserver.gameserver.datatables.FishingMonstersData; import com.l2jserver.gameserver.datatables.FishingRodsData; import com.l2jserver.gameserver.datatables.HelperBuffTable; import com.l2jserver.gameserver.datatables.HennaData; import com.l2jserver.gameserver.datatables.HerbDropTable; import com.l2jserver.gameserver.datatables.HitConditionBonus; import com.l2jserver.gameserver.datatables.InitialEquipmentData; import com.l2jserver.gameserver.datatables.ItemTable; import com.l2jserver.gameserver.datatables.ManorData; import com.l2jserver.gameserver.datatables.MerchantPriceConfigTable; import com.l2jserver.gameserver.datatables.MultiSell; import com.l2jserver.gameserver.datatables.NpcBufferTable; import com.l2jserver.gameserver.datatables.NpcTable; import com.l2jserver.gameserver.datatables.NpcWalkerRoutesData; import com.l2jserver.gameserver.datatables.OfflineTradersTable; import com.l2jserver.gameserver.datatables.PetDataTable; import com.l2jserver.gameserver.datatables.RecipeData; import com.l2jserver.gameserver.datatables.SkillTable; import com.l2jserver.gameserver.datatables.SkillTreesData; import com.l2jserver.gameserver.datatables.SpawnTable; import com.l2jserver.gameserver.datatables.StaticObjects; import com.l2jserver.gameserver.datatables.SummonItemsData; import com.l2jserver.gameserver.datatables.SummonSkillsTable; import com.l2jserver.gameserver.datatables.TeleportLocationTable; import com.l2jserver.gameserver.datatables.UITable; import com.l2jserver.gameserver.geoeditorcon.GeoEditorListener; import com.l2jserver.gameserver.handler.EffectHandler; import com.l2jserver.gameserver.idfactory.IdFactory; import com.l2jserver.gameserver.instancemanager.AirShipManager; import com.l2jserver.gameserver.instancemanager.AntiFeedManager; import com.l2jserver.gameserver.instancemanager.AuctionManager; import com.l2jserver.gameserver.instancemanager.BoatManager; import com.l2jserver.gameserver.instancemanager.CHSiegeManager; import com.l2jserver.gameserver.instancemanager.CastleManager; import com.l2jserver.gameserver.instancemanager.CastleManorManager; import com.l2jserver.gameserver.instancemanager.ClanHallManager; import com.l2jserver.gameserver.instancemanager.CoupleManager; import com.l2jserver.gameserver.instancemanager.CursedWeaponsManager; import com.l2jserver.gameserver.instancemanager.DayNightSpawnManager; import com.l2jserver.gameserver.instancemanager.DimensionalRiftManager; import com.l2jserver.gameserver.instancemanager.FortManager; import com.l2jserver.gameserver.instancemanager.FortSiegeManager; import com.l2jserver.gameserver.instancemanager.FourSepulchersManager; import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager; import com.l2jserver.gameserver.instancemanager.GraciaSeedsManager; import com.l2jserver.gameserver.instancemanager.GrandBossManager; import com.l2jserver.gameserver.instancemanager.HellboundManager; import com.l2jserver.gameserver.instancemanager.InstanceManager; import com.l2jserver.gameserver.instancemanager.ItemAuctionManager; import com.l2jserver.gameserver.instancemanager.ItemsOnGroundManager; import com.l2jserver.gameserver.instancemanager.MailManager; import com.l2jserver.gameserver.instancemanager.MapRegionManager; import com.l2jserver.gameserver.instancemanager.MercTicketManager; import com.l2jserver.gameserver.instancemanager.PetitionManager; import com.l2jserver.gameserver.instancemanager.QuestManager; import com.l2jserver.gameserver.instancemanager.RaidBossPointsManager; import com.l2jserver.gameserver.instancemanager.RaidBossSpawnManager; import com.l2jserver.gameserver.instancemanager.SiegeManager; import com.l2jserver.gameserver.instancemanager.TerritoryWarManager; import com.l2jserver.gameserver.instancemanager.TransformationManager; import com.l2jserver.gameserver.instancemanager.WalkingManager; import com.l2jserver.gameserver.instancemanager.ZoneManager; import com.l2jserver.gameserver.model.AutoChatHandler; import com.l2jserver.gameserver.model.AutoSpawnHandler; import com.l2jserver.gameserver.model.L2World; import com.l2jserver.gameserver.model.PartyMatchRoomList; import com.l2jserver.gameserver.model.PartyMatchWaitingList; import com.l2jserver.gameserver.model.entity.Hero; import com.l2jserver.gameserver.model.entity.TvTManager; import com.l2jserver.gameserver.model.olympiad.Olympiad; import com.l2jserver.gameserver.network.L2GameClient; import com.l2jserver.gameserver.network.L2GamePacketHandler; import com.l2jserver.gameserver.network.communityserver.CommunityServerThread; import com.l2jserver.gameserver.pathfinding.PathFinding; import com.l2jserver.gameserver.script.faenor.FaenorScriptEngine; import com.l2jserver.gameserver.scripting.L2ScriptEngineManager; import com.l2jserver.gameserver.taskmanager.AutoAnnounceTaskManager; import com.l2jserver.gameserver.taskmanager.KnownListUpdateTaskManager; import com.l2jserver.gameserver.taskmanager.TaskManager; import com.l2jserver.status.Status; import com.l2jserver.util.DeadLockDetector; import com.l2jserver.util.IPv4Filter; public class GameServer { private static final Logger _log = Logger.getLogger(GameServer.class.getName()); private final SelectorThread _selectorThread; private final L2GamePacketHandler _gamePacketHandler; private final DeadLockDetector _deadDetectThread; private final IdFactory _idFactory; public static GameServer gameServer; private final LoginServerThread _loginThread; private static Status _statusServer; public static final Calendar dateTimeServerStarted = Calendar.getInstance(); public long getUsedMemoryMB() { return (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1048576; // ; } public SelectorThread getSelectorThread() { return _selectorThread; } public L2GamePacketHandler getL2GamePacketHandler() { return _gamePacketHandler; } public DeadLockDetector getDeadLockDetectorThread() { return _deadDetectThread; } public GameServer() throws Exception { long serverLoadStart = System.currentTimeMillis(); gameServer = this; _log.finest(getClass().getSimpleName() + ": used mem:" + getUsedMemoryMB() + "MB"); if (Config.SERVER_VERSION != null) { _log.info(getClass().getSimpleName() + ": L2J Server Version: " + Config.SERVER_VERSION); } if (Config.DATAPACK_VERSION != null) { _log.info(getClass().getSimpleName() + ": L2J Datapack Version: " + Config.DATAPACK_VERSION); } _idFactory = IdFactory.getInstance(); if (!_idFactory.isInitialized()) { _log.severe(getClass().getSimpleName() + ": Could not read object IDs from DB. Please Check Your Data."); throw new Exception("Could not initialize the ID factory"); } ThreadPoolManager.getInstance(); new File(Config.DATAPACK_ROOT, "data/crests").mkdirs(); new File("log/game").mkdirs(); // load script engines printSection("Engines"); L2ScriptEngineManager.getInstance(); printSection("World"); // start game time control early GameTimeController.getInstance(); InstanceManager.getInstance(); L2World.getInstance(); MapRegionManager.getInstance(); Announcements.getInstance(); GlobalVariablesManager.getInstance(); printSection("Skills"); EffectHandler.getInstance().executeScript(); EnchantGroupsData.getInstance(); SkillTreesData.getInstance(); SkillTable.getInstance(); SummonSkillsTable.getInstance(); printSection("Items"); ItemTable.getInstance(); EnchantItemData.getInstance(); EnchantOptionsData.getInstance(); SummonItemsData.getInstance(); EnchantHPBonusData.getInstance(); MerchantPriceConfigTable.getInstance().loadInstances(); TradeController.getInstance(); MultiSell.getInstance(); RecipeData.getInstance(); ArmorSetsData.getInstance(); FishData.getInstance(); FishingMonstersData.getInstance(); FishingRodsData.getInstance(); HennaData.getInstance(); printSection("Characters"); ClassListData.getInstance(); InitialEquipmentData.getInstance(); ExperienceTable.getInstance(); HitConditionBonus.getInstance(); CharTemplateTable.getInstance(); CharNameTable.getInstance(); AdminTable.getInstance(); RaidBossPointsManager.getInstance(); PetDataTable.getInstance(); CharSummonTable.getInstance().init(); printSection("Clans"); ClanTable.getInstance(); CHSiegeManager.getInstance(); ClanHallManager.getInstance(); AuctionManager.getInstance(); printSection("Geodata"); GeoData.getInstance(); if (Config.GEODATA == 2) { PathFinding.getInstance(); } printSection("NPCs"); HerbDropTable.getInstance(); NpcTable.getInstance(); NpcWalkerRoutesData.getInstance(); WalkingManager.getInstance(); StaticObjects.getInstance(); ZoneManager.getInstance(); DoorTable.getInstance(); ItemAuctionManager.getInstance(); CastleManager.getInstance().loadInstances(); FortManager.getInstance().loadInstances(); NpcBufferTable.getInstance(); SpawnTable.getInstance(); HellboundManager.getInstance(); RaidBossSpawnManager.getInstance(); DayNightSpawnManager.getInstance().trim().notifyChangeMode(); GrandBossManager.getInstance().initZones(); FourSepulchersManager.getInstance().init(); DimensionalRiftManager.getInstance(); EventDroplist.getInstance(); printSection("Siege"); SiegeManager.getInstance().getSieges(); FortSiegeManager.getInstance(); TerritoryWarManager.getInstance(); CastleManorManager.getInstance(); MercTicketManager.getInstance(); ManorData.getInstance(); printSection("Olympiad"); Olympiad.getInstance(); Hero.getInstance(); // Call to load caches printSection("Cache"); HtmCache.getInstance(); CrestCache.getInstance(); TeleportLocationTable.getInstance(); UITable.getInstance(); PartyMatchWaitingList.getInstance(); PartyMatchRoomList.getInstance(); PetitionManager.getInstance(); HelperBuffTable.getInstance(); AugmentationData.getInstance(); CursedWeaponsManager.getInstance(); printSection("Scripts"); QuestManager.getInstance(); TransformationManager.getInstance(); BoatManager.getInstance(); AirShipManager.getInstance(); GraciaSeedsManager.getInstance(); try { _log.info(getClass().getSimpleName() + ": Loading Server Scripts"); File scripts = new File(Config.DATAPACK_ROOT, "data/scripts.cfg"); if (!Config.ALT_DEV_NO_HANDLERS || !Config.ALT_DEV_NO_QUESTS) { L2ScriptEngineManager.getInstance().executeScriptList(scripts); } } catch (IOException ioe) { _log.severe(getClass().getSimpleName() + ": Failed loading scripts.cfg, no script going to be loaded"); } QuestManager.getInstance().report(); TransformationManager.getInstance().report(); if (Config.SAVE_DROPPED_ITEM) { ItemsOnGroundManager.getInstance(); } if ((Config.AUTODESTROY_ITEM_AFTER > 0) || (Config.HERB_AUTO_DESTROY_TIME > 0)) { ItemsAutoDestroy.getInstance(); } MonsterRace.getInstance(); SevenSigns.getInstance().spawnSevenSignsNPC(); SevenSignsFestival.getInstance(); AutoSpawnHandler.getInstance(); AutoChatHandler.getInstance(); FaenorScriptEngine.getInstance(); // Init of a cursed weapon manager _log.info("AutoChatHandler: Loaded " + AutoChatHandler.getInstance().size() + " handlers in total."); _log.info("AutoSpawnHandler: Loaded " + AutoSpawnHandler.getInstance().size() + " handlers in total."); if (Config.L2JMOD_ALLOW_WEDDING) { CoupleManager.getInstance(); } TaskManager.getInstance(); AntiFeedManager.getInstance().registerEvent(AntiFeedManager.GAME_ID); MerchantPriceConfigTable.getInstance().updateReferences(); CastleManager.getInstance().activateInstances(); FortManager.getInstance().activateInstances(); if (Config.ALLOW_MAIL) { MailManager.getInstance(); } if (Config.ACCEPT_GEOEDITOR_CONN) { GeoEditorListener.getInstance(); } Runtime.getRuntime().addShutdownHook(Shutdown.getInstance()); _log.info("IdFactory: Free ObjectID's remaining: " + IdFactory.getInstance().size()); TvTManager.getInstance(); KnownListUpdateTaskManager.getInstance(); if ((Config.OFFLINE_TRADE_ENABLE || Config.OFFLINE_CRAFT_ENABLE) && Config.RESTORE_OFFLINERS) { OfflineTradersTable.getInstance().restoreOfflineTraders(); } if (Config.DEADLOCK_DETECTOR) { _deadDetectThread = new DeadLockDetector(); _deadDetectThread.setDaemon(true); _deadDetectThread.start(); } else { _deadDetectThread = null; } System.gc(); // maxMemory is the upper limit the jvm can use, totalMemory the size of // the current allocation pool, freeMemory the unused memory in the // allocation pool long freeMem = ((Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory()) + Runtime.getRuntime().freeMemory()) / 1048576; long totalMem = Runtime.getRuntime().maxMemory() / 1048576; _log.info(getClass().getSimpleName() + ": Started, free memory " + freeMem + " Mb of " + totalMem + " Mb"); Toolkit.getDefaultToolkit().beep(); _loginThread = LoginServerThread.getInstance(); _loginThread.start(); CommunityServerThread.initialize(); final SelectorConfig sc = new SelectorConfig(); sc.MAX_READ_PER_PASS = Config.MMO_MAX_READ_PER_PASS; sc.MAX_SEND_PER_PASS = Config.MMO_MAX_SEND_PER_PASS; sc.SLEEP_TIME = Config.MMO_SELECTOR_SLEEP_TIME; sc.HELPER_BUFFER_COUNT = Config.MMO_HELPER_BUFFER_COUNT; sc.TCP_NODELAY = Config.MMO_TCP_NODELAY; _gamePacketHandler = new L2GamePacketHandler(); _selectorThread = new SelectorThread<>(sc, _gamePacketHandler, _gamePacketHandler, _gamePacketHandler, new IPv4Filter()); InetAddress bindAddress = null; if (!Config.GAMESERVER_HOSTNAME.equals("*")) { try { bindAddress = InetAddress.getByName(Config.GAMESERVER_HOSTNAME); } catch (UnknownHostException e1) { _log.log(Level.SEVERE, getClass().getSimpleName() + ": WARNING: The GameServer bind address is invalid, using all avaliable IPs. Reason: " + e1.getMessage(), e1); } } try { _selectorThread.openServerSocket(bindAddress, Config.PORT_GAME); } catch (IOException e) { _log.log(Level.SEVERE, getClass().getSimpleName() + ": FATAL: Failed to open server socket. Reason: " + e.getMessage(), e); System.exit(1); } _selectorThread.start(); _log.info("Maximum Numbers of Connected Players: " + Config.MAXIMUM_ONLINE_USERS); long serverLoadEnd = System.currentTimeMillis(); _log.info("Server Loaded in " + ((serverLoadEnd - serverLoadStart) / 1000) + " seconds"); AutoAnnounceTaskManager.getInstance(); } public static void main(String[] args) throws Exception { Server.serverMode = Server.MODE_GAMESERVER; // Local Constants final String LOG_FOLDER = "log"; // Name of folder for log file final String LOG_NAME = "./log.cfg"; // Name of log file /*** Main ***/ // Create log folder File logFolder = new File(Config.DATAPACK_ROOT, LOG_FOLDER); logFolder.mkdir(); // Create input stream for log file -- or store file data into memory try (InputStream is = new FileInputStream(new File(LOG_NAME))) { LogManager.getLogManager().readConfiguration(is); } // Initialize config Config.load(); printSection("Database"); L2DatabaseFactory.getInstance(); gameServer = new GameServer(); if (Config.IS_TELNET_ENABLED) { _statusServer = new Status(Server.serverMode); _statusServer.start(); } else { _log.info(GameServer.class.getSimpleName() + ": Telnet server is currently disabled."); } } public static void printSection(String s) { s = "=[ " + s + " ]"; while (s.length() < 78) { s = "-" + s; } _log.info(s); } }