/**
* This file is part of Aion-Lightning <aion-lightning.org>.
*
* Aion-Lightning 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 2 of the License, or (at your option) any
* later version.
*
* Aion-Lightning 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
* Aion-Lightning. If not, see <
http://www.gnu.org/licenses/>.
*
*
* Credits goes to all Open Source Core Developer Groups listed below Please do
* not change here something, ragarding the developer credits, except the
* "developed by XXXX". Even if you edit a lot of files in this source, you
* still have no rights to call it as "your Core". Everybody knows that this
* Emulator Core was developed by Aion Lightning
*
* @-Aion-Unique-
* @-Aion-Lightning
* @Aion-Engine
* @Aion-Extreme
* @Aion-NextGen
* @Aion-Core Dev.
*/
package com.darkness.gameserver;
import ch.lambdaj.*;
import ch.qos.logback.classic.*;
import ch.qos.logback.classic.joran.*;
import ch.qos.logback.core.joran.spi.*;
import com.darkness.commons.database.*;
import com.darkness.commons.database.dao.*;
import com.darkness.commons.network.*;
import com.darkness.commons.services.*;
import com.darkness.commons.utils.*;
import com.darkness.gameserver.ai2.*;
import com.darkness.gameserver.cache.*;
import com.darkness.gameserver.configs.*;
import com.darkness.gameserver.configs.main.*;
import com.darkness.gameserver.configs.network.*;
import com.darkness.gameserver.dao.*;
import com.darkness.gameserver.dataholders.*;
import com.darkness.gameserver.eventengine.events.*;
import com.darkness.gameserver.instance.*;
import com.darkness.gameserver.model.*;
import com.darkness.gameserver.model.house.*;
import com.darkness.gameserver.model.siege.*;
import com.darkness.gameserver.network.*;
import com.darkness.gameserver.network.aion.*;
import com.darkness.gameserver.network.chatserver.*;
import com.darkness.gameserver.network.loginserver.*;
import com.darkness.gameserver.questEngine.*;
import com.darkness.gameserver.services.*;
import com.darkness.gameserver.services.abyss.*;
import com.darkness.gameserver.services.custom.*;
import com.darkness.gameserver.services.custom.cp.*;
import com.darkness.gameserver.services.custom.ffa.*;
import com.darkness.gameserver.services.drop.*;
import com.darkness.gameserver.services.ecfunctions.*;
import com.darkness.gameserver.services.instance.*;
import com.darkness.gameserver.services.player.*;
import com.darkness.gameserver.services.reward.*;
import com.darkness.gameserver.services.transfers.*;
import com.darkness.gameserver.spawnengine.*;
import com.darkness.gameserver.taskmanager.fromdb.*;
import com.darkness.gameserver.taskmanager.tasks.*;
import com.darkness.gameserver.utils.*;
import com.darkness.gameserver.utils.chathandlers.*;
import com.darkness.gameserver.utils.cron.*;
import com.darkness.gameserver.utils.gametime.*;
import com.darkness.gameserver.utils.i18n.*;
import com.darkness.gameserver.utils.idfactory.*;
import com.darkness.gameserver.utils.javaagent.*;
import com.darkness.gameserver.world.*;
import com.darkness.gameserver.world.geo.*;
import com.darkness.gameserver.world.zone.*;
import java.io.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.zip.*;
import org.slf4j.Logger;
import org.slf4j.*;
/**
* <tt>GameServer </tt> is the main class of the application and represents the
* whole game server.<br>
* This class is also an entry point with main() method.
*
* @author -Nemesiss-
* @authors Online, Darkness, Treals.
* @author cura
* @authors Online, Darkness, Treals. - reworked and removed the trash
*/
public class GameServer {
private static final Logger log = LoggerFactory.getLogger(GameServer.class);
public static HashSet<String> npcs_count = new HashSet<String>();
private static void initalizeLoggger() {
new File("./log/backup/").mkdirs();
File[] files = new File("log").listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".log");
}
});
if (files != null && files.length > 0) {
byte[] buf = new byte[1024];
try {
String outFilename = "./log/backup/" + new SimpleDateFormat("yyyy-MM-dd HHmmss").format(new Date()) + ".zip";
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outFilename));
out.setMethod(ZipOutputStream.DEFLATED);
out.setLevel(Deflater.BEST_COMPRESSION);
for (File logFile : files) {
FileInputStream in = new FileInputStream(logFile);
out.putNextEntry(new ZipEntry(logFile.getName()));
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.closeEntry();
in.close();
logFile.delete();
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
try {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();
configurator.doConfigure("config/slf4j-logback.xml");
} catch (JoranException je) {
throw new RuntimeException("Failed to configure loggers, shutting down...", je);
}
}
/**
* Launching method for GameServer
*
* @param args arguments, not used
*/
public static void main(String[] args) {
long start = System.currentTimeMillis();
Lambda.enableJitting(true);
final GameEngine[] parallelEngines = new GameEngine[]{
QuestEngine.getInstance(), InstanceEngine.getInstance(),
AI2Engine.getInstance(), ChatProcessor.getInstance()
};
final CountDownLatch progressLatch = new CountDownLatch(parallelEngines.length);
initalizeLoggger();
initUtilityServicesAndConfig();
Util.printSection("===========DATA============");
DataManager.getInstance();
IDFactory.getInstance();
Util.printSection("===========================");
Util.printSection("===========WORLD===========");
ZoneService.getInstance().load(null);
GeoService.getInstance().initializeGeo();
System.gc();
World.getInstance();
DropRegistrationService.getInstance();
Util.printSection("===========================");
Util.printSection("==========CLEANING=========");
GameServer gs = new GameServer();
DAOManager.getDAO(PlayerDAO.class).setPlayersOffline(false);
DatabaseCleaningService.getInstance();
BannedMacManager.getInstance();
Util.printSection("===========================");
Util.printSection("==========ENGINES==========");
for (int i = 0; i < parallelEngines.length; i++) {
final int index = i;
ThreadPoolManager.getInstance().execute(new Runnable() {
@Override
public void run() {
parallelEngines[index].load(progressLatch);
}
});
}
try {
progressLatch.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
Util.printSection("===========================");
// This is loading only siege location data
// No Siege schedule or spawns
Util.printSection("=========LOCATIONS=========");
BaseService.getInstance().initBaseLocations();
InvasionRaidService.getInstance().initRaidLocations();
SiegeService.getInstance().initSiegeLocations();
VortexService.getInstance().initVortexLocations();
RiftService.getInstance().initRiftLocations();
Util.printSection("===========================");
Util.printSection("==========SPAWNS===========");
SpawnEngine.spawnAll();
RiftService.getInstance().initRifts();
InstanceRiftSpawnManager.spawnAll();
TemporarySpawnEngine.spawnAll();
if (SiegeConfig.SIEGE_ENABLED) {
ShieldService.getInstance().spawnAll();
}
Util.printSection("===========================");
Util.printSection("==========SIEGES===========");
// Init Sieges... It's separated due to spawn engine.
// It should not spawn siege NPCs
SiegeService.getInstance().initSieges();
BaseService.getInstance().initBases();
InvasionRaidService.getInstance().initRaids();
SerialKillerService.getInstance().initSerialKillers();
DisputeLandService.getInstance().init();
Util.printSection("===========================");
Util.printSection("===========TASKS===========");
PacketBroadcaster.getInstance();
PeriodicSaveService.getInstance();
AbyssRankUpdateService.getInstance().scheduleUpdate();
TaskFromDBManager.getInstance();
Util.printSection("===========================");
Util.printSection("==========SERVICES=========");
LimitedItemTradeService.getInstance().start();
if (CustomConfig.LIMITS_ENABLED) {
PlayerLimitService.getInstance().scheduleUpdate();
}
GameTimeManager.startClock();
GameTimeService.getInstance();
AnnouncementService.getInstance();
DebugService.getInstance();
WeatherService.getInstance();
BrokerService.getInstance();
Influence.getInstance();
ExchangeService.getInstance();
FatigueService.getInstance();
//PetitionService.getInstance();
if (AIConfig.SHOUTS_ENABLE) {
NpcShoutsService.getInstance();
}
InstanceService.load();
FlyRingService.getInstance();
LanguageHandler.getInstance();
CuringZoneService.getInstance();
RoadService.getInstance();
HTMLCache.getInstance();
if (CustomConfig.ENABLE_REWARD_SERVICE) {
RewardService.getInstance();
}
if (EventsConfig.EVENT_ENABLED) {
PlayerEventService.getInstance();
}
if (EventsConfig.ENABLE_EVENT_SERVICE) {
EventService.getInstance().start();
}
if (WeddingsConfig.WEDDINGS_ENABLE) {
WeddingService.getInstance();
}
if (AutoGroupConfig.AUTO_GROUP_ENABLE && AutoGroupConfig.DREDGION2_ENABLE) {
DredgionService.getInstance().start();
}
if (AutoGroupConfig.AUTO_GROUP_ENABLE && AutoGroupConfig.KAMAR_ENABLE) {
KamarBattlefieldService.getInstance().start();
}
if (AutoGroupConfig.AUTO_GROUP_ENABLE && AutoGroupConfig.OPHIDAN_ENABLE) {
OphidanBridgeService.getInstance().start();
}
if (AutoGroupConfig.AUTO_GROUP_ENABLE && AutoGroupConfig.IRONWALL_ENABLE) {
IronWallWarFrontService.getInstance().start();
}
if (CustomConfig.EVENT_MODE) {
EventManager.getInstance().Init();
log.info("EventManager is Turn ON");
}
if (CustomConfig.ENABLE_FFA_GROUP) {
FfaGroupService.initializeFfaGroup();
}
if (CustomConfig.FFA_MODE) {
FfaPlayers.getInstance();
}
if (CustomConfig.ENABLE_FFA_LEGION) {
FfaLegionService.initializeFfaLegion();
}
if (CustomConfig.NEW_PVP_MODE) {
NewSpawn.spawn();
}
if (CustomConfig.NEW_PVP_2) {
MixFight.initializeFfaGroup();
MixFight6.initializeFfaGroup();
PvPLocationService.initialize();
}
if (CapturePointsConfig.CP_ENABLE) {
CapturePointsServices.initialize();
}
if (CustomConfig.NPC_CLERIC_ENABLE) {
NewSpawn.npcCleric();
}
LivePartyConcertHall.getInstance().init();
AdminService.getInstance();
PlayerTransferService.getInstance();
Util.printSection("===========================");
Util.printSection("==========HOUSING==========");
HousingBidService.getInstance().start();
MaintenanceTask.getInstance();
TownService.getInstance();
ChallengeTaskService.getInstance();
Util.printSection("===========================");
Util.printSection("==========CUSTOMS==========");
WordFilterService.getInstance();
SupportService.getInstance();
OnlineBonus.getInstance();
Util.printSection("===========================");
Util.printSection("===========SYSTEM==========");
System.gc();
AEInfos.printAllInfos();
Util.printSection("GameServerLog");
log.info("Aion Darkness GameServer started in " + (System.currentTimeMillis() - start) / 1000 + " seconds.");
try {
ZCXInfo.getInfo();
} catch (IOException e) {
e.printStackTrace();
}
gs.startServers();
Runtime.getRuntime().addShutdownHook(ShutdownHook.getInstance());
ZCXInfo.checkForRatioLimitation();
onStartup();
}
/**
* Starts servers for connection with aion client and login\chat server.
*/
private void startServers() {
Util.printSection("===========NETWORK=========");
NioServer nioServer = new NioServer(NetworkConfig.NIO_READ_WRITE_THREADS, new ServerCfg(NetworkConfig.GAME_BIND_ADDRESS, NetworkConfig.GAME_PORT, "Game Connections", new GameConnectionFactoryImpl()));
LoginServer ls = LoginServer.getInstance();
ChatServer cs = ChatServer.getInstance();
ls.setNioServer(nioServer);
cs.setNioServer(nioServer);
// Nio must go first
nioServer.connect();
ls.connect();
if (GSConfig.ENABLE_CHAT_SERVER) {
cs.connect();
}
Util.printSection("===========================");
}
/**
* Initialize all helper services, that are not directly related to aion gs,
* which includes:
* <ul>
* <li>Logging</li>
* <li>Database factory</li>
* <li>Thread pool</li>
* </ul>
* This method also initializes {@link Config}
*/
private static void initUtilityServicesAndConfig() {
// Set default uncaught exception handler
Thread.setDefaultUncaughtExceptionHandler(new ThreadUncaughtExceptionHandler());
// make sure that callback code was initialized
if (JavaAgentUtils.isConfigured()) {
log.info("JavaAgent [Callback Support] is configured.");
}
// Initialize cron service
CronService.initSingleton(ThreadPoolManagerRunnableRunner.class);
Util.printSection("===========CONFIG==========");
// init config
Config.load();
// DateTime zone override from configs
DateTimeUtil.init();
// Second should be database factory
Util.printSection("===========================");
Util.printSection("==========DATABASE=========");
DatabaseFactory.init();
// Initialize DAOs
DAOManager.init();
// Initialize thread pools
Util.printSection("===========================");
Util.printSection("==========THREADS==========");
ThreadConfig.load();
ThreadPoolManager.getInstance();
Util.printSection("===========================");
}
private static Set<StartupHook> startUpHooks = new HashSet<StartupHook>();
public synchronized static void addStartupHook(StartupHook hook) {
if (startUpHooks != null) {
startUpHooks.add(hook);
} else {
hook.onStartup();
}
}
private synchronized static void onStartup() {
final Set<StartupHook> startupHooks = startUpHooks;
startUpHooks = null;
for (StartupHook hook : startupHooks) {
hook.onStartup();
}
}
public interface StartupHook {
public void onStartup();
}
}
[/CODE]