int AgentApp::OnStart() { int ret = 0; //share memory ret = StartShmCenter(); if(ret) { LOG_ERROR("start init error !"); return -1; } //db (mysql) ret = StartDB(); if(ret) { LOG_ERROR("db start error !"); return -1; } ret = StartCache(); if(ret) { LOG_ERROR("cache start error !"); return -1; } return 0; }
/// Launch the realm server extern int main(int argc, char **argv) { ///- Command line parsing to get the configuration file name char const* cfg_file = _REALMD_CONFIG; int c=1; while( c < argc ) { if( strcmp(argv[c],"-c") == 0) { if( ++c >= argc ) { sLog.outError("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } #ifdef WIN32 //////////// //Services// //////////// if( strcmp(argv[c],"-s") == 0) { if( ++c >= argc ) { sLog.outError("Runtime-Error: -s option requires an input argument"); usage(argv[0]); return 1; } if( strcmp(argv[c],"install") == 0) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } else if( strcmp(argv[c],"uninstall") == 0) { if(WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; } else { sLog.outError("Runtime-Error: unsupported option %s",argv[c]); usage(argv[0]); return 1; } } if( strcmp(argv[c],"--service") == 0) { WinServiceRun(); } //// #endif ++c; } if (!sConfig.SetSource(cfg_file)) { sLog.outError("Could not find configuration file %s.", cfg_file); return 1; } sLog.outString("Using configuration file %s.", cfg_file); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); clock_t pause = 3000 + clock(); while (pause > clock()); } sLog.outString( "MaNGOS realm daemon %s", _FULLVERSION ); sLog.outString( "<Ctrl-C> to stop.\n" ); /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if(!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if( !pid ) { sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); return 1; } sLog.outString( "Daemon PID: %u\n", pid ); } ///- Initialise the database connection std::string dbstring; if(!StartDB(dbstring)) return 1; ///- Get the list of realms for the server m_realmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (m_realmList.size() == 0) { sLog.outError("No valid realms specified."); return 1; } ///- Launch the listening network socket port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT ); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); SocketHandler h; ListenSocket<AuthSocket> authListenSocket(h); if ( authListenSocket.Bind(bind_ip.c_str(),rmport)) { sLog.outError( "MaNGOS realmd can not bind to %s:%d",bind_ip.c_str(), rmport ); return 1; } h.Add(&authListenSocket); ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if(Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if(!curAff ) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); } else { if(SetProcessAffinityMask(hProcess,curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if(Prio) { if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) sLog.outString("realmd process priority class set to HIGH"); else sLog.outError("ERROR: Can't set realmd process priority class."); sLog.outString(); } } #endif // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; ///- Wait for termination signal while (!stopEvent) { h.Select(0, 100000); if( (++loopCounter) == numLoops ) { loopCounter = 0; sLog.outDetail("Ping MySQL to keep connection alive"); delete dbRealmServer.Query("SELECT 1 FROM realmlist LIMIT 1"); } #ifdef WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } ///- Wait for the delay thread to exit dbRealmServer.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString( "Halting process..." ); return 0; }
/// Launch the auth server extern int main(int argc, char **argv) { // Command line parsing to get the configuration file name char const* cfg_file = _TRINITY_REALM_CONFIG; int c = 1; while (c < argc) { if (strcmp(argv[c], "-c") == 0) { if (++c >= argc) { printf("Runtime-Error: -c option requires an input argument\n"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } ++c; } if (!ConfigMgr::Load(cfg_file)) { printf("Invalid or missing configuration file : %s\n", cfg_file); printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n"); return 1; } sLog->outInfo(LOG_FILTER_AUTHSERVER, "%s (authserver)", _FULLVERSION); sLog->outInfo(LOG_FILTER_AUTHSERVER, " "); sLog->outInfo(LOG_FILTER_AUTHSERVER, " "); sLog->outInfo(LOG_FILTER_AUTHSERVER, "<Ctrl-C> to stop.\n"); sLog->outInfo(LOG_FILTER_AUTHSERVER, "██████╗ ███████╗ █████╗ ████████╗██╗ ██╗"); sLog->outInfo(LOG_FILTER_AUTHSERVER, "██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██║ ██║"); sLog->outInfo(LOG_FILTER_AUTHSERVER, "██║ ██║█████╗ ███████║ ██║ ███████║"); sLog->outInfo(LOG_FILTER_AUTHSERVER, "██║ ██║██╔══╝ ██╔══██║ ██║ ██╔══██║"); sLog->outInfo(LOG_FILTER_AUTHSERVER, "██████╔╝███████╗██║ ██║ ██║ ██║ ██║"); sLog->outInfo(LOG_FILTER_AUTHSERVER, "╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝"); sLog->outInfo(LOG_FILTER_AUTHSERVER, " ██████╗ ██████╗ ██████╗ ███████╗"); sLog->outInfo(LOG_FILTER_AUTHSERVER, " ██╔════╝██╔═══██╗██╔══██╗██╔════╝"); sLog->outInfo(LOG_FILTER_AUTHSERVER, " ██║ ██║ ██║██████╔╝█████╗"); sLog->outInfo(LOG_FILTER_AUTHSERVER, " ██║ ██║ ██║██╔══██╗██╔══╝"); sLog->outInfo(LOG_FILTER_AUTHSERVER, " ╚██████╗╚██████╔╝██║ ██║███████╗"); sLog->outInfo(LOG_FILTER_AUTHSERVER, " ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝"); sLog->outInfo(LOG_FILTER_AUTHSERVER, " Noffearr Death ProjecT 2015(c) Open-Sourced Game Emulation "); sLog->outInfo(LOG_FILTER_AUTHSERVER, " http://www.noffearrdeathproject.net \n"); sLog->outWarn(LOG_FILTER_AUTHSERVER, "%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog->outDebug(LOG_FILTER_AUTHSERVER, "Max allowed open files is %d", ACE::max_handles()); // authserver PID file creation std::string pidfile = ConfigMgr::GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog->outError(LOG_FILTER_AUTHSERVER, "Cannot create PID file %s.\n", pidfile.c_str()); return 1; } sLog->outInfo(LOG_FILTER_AUTHSERVER, "Daemon PID: %u\n", pid); } // Initialize the database connection if (!StartDB()) return 1; // Get the list of realms for the server sRealmList->Initialize(ConfigMgr::GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { sLog->outError(LOG_FILTER_AUTHSERVER, "No valid realms specified."); return 1; } // Launch the listening network socket RealmAcceptor acceptor; int32 rmport = ConfigMgr::GetIntDefault("RealmServerPort", 3724); if (rmport < 0 || rmport > 0xFFFF) { sLog->outError(LOG_FILTER_AUTHSERVER, "Specified port out of allowed range (1-65535)"); return 1; } std::string bind_ip = ConfigMgr::GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(uint16(rmport), bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog->outError(LOG_FILTER_AUTHSERVER, "Auth server can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialise the signal handlers AuthServerSignalHandler SignalINT, SignalTERM; // Register authservers's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = ConfigMgr::GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) sLog->outError(LOG_FILTER_AUTHSERVER, "Processors marked in UseProcessors bitmask (hex) %x not accessible for authserver. Accessible processors bitmask (hex): %x", Aff, appAff); else if (SetProcessAffinityMask(hProcess, curAff)) sLog->outInfo(LOG_FILTER_AUTHSERVER, "Using processors (bitmask, hex): %x", curAff); else sLog->outError(LOG_FILTER_AUTHSERVER, "Can't set used processors (hex): %x", curAff); } } bool Prio = ConfigMgr::GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog->outInfo(LOG_FILTER_AUTHSERVER, "The auth server process priority class has been set to HIGH"); else sLog->outError(LOG_FILTER_AUTHSERVER, "Can't set auth server process priority class."); } } #endif // maximum counter for next ping uint32 numLoops = (ConfigMgr::GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; sLog->outInfo(LOG_FILTER_AUTHSERVER, "Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); } } // Close the Database Pool and library StopDB(); sLog->outInfo(LOG_FILTER_AUTHSERVER, "Halting process..."); return 0; }
// Launch the auth server extern int main(int argc, char **argv) { // Command line parsing char const* cfg_file = _DARMIX_REALM_CONFIG; #ifdef _WIN32 char const *options = ":c:s:"; #else char const *options = ":c:"; #endif ACE_Get_Opt cmd_opts(argc, argv, options); cmd_opts.long_option("version", 'v'); int option; while ((option = cmd_opts()) != EOF) { switch (option) { case 'c': cfg_file = cmd_opts.opt_arg(); break; case 'v': printf("%s\n", _FULLVERSION); return 0; #ifdef _WIN32 case 's': { const char *mode = cmd_opts.opt_arg(); if (!strcmp(mode, "install")) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } else if (!strcmp(mode, "uninstall")) { if (WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; } else if (!strcmp(mode, "run")) WinServiceRun(); else { sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode); usage(argv[0]); return 1; } break; } #endif case ':': sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt()); usage(argv[0]); return 1; default: sLog.outError("Runtime-Error: bad format of commandline arguments"); usage(argv[0]); return 1; } } if (!sConfig.SetSource(cfg_file)) { sLog.outError("Invalid or missing configuration file : %s", cfg_file); sLog.outError("Verify that the file exists and has \'[realm-server]\' written in the top of the file!"); return 1; } sLog.Initialize(); sLog.outString("*************************************************************************"); sLog.outString(" %s(realm) Rev: %s Hash: %s ", _PACKAGENAME, _REVISION, _HASH); sLog.outString("*************************************************************************"); sLog.outString("<Ctrl-C> to stop."); sLog.outString(" "); // Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion != _DARMIX_REALM_CONFVER) { sLog.outError(" WARNING:"); sLog.outError(" Your %s file is out of date.", cfg_file); sLog.outError(" Please, check for updates."); sleep(5); } sLog.outDetail("Using ACE: %s", ACE_VERSION); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog.outBasic("Max allowed open files is %d", ACE::max_handles()); // RealmServer PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); return 1; } sLog.outString( "Daemon PID: %u\n", pid ); } // Initialize the database connection if (!StartDB()) return 1; // Get the list of realms for the server sRealmList->Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { sLog.outError("No valid realms specified."); sleep(5); return 1; } // cleanup query // delete expired bans LoginDatabase.Execute("DELETE FROM account_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); // Launch the listening network socket ACE_Acceptor<AuthSocket, ACE_SOCK_Acceptor> acceptor; uint16 rmport = sConfig.GetIntDefault("AuthServerPort", DEFAULT_AUTHSERVER_PORT); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog.outError("Realm-Server can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Catch termination signals HookSignals(); sLog.outString("Realm-Server started"); // Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess,&appAff,&sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff ) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for authserver. Accessible processors bitmask (hex): %x",Aff,appAff); } else { if (SetProcessAffinityMask(hProcess,curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) sLog.outString("Realm-Server process priority class set to HIGH"); else sLog.outError("ERROR: Can't set AuthServer process priority class."); sLog.outString(); } } #endif // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ( (++loopCounter) == numLoops ) { loopCounter = 0; sLog.outDetail("Ping MySQL to keep connection alive"); LoginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1"); } #ifdef _WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } // Wait for the delay thread to exit LoginDatabase.HaltDelayThread(); // Remove signal handling before leaving UnhookSignals(); sLog.outString( "Halting process..." ); return 0; }
/// Launch the realm server extern int main(int argc, char **argv) { sLog.SetLogDB(false); ///- Command line parsing to get the configuration file name char const* cfg_file = _TRINITY_REALM_CONFIG; int c = 1; while(c < argc) { if (strcmp(argv[c],"-c") == 0) { if (++c >= argc) { sLog.outError("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } #ifdef _WIN32 //////////// //Services// //////////// if (strcmp(argv[c],"-s") == 0) { if (++c >= argc) { sLog.outError("Runtime-Error: -s option requires an input argument"); usage(argv[0]); return 1; } if (strcmp(argv[c],"install") == 0) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } else if (strcmp(argv[c],"uninstall") == 0) { if (WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; } else { sLog.outError("Runtime-Error: unsupported option %s",argv[c]); usage(argv[0]); return 1; } } if (strcmp(argv[c],"--service") == 0) WinServiceRun(); #endif ++c; } if (!sConfig.SetSource(cfg_file)) { sLog.outError("Invalid or missing configuration file : %s", cfg_file); sLog.outError("Verify that the file exists and has \'[authserver]\' written in the top of the file!"); return 1; } sLog.Initialize(); sLog.outString("%s (realm-daemon)", _FULLVERSION); sLog.outString("<Ctrl-C> to stop.\n"); sLog.outString("Using configuration file %s.", cfg_file); sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog.outBasic("Max allowed open files is %d", ACE::max_handles()); /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog.outError("Cannot create PID file %s.\n", pidfile.c_str()); return 1; } sLog.outString("Daemon PID: %u\n", pid); } ///- Initialize the database connection if (!StartDB()) return 1; ///- Initialize the log database sLog.SetLogDBLater(sConfig.GetBoolDefault("EnableLogDB", false)); // set var to enable DB logging once startup finished. sLog.SetLogDB(false); sLog.SetRealmID(0); // ensure we've set realm to 0 (realmd realmid) ///- Get the list of realms for the server sRealmList->Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { sLog.outError("No valid realms specified."); return 1; } ///- Launch the listening network socket RealmAcceptor acceptor; uint16 rmport = sConfig.GetIntDefault("RealmServerPort", 3724); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog.outError("Trinity realm can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialise the signal handlers RealmdSignalHandler SignalINT, SignalTERM; #ifdef _WIN32 RealmdSignalHandler SignalBREAK; #endif /* _WIN32 */ // Register realmd's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); #ifdef _WIN32 Handler.register_handler(SIGBREAK, &SignalBREAK); #endif /* _WIN32 */ ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); else if (SetProcessAffinityMask(hProcess, curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog.outString("TrinityRealm process priority class set to HIGH"); else sLog.outError("Can't set realmd process priority class."); sLog.outString(); } } #endif // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault("MaxPingTime", 30) * (MINUTE * 10)); uint32 loopCounter = 0; // possibly enable db logging; avoid massive startup spam by doing it here. if (sLog.GetLogDBLater()) { sLog.outString("Enabling database logging..."); sLog.SetLogDBLater(false); // login db needs thread for logging sLog.SetLogDB(true); } else sLog.SetLogDB(false); ///- Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; sLog.outDetail("Ping MySQL to keep connection alive"); LoginDatabase.Query("SELECT 1 FROM realmlist"); } #ifdef _WIN32 if (m_ServiceStatus == 0) stopEvent = true; else { while (m_ServiceStatus == 2) Sleep(1000); } #endif } ///- Close the Database Pool LoginDatabase.Close(); sLog.outString("Halting process..."); return 0; }
/// Launch the auth server extern int main(int argc, char** argv) { // Command line parsing to get the configuration file name char const* configFile = _TRINITY_REALM_CONFIG; int count = 1; while (count < argc) { if (strcmp(argv[count], "-c") == 0) { if (++count >= argc) { printf("Runtime-Error: -c option requires an input argument\n"); usage(argv[0]); return 1; } else configFile = argv[count]; } ++count; } if (!sConfigMgr->LoadInitial(configFile)) { printf("Invalid or missing configuration file : %s\n", configFile); printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n"); return 1; } sLog->outString("%s (authserver)", _FULLVERSION); sLog->outString("<Ctrl-C> to stop.\n"); sLog->outString(" ░ ░"); sLog->outString(" ▄▓▄ ░ ░░░▄▄▄▄▄▄▄▄▄▄░░░░ ░"); sLog->outString(" ▀ ░ ░ ▄▄▄██▓▓▓▓▓▓▓███▓▓▓▓▓▓▓▓▄▄▄ ░ ░"); sLog->outString(" ▄▄▄██████▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓██████▄▄▄"); sLog->outString(" ▄███▀▀ ▄██▓▓▓▓█████▓▓▓▓▓▓█████▓▓▓▓▓█▄ ▀▀███▄░"); sLog->outString(" ▓█▓ ░ ▀████████████▓▓████████████▀ ░ ░▓█▓░"); sLog->outString(" ▓██▌ ░░ ▒ ▀▀▀██████▓▓▓███████▀▀▀ ▒ ░ ▐██▓░"); sLog->outString(" ▐██▄░░░ ▓▓ ▀▀███▓████▀▀ ▓▓ ░░▄██▌"); sLog->outString(" ░▀██▌ ░░ ▀██▄ ░░ ▄▒█▄ ▄██▀ ░░░▐██▀░"); sLog->outString(" ▄▒▒▒▄▀█▄▄ ░░░░ ░░▄▄▄▓▓▓█▓▓▓▄▄▄▄░░ ░░░ ▄▄▓▀▄▒▒▄▄"); sLog->outString(" ▐▓▓▓▓▓███████▄▄▄▄█▒▓▓▓▓▓███████▓▓▓▓▒▒▒▒▄▄▄▄███████▓▓▓▓▓▌"); sLog->outString(" ░▓█▓▓█████████████████████▀▀ ▀▀▀█████▓▓▓▓▓████████████▓▓▓ ░"); sLog->outString(" ▐█▓▓▓█████▓▓▓█████▓███▀░ ▄▓▄ ░▀████▓██████████████▓▓▌"); sLog->outString(" ▀▀█▒▒▓▓▓▓▀▀░ ▀▀▀██▓█▌░ ░▓█▓██▄ ░▐██▓▓█▀▀▀ ▀▀██▓▓▓▒▒▀▀"); sLog->outString(" ▀ ░░ ▄ ▒█▓▓▓█▄ ▐██▓██▌░▄███▓▓█▒ ▄ ▄ ▀ ░"); sLog->outString(" ▄ ▄ ▄ ▄▄▄▄▄▄▀█▄ ░▓█▓▓▓████▄█▓▓▓█▄██████▓▓█▓░ ▄█▀█▄▄▄▄▄ ▄ ▄ ▄"); sLog->outString(" ▄ ▄ ▄ ▄▄▄▄▄▄▀▄▄ ▀█▓▓▓████████▓██████████▓▓█▀ ▄▄▀▄▄▄▄▄▄ ▄ ▄ ▄"); sLog->outString(" █▀█ ▒▄ ▄▀▀▀▀▀████▓▓████▀▀▀▀▀▄ ▄▒ █▀█"); sLog->outString(" ▓ ▓ ░▓█▓▐██▀▄▄▄ ▄▄ ▄▄▄ ▄▄▄▀▓█▌▓█▓░ ▓ ▓"); sLog->outString(" ▒ ▒ ▐█▒ ▐▓░ ▐▓░ ▐▓░▐█▌ ░▓▌ ▒▌ ▒█▌ ▒ ▒"); sLog->outString(" ░ ░ ▀ ▀ ▄ ▀ ▄ ▀▄ ▀ ▄ ▀ ▄ ▀ ▀ ░ ░"); sLog->outString(" ░ ░ ▀ ░▀ ▀▀ ▀▀▀ ▀░ ▀ ░ ░"); sLog->outString(" ░ ░ ▀▓▓▓▓██████▓▓▀ ░ ░"); sLog->outString(" ReinsCoreWotlk 2016(c) Open-sourced Game Emulation "); sLog->outString(" <https://github.com/ReinsCoreWotlk/Core> ReinsCoreWotlk 3.3.5 "); sLog->outString("Using configuration file %s.", configFile); sLog->outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog->outBasic("Max allowed open files is %d", ACE::max_handles()); // authserver PID file creation std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); if (!pidFile.empty()) { if (uint32 pid = CreatePIDFile(pidFile)) sLog->outError("Daemon PID: %u\n", pid); else { sLog->outError("Cannot create PID file %s.\n", pidFile.c_str()); return 1; } } // Initialize the database connection if (!StartDB()) return 1; // Initialize the log database sLog->SetLogDB(false); sLog->SetRealmID(0); // ensure we've set realm to 0 (authserver realmid) // Get the list of realms for the server sRealmList->Initialize(sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { sLog->outError("No valid realms specified."); return 1; } // Launch the listening network socket RealmAcceptor acceptor; int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724); if (rmport < 0 || rmport > 0xFFFF) { sLog->outError("Specified port out of allowed range (1-65535)"); return 1; } std::string bind_ip = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(uint16(rmport), bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog->outError("Auth server can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialize the signal handlers AuthServerSignalHandler SignalINT, SignalTERM; // Register authservers's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); #if defined(_WIN32) || defined(__linux__) ///- Handle affinity for multiple processors and process priority uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0); bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false); #ifdef _WIN32 // Windows HANDLE hProcess = GetCurrentProcess(); if (affinity > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { // remove non accessible processors ULONG_PTR currentAffinity = affinity & appAff; if (!currentAffinity) sLog->outError("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff); else if (SetProcessAffinityMask(hProcess, currentAffinity)) sLog->outString("server.authserver", "Using processors (bitmask, hex): %x", currentAffinity); else sLog->outError("server.authserver", "Can't set used processors (hex): %x", currentAffinity); } } if (highPriority) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog->outString("server.authserver", "authserver process priority class set to HIGH"); else sLog->outError("server.authserver", "Can't set authserver process priority class."); } #else // Linux if (affinity > 0) { cpu_set_t mask; CPU_ZERO(&mask); for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) if (affinity & (1 << i)) CPU_SET(i, &mask); if (sched_setaffinity(0, sizeof(mask), &mask)) sLog->outError("server.authserver", "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); else { CPU_ZERO(&mask); sched_getaffinity(0, sizeof(mask), &mask); sLog->outString("server.authserver", "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); } } if (highPriority) { if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) sLog->outError("server.authserver", "Can't set authserver process priority class, error: %s", strerror(errno)); else sLog->outString("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0)); } #endif #endif // maximum counter for next ping uint32 numLoops = (sConfigMgr->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // possibly enable db logging; avoid massive startup spam by doing it here. if (sConfigMgr->GetBoolDefault("EnableLogDB", false)) { sLog->outString("Enabling database logging..."); sLog->SetLogDB(true); } // Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; sLog->outDetail("Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); } } // Close the Database Pool and library StopDB(); sLog->outString("Halting process..."); return 0; }
/// Launch the realm server extern int main(int argc, char** argv) { ///- Command line parsing char const* cfg_file = _REALMD_CONFIG; char const* options = ":c:s:"; ACE_Get_Opt cmd_opts(argc, argv, options); cmd_opts.long_option("version", 'v'); char serviceDaemonMode = '\0'; int option; while ((option = cmd_opts()) != EOF) { switch (option) { case 'c': cfg_file = cmd_opts.opt_arg(); break; case 'v': printf("%s\n", _FULLVERSION(REVISION_DATE, REVISION_TIME, REVISION_NR, REVISION_ID)); return 0; case 's': { const char* mode = cmd_opts.opt_arg(); if (!strcmp(mode, "run")) { serviceDaemonMode = 'r'; } #ifdef WIN32 else if (!strcmp(mode, "install")) { serviceDaemonMode = 'i'; } else if (!strcmp(mode, "uninstall")) { serviceDaemonMode = 'u'; } #else else if (!strcmp(mode, "stop")) { serviceDaemonMode = 's'; } #endif else { sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } break; } case ':': sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt()); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; default: sLog.outError("Runtime-Error: bad format of commandline arguments"); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } } #ifdef WIN32 // windows service command need execute before config read switch (serviceDaemonMode) { case 'i': if (WinServiceInstall()) { sLog.outString("Installing service"); } return 1; case 'u': if (WinServiceUninstall()) { sLog.outString("Uninstalling service"); } return 1; case 'r': WinServiceRun(); break; } #endif if (!sConfig.SetSource(cfg_file)) { sLog.outError("Could not find configuration file %s.", cfg_file); Log::WaitBeforeContinueIfNeed(); return 1; } #ifndef WIN32 // posix daemon commands need apply after config read switch (serviceDaemonMode) { case 'r': startDaemon(); break; case 's': stopDaemon(); break; } #endif sLog.Initialize(); sLog.outString("%s [realm-daemon]", _FULLVERSION(REVISION_DATE, REVISION_TIME, REVISION_NR, REVISION_ID)); sLog.outString("<Ctrl-C> to stop.\n"); sLog.outString("Using configuration file %s.", cfg_file); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); Log::WaitBeforeContinueIfNeed(); } DETAIL_LOG("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); if (SSLeay() < 0x009080bfL) { DETAIL_LOG("WARNING: Outdated version of OpenSSL lib. Logins to server may not work!"); DETAIL_LOG("WARNING: Minimal required version [OpenSSL 0.9.8k]"); } DETAIL_LOG("Using ACE: %s", ACE_VERSION); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog.outBasic("Max allowed open files is %d", ACE::max_handles()); /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog.outError("Can not create PID file %s.\n", pidfile.c_str()); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.outString("Daemon PID: %u\n", pid); } ///- Initialize the database connection if (!StartDB()) { Log::WaitBeforeContinueIfNeed(); return 1; } ///- Get the list of realms for the server sRealmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList.size() == 0) { sLog.outError("No valid realms specified."); Log::WaitBeforeContinueIfNeed(); return 1; } // cleanup query // set expired bans to inactive LoginDatabase.BeginTransaction(); LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.CommitTransaction(); ///- Launch the listening network socket ACE_Acceptor<AuthSocket, ACE_SOCK_Acceptor> acceptor; uint16 rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog.outError("MaNGOS realmd can not bind to %s:%d", bind_ip.c_str(), rmport); Log::WaitBeforeContinueIfNeed(); return 1; } ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x", Aff, appAff); } else { if (SetProcessAffinityMask(hProcess, curAff)) { sLog.outString("Using processors (bitmask, hex): %x", curAff); } else { sLog.outError("Can't set used processors (hex): %x", curAff); } } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) { sLog.outString("realmd process priority class set to HIGH"); } else { sLog.outError("Can't set realmd process priority class."); } sLog.outString(); } } #endif // server has started up successfully => enable async DB requests LoginDatabase.AllowAsyncTransactions(); // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; #ifndef WIN32 detachDaemon(); #endif ///- Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) { break; } if ((++loopCounter) == numLoops) { loopCounter = 0; DETAIL_LOG("Ping MySQL to keep connection alive"); LoginDatabase.Ping(); } #ifdef WIN32 if (m_ServiceStatus == 0) { stopEvent = true; } while (m_ServiceStatus == 2) { Sleep(1000); } #endif } ///- Wait for the delay thread to exit LoginDatabase.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString("Halting process..."); return 0; }
// Launch the auth server extern int main(int argc, char **argv) { sLog->SetLogDB(false); // Command line parsing to get the configuration file name char const *cfg_file = _TRINITY_REALM_CONFIG; int c = 1; while(c < argc) { if (strcmp(argv[c], "-c") == 0) { if (++c >= argc) { sLog->outError("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } ++c; } if (!sConfig->SetSource(cfg_file)) { sLog->outError("Invalid or missing configuration file : %s", cfg_file); sLog->outError("Verify that the file exists and has \'[authserver]\' written in the top of the file!"); return 1; } sLog->Initialize(); sLog->outString("ALiveCore2 LoginServer for World of Warcraft 3.3.5.12340"); sLog->outString(" _ _ _ "); sLog->outString(" / \\ | | (_)_ _____ "); sLog->outString(" / _ \\ | | | \\ \\ / / _ \\"); sLog->outString(" / ___ \\| |___| |\\ V / __/"); sLog->outString("/_/ \\_\\_____|_| \\_/ \\___|"); sLog->outString("C O R E"); sLog->outString(" "); sLog->outString(" ALiveCore 2011(c) World of Warcraft Server Emulation"); sLog->outString(" "); sLog->outString("http://wow-alive.de/"); sLog->outString(" "); sLog->outString("Using configuration file %s.", cfg_file); sLog->outString(" "); sLog->outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); sLog->outString(" "); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog->outBasic("Max allowed open files is %d", ACE::max_handles()); // authserver PID file creation std::string pidfile = sConfig->GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog->outError("Cannot create PID file %s.\n", pidfile.c_str()); return 1; } sLog->outString("LoginServer Progress ID: %u\n", pid); } // Initialize the database connection if (!StartDB()) return 1; // Initialize the log database sLog->SetLogDBLater(sConfig->GetBoolDefault("EnableLogDB", false)); // set var to enable DB logging once startup finished. sLog->SetLogDB(false); sLog->SetRealmID(0); // ensure we've set realm to 0 (authserver realmid) // Get the list of realms for the server sRealmList->Initialize(sConfig->GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { sLog->outError("No valid realms specified."); return 1; } // Launch the listening network socket RealmAcceptor acceptor; uint16 rmport = sConfig->GetIntDefault("RealmServerPort", 3724); std::string bind_ip = sConfig->GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog->outError("ALiveCore2 LoginServer can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialise the signal handlers AuthServerSignalHandler SignalINT, SignalTERM; // Register authservers's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig->GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) sLog->outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for authserver. Accessible processors bitmask (hex): %x", Aff, appAff); else if (SetProcessAffinityMask(hProcess, curAff)) sLog->outString("Using processors (bitmask, hex): %x", curAff); else sLog->outError("Can't set used processors (hex): %x", curAff); } sLog->outString(); } bool Prio = sConfig->GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog->outString("ALiveCore2 LoginServer process priority class has been set to HIGH"); else sLog->outError("Can't set ALiveCore2 LoginServer process priority class."); sLog->outString(); } } #endif // maximum counter for next ping uint32 numLoops = (sConfig->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // possibly enable db logging; avoid massive startup spam by doing it here. if (sLog->GetLogDBLater()) { sLog->outString("Enabling database logging..."); sLog->SetLogDBLater(false); // login db needs thread for logging sLog->SetLogDB(true); } else sLog->SetLogDB(false); // Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; sLog->outDetail("Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); } } // Close the Database Pool and library StopDB(); sLog->outString("Halting process..."); return 0; }
/// Launch the realm server extern int main(int argc, char** argv) { ///- Command line parsing std::string cfg_file; std::string serviceDaemonMode; boost::program_options::options_description description("Allowed options"); description.add_options() ("version,v", "print version and exit") ("help,h", "print commandline help and exit") ("config,c", boost::program_options::value<std::string>(&cfg_file)->default_value(_REALMD_CONFIG), "use as configuration file") #ifdef WIN32 ("service,s", boost::program_options::value<std::string>(&serviceDaemonMode), "running as service, arg functions: run, install, uninstall") #else ("service,s", boost::program_options::value<std::string>(&serviceDaemonMode), "running as daemon, arg functions: run, stop") #endif ; // parse option boost::program_options::variables_map vm; try { boost::program_options::store(boost::program_options::command_line_parser(argc, argv). options(description).run(), vm); boost::program_options::notify(vm); } catch (boost::program_options::unknown_option const& ex) { sLog.outError("Runtime-Error: unknown option %s", ex.get_option_name().c_str()); usage(description, argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } catch (boost::program_options::invalid_command_line_syntax const& ex) { sLog.outError("Runtime-Error: invalid syntax for option %s", ex.get_option_name().c_str()); usage(description, argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } if (vm.count("version")) { printf("%s\n", _FULLVERSION(REVISION_DATE, REVISION_TIME, REVISION_NR, REVISION_ID)); return 0; } if (vm.count("help")) { usage(description, argv[0]); return 0; } if (!serviceDaemonMode.empty()) { #ifdef WIN32 char const* const serviceModes[] = { "run", "install", "uninstall", NULL }; #else char const* const serviceModes[] = { "run", "stop", NULL }; #endif char const* const* mode_ptr = &serviceModes[0]; for(; *mode_ptr != NULL; ++mode_ptr) if (*mode_ptr == serviceDaemonMode) break; if (!*mode_ptr) { sLog.outError("Runtime-Error: -s unsupported argument %s", serviceDaemonMode.c_str()); usage(description, argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } } #ifdef WIN32 // windows service command need execute before config read switch (serviceDaemonMode[0]) { case 'i': if (WinServiceInstall()) sLog.outString("Installing service"); return 1; case 'u': if (WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; case 'r': WinServiceRun(); break; } #endif if (!sConfig.SetSource(cfg_file, "RealmdConf")) { sLog.outError("Could not find configuration file %s.", cfg_file.c_str()); Log::WaitBeforeContinueIfNeed(); return 1; } #ifndef WIN32 // posix daemon commands need apply after config read switch (serviceDaemonMode[0]) { case 'r': startDaemon(); break; case 's': stopDaemon(); break; } #endif sLog.Initialize(); sLog.outString("%s [realm-daemon]", _FULLVERSION(REVISION_DATE, REVISION_TIME, REVISION_NR, REVISION_ID)); sLog.outString("<Ctrl-C> to stop.\n"); sLog.outString("Using configuration file %s.", cfg_file.c_str()); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); Log::WaitBeforeContinueIfNeed(); } DETAIL_LOG("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); if (SSLeay() < 0x009080bfL) { DETAIL_LOG("WARNING: Outdated version of OpenSSL lib. Logins to server may not work!"); DETAIL_LOG("WARNING: Minimal required version [OpenSSL 0.9.8k]"); } DETAIL_LOG("Using ACE: %s", ACE_VERSION); DETAIL_LOG("Using BOOST: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100); sLog.outBasic("Max allowed open files is %d", boost::asio::socket_base::max_connections); /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog.outError("Cannot create PID file %s.\n", pidfile.c_str()); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.outString("Daemon PID: %u\n", pid); } ///- Initialize the database connection if (!StartDB()) { Log::WaitBeforeContinueIfNeed(); return 1; } ///- Get the list of realms for the server sRealmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList.size() == 0) { sLog.outError("No valid realms specified."); Log::WaitBeforeContinueIfNeed(); return 1; } // cleanup query // set expired bans to inactive LoginDatabase.BeginTransaction(); LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.CommitTransaction(); ///- Launch the listening network socket uint16 rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); std::auto_ptr< SessionManager > manager(new SessionManager()); if (!manager->StartNetwork(rmport, bind_ip)) { sLog.outError("MaNGOS realmd can not bind to %s:%d", bind_ip.c_str(), rmport); Log::WaitBeforeContinueIfNeed(); return 1; } ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x", Aff, appAff); } else { if (SetProcessAffinityMask(hProcess, curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog.outString("realmd process priority class set to HIGH"); else sLog.outError("Can't set realmd process priority class."); sLog.outString(); } } #endif // server has started up successfully => enable async DB requests LoginDatabase.AllowAsyncTransactions(); // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; #ifndef WIN32 detachDaemon(); #endif ///- Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it boost::this_thread::sleep(boost::posix_time::milliseconds(10)); if ((++loopCounter) == numLoops) { loopCounter = 0; DETAIL_LOG("Ping MySQL to keep connection alive"); LoginDatabase.Ping(); } #ifdef WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } manager->StopNetwork(); manager.reset(); ///- Wait for the delay thread to exit LoginDatabase.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString("Halting process..."); return 0; }
/// Launch the realm server int main(int argc, char* argv[]) { std::string configFile, serviceParameter; boost::program_options::options_description desc("Allowed options"); desc.add_options() ("config,c", boost::program_options::value<std::string>(&configFile)->default_value(_REALMD_CONFIG), "configuration file") ("version,v", "print version and exit") #ifdef _WIN32 ("s", boost::program_options::value<std::string>(&serviceParameter), "<run, install, uninstall> service"); #else ("s", boost::program_options::value<std::string>(&serviceParameter), "<run, stop> service"); #endif boost::program_options::variables_map vm; try { boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); boost::program_options::notify(vm); } catch (boost::program_options::error const& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; std::cerr << desc << std::endl; return 1; } #ifdef _WIN32 // windows service command need execute before config read if (vm.count("s")) { switch (::tolower(serviceParameter[0])) { case 'i': if (WinServiceInstall()) sLog.outString("Installing service"); return 1; case 'u': if (WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; case 'r': WinServiceRun(); break; } } #endif if (!sConfig.SetSource(configFile)) { sLog.outError("Could not find configuration file %s.", configFile.c_str()); Log::WaitBeforeContinueIfNeed(); return 1; } #ifndef _WIN32 // posix daemon commands need apply after config read if (vm.count("s")) { switch (::tolower(serviceParameter[0])) { case 'r': startDaemon(); break; case 's': stopDaemon(); break; } } #endif sLog.Initialize(); sLog.outString("%s [realm-daemon]", _FULLVERSION(REVISION_DATE, REVISION_ID)); sLog.outString("<Ctrl-C> to stop.\n"); sLog.outString("Using configuration file %s.", configFile.c_str()); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); Log::WaitBeforeContinueIfNeed(); } DETAIL_LOG("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); if (SSLeay() < 0x009080bfL) { DETAIL_LOG("WARNING: Outdated version of OpenSSL lib. Logins to server may not work!"); DETAIL_LOG("WARNING: Minimal required version [OpenSSL 0.9.8k]"); } /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile"); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog.outError("Cannot create PID file %s.\n", pidfile.c_str()); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.outString("Daemon PID: %u\n", pid); } ///- Initialize the database connection if (!StartDB()) { Log::WaitBeforeContinueIfNeed(); return 1; } ///- Get the list of realms for the server sRealmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList.size() == 0) { sLog.outError("No valid realms specified."); Log::WaitBeforeContinueIfNeed(); return 1; } // cleanup query // set expired bans to inactive LoginDatabase.BeginTransaction(); LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.CommitTransaction(); // FIXME - more intelligent selection of thread count is needed here. config option? MaNGOS::Listener<AuthSocket> listener(sConfig.GetStringDefault("BindIP", "0.0.0.0"), sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT), 1); ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x", Aff, appAff); } else { if (SetProcessAffinityMask(hProcess, curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog.outString("realmd process priority class set to HIGH"); else sLog.outError("Can't set realmd process priority class."); sLog.outString(); } } #endif // server has started up successfully => enable async DB requests LoginDatabase.AllowAsyncTransactions(); // maximum counter for next ping auto const numLoops = sConfig.GetIntDefault("MaxPingTime", 30) * MINUTE * 10; uint32 loopCounter = 0; #ifndef _WIN32 detachDaemon(); #endif ///- Wait for termination signal while (!stopEvent) { if ((++loopCounter) == numLoops) { loopCounter = 0; DETAIL_LOG("Ping MySQL to keep connection alive"); LoginDatabase.Ping(); } std::this_thread::sleep_for(std::chrono::milliseconds(100)); #ifdef _WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } ///- Wait for the delay thread to exit LoginDatabase.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString("Halting process..."); return 0; }
/// Launch the realm server extern int main(int argc, char **argv) { ///- Command line parsing char const* cfg_file = _REALMD_CONFIG; #ifdef WIN32 char const *options = ":c:s:"; #else char const *options = ":c:"; #endif ACE_Get_Opt cmd_opts(argc, argv, options); cmd_opts.long_option("version", 'v'); int option; while ((option = cmd_opts()) != EOF) { switch (option) { case 'c': cfg_file = cmd_opts.opt_arg(); break; case 'v': printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); return 0; #ifdef WIN32 case 's': { const char *mode = cmd_opts.opt_arg(); if (!strcmp(mode, "install")) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } else if (!strcmp(mode, "uninstall")) { if (WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; } else if (!strcmp(mode, "run")) WinServiceRun(); else { sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } break; } #endif case ':': sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt()); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; default: sLog.outError("Runtime-Error: bad format of commandline arguments"); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } } if (!sConfig.SetSource(cfg_file)) { sLog.outError("Could not find configuration file %s.", cfg_file); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.Initialize(); sLog.outString( "%s [realm-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID) ); sLog.outString( "<Ctrl-C> to stop.\n" ); sLog.outString("Using configuration file %s.", cfg_file); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); Log::WaitBeforeContinueIfNeed(); } DETAIL_LOG("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); if (SSLeay() < 0x009080bfL ) { DETAIL_LOG("WARNING: Outdated version of OpenSSL lib. Logins to server may not work!"); DETAIL_LOG("WARNING: Minimal required version [OpenSSL 0.9.8k]"); } DETAIL_LOG("Using ACE: %s", ACE_VERSION); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog.outBasic("Max allowed open files is %d", ACE::max_handles()); /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if(!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if( !pid ) { sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.outString( "Daemon PID: %u\n", pid ); } ///- Initialize the database connection if(!StartDB()) { Log::WaitBeforeContinueIfNeed(); return 1; } ///- Get the list of realms for the server sRealmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList.size() == 0) { sLog.outError("No valid realms specified."); Log::WaitBeforeContinueIfNeed(); return 1; } // cleanup query // set expired bans to inactive LoginDatabase.BeginTransaction(); LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.CommitTransaction(); ///- Launch the listening network socket ACE_Acceptor<AuthSocket, ACE_SOCK_Acceptor> acceptor; uint16 rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if(acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog.outError("MaNGOS realmd can not bind to %s:%d", bind_ip.c_str(), rmport); Log::WaitBeforeContinueIfNeed(); return 1; } // FG: "bad points" system related uint32 badPointsDropInterval = sConfig.GetIntDefault("BadPoints.DropInterval", HOUR); uint32 badPointsDropAmount = sConfig.GetIntDefault("BadPoints.DropAmount", 1); uint32 badPointsDropWaitTime = sConfig.GetIntDefault("BadPoints.WaitTime", WEEK); IntervalTimer badPointsTimer; badPointsTimer.SetInterval(badPointsDropInterval * IN_MILLISECONDS); ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if(Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if(!curAff ) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); } else { if(SetProcessAffinityMask(hProcess,curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if(Prio) { if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) sLog.outString("realmd process priority class set to HIGH"); else sLog.outError("Can't set realmd process priority class."); sLog.outString(); } } #endif //server has started up successfully => enable async DB requests LoginDatabase.AllowAsyncTransactions(); // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; uint32 last_ping_time = 0; uint32 now = WorldTimer::getMSTime(); uint32 diff; uint32 lasttime = now; uint32 last_ipprops_cleanup = 0; ///- Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; now = WorldTimer::getMSTime(); diff = WorldTimer::getMSTimeDiff(lasttime, now); lasttime = now; badPointsTimer.Update(diff); if( (++loopCounter) == numLoops ) { // FG: protect against network system overloading // if that happens, force realmd close (autorestarter ftw!) if(WorldTimer::getMSTimeDiff(last_ping_time, now) < 10000) { sLog.outError("NETWORK SYSTEM OVERLOAD"); raise(SIGSEGV); // force close abort(); } last_ping_time = now; loopCounter = 0; DETAIL_LOG("Ping MySQL to keep connection alive"); LoginDatabase.Ping(); } // FG: clear flood protect buffer periodically if(WorldTimer::getMSTimeDiff(last_ipprops_cleanup, now) > 30000) // flush stored IPs every 30 secs { last_ipprops_cleanup = now; uint32 flushed = 0, blocked = 0, stored = 0; CleanupIPPropmap(flushed, blocked, stored); sLog.outDetail("IPProp: Flushed %u total, %u of them blocked, now %u stored", flushed, blocked, stored); } // FG: handle "bad points" drop if(badPointsTimer.Passed()) { badPointsTimer.Reset(); if(badPointsDropAmount) { uint64 goodtime = uint64(time(NULL)) - badPointsDropWaitTime; LoginDatabase.Execute("UPDATE account_badpoints SET maxpts = curpts WHERE maxpts < curpts"); LoginDatabase.PExecute("UPDATE account_badpoints SET curpts = 0 WHERE curpts <= %u AND lasttime < "UI64FMTD, badPointsDropAmount, goodtime); LoginDatabase.PExecute("UPDATE account_badpoints SET curpts = curpts - %u WHERE curpts > %u AND lasttime < "UI64FMTD, badPointsDropAmount, badPointsDropAmount, goodtime); } } #ifdef WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } ///- Wait for the delay thread to exit LoginDatabase.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString( "Halting process..." ); return 0; }
// Launch the auth server extern int main(int argc, char **argv) { sLogMgr->ResetLogDb(); // Command line parsing to get the configuration file name char const* cfg_file = _AUTHSERVER_CONFIG; int c = 1; while (c < argc) { if (strcmp(argv[c], "-c") == 0) { if (++c >= argc) { sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } ++c; } if (!ConfigMgr::Load(cfg_file)) { sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "Invalid or missing configuration file : %s", cfg_file); sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "Verify that the file exists and has \'[authserver]\' written in the top of the file!"); return 1; } sLogMgr->Initialize(); sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, "%s (authserver)", _FULLVERSION); sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, "<Ctrl-C> to stop.\n"); sLog->outString("####### ####### # # # # "); sLog->outString(" # ##### # # # # # # # # # ## ## # # "); sLog->outString(" # # # # # # # # # ## ## # # # # # # # "); sLog->outString(" # # # # # # # # # # ## # ##### # # # # # "); sLog->outString(" # ##### # # # # # # # # # # # # # "); sLog->outString(" # # # # # # # # # # # # # # # # "); sLog->outString(" # # # # ###### ###### # #### # # ####### # # ##### "); sLog->outString(" "); sLog->outString("World of Warcraft: Cataclysm Emulator Framework"); sLog->outString("Arkania Community 2011 (c) "); sLog->outString("Website: http://arkania.net "); sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, "Using configuration file %s.", cfg_file); sLogMgr->WriteLn(SERVER_LOG, LOGL_INFO, "%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLogMgr->WriteLn(SERVER_LOG, LOGL_WARNING, "Max allowed open files is %d", ACE::max_handles()); // authserver PID file creation std::string pidfile = ConfigMgr::GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "Cannot create PID file %s.\n", pidfile.c_str()); return 1; } sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, "Daemon PID: %u\n", pid); } // Initialize the database connection if (!StartDB()) return 1; // Initialize the log database sLogMgr->ResetLogDb(); sLogMgr->SetRealmId(0); // Get the list of realms for the server sRealmList->Initialize(ConfigMgr::GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "No valid realms specified."); return 1; } // Launch the listening network socket RealmAcceptor acceptor; uint16 rmport = ConfigMgr::GetIntDefault("RealmServerPort", 3724); std::string bind_ip = ConfigMgr::GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "Auth server can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialise the signal handlers AuthServerSignalHandler SignalINT, SignalTERM; // Register authservers's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = ConfigMgr::GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "Processors marked in UseProcessors bitmask (hex) %x not accessible for authserver. Accessible processors bitmask (hex): %x", Aff, appAff); else if (SetProcessAffinityMask(hProcess, curAff)) sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, "Using processors (bitmask, hex): %x", curAff); else sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "Can't set used processors (hex): %x", curAff); } sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, std::string()); } bool Prio = ConfigMgr::GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, "The auth server process priority class has been set to HIGH"); else sLogMgr->WriteLn(SERVER_LOG, LOGL_ERROR, "Can't set auth server process priority class."); sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, std::string()); } } #endif sLog->outString("%s (authserver-daemon) ready...", _FULLVERSION); // maximum counter for next ping uint32 numLoops = (ConfigMgr::GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // possibly enable db logging; avoid massive startup spam by doing it here. sLogMgr->SetLogDb(); // Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; sLogMgr->WriteLn(SERVER_LOG, LOGL_INFO, "Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); } } // Close the Database Pool and library StopDB(); sLogMgr->WriteLn(SERVER_LOG, LOGL_STRING, "Halting process..."); return 0; }
/// Launch the auth server extern int main(int argc, char** argv) { // Command line parsing to get the configuration file name char const* configFile = _TRINITY_REALM_CONFIG; int count = 1; while (count < argc) { if (strcmp(argv[count], "-c") == 0) { if (++count >= argc) { printf("Runtime-Error: -c option requires an input argument\n"); usage(argv[0]); return 1; } else configFile = argv[count]; } ++count; } if (!sConfigMgr->LoadInitial(configFile)) { printf("Invalid or missing configuration file : %s\n", configFile); printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n"); return 1; } TC_LOG_INFO("server.authserver", "%s (authserver)", _FULLVERSION); TC_LOG_INFO("server.authserver", " "); TC_LOG_INFO("server.authserver", " A World of Warcraft Cataclsym 4.3.4 Emulator "); TC_LOG_INFO("server.authserver", " _/_/ _/ _/_/_/ _/_/ _/_/_/ _/_/_/_/ "); TC_LOG_INFO("server.authserver", " _/ _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ "); TC_LOG_INFO("server.authserver", " _/_/_/_/ _/_/ _/_/ _/ _/ _/ _/_/_/ _/_/_/ "); TC_LOG_INFO("server.authserver", " _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ "); TC_LOG_INFO("server.authserver", " _/ _/ _/ _/ _/ _/_/_/ _/_/ _/ _/ _/_/_/_/ "); TC_LOG_INFO("server.authserver", " Arkania Community (c) 2014!"); TC_LOG_INFO("server.authserver", " <http://arkania.net/>"); TC_LOG_INFO("server.authserver", " "); TC_LOG_INFO("server.authserver", "<Ctrl-C> to stop.\n"); TC_LOG_INFO("server.authserver", "Using configuration file %s.", configFile); TC_LOG_INFO("server.authserver", "%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif TC_LOG_DEBUG("server.authserver", "Max allowed open files is %d", ACE::max_handles()); // authserver PID file creation std::string pidFile = sConfigMgr->GetStringDefault("PidFile", ""); if (!pidFile.empty()) { if (uint32 pid = CreatePIDFile(pidFile)) TC_LOG_INFO("server.authserver", "Daemon PID: %u\n", pid); else { TC_LOG_ERROR("server.authserver", "Cannot create PID file %s.\n", pidFile.c_str()); return 1; } } // Initialize the database connection if (!StartDB()) return 1; // Get the list of realms for the server sRealmList->Initialize(sConfigMgr->GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { TC_LOG_ERROR("server.authserver", "No valid realms specified."); return 1; } // Launch the listening network socket RealmAcceptor acceptor; int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724); if (rmport < 0 || rmport > 0xFFFF) { TC_LOG_ERROR("server.authserver", "Specified port out of allowed range (1-65535)"); return 1; } std::string bind_ip = sConfigMgr->GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(uint16(rmport), bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { TC_LOG_ERROR("server.authserver", "Auth server can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialize the signal handlers AuthServerSignalHandler SignalINT, SignalTERM; // Register authservers's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); #if defined(_WIN32) || defined(__linux__) ///- Handle affinity for multiple processors and process priority uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0); bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false); #ifdef _WIN32 // Windows HANDLE hProcess = GetCurrentProcess(); if (affinity > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { // remove non accessible processors ULONG_PTR currentAffinity = affinity & appAff; if (!currentAffinity) TC_LOG_ERROR("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff); else if (SetProcessAffinityMask(hProcess, currentAffinity)) TC_LOG_INFO("server.authserver", "Using processors (bitmask, hex): %x", currentAffinity); else TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x", currentAffinity); } } if (highPriority) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) TC_LOG_INFO("server.authserver", "authserver process priority class set to HIGH"); else TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class."); } #else // Linux if (affinity > 0) { cpu_set_t mask; CPU_ZERO(&mask); for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) if (affinity & (1 << i)) CPU_SET(i, &mask); if (sched_setaffinity(0, sizeof(mask), &mask)) TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); else { CPU_ZERO(&mask); sched_getaffinity(0, sizeof(mask), &mask); TC_LOG_INFO("server.authserver", "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); } } if (highPriority) { if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class, error: %s", strerror(errno)); else TC_LOG_INFO("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0)); } #endif #endif // maximum counter for next ping uint32 numLoops = (sConfigMgr->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; TC_LOG_INFO("server.authserver", "Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); } } // Close the Database Pool and library StopDB(); TC_LOG_INFO("server.authserver", "Halting process..."); return 0; }
/// Launch the realm server extern int main(int argc, char **argv) { sLog.SetLogDB(false); ///- Command line parsing to get the configuration file name char const* cfg_file = _RIBON_REALM_CONFIG; int c=1; while( c < argc ) { if( strcmp(argv[c],"-c") == 0) { if( ++c >= argc ) { sLog.outError("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } #ifdef WIN32 //////////// //Services// //////////// if( strcmp(argv[c],"-s") == 0) { if( ++c >= argc ) { sLog.outError("Runtime-Error: -s option requires an input argument"); usage(argv[0]); return 1; } if( strcmp(argv[c],"install") == 0) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } else if( strcmp(argv[c],"uninstall") == 0) { if(WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; } else { sLog.outError("Runtime-Error: unsupported option %s",argv[c]); usage(argv[0]); return 1; } } if( strcmp(argv[c],"--service") == 0) { WinServiceRun(); } //// #endif ++c; } if (!sConfig.SetSource(cfg_file)) { sLog.outError("Could not find configuration file %s.", cfg_file); return 1; } sLog.outString( "(logon-daemon) Revision: %s ", _FULLVERSION ); sLog.outString( "Build Date: %s", __DATE__ ); sLog.outString( "Build Time: %s", __TIME__ ); sLog.outString( "<Ctrl-C> to stop.\n" ); sLog.outString( "'########::'####:'########:::'#######::'##::: ##:"); sLog.outString( " ##.... ##:. ##:: ##.... ##:'##.... ##: ###:: ##:"); sLog.outString( " ##:::: ##:: ##:: ##:::: ##: ##:::: ##: ####: ##:"); sLog.outString( " ########::: ##:: ########:: ##:::: ##: ## ## ##:"); sLog.outString( " ##.. ##:::: ##:: ##.... ##: ##:::: ##: ##. ####:"); sLog.outString( " ##::. ##::: ##:: ##:::: ##: ##:::: ##: ##:. ###:"); sLog.outString( " ##:::. ##:'####: ########::. #######:: ##::. ##:"); sLog.outString( "..:::::..::....::........::::.......:::..::::..::"); sLog.outString( " L O G O N"); sLog.outString( "http://www.dark-resurrection.de/wowsp/ \n"); sLog.outString("Using configuration file %s.", cfg_file); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your RibonLogon.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); clock_t pause = 3000 + clock(); while (pause > clock()) {} } sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); if (SSLeay() < 0x009080bfL ) { sLog.outDetail("WARNING: Outdated version of OpenSSL lib. Logins to server impossible!"); sLog.outDetail("WARNING: Minimal required version [OpenSSL 0.9.8k]"); } /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if(!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if( !pid ) { sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); return 1; } sLog.outString( "Daemon PID: %u\n", pid ); } ///- Initialize the database connection if(!StartDB()) return 1; ///- Initialize the log database if(sConfig.GetBoolDefault("EnableLogDB", false)) { // everything successful - set var to enable DB logging once startup finished. sLog.SetLogDBLater(true); sLog.SetLogDB(false); // ensure we've set realm to 0 (realmd realmid) sLog.SetRealmID(0); } else { sLog.SetLogDBLater(false); sLog.SetLogDB(false); sLog.SetRealmID(0); } ///- Get the list of realms for the server m_realmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (m_realmList.size() == 0) { sLog.outError("No valid realms specified."); return 1; } ///- Launch the listening network socket port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT ); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); SocketHandler h; ListenSocket<AuthSocket> authListenSocket(h); if ( authListenSocket.Bind(bind_ip.c_str(),rmport)) { sLog.outError( "RibonLogon can not bind to %s:%d",bind_ip.c_str(), rmport ); return 1; } h.Add(&authListenSocket); ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if(Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if(!curAff ) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); } else { if(SetProcessAffinityMask(hProcess,curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if(Prio) { if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) sLog.outString("RibonLogon process priority class set to HIGH"); else sLog.outError("ERROR: Can't set realmd process priority class."); sLog.outString(); } } #endif // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // possibly enable db logging; avoid massive startup spam by doing it here. if (sLog.GetLogDBLater()) { sLog.outString("Enabling database logging..."); sLog.SetLogDBLater(false); // login db needs thread for logging sLog.SetLogDB(true); } else { sLog.SetLogDB(false); sLog.SetLogDBLater(false); } ///- Wait for termination signal while (!stopEvent) { h.Select(0, 100000); if( (++loopCounter) == numLoops ) { loopCounter = 0; sLog.outDetail("Ping MySQL to keep connection alive"); delete loginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1"); } #ifdef WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } ///- Wait for the delay thread to exit loginDatabase.ThreadEnd(); loginDatabase.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString( "Halting process..." ); return 0; }
static int _StartBatch(MessageHandler *handler, char *name, char *param) { int pid; int pDBR[2], pDBW[2]; char line[SIZE_BUFF], **cmd; int rc; int pAPR[2], pAPW[2]; if (handler->loadpath == NULL) { handler->loadpath = ExecPath; } signal(SIGPIPE, SignalHandler); if (LibPath == NULL) { ExecPath = getenv("APS_EXEC_PATH"); } else { ExecPath = LibPath; } if (pipe(pAPR) != 0) { perror("pipe"); exit(1); } if (pipe(pAPW) != 0) { perror("pipe"); exit(1); } if (pipe(pDBR) != 0) { perror("pipe"); exit(1); } if (pipe(pDBW) != 0) { perror("pipe"); exit(1); } ExpandStart(line, handler->start, handler->loadpath, name, param); cmd = ParCommandLine(line); if (setjmp(SubError) == 0) { if ((pid = fork()) == 0) { dup2(pAPW[0], STDIN_FILENO); dup2(pAPR[1], STDOUT_FILENO); close(pAPW[0]); close(pAPW[1]); close(pAPR[0]); close(pAPR[1]); dup2(pDBW[0], DBIN_FILENO); dup2(pDBR[1], DBOUT_FILENO); close(pDBW[0]); close(pDBW[1]); close(pDBR[0]); close(pDBR[1]); execv(cmd[0], cmd); } else { close(pAPR[1]); close(pAPW[0]); fpDBR = FileToNet(pDBR[0]); close(pDBR[1]); fpDBW = FileToNet(pDBW[1]); close(pDBW[0]); StartDB(handler); } (void)wait(&pid); CancelDB(); CloseNet(fpDBW); CloseNet(fpDBR); rc = TRUE; } else { rc = FALSE; } return (rc); }
static Bool _ExecuteProcess(MessageHandler *handler, ProcessNode *node) { char *module; int pid; int pAPR[2], pAPW[2], pDBR[2], pDBW[2]; Bool rc; NETFILE *fpAPR, *fpAPW; char line[SIZE_BUFF], **cmd; if (handler->loadpath == NULL) { handler->loadpath = ExecPath; } signal(SIGPIPE, SignalHandler); module = ValueStringPointer(GetItemLongName(node->mcprec->value, "dc.module")); ExpandStart(line, handler->start, handler->loadpath, module, ""); cmd = ParCommandLine(line); if (pipe(pAPR) != 0) { perror("pipe"); exit(1); } if (pipe(pAPW) != 0) { perror("pipe"); exit(1); } if (pipe(pDBR) != 0) { perror("pipe"); exit(1); } if (pipe(pDBW) != 0) { perror("pipe"); exit(1); } if (setjmp(SubError) == 0) { if ((pid = fork()) == 0) { dup2(pAPW[0], STDIN_FILENO); dup2(pAPR[1], STDOUT_FILENO); close(pAPW[0]); close(pAPW[1]); close(pAPR[0]); close(pAPR[1]); dup2(pDBW[0], DBIN_FILENO); dup2(pDBR[1], DBOUT_FILENO); close(pDBW[0]); close(pDBW[1]); close(pDBR[0]); close(pDBR[1]); execv(cmd[0], cmd); } else { fpAPR = FileToNet(pAPR[0]); close(pAPR[1]); fpAPW = FileToNet(pAPW[1]); close(pAPW[0]); fpDBR = FileToNet(pDBR[0]); close(pDBR[1]); fpDBW = FileToNet(pDBW[1]); close(pDBW[0]); StartDB(handler); PutApplication(handler, fpAPW, node); GetApplication(handler, fpAPR, node); (void)wait(&pid); CancelDB(); signal(SIGPIPE, SIG_DFL); CloseNet(fpAPW); CloseNet(fpAPR); CloseNet(fpDBW); CloseNet(fpDBR); } rc = TRUE; } else { rc = FALSE; } return (rc); }