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();
}
Beispiel #2
0
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();
	}
}