void CLobbyApp::UpdatePerfCounters() { static CTempTimer timerPerfCounters("assembling perf info", .05f); timerPerfCounters.Start(); m_fmClients.GetSendQueue(&(m_pCounters->cOutboundQueueLength), &(m_pCounters->cOutboundQueueSize)); m_fmClients.GetReceiveQueue(&(m_pCounters->cInboundQueueLength), &(m_pCounters->cInboundQueueSize)); m_pCounters->cPlayersLobby = m_fmClients.GetCountConnections(); m_pCounters->cServers = m_fmServers.GetConnectionCount(); // Get all the per server stuff, and agregate the count of missions and players ListConnections::Iterator iterCnxn(*m_fmServers.GetConnections()); int cMissions = 0; DWORD cPlayers = 0; while (!iterCnxn.End()) { CFLServer * pServerT = CFLServer::FromConnection(*iterCnxn.Value()); cMissions += (pServerT->GetCounters()->cMissions = pServerT->GetMissions()->GetCount()); cPlayers += (pServerT->GetCounters()->cPlayers = pServerT->GetPlayerCount()); pServerT->GetCounters()->percentLoad = pServerT->GetPercentLoad(); iterCnxn.Next(); } m_pCounters->cMissions = cMissions; m_pCounters->cPlayersMissions = cPlayers; timerPerfCounters.Stop(); }
void CLobbyApp::SendGameInfo() { ZGameServerInfoMsg* gameInfo = GetGameServerInfoMsg(); SetVariableGameInfo(); //must do endian so both side of network get correct numbers //gameinfo used on Unix and Intel boxes //note that doing this once will invalidate all numbers //so set gameInfo->info[0] numbers again. ZGameInstanceInfoMsgEndian( gameInfo->info ); //send, usually to many Ip addresses which are Zone Web servers, so add this to your game configuration for (int i = 0; i < m_cReportServers; i++) ZGameInfoSendTo(m_rgulIP[i], 2000, GetGameServerInfoMsg(), sizeof(m_GameInfoBuf)); //Imago 9/14 if (m_fmServers.GetConnections()->GetCount() > 0) { int offset = 0; char * PostData = new char[BUFFSIZE]; ZeroMemory(PostData,BUFFSIZE); ListConnections::Iterator iterCnxn(*m_fmServers.GetConnections()); while (!iterCnxn.End()) { CFLServer * pServerT = CFLServer::FromConnection(*iterCnxn.Value()); MissionList::Iterator iterMission(*pServerT->GetMissions()); while (!iterMission.End()){ CFLMission* mission = iterMission.Value(); FMD_LS_LOBBYMISSIONINFO *info = mission->GetMissionInfo(); if (info) { memcpy(PostData + offset, info, info->cbmsg); offset += info->cbmsg; iterMission.Next(); } } iterCnxn.Next(); } if (offset > 0) { pHTTP settings; Strcpy(settings.hdrs,"Content-Type: application/octet-stream\r\n"); Strcpy(settings.verb,"POST"); Strcpy(settings.uri,"/lobbyinfo.ashx"); Strcpy(settings.host,"allegiancezone.com"); ZeroMemory(settings.data,BUFFSIZE); memcpy(settings.data,PostData,offset); settings.size = offset; DWORD lpExitCode; GetExitCodeThread(m_threadPost,&lpExitCode); if (lpExitCode != STILL_ACTIVE) { debugf("Creating post thread.\n"); DWORD dum; m_threadPost = CreateThread(NULL, 0, PostThread, (void*)&settings, 0, &dum); } else debugf("Post thread was still running...\n"); } } }
void CLobbyApp::RollCall() { ListConnections::Iterator iterCnxn(*m_fmServers.GetConnections()); while (!iterCnxn.End()) { CFMConnection & cnxn = *iterCnxn.Value(); iterCnxn.Next(); // have to move iterator FIRST, because we might kill the current node CFLServer * pServerT = CFLServer::FromConnection(cnxn); if (pServerT->GetHere()) { // not combining ifs, since order would matter if (cnxn.IncAbsentCount() > 4) // dead--nuke 'em { m_plas->LogEvent(EVENTLOG_WARNING_TYPE, LE_ServerMissedRollCall, cnxn.GetName()); m_fmServers.DeleteConnection(cnxn); } } } }
void CLobbyApp::SendGameInfoToAz() { //Imago 9/14 if (m_fmServers.GetConnections()->GetCount() > 0) { int offset = 0; char * PostData = new char[BUFFSIZE]; ZeroMemory(PostData, BUFFSIZE); ListConnections::Iterator iterCnxn(*m_fmServers.GetConnections()); while (!iterCnxn.End()) { CFLServer * pServerT = CFLServer::FromConnection(*iterCnxn.Value()); MissionList::Iterator iterMission(*pServerT->GetMissions()); while (!iterMission.End()){ CFLMission* mission = iterMission.Value(); FMD_LS_LOBBYMISSIONINFO *info = mission->GetMissionInfo(); if (info) { memcpy(PostData + offset, info, info->cbmsg); offset += info->cbmsg; iterMission.Next(); } } iterCnxn.Next(); } if (offset > 0) { pHTTP settings; Strcpy(settings.hdrs, "Content-Type: application/octet-stream\r\n"); Strcpy(settings.verb, "POST"); Strcpy(settings.uri, "/lobbyinfo.ashx"); Strcpy(settings.host, "allegiancezone.com"); ZeroMemory(settings.data, BUFFSIZE); memcpy(settings.data, PostData, offset); settings.size = offset; DWORD lpExitCode; GetExitCodeThread(m_threadPost, &lpExitCode); if (lpExitCode != STILL_ACTIVE) { debugf("Creating post thread.\n"); DWORD dum; m_threadPost = CreateThread(NULL, 0, PostThread, (void*)&settings, 0, &dum); } else debugf("Post thread was still running...\n"); } } }
int CLobbyApp::Run() { const DWORD c_dwUpdateInterval = 200; // milliseconds DWORD dwSleep = c_dwUpdateInterval; DWORD dwWait = WAIT_TIMEOUT; InitializeCriticalSectionAndSpinCount(&HttpCriticalSection, 0x00000400); InitializeCriticalSectionAndSpinCount(GetLogonCS(), 0x00000400); m_plas->LogEvent(EVENTLOG_INFORMATION_TYPE, LE_Running); puts("---------Press Q to exit---------"); printf("Ready for clients/servers.\n"); CTempTimer timerIterations("between iterations", .25f); timerIterations.Start(); CTempTimer timerReceiveClientsMessages("in clients ReceiveMessages()", .05f); CTempTimer timerReceiveServersMessages("in servers ReceiveMessages()", .05f); Time timeLastQueueCheck = Time::Now(); Time timeLastGameInfo = Time::Now(); while (true) { timerIterations.Stop(); timerIterations.Start(); if (ProcessMsgPump() || (_kbhit() && toupper(_getch()) == 'Q')) { //Imago #111 7/10 if(g_pAutoUpdate) { char szFileName[MAX_PATH+16]; strcpy(szFileName, _Module.GetModulePath()); Strcat(szFileName, "FileList.txt"); g_pAutoUpdate->LoadCRC(szFileName); FedMessaging * pfm = &g_pLobbyApp->GetFMClients(); int count = pfm->GetConnectionCount(); ListConnections::Iterator iterCnxn(*pfm->GetConnections()); while (!iterCnxn.End()) { BEGIN_PFM_CREATE(*pfm, pfmAutoUpdate, L, AUTO_UPDATE_INFO) FM_VAR_PARM(g_pAutoUpdate->GetFTPServer(), CB_ZTS) FM_VAR_PARM(g_pAutoUpdate->GetFTPInitialDir(), CB_ZTS) FM_VAR_PARM(g_pAutoUpdate->GetFTPAccount(), CB_ZTS) FM_VAR_PARM(g_pAutoUpdate->GetFTPPassword(), CB_ZTS) END_PFM_CREATE pfmAutoUpdate->crcFileList = g_pAutoUpdate->GetFileListCRC(); pfmAutoUpdate->nFileListSize = g_pAutoUpdate->GetFileListSize(); pfm->SendMessages(iterCnxn.Value(), FM_GUARANTEED, FM_FLUSH); iterCnxn.Next(); } } return 0; } SetNow(); m_pCounters->timeInnerLoop = timerIterations.LastInterval(); // receive any messages in the queue timerReceiveClientsMessages.Start(); m_fmClients.ReceiveMessages(); timerReceiveClientsMessages.Stop(); timerReceiveServersMessages.Start(); m_fmServers.ReceiveMessages(); timerReceiveServersMessages.Stop(); if (GetNow() - timeLastQueueCheck >= 1.0f) { // count the fairly expensive stuff no more than once a second UpdatePerfCounters(); timeLastQueueCheck = GetNow(); if (GetNow() - timeLastGameInfo >= (float) m_sGameInfoInterval) { SendGameInfo(); timeLastGameInfo = GetNow(); } // Do a periodic roll call. If we haven't heard from anyone for two roll calls in a row, waste 'em static Time timeRollCall = Time::Now(); if (GetNow() - timeRollCall >= 5.0f) { RollCall(); timeRollCall = GetNow(); } } Sleep(1); } DeleteCriticalSection(GetLogonCS()); DeleteCriticalSection(&HttpCriticalSection); return 0; }
void CLobbyApp::BuildStaticCoreInfo() { // build the master core list // then set coremask for each server // 1. get ride of the old list FreeStaticCoreInfo(); // 2. loop thru unpaused servers and build a TList of StaticCoreInfo and the coremask ListConnections::Iterator iterCnxn(*GetFMServers().GetConnections()); TList<StaticCoreInfo*,StaticCoreInfoEquals> CoreList; while (!iterCnxn.End()) { CFLServer * pServerT = CFLServer::FromConnection(*iterCnxn.Value()); if (pServerT) // skip lost/terminating server { pServerT->SetStaticCoreMask(0); // clear the core mask, not really needed here but it doesnt hurt int c = pServerT->GetcStaticCoreInfo(); if (!pServerT->GetPaused()) // skip paused serveR for (int i=0; i<c; i++) { if (!CoreList.Find(&(pServerT->GetvStaticCoreInfo()[i]))) CoreList.PushFront(&(pServerT->GetvStaticCoreInfo()[i])); } } iterCnxn.Next(); } // 3. Allocate mem m_cStaticCoreInfo = CoreList.GetCount(); if (m_cStaticCoreInfo) m_vStaticCoreInfo = new StaticCoreInfo[m_cStaticCoreInfo]; else return; // no core, all done // 4. transform the TList into an array for (int i = 0; i < m_cStaticCoreInfo; i++) Strcpy(m_vStaticCoreInfo[i].cbIGCFile,CoreList[i]->cbIGCFile); CoreList.SetEmpty(); // 5. loop thru unpaused servers and build the coremask ListConnections::Iterator iterCnxn2(*GetFMServers().GetConnections()); while (!iterCnxn2.End()) { CFLServer * pServerT = CFLServer::FromConnection(*iterCnxn2.Value()); if (pServerT) // skip lost/terminating server { int c = pServerT->GetcStaticCoreInfo(); pServerT->SetStaticCoreMask(0); // clear the core mask if (!pServerT->GetPaused()) // skip paused server for (int i=0; i<c; i++) { for (int j = 0; j < m_cStaticCoreInfo; j++) if (strcmp(pServerT->GetvStaticCoreInfo()[i].cbIGCFile,m_vStaticCoreInfo[j].cbIGCFile) == 0) pServerT->SetStaticCoreMask(pServerT->GetStaticCoreMask() | 1<<j); } } iterCnxn2.Next(); } }