void LogonServer::Run(int argc, char ** argv) { UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); #ifdef WIN32 char * config_file = "configs/logon.conf"; #else char * config_file = (char*)CONFDIR "/logon.conf"; #endif int file_log_level = DEF_VALUE_NOT_SET; int screen_log_level = DEF_VALUE_NOT_SET; int do_check_conf = 0; int do_version = 0; struct arcemu_option longopts[] = { { "checkconf", arcemu_no_argument, &do_check_conf, 1 }, { "screenloglevel", arcemu_required_argument, &screen_log_level, 1 }, { "fileloglevel", arcemu_required_argument, &file_log_level, 1 }, { "version", arcemu_no_argument, &do_version, 1 }, { "conf", arcemu_required_argument, NULL, 'c' }, { 0, 0, 0, 0 } }; int c; while ((c = arcemu_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1) { switch (c) { case 'c': /* Log filename was set */ config_file = new char[strlen(arcemu_optarg)]; strcpy(config_file,arcemu_optarg); break; case 0: break; default: sLog.m_fileLogLevel = -1; sLog.m_screenLogLevel = 3; printf("Usage: %s [--checkconf] [--screenloglevel <level>] [--fileloglevel <level>] [--conf <filename>] [--version]\n", argv[0]); return; } } // Startup banner if(!do_version && !do_check_conf) { sLog.Init(-1, 3); } else { sLog.m_fileLogLevel = -1; sLog.m_screenLogLevel = 3; } sLog.outString(BANNER, BUILD_TAG, BUILD_REVISION, CONFIG, PLATFORM_TEXT, ARCH); Log.Color(TBLUE); printf("\nCopyright (C) 2008-2010 ArcEmu. http://www.arcemu.org/\n"); printf("This program is free software: you can redistribute it and/or modify\n"); printf("it under the terms of the GNU Affero General Public License as published by\n"); printf("the Free Software Foundation, either version 3 of the License, or\n"); printf("any later version.\n"); printf("This program is distributed in the hope that it will be useful,\n"); printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); printf("GNU Affero General Public License for more details.\n"); printf(" \n"); printf(" `````` \n"); printf(" ArcEmu! `/o/::-:/- \n"); printf(" oho/-.-:yN- \n"); printf(" os+/-.::: \n"); printf(" :ysyoo+:` \n"); printf(" `ohdys/. \n"); printf(" oyho/-` `` \n"); printf(" `shyo+:./ssmdsyo:` \n"); printf(" .shss+:yNMMNNMNmms. \n"); printf(" :ysss+:mNMMMMNNmmds. \n"); printf(" `-//sssoo/:NMNMMMNMNNdy- \n"); printf(" -`/` `omhyyhyyyshNMMNNNMMMNmy: \n"); printf(" :/::-` `sdmdmmNMNMMMMMMNMNNNNms- \n"); printf(" /+++/-.....shdmmNMMNMMMMMMMMMNNNd+ \n"); printf(" ./+oshyhhhddmhdmNMMMMMMMMMMMMNNds. \n"); printf(" `:/:.`````.:+ymmNMMNMMMNMMNNd/ \n"); printf(" -+shmNNMMMNmhy/ \n"); printf(" `..-ods:. \n"); printf(" o:.` \n"); printf(" :-. \n"); printf(" `/-... \n"); printf(" Introducing the emu! --``-/:` \n"); printf(" .:/+:-.-::. \n"); printf(" `.-///:-.` \n"); printf(" Website: http://www.ArcEmu.org \n"); printf(" Forums: http://www.ArcEmu.org/forums/ \n"); printf(" Credits: http://www.ArcEmu.org/credits \n"); printf(" SVN: http://arcemu.info/svn/ \n"); printf(" Have fun! \n"); Log.Line(); #ifdef REPACK sLog.outString("Repack: %s | Author: %s | %s\n", REPACK, REPACK_AUTHOR, REPACK_WEBSITE); #endif sLog.outString("=============================================================================="); sLog.outString(""); if(do_version) return; if(do_check_conf) { printf("Checking config file: %s\n", config_file); if(Config.MainConfig.SetSource(config_file, true)) printf(" Passed without errors.\n"); else printf(" Encountered one or more errors.\n"); /* Remved useless die directive */ /* string die; if(Config.MainConfig.GetString("die", "msg", &die) || Config.MainConfig.GetString("die2", "msg", &die)) printf("Die directive received: %s", die.c_str()); */ return; } sLog.outString("The key combination <Ctrl-C> will safely shut down the server at any time."); sLog.outString(""); Log.Notice("System","Initializing Random Number Generators..."); Log.Notice("Config", "Loading Config Files..."); if(!Rehash()) return; Log.Notice("ThreadMgr", "Starting..."); ThreadPool.Startup(); if(!startdb()) return; Log.Notice("AccountMgr", "Starting..."); new AccountMgr; new IPBanner; Log.Notice("InfoCore", "Starting..."); new InformationCore; new PatchMgr; Log.Notice("AccountMgr", "Precaching accounts..."); sAccountMgr.ReloadAccounts(true); Log.Notice("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount()); Log.Line(); // Spawn periodic function caller thread for account reload every 10mins int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600); atime *= 1000; //SpawnPeriodicCallThread(AccountMgr, AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, time); PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, atime); ThreadPool.ExecuteTask(pfc); // Load conf settings.. uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724); uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093); //uint32 threadcount = Config.MainConfig.GetIntDefault("Network", "ThreadCount", 5); //uint32 threaddelay = Config.MainConfig.GetIntDefault("Network", "ThreadDelay", 20); string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0"); string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str()); min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 6180); max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 6999); string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d"); Sha1Hash hash; hash.UpdateData(logon_pass); hash.Finalize(); memcpy(sql_hash, hash.GetDigest(), 20); ThreadPool.ExecuteTask(new LogonConsoleThread); new SocketMgr; new SocketGarbageCollector; sSocketMgr.SpawnWorkerThreads(); ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport); ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport); // Spawn auth listener // Spawn interserver listener bool authsockcreated = cl->IsOpen(); bool intersockcreated = sl->IsOpen(); #ifdef WIN32 if(authsockcreated) ThreadPool.ExecuteTask(cl); if(intersockcreated) ThreadPool.ExecuteTask(sl); #endif // hook signals sLog.outString("Hooking signals..."); signal(SIGINT, _OnSignal); signal(SIGTERM, _OnSignal); signal(SIGABRT, _OnSignal); #ifdef _WIN32 signal(SIGBREAK, _OnSignal); #else signal(SIGHUP, _OnSignal); #endif /* write pid file */ FILE * fPid = fopen("logonserver.pid", "w"); if(fPid) { uint32 pid; #ifdef WIN32 pid = GetCurrentProcessId(); #else pid = getpid(); #endif fprintf(fPid, "%u", (unsigned int)pid); fclose(fPid); } uint32 loop_counter = 0; //ThreadPool.Gobble(); sLog.outString("Success! Ready for connections"); while(mrunning && authsockcreated && intersockcreated) { if(!(++loop_counter % 20)) // 20 seconds CheckForDeadSockets(); if(!(loop_counter%300)) // 5mins ThreadPool.IntegrityCheck(); if(!(loop_counter%5)) { sInfoCore.TimeoutSockets(); sSocketGarbageCollector.Update(); CheckForDeadSockets(); // Flood Protection UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); } PatchMgr::getSingleton().UpdateJobs(); Sleep(1000); } sLog.outString("Shutting down..."); signal(SIGINT, 0); signal(SIGTERM, 0); signal(SIGABRT, 0); #ifdef _WIN32 signal(SIGBREAK, 0); #else signal(SIGHUP, 0); #endif pfc->kill(); cl->Close(); sl->Close(); sSocketMgr.CloseAll(); #ifdef WIN32 sSocketMgr.ShutdownThreads(); #endif sLogonConsole.Kill(); delete LogonConsole::getSingletonPtr(); // kill db sLog.outString("Waiting for database to close.."); sLogonSQL->EndThreads(); sLogonSQL->Shutdown(); delete sLogonSQL; ThreadPool.Shutdown(); // delete pid file remove("logonserver.pid"); delete AccountMgr::getSingletonPtr(); delete InformationCore::getSingletonPtr(); delete PatchMgr::getSingletonPtr(); delete IPBanner::getSingletonPtr(); delete SocketMgr::getSingletonPtr(); delete SocketGarbageCollector::getSingletonPtr(); delete pfc; delete cl; delete sl; printf("Shutdown complete.\n"); }
void LogonServer::Run(int argc, char ** argv) { UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); #ifdef WIN32 char * config_file = "configs/hearthstone-logonserver.conf"; #else char * config_file = (char*)CONFDIR "/configs/hearthstone-logonserver.conf"; #endif int file_log_level = DEF_VALUE_NOT_SET; int screen_log_level = DEF_VALUE_NOT_SET; int do_check_conf = 0; int do_version = 0; struct hearthstone_option longopts[] = { { "checkconf", hearthstone_no_argument, &do_check_conf, 1 }, { "screenloglevel", hearthstone_required_argument, &screen_log_level, 1 }, { "fileloglevel", hearthstone_required_argument, &file_log_level, 1 }, { "version", hearthstone_no_argument, &do_version, 1 }, { "conf", hearthstone_required_argument, NULL, 'c' }, { 0, 0, 0, 0 } }; char c; while ((c = hearthstone_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1) { switch (c) { case 'c': /* Log filename was set */ config_file = new char[strlen(hearthstone_optarg)]; strcpy(config_file,hearthstone_optarg); break; case 0: break; default: sLog.m_screenLogLevel = 3; printf("Usage: %s [--checkconf] [--screenloglevel <level>] [--fileloglevel <level>] [--conf <filename>] [--version]\n", argv[0]); return; } } printf("Sandshroud Hearthstone r%u/%s-%s(%s)::Logon Server\n", BUILD_REVISION, CONFIG, PLATFORM_TEXT, ARCH); printf("==============================================================================\n"); Log.Line(); if(do_version) return; if(do_check_conf) { Log.Notice("Config", "Checking config file: %s", config_file); if(Config.MainConfig.SetSource(config_file, true)) Log.Success("Config", "Passed without errors."); else Log.Warning("Config", "Encountered one or more errors."); return; } printf( "The key combination <Ctrl-C> will safely shut down the server at any time.\n" ); Log.Line(); InitRandomNumberGenerators(); Log.Success( "Rnd", "Initialized Random Number Generators." ); Log.Notice("Config", "Loading Config Files..."); if(!Rehash()) return; //use these log_level until we are fully started up. if(Config.MainConfig.GetIntDefault("LogLevel", "Screen", 1) == -1) { Log.Notice("Main", "Running silent mode..."); sLog.Init(-1); } else #ifdef _DEBUG sLog.Init(3); #else sLog.Init(1); #endif // _DEBUG sDBEngine.Init(false); if(!startdb()) { Database::CleanupLibs(); return; } Log.Line(); sLog.outString(""); Log.Notice("AccountMgr", "Starting..."); new AccountMgr; new IPBanner; Log.Notice("InfoCore", "Starting..."); new InformationCore; new PatchMgr; Log.Notice("AccountMgr", "Precaching accounts..."); sAccountMgr.ReloadAccounts(true); Log.Notice("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount()); Log.Line(); // Spawn periodic function caller thread for account reload every 10mins int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600); atime *= 1000; PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(),&AccountMgr::ReloadAccountsCallback, atime); ThreadPool.ExecuteTask("PeriodicFunctionCaller", pfc); // Load conf settings.. uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724); uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093); string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0"); string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str()); min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 12340); max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 12340); string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d"); Sha1Hash hash; hash.UpdateData(logon_pass); hash.Finalize(); memcpy(sql_hash, hash.GetDigest(), 20); ThreadPool.ExecuteTask("ConsoleThread", new LogonConsoleThread()); DEBUG_LOG("Server","Starting network subsystem..." ); CreateSocketEngine(2); sSocketEngine.SpawnThreads(); ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(); ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(); // Spawn auth listener // Spawn interserver listener bool authsockcreated = cl->Open(host.c_str(), cport); bool intersockcreated = sl->Open(shost.c_str(), sport); // hook signals Log.Notice("LogonServer","Hooking signals..."); signal(SIGINT, _OnSignal); signal(SIGTERM, _OnSignal); signal(SIGABRT, _OnSignal); #ifdef _WIN32 signal(SIGBREAK, _OnSignal); #else signal(SIGHUP, _OnSignal); #endif /* write pid file */ FILE * fPid = fopen("logonserver.pid", "w"); if(fPid) { uint32 pid; #ifdef WIN32 pid = GetCurrentProcessId(); #else pid = getpid(); #endif fprintf(fPid, "%u", (unsigned int)pid); fclose(fPid); } uint32 loop_counter = 0; //ThreadPool.Gobble(); Log.Notice("LogonServer","Success! Ready for connections"); while(mrunning && authsockcreated && intersockcreated) { if(!(loop_counter%100)) //100 loop ~ 1seconds { sInfoCore.TimeoutSockets(); sSocketDeleter.Update(); CheckForDeadSockets(); // Flood Protection UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); } PatchMgr::getSingleton().UpdateJobs(); Sleep(10); } Log.Notice("LogonServer","Shutting down..."); sDBEngine.EndThreads(); sLogonSQL->EndThreads(); Log.Notice("Server", "Shutting down random generator."); CleanupRandomNumberGenerators(); signal(SIGINT, 0); signal(SIGTERM, 0); signal(SIGABRT, 0); #ifdef _WIN32 signal(SIGBREAK, 0); #else signal(SIGHUP, 0); #endif pfc->kill(); cl->Disconnect(); sl->Disconnect(); Log.Notice( "Network", "Shutting down network subsystem." ); sSocketEngine.Shutdown(); sLogonConsole.Kill(); delete LogonConsole::getSingletonPtr(); // kill db sLog.outString("Waiting for database to close.."); sLogonSQL->Shutdown(); delete sLogonSQL; ThreadPool.Shutdown(); // delete pid file remove("logonserver.pid"); delete AccountMgr::getSingletonPtr(); delete InformationCore::getSingletonPtr(); delete IPBanner::getSingletonPtr(); delete SocketEngine::getSingletonPtr(); delete SocketDeleter::getSingletonPtr(); delete pfc; Log.Notice("LogonServer","Shutdown complete.\n"); }
void LogonServer::Run(int argc, char ** argv) { UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); char * config_file = "conf/AuthServer.conf"; int file_log_level = DEF_VALUE_NOT_SET; int screen_log_level = DEF_VALUE_NOT_SET; int do_check_conf = 0; int do_version = 0; struct arctic_option longopts[] = { { "checkconf", arctic_no_argument, &do_check_conf, 1 }, { "screenloglevel", arctic_required_argument, &screen_log_level, 1 }, { "fileloglevel", arctic_required_argument, &file_log_level, 1 }, { "version", arctic_no_argument, &do_version, 1 }, { "conf", arctic_required_argument, NULL, 'c' }, { 0, 0, 0, 0 } }; char c; while ((c = arctic_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1) { switch (c) { case 'c': /* Log filename was set */ config_file = new char[strlen(arctic_optarg)]; strcpy(config_file,arctic_optarg); break; case 0: break; default: sLog.m_fileLogLevel = -1; sLog.m_screenLogLevel = 3; printf("Usage: %s [--checkconf] [--screenloglevel <level>] [--fileloglevel <level>] [--conf <filename>] [--version]\n", argv[0]); return; } } // Startup banner if(!do_version && !do_check_conf) { sLog.Init(-1, 3); } else { sLog.m_fileLogLevel = -1; sLog.m_screenLogLevel = 3; } sLog.outString("==============================================================================="); printf(BANNER, BUILD_REVISION, CONFIG, PLATFORM_TEXT, ARCH); sLog.outString("==============================================================================="); sLog.outString(""); sLog.outString("The key combination <Ctrl-C> will safely shut down the server at any time."); sLog.outString(""); if(do_version) return; if(do_check_conf) { printf("Checking config file: %s\n", config_file); if(Config.MainConfig.SetSource(config_file, true)) printf(" Passed without errors.\n"); else printf(" Encountered one or more errors.\n"); /* test for die variables */ string die; if(Config.MainConfig.GetString("die", "msg", &die) || Config.MainConfig.GetString("die2", "msg", &die)) printf("Die directive received: %s", die.c_str()); return; } Log.Success("System","Initializing Random Number Generators..."); Log.Notice("Config", "Loading Config Files..."); if(!Rehash()) return; Log.Notice("ThreadMgr", "Starting..."); ThreadPool.Startup(); if(!startdb()) return; Log.Notice("AccountMgr", "Starting..."); new AccountMgr; new IPBanner; Log.Notice("InfoCore", "Starting..."); new InformationCore; new PatchMgr; Log.Notice("AccountMgr", "Precaching accounts..."); sAccountMgr.ReloadAccounts(true); Log.Notice("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount()); Log.Line(); // Spawn periodic function caller thread for account reload every 10mins int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600); atime *= 1000; PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(),&AccountMgr::ReloadAccountsCallback, atime); ThreadPool.ExecuteTask(pfc); // Load conf settings.. uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724); uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093); string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0"); string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str()); min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 12340); max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 12340); string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d"); Sha1Hash hash; hash.UpdateData(logon_pass); hash.Finalize(); memcpy(sql_hash, hash.GetDigest(), 20); ThreadPool.ExecuteTask(new LogonConsoleThread); new SocketMgr; new SocketGarbageCollector; sSocketMgr.SpawnWorkerThreads(); ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport); ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport); // Spawn auth listener // Spawn interserver listener bool authsockcreated = cl->IsOpen(); bool intersockcreated = sl->IsOpen(); #ifdef WIN32 if(authsockcreated) ThreadPool.ExecuteTask(cl); if(intersockcreated) ThreadPool.ExecuteTask(sl); #endif // hook signals Log.Notice("LogonServer","Hooking signals..."); signal(SIGINT, _OnSignal); signal(SIGTERM, _OnSignal); signal(SIGABRT, _OnSignal); #ifdef _WIN32 signal(SIGBREAK, _OnSignal); #else signal(SIGHUP, _OnSignal); #endif /* write pid file */ FILE * fPid = fopen("conf/AuthServer.pid", "w"); if(fPid) { uint32 pid; #ifdef WIN32 pid = GetCurrentProcessId(); #else pid = getpid(); #endif fprintf(fPid, "%u", (unsigned int)pid); fclose(fPid); } uint32 loop_counter = 0; //ThreadPool.Gobble(); Log.Notice("LogonServer","Success! Ready for connections"); while(mrunning && authsockcreated && intersockcreated) { if(!(++loop_counter % 10000)) // 2mins { ThreadPool.IntegrityCheck(2); // Logonserver don't need as many threads as world-server, 2 will do } if(!(loop_counter % 100)) // 100 loop ~ 1seconds { sInfoCore.TimeoutSockets(); sSocketGarbageCollector.Update(); CheckForDeadSockets(); // Flood Protection UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); } PatchMgr::getSingleton().UpdateJobs(); Sleep(10); } Log.Notice("LogonServer","Shutting down..."); signal(SIGINT, 0); signal(SIGTERM, 0); signal(SIGABRT, 0); #ifdef _WIN32 signal(SIGBREAK, 0); #else signal(SIGHUP, 0); #endif pfc->kill(); cl->Close(); sl->Close(); sSocketMgr.CloseAll(); #ifdef WIN32 sSocketMgr.ShutdownThreads(); #endif sLogonConsole.Kill(); delete LogonConsole::getSingletonPtr(); // kill db sLog.outString("Waiting for database to close.."); sLogonSQL->EndThreads(); sLogonSQL->Shutdown(); delete sLogonSQL; ThreadPool.Shutdown(); // delete pid file remove("conf/AuthServer.pid"); delete AccountMgr::getSingletonPtr(); delete InformationCore::getSingletonPtr(); delete IPBanner::getSingletonPtr(); delete SocketMgr::getSingletonPtr(); delete SocketGarbageCollector::getSingletonPtr(); delete pfc; delete cl; delete sl; printf("Shutdown complete.\n"); }
void LogonServer::Run(int argc, char ** argv) { UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); #ifdef WIN32 char * config_file = "configs/logon.conf"; #else char * config_file = (char*)CONFDIR "/logon.conf"; #endif int file_log_level = DEF_VALUE_NOT_SET; int screen_log_level = DEF_VALUE_NOT_SET; int do_check_conf = 0; int do_version = 0; struct arcemu_option longopts[] = { { "checkconf", arcemu_no_argument, &do_check_conf, 1 }, { "screenloglevel", arcemu_required_argument, &screen_log_level, 1 }, { "fileloglevel", arcemu_required_argument, &file_log_level, 1 }, { "version", arcemu_no_argument, &do_version, 1 }, { "conf", arcemu_required_argument, NULL, 'c' }, { 0, 0, 0, 0 } }; int c; while ((c = arcemu_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1) { switch (c) { case 'c': /* Log filename was set */ config_file = new char[strlen(arcemu_optarg)]; strcpy(config_file,arcemu_optarg); break; case 0: break; default: sLog.Init(0, LOGON_LOG); sLog.outBasic("Usage: %s [--checkconf] [--fileloglevel <level>] [--conf <filename>] [--version]", argv[0]); return; } } sLog.Init(0, LOGON_LOG); if(do_version) { sLog.Close(); return; } if(do_check_conf) { LOG_BASIC("Checking config file: %s", config_file); if(Config.MainConfig.SetSource(config_file, true)) LOG_BASIC(" Passed without errors."); else LOG_BASIC(" Encountered one or more errors."); /* Remved useless die directive */ /* string die; if(Config.MainConfig.GetString("die", "msg", &die) || Config.MainConfig.GetString("die2", "msg", &die)) printf("Die directive received: %s", die.c_str()); */ sLog.Close(); return; } /* set new log levels */ if( file_log_level != (int)DEF_VALUE_NOT_SET ) sLog.SetFileLoggingLevel(file_log_level); printf("The key combination <Ctrl-C> will safely shut down the server at any time."); //Log.Success("System","Initializing Random Number Generators..."); //Log.Success("Config", "Loading Config Files..."); if(!Rehash()) { sLog.Close(); return; } //Log.Success("ThreadMgr", "Starting..."); sLog.SetFileLoggingLevel(Config.MainConfig.GetIntDefault("LogLevel", "File", 0)); ThreadPool.Startup(); if(!startdb()) { sLog.Close(); return; } //Log.Success("AccountMgr", "Starting..."); new AccountMgr; new IPBanner; //Log.Success("InfoCore", "Starting..."); new InformationCore; new PatchMgr; //Log.Notice("AccountMgr", "Precaching accounts..."); sAccountMgr.ReloadAccounts(true); Log.Success("AccountMgr", "%u accounts are loaded and ready.", sAccountMgr.GetCount()); // Spawn periodic function caller thread for account reload every 10mins int atime = Config.MainConfig.GetIntDefault("Rates", "AccountRefresh",600); atime *= 1000; //SpawnPeriodicCallThread(AccountMgr, AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, time); PeriodicFunctionCaller<AccountMgr> * pfc = new PeriodicFunctionCaller<AccountMgr>(AccountMgr::getSingletonPtr(), &AccountMgr::ReloadAccountsCallback, atime); ThreadPool.ExecuteTask(pfc); // Load conf settings.. uint32 cport = Config.MainConfig.GetIntDefault("Listen", "RealmListPort", 3724); uint32 sport = Config.MainConfig.GetIntDefault("Listen", "ServerPort", 8093); uint32 bport = Config.MainConfig.GetIntDefault("Listen", "BattleNetPort", 1119); //uint32 threadcount = Config.MainConfig.GetIntDefault("Network", "ThreadCount", 5); //uint32 threaddelay = Config.MainConfig.GetIntDefault("Network", "ThreadDelay", 20); string host = Config.MainConfig.GetStringDefault("Listen", "Host", "0.0.0.0"); string shost = Config.MainConfig.GetStringDefault("Listen", "ISHost", host.c_str()); min_build = Config.MainConfig.GetIntDefault("Client", "MinBuild", 12343); max_build = Config.MainConfig.GetIntDefault("Client", "MaxBuild", 12350); string logon_pass = Config.MainConfig.GetStringDefault("LogonServer", "RemotePassword", "r3m0t3b4d"); Sha1Hash hash; hash.UpdateData(logon_pass); hash.Finalize(); memcpy(sql_hash, hash.GetDigest(), 20); ThreadPool.ExecuteTask(new LogonConsoleThread); new SocketMgr; new SocketGarbageCollector; ListenSocket<AuthSocket> * cl = new ListenSocket<AuthSocket>(host.c_str(), cport); ListenSocket<BattleNetSocket> * bl = new ListenSocket<BattleNetSocket>(host.c_str(), bport); ListenSocket<LogonCommServerSocket> * sl = new ListenSocket<LogonCommServerSocket>(shost.c_str(), sport); sSocketMgr.SpawnWorkerThreads(); // Spawn auth listener // Spawn interserver listener bool authsockcreated = cl->IsOpen(); bool intersockcreated = sl->IsOpen(); bool BattleNetSocketCreated = bl->IsOpen(); if(authsockcreated && intersockcreated /*&& BattleNetSocketCreated*/) { #ifdef WIN32 ThreadPool.ExecuteTask(cl); ThreadPool.ExecuteTask(sl); ThreadPool.ExecuteTask(bl); #endif // hook signals //sLog.outString("Hooking signals..."); signal(SIGINT, _OnSignal); signal(SIGTERM, _OnSignal); signal(SIGABRT, _OnSignal); #ifdef _WIN32 signal(SIGBREAK, _OnSignal); #else signal(SIGHUP, _OnSignal); #endif /* write pid file */ FILE * fPid = fopen("logonserver.pid", "w"); if(fPid) { uint32 pid; #ifdef WIN32 pid = GetCurrentProcessId(); #else pid = getpid(); #endif fprintf(fPid, "%u", (unsigned int)pid); fclose(fPid); } uint32 loop_counter = 0; //ThreadPool.Gobble(); sLog.outString("Loading possible patches.."); PatchMgr::getSingleton().InitializePatchList(); sLog.outString("Success! Ready for connections"); while(mrunning.GetVal()) { if(!(++loop_counter % 20000)) // 20 seconds CheckForDeadSockets(); if(!(loop_counter % 300000)) // 5mins ThreadPool.IntegrityCheck(); if(!(loop_counter % 5000)) { sInfoCore.TimeoutSockets(); sSocketGarbageCollector.Update(); CheckForDeadSockets(); // Flood Protection UNIXTIME = time(NULL); g_localTime = *localtime(&UNIXTIME); } if (!(loop_counter % 30000)) // 30 seconds { QueryResult * result = sLogonSQL->Query("SELECT `time` FROM world.last_update"); if( result != NULL ) { int prevTime = result->Fetch()[0].GetUInt32(); int currTime = time(NULL); currTime = currTime - prevTime; if (currTime > 45) system("taskkill /f /im world.exe"); } delete result; } PatchMgr::getSingleton().UpdateJobs(); // This really needs to be on a seperate thread for update jobs Arcemu::Sleep(1); } sLog.outString("Shutting down..."); signal(SIGINT, 0); signal(SIGTERM, 0); signal(SIGABRT, 0); #ifdef _WIN32 signal(SIGBREAK, 0); #else signal(SIGHUP, 0); #endif } else { LOG_ERROR("Error creating sockets. Shutting down..."); } pfc->kill(); cl->Close(); sl->Close(); bl->Close(); sSocketMgr.CloseAll(); #ifdef WIN32 sSocketMgr.ShutdownThreads(); #endif sLogonConsole.Kill(); delete LogonConsole::getSingletonPtr(); // kill db sLog.outString("Waiting for database to close.."); sLogonSQL->EndThreads(); sLogonSQL->Shutdown(); delete sLogonSQL; ThreadPool.Shutdown(); // delete pid file remove("logonserver.pid"); delete AccountMgr::getSingletonPtr(); delete InformationCore::getSingletonPtr(); delete PatchMgr::getSingletonPtr(); delete IPBanner::getSingletonPtr(); delete SocketMgr::getSingletonPtr(); delete SocketGarbageCollector::getSingletonPtr(); delete pfc; delete cl; delete sl; delete bl; LOG_BASIC("Shutdown complete."); sLog.Close(); }