Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
string ClusterInterface::GenerateVersionString()
{
	char str[200];
	snprintf(str, 200, "ArcEmu r%u/%s-%s-%s", g_getRevision(), CONFIG, PLATFORM_TEXT, ARCH);
	return string(str);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
void CConsole::ProcessVersion()
{
    sLog.outString("Console: Server %s, Rev: %d", _FULLVERSION, g_getRevision());
}