void ClusterInterface::HandleAuthRequest(WorldPacket & pck) { uint32 x; pck >> x; Log.Debug("ClusterInterface", "Incoming auth request from %s (RS build %u)", _clientSocket->GetRemoteIP().c_str(), x); WorldPacket data(ICMSG_AUTH_REPLY, 50); data.append(key, 20); data << uint32(g_getRevision()); data << GenerateVersionString(); SendPacket(&data); m_latency = getMSTime() - m_latency; Log.Notice("ClusterInterface", "Latency between realm server is %u ms", m_latency); }
bool HandleInfoCommand(BaseConsole * pConsole, int argc, const char * argv[]) { uint32 clientsNum = (uint32)sWorld.GetSessionCount(); int gm = 0; int count = 0; int avg = 0; PlayerStorageMap::const_iterator itr; objmgr._playerslock.AcquireReadLock(); for (itr = objmgr._players.begin(); itr != objmgr._players.end(); itr++) { if(itr->second->GetSession()) { count++; avg += itr->second->GetSession()->GetLatency(); if(itr->second->GetSession()->GetPermissionCount()) gm++; } } objmgr._playerslock.ReleaseReadLock(); pConsole->Write("======================================================================\r\n"); pConsole->Write("Server Information: \r\n"); pConsole->Write("======================================================================\r\n"); pConsole->Write("Server Revision: Ascent r%u/%s-%s-%s (ascentemu.com)\r\n", g_getRevision(), CONFIG, PLATFORM_TEXT, ARCH); pConsole->Write("Server Uptime: %s\r\n", sWorld.GetUptimeString().c_str()); pConsole->Write("Current Players: %d (%d GMs, %d queued)\r\n", clientsNum, gm, 0); pConsole->Write("Active Thread Count: %u\r\n", ThreadPool.GetActiveThreadCount()); pConsole->Write("Free Thread Count: %u\r\n", ThreadPool.GetFreeThreadCount()); pConsole->Write("Average Latency: %.3fms\r\n", count ? ((float)((float)avg / (float)count)) : 0.0f); pConsole->Write("SQL Query Cache Size (World): %u queries delayed\r\n", WorldDatabase.GetQueueSize()); pConsole->Write("SQL Query Cache Size (Character): %u queries delayed\r\n", CharacterDatabase.GetQueueSize()); pConsole->Write("======================================================================\r\n\r\n"); return true; }
string ClusterInterface::GenerateVersionString() { char str[200]; snprintf(str, 200, "ArcEmu r%u/%s-%s-%s", g_getRevision(), CONFIG, PLATFORM_TEXT, ARCH); return string(str); }
void StatDumper::DumpStats() { if (!Filename) return; FILE * f = fopen(Filename, "w"); if (!f) return; // Dump Header fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fprintf(f, "<?xml-stylesheet type=\"text/xsl\" href=\"server_stats.xsl\"?>\n"); fprintf(f, "<serverpage>\n"); fprintf(f, " <status>\n"); std::deque<Player*> gms; { // Dump server information. #ifdef WIN32 fprintf(f, " <platform>Antrix/Win32 v2.1.0-%u</platform>\n", g_getRevision()); #else fprintf(f, " <platform>Antrix/Linux v2.1.0-%u</platform>\n", g_getRevision()); #endif char uptime[80]; GenerateUptimeString(uptime); float AvgLat; uint32 GMCount; int gm = 0; int count = 0; int avg = 0; // lock players reader objmgr._playerslock.AcquireReadLock(); HM_NAMESPACE::hash_map<uint32, Player*>::const_iterator itr; for (itr = objmgr._players.begin(); itr != objmgr._players.end(); itr++) { if(itr->second->GetSession() && itr->second->IsInWorld()) { count++; avg += itr->second->GetSession()->GetLatency(); if(itr->second->GetSession()->GetPermissionCount()) { gm++; gms.push_back(itr->second); } } } objmgr._playerslock.ReleaseReadLock(); AvgLat = count ? (float)((float)avg / (float)count) : 0; GMCount = gm; fprintf(f, " <uptime>%s</uptime>\n", uptime); fprintf(f, " <oplayers>%u</oplayers>\n", (unsigned int)(sWorld.AlliancePlayers + sWorld.HordePlayers)); fprintf(f, " <cpu>%2.2f</cpu>\n", GetCPUUsage()); fprintf(f, " <qplayers>%u</qplayers>\n", (unsigned int)sWorld.GetQueueCount()); fprintf(f, " <ram>%.3f</ram>\n", GetRAMUsage()); fprintf(f, " <avglat>%.3f</avglat>\n", AvgLat); fprintf(f, " <threads>%u</threads>\n", (unsigned int)sThreadMgr.GetThreadCount()); time_t t = time(NULL); fprintf(f, " <gmcount>%u</gmcount>\n", (unsigned int)GMCount); fprintf(f, " <lastupdate>%s</lastupdate>\n", asctime(localtime(&t))); fprintf(f, " <alliance>%u</alliance>\n", (unsigned int)sWorld.AlliancePlayers); fprintf(f, " <horde>%u</horde>\n", (unsigned int)sWorld.HordePlayers); fprintf(f, " <acceptedconns>%u</acceptedconns>\n", (unsigned int)sWorld.mAcceptedConnections); fprintf(f, " <peakcount>%u</peakcount>\n", (unsigned int)sWorld.PeakSessionCount); fprintf(f, " <wdbquerysize>%u</wdbquerysize>\n", (unsigned int)(((MySQLDatabase*)Database_World)->GetQueueSize())); fprintf(f, " <cdbquerysize>%u</cdbquerysize>\n", (unsigned int)(((MySQLDatabase*)Database_Character)->GetQueueSize())); } fprintf(f, " </status>\n"); Player * plr; uint32 t = time(NULL); char otime[100]; { fprintf(f, " <instances>\n"); // need a big buffer.. static char buf[500000]; memset(buf, 0, 500000); // Dump Instance Information sWorldCreator.BuildXMLStats(buf); fprintf(f, buf); fprintf(f, " </instances>\n"); } { // GM Information fprintf(f, " <gms>\n"); while(!gms.empty()) { plr = gms.front(); gms.pop_front(); FillOnlineTime(t - plr->OnlineTime, otime); fprintf(f, " <gmplr>\n"); fprintf(f, " <name>%s</name>\n", plr->GetName()); fprintf(f, " <race>%u</race>\n", plr->getRace()); fprintf(f, " <class>%u</class>\n", (unsigned int)plr->getClass()); fprintf(f, " <gender>%u</gender>\n", (unsigned int)plr->getGender()); fprintf(f, " <pvprank>%u</pvprank>\n", (unsigned int)plr->GetPVPRank()); fprintf(f, " <level>%u</level>\n", (unsigned int)plr->GetUInt32Value(UNIT_FIELD_LEVEL)); fprintf(f, " <map>%u</map>\n", (unsigned int)plr->GetMapId()); fprintf(f, " <areaid>%u</areaid>\n", (unsigned int)plr->GetAreaID()); fprintf(f, " <ontime>%s</ontime>\n", otime); fprintf(f, " <latency>%u</latency>\n", (unsigned int)plr->GetSession()->GetLatency()); fprintf(f, " <permissions>%s</permissions>\n", plr->GetSession()->GetPermissions()); fprintf(f, " </gmplr>\n"); } fprintf(f, " </gms>\n"); } { fprintf(f, " <sessions>\n"); // Dump Player Information objmgr._playerslock.AcquireReadLock(); HM_NAMESPACE::hash_map<uint32, Player*>::const_iterator itr; for (itr = objmgr._players.begin(); itr != objmgr._players.end(); itr++) { plr = itr->second; if(itr->second->GetSession() && itr->second->IsInWorld()) { FillOnlineTime(t - plr->OnlineTime, otime); fprintf(f, " <plr>\n"); fprintf(f, " <name>%s</name>\n", plr->GetName()); fprintf(f, " <race>%u</race>\n", (unsigned int)plr->getRace()); fprintf(f, " <class>%u</class>\n", (unsigned int)plr->getClass()); fprintf(f, " <gender>%u</gender>\n", (unsigned int)plr->getGender()); fprintf(f, " <pvprank>%u</pvprank>\n", (unsigned int)plr->GetPVPRank()); fprintf(f, " <level>%u</level>\n", (unsigned int)plr->GetUInt32Value(UNIT_FIELD_LEVEL)); fprintf(f, " <map>%u</map>\n", (unsigned int)plr->GetMapId()); fprintf(f, " <areaid>%u</areaid>\n", (unsigned int)plr->GetAreaID()); //requested by Zdarkside for he's online map. I hope it does not scre up any parser. If so, then make a better one :P fprintf(f, " <xpos>%f</xpos>\n", plr->GetPositionX ()); fprintf(f, " <ypos>%f</ypos>\n", plr->GetPositionY()); fprintf(f, " <ontime>%s</ontime>\n", otime); fprintf(f, " <latency>%u</latency>\n", (unsigned int)plr->GetSession()->GetLatency()); fprintf(f, " </plr>\n"); if(plr->GetSession()->GetPermissionCount() > 0) gms.push_back(plr); } } objmgr._playerslock.ReleaseReadLock(); fprintf(f, " </sessions>\n"); } fprintf(f, "</serverpage>\n"); fclose(f); }
bool Master::Run(int argc, char ** argv) { #ifdef WIN32 char * config_file = "antrix.conf"; char * realm_config_file = "realms.conf"; #else char * config_file = CONFDIR "/antrix.conf"; char * realm_config_file = CONFDIR "/realms.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 antrix_option longopts[] = { { "checkconf", antrix_no_argument, &do_check_conf, 1 }, { "screenloglevel", antrix_required_argument, &screen_log_level, 1 }, { "fileloglevel", antrix_required_argument, &file_log_level, 1 }, { "version", antrix_no_argument, &do_version, 1 }, { "conf", antrix_required_argument, NULL, 'c' }, { "realmconf", antrix_required_argument, NULL, 'r' }, { 0, 0, 0, 0 } }; char c; while ((c = antrix_getopt_long_only(argc, argv, ":f:", longopts, NULL)) != -1) { switch (c) { case 'c': config_file = new char[strlen(antrix_optarg)]; strcpy(config_file, antrix_optarg); break; case 'r': realm_config_file = new char[strlen(antrix_optarg)]; strcpy(realm_config_file, antrix_optarg); break; case 0: break; default: sLog.m_fileLogLevel = -1; sLog.m_screenLogLevel = 3; printf("Usage: %s [--checkconf] [--screenloglevel <level>] [--fileloglevel <level>] [--conf <filename>] [--realmconf <filename>] [--version]\n", argv[0]); return true; } } // Startup banner if(!do_version && !do_check_conf) { launch_thread(new TextLoggerThread); sLog.Init(-1, 3); } else { sLog.m_fileLogLevel = -1; sLog.m_screenLogLevel = 3; } sLog.outString("=============================================================================="); sLog.outString(BANNER, g_getRevision()); sLog.outString(""); sLog.outString("Copyright (c) 2007 Antrix Team. This software is under the QPL license, for"); sLog.outString("more information look under the COPYING file in this distribution."); sLog.outString("=============================================================================="); sLog.outString(""); if(do_version) return true; 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"); printf("\nChecking config file: %s\n", realm_config_file); if(Config.RealmConfig.SetSource(realm_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 true; } sLog.outString("The key combination <Ctrl-C> will safely shut down the server at any time."); sLog.outString(""); sLog.outString("Initializing File Loggers..."); Crash_Log = new TextLogger(FormatOutputString("logs", "CrashLog", true).c_str(), false); sLog.outString("Initializing Random Number Generators..."); uint32 seed = time(NULL); new MTRand(seed); srand(seed); sLog.outString("Starting Thread Manager...\n"); new ThreadMgr; uint32 LoadingTime = getMSTime(); sLog.outColor(TNORMAL, "Loading Config Files...\n"); sLog.outColor(TYELLOW, " >> %s :: ", config_file); if(Config.MainConfig.SetSource(config_file)) { sLog.outColor(TGREEN, "ok!"); sLog.outColor(TNORMAL, "\n"); } else { sLog.outColor(TRED, "fail."); sLog.outColor(TNORMAL, "\n"); return false; } /* 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 false; } sLog.outColor(TYELLOW, " >> %s :: ", realm_config_file); if(Config.RealmConfig.SetSource(realm_config_file)) { sLog.outColor(TGREEN, "ok!"); sLog.outColor(TNORMAL, "\n\n"); } else { sLog.outColor(TRED, "fail."); sLog.outColor(TNORMAL, "\n\n"); return false; } if(!_StartDB()) { return false; } sLog.outString(""); ScriptSystem = new ScriptEngine; ScriptSystem->Reload(); new EventMgr; new World; // open cheat log file Anticheat_Log = new SessionLogWriter(FormatOutputString("logs", "cheaters", false).c_str(), false); GMCommand_Log = new SessionLogWriter(FormatOutputString("logs", "gmcommand", false).c_str(), false); /* load the config file */ sWorld.Rehash(false); /* set new log levels */ if(screen_log_level != (int)DEF_VALUE_NOT_SET) sLog.SetScreenLoggingLevel(screen_log_level); if(file_log_level != (int)DEF_VALUE_NOT_SET) sLog.SetFileLoggingLevel(file_log_level); // Initialize Opcode Table WorldSession::InitPacketHandlerTable(); string host = Config.MainConfig.GetStringDefault("Listen", "Host", DEFAULT_HOST); int wsport = Config.MainConfig.GetIntDefault("Listen", "WorldServerPort", DEFAULT_WORLDSERVER_PORT); new ScriptMgr; sWorld.SetInitialWorldSettings(); sWorld.SetStartTime((uint32)time(NULL)); _HookSignals(); launch_thread(new CConsoleThread); uint32 realCurrTime, realPrevTime; realCurrTime = realPrevTime = getMSTime(); // initialize thread system sThreadMgr.Initialize(); // Socket loop! uint32 start; uint32 diff; uint32 last_time = now(); uint32 etime; uint32 next_printout = getMSTime(), next_send = getMSTime(); // Start Network Subsystem sLog.outString("Starting network subsystem..."); new SocketMgr; new SocketGarbageCollector; sSocketMgr.SpawnWorkerThreads(); sScriptMgr.LoadScripts(); sLog.outString("Threading system initialized, currently %u threads are active.", sThreadMgr.GetThreadCount()); LoadingTime = getMSTime() - LoadingTime; sLog.outString ("\nServer is ready for connections. Startup time: %ums\n", LoadingTime ); /* write pid file */ FILE * fPid = fopen("antrix.pid", "w"); if(fPid) { uint32 pid; #ifdef WIN32 pid = GetCurrentProcessId(); #else pid = getpid(); #endif fprintf(fPid, "%u", (unsigned int)pid); fclose(fPid); } #ifndef CLUSTERING /* Connect to realmlist servers / logon servers */ new LogonCommHandler(); sLogonCommHandler.Startup(); // Create listener ListenSocket<WorldSocket> * ls = new ListenSocket<WorldSocket>(host.c_str(), wsport); bool listnersockcreate = ls->IsOpen(); while(!m_stopEvent && listnersockcreate) #else new ClusterInterface; sClusterInterface.ConnectToRealmServer(); while(!m_stopEvent) #endif { start = now(); diff = start - last_time; #ifndef CLUSTERING sLogonCommHandler.UpdateSockets(); ls->Update(); #else sClusterInterface.Update(); #endif sSocketGarbageCollector.Update(); /* UPDATE */ last_time = now(); etime = last_time - start; if(m_ShutdownEvent) { if(getMSTime() >= next_printout) { if(m_ShutdownTimer > 60000.0f) { if(!((int)(m_ShutdownTimer)%60000)) sLog.outString("Server shutdown in %i minutes.", (int)(m_ShutdownTimer / 60000.0f)); } else sLog.outString("Server shutdown in %i seconds.", (int)(m_ShutdownTimer / 1000.0f)); next_printout = getMSTime() + 500; } if(getMSTime() >= next_send) { // broadcast packet. WorldPacket data(20); data.SetOpcode(SMSG_SERVER_MESSAGE); data << uint32(SERVER_MSG_SHUTDOWN_TIME); int time = m_ShutdownTimer / 1000; if(time > 0) { int mins = 0, secs = 0; if(time > 60) mins = time / 60; if(mins) time -= (mins*60); secs = time; char str[20]; snprintf(str, 20, "%02u:%02u", mins, secs); data << str; sWorld.SendGlobalMessage(&data, NULL); } next_send = getMSTime() + 1000; } if(diff >= m_ShutdownTimer) break; else m_ShutdownTimer -= diff; } Database_Character->CheckConnections(); Database_World->CheckConnections(); sWorld.UpdateQueuedSessions(diff); if(50 > etime) Sleep(50 - etime); } _UnhookSignals(); CConsoleThread *thread = (CConsoleThread*)sThreadMgr.GetThreadByType(THREADTYPE_CONSOLEINTERFACE); ASSERT(thread); thread->SetThreadState(THREADSTATE_TERMINATE); // have to cleanup manually. sThreadMgr.RemoveThread(thread); sLog.outString("Killing all sockets and network subsystem."); #ifndef CLUSTERING ls->Close(); delete ls; #endif #ifdef WIN32 sSocketMgr.ShutdownThreads(); #endif sSocketMgr.CloseAll(); // begin server shutdown time_t st = time(NULL); sLog.outString("Server shutdown initiated at %s", ctime(&st)); // send a query to wake it up if its inactive sLog.outString("Executing pending database queries and closing database thread..."); // kill the database thread first so we don't lose any queries/data ((MySQLDatabase*)Database_Character)->SetThreadState(THREADSTATE_TERMINATE); ((MySQLDatabase*)Database_World)->SetThreadState(THREADSTATE_TERMINATE); CharacterDatabase.Execute("UPDATE characters SET online = 0"); WorldDatabase.Execute("UPDATE characters SET online = 0"); // wait for it to finish its work while(((MySQLDatabase*)Database_Character)->ThreadRunning || ((MySQLDatabase*)Database_World)->ThreadRunning) { Sleep(100); } sThreadMgr.RemoveThread(((MySQLDatabase*)Database_Character)); sThreadMgr.RemoveThread(((MySQLDatabase*)Database_World)); sLog.outString("All pending database operations cleared.\n"); sWorld.SaveAllPlayers(); sLog.outString(""); delete LogonCommHandler::getSingletonPtr(); sWorld.ShutdownClasses(); sLog.outString("\nDeleting World..."); delete World::getSingletonPtr(); sLog.outString("Deleting Event Manager..."); delete EventMgr::getSingletonPtr(); sLog.outString("Terminating MySQL connections...\n"); _StopDB(); sLog.outString("Deleting Network Subsystem..."); delete SocketMgr::getSingletonPtr(); delete SocketGarbageCollector::getSingletonPtr(); sLog.outString("Deleting Script Engine..."); delete ScriptSystem; sLog.outString("\nServer shutdown completed successfully.\n"); // close the logs TextLogger::Thread->Die(); #ifdef WIN32 WSACleanup(); // Terminate Entire Application //HANDLE pH = OpenProcess(PROCESS_TERMINATE, TRUE, GetCurrentProcessId()); //TerminateProcess(pH, 0); //CloseHandle(pH); #endif return true; }
void CConsole::ProcessVersion() { sLog.outString("Console: Server %s, Rev: %d", _FULLVERSION, g_getRevision()); }