예제 #1
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");
		}
	}
}
예제 #2
0
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);
      }
    }
  }
}
예제 #3
0
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");
		}
	}
}
예제 #4
0
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();
}
예제 #5
0
HRESULT LobbyServerSite::OnAppMessage(FedMessaging * pthis, CFMConnection & cnxnFrom, FEDMESSAGE * pfm)
{
  CFLServer * pServer = CFLServer::FromConnection(cnxnFrom);
  assert(pServer);

  cnxnFrom.ResetAbsentCount();

  switch (pfm->fmid)
  {
    case FM_S_LOGON_LOBBY:
    {
      CASTPFM(pfmLogon, S, LOGON_LOBBY, pfm);
	  pfmLogon->cbvStaticCoreInfo;
	  char szRemote[16];
      if (pfmLogon->verLobby == LOBBYVER_LS)
      {
        if(pfmLogon->dwPort != 0)						// A port of 0 means the server couldn't find out its listening port
          pServer->SetServerPort(pfmLogon->dwPort);
        else
          pServer->SetServerPort(6073);				// Tell the client to enum the old fashioned way
		//KGJV #114
		// fill in StaticCoreInfo
		StaticCoreInfo* pcoreinfo  = (StaticCoreInfo*)FM_VAR_REF(pfmLogon, vStaticCoreInfo);
		pServer->SetStaticCoreInfo(pfmLogon->cStaticCoreInfo, pcoreinfo);
		//Imago: reorganized some stuff to get a better debug message		
		// location
		char * szLoc =  FM_VAR_REF(pfmLogon, szLocation);
		pServer->SetLocation(szLoc);
		//Imago #2 6/10
		char * szPrivilegedUsers =  FM_VAR_REF(pfmLogon, szPrivilegedUsers);
		pServer->SetPrivilegedUsers(szPrivilegedUsers);
		//Imago #62 6/10
		char * szVersion =  FM_VAR_REF(pfmLogon, szServerVersion);
		pServer->SetVersion(szVersion);
		// max games
		pServer->SetMaxGamesAllowed(pfmLogon->MaxGames);
		
		// current games (allow servers to update) - Imago 6/25/08
		pServer->SetCurrentGamesCount(pfmLogon->CurGames);

		// rebuild the master core list
		g_pLobbyApp->BuildStaticCoreInfo();
		// break; mmf took out break so we can check ip below
		// KGJV moved mmf's stuff inside lobby version check
		// mmf add check to see if they are an allowed or blocked server

		  pthis->GetIPAddress(cnxnFrom, szRemote);
		  debugf("FM_S_LOGON_LOBBY: %s:%d loc:%s #games:%i\n",&szRemote,pfmLogon->dwPort,pServer->GetLocation(),pfmLogon->CurGames);
		  if (!strncmp("127.0.0.1",szRemote,9)) break;  // check for loopback and always allow
		  if (IsServerAllowed(szRemote)) break;
	  }

	  char * szReason;

	  // if we got this far we are not on the approved list fall through to reject below
	  szReason = "Your server IP address is not approved for connection to this Lobby.  Please contact the Lobby Admin."; //Imago fix typo 6/10
	  // end mmf
	  
      if (pfmLogon->verLobby > LOBBYVER_LS)
        szReason = "The Public Lobby server that you connected to is older than your version.  The Zone needs to update their lobby server.  Please try again later.";
      if (pfmLogon->verLobby < LOBBYVER_LS) // mmf took out the else and made this an explicit if for above szReason
        szReason = "Your server's version did not get auto-updated properly.  Please try again later.";

      BEGIN_PFM_CREATE(*pthis, pfmNewMissionAck, L, LOGON_SERVER_NACK)
          FM_VAR_PARM((char *)szReason, CB_ZTS)
      END_PFM_CREATE
      pthis->SendMessages(&cnxnFrom, FM_GUARANTEED, FM_FLUSH);
      pthis->DeleteConnection(cnxnFrom);
      break;
    }

    case FM_S_NEW_MISSION:
    {
      // a server has created a mission of their own volition. We need to map it into our "cookie space"
      CASTPFM(pfmNewMission, S, NEW_MISSION, pfm);
      CFLMission * pMission = pServer->CreateMission(NULL); // NULL = no client created this
      BEGIN_PFM_CREATE(*pthis, pfmNewMissionAck, L, NEW_MISSION_ACK)
      END_PFM_CREATE
      pfmNewMissionAck->dwIGCMissionID = pfmNewMission->dwIGCMissionID;
      pfmNewMissionAck->dwCookie = (DWORD) pMission;
      pthis->SendMessages(&cnxnFrom, FM_GUARANTEED, FM_FLUSH);
      // we won't broadcast it until the server sends us a lobby mission info, when it's good and ready
	  debugf("FM_S_NEW_MISSION id:%d cookie:%d\n",pfmNewMissionAck->dwIGCMissionID,pfmNewMissionAck->dwCookie);
    }
    break;

    case FM_LS_LOBBYMISSIONINFO:
    {
      CASTPFM(pfmLobbyMissionInfo, LS, LOBBYMISSIONINFO, pfm);
      CFLMission * pMission = CFLMission::FromCookie(pfmLobbyMissionInfo->dwCookie);
      if (pMission) // if it's already gone away--just ignore it. 
      {		  
		  //Imago 6/26/08
		  //Moved this code inside the mission check
		  //now the lobby does not crash trying to find a disconnected server's IP


			//KGJV #114 - server didnt fill szServerAddr but only reserved the bits. We fill it here.
			debugf("FM_LS_LOBBYMISSIONINFO:%d (pmission:%x cookie:%x) sent cookie:%x connected?%i\n",pfmLobbyMissionInfo->dwPort,pMission,pfmLobbyMissionInfo->dwCookie,pfmLobbyMissionInfo->dwCookie,(pthis->IsConnected()) ? 1 : 0);  
			char szAddr[16];
			pthis->GetIPAddress(cnxnFrom, szAddr); // get the real addr
			debugf("\tFM_LS_LOBBYMISSIONINFO:%s sent port %d\n",&szAddr,pfmLobbyMissionInfo->dwPort);		
			char *pfmdata = FM_VAR_REF(pfmLobbyMissionInfo, szServerAddr); // get the addr in the message	  
			Strcpy(pfmdata,szAddr); // overwrite with the real addr

			//end move code

        pMission->SetLobbyInfo(pfmLobbyMissionInfo);
        pMission->NotifyCreator();
      }
      // else TODO: do something about waiting client, if there is one
    }
    break;

    case FM_LS_MISSION_GONE:
    {
      CASTPFM(pfmMissionGone, LS, MISSION_GONE, pfm);
      CFLMission * pMission = CFLMission::FromCookie(pfmMissionGone->dwCookie);
	  debugf("deleting GONE mission: %x\n",pfmMissionGone->dwCookie);
      pServer->DeleteMission(pMission);
    }
    break;

    case FM_S_HEARTBEAT:
      // don't boot for missing roll call until we get one from them
      pServer->SetHere();
    break;
    
    case FM_S_PLAYER_JOINED:
    {
      CASTPFM(pfmPlayerJoined, S, PLAYER_JOINED, pfm);
      CFLMission * pMission = CFLMission::FromCookie(pfmPlayerJoined->dwMissionCookie);
      const char* szCharacterName = FM_VAR_REF(pfmPlayerJoined, szCharacterName);
      const char* szCDKey = FM_VAR_REF(pfmPlayerJoined, szCDKey);

      if (NULL == szCharacterName || '\0' != szCharacterName[pfmPlayerJoined->cbszCharacterName-1])
          /* || NULL == szCDKey || '\0' != szCDKey[pfmPlayerJoined->cbszCDKey-1]  
		  Imago 6/25/08 removed above
		  */ 
      {
        // corrupt data
        g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_ERROR_TYPE, LE_CorruptPlayerJoinMsg,
          cnxnFrom.GetName());
      }
      else if (NULL == pMission)
      {
        // the requested game does not exist
        g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_WARNING_TYPE, LE_PlayerJoinInvalidMission,
          szCharacterName, cnxnFrom.GetName(), pfmPlayerJoined->dwMissionCookie);
      }
      else
      {
        if (g_pLobbyApp->EnforceCDKey())
        {
          char * szUnencryptedCDKey = (char*)_alloca(strlen(szCDKey) + 1);
          ZUnscramble(szUnencryptedCDKey, szCDKey, szCharacterName);

          szCDKey = szUnencryptedCDKey;
        }

        g_pLobbyApp->SetPlayerMission(szCharacterName, szCDKey, pMission);
      }
    }
    break;

    case FM_S_PLAYER_QUIT:
    {
      CASTPFM(pfmPlayerQuit, S, PLAYER_QUIT, pfm);
      CFLMission * pMission = CFLMission::FromCookie(pfmPlayerQuit->dwMissionCookie);
      const char* szCharacterName = FM_VAR_REF(pfmPlayerQuit, szCharacterName);

      if (NULL == szCharacterName || '\0' != szCharacterName[pfmPlayerQuit->cbszCharacterName-1])
      {
        // corrupt data
        g_pLobbyApp->GetSite()->LogEvent(EVENTLOG_ERROR_TYPE, LE_CorruptPlayerQuitMsg,
          cnxnFrom.GetName());
      }
      else
        g_pLobbyApp->RemovePlayerFromMission(szCharacterName, pMission);
    }
    break;

    case FM_S_PAUSE:
    {
      CASTPFM(pfmPause, S, PAUSE, pfm);
      pServer->Pause(pfmPause->fPause);
	  // KGJV #114 cant create game on paused server
      g_pLobbyApp->BuildStaticCoreInfo();
      break;
    }      

    default:
      ZError("unknown message\n");
  }
  return S_OK;
}
예제 #6
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();
	}
}