Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
HRESULT FedSrvLobbySite::OnAppMessage(FedMessaging * pthis, CFMConnection & cnxnFrom, FEDMESSAGE * pfm)
{
	HRESULT hr = S_OK;
	assert(&g.fmLobby == pthis);

	static CTempTimer timerOnAppMessage("in FedSrvLobbySite::OnAppMessage", .02f);
	timerOnAppMessage.Start();

	switch (pfm->fmid)
	{
		// KGJV #114 - reactivate create mission
	  //#if !defined(ALLSRV_STANDALONE)
	case FM_L_CREATE_MISSION_REQ:
	{
#if !defined(SRV_CHILD)
		CASTPFM(pfmCreateMissionReq, L, CREATE_MISSION_REQ, pfm);
		MissionParams mp;
		Strcpy(mp.strGameName, ZString(FM_VAR_REF(pfmCreateMissionReq, GameName)));// + "'s game");
		Strcpy(mp.szIGCStaticFile, ZString(FM_VAR_REF(pfmCreateMissionReq, IGCStaticFile)));
		mp.bScoresCount = false;// dont set to true till clients can change this!
		mp.iMaxImbalance = 0x7ffe;// added
		assert(!mp.Invalid());
#endif

		//Imago - give birth right here, feed it and off it goes...

#if defined(SRV_PARENT)
		//start missions as thier own process
		STARTUPINFO si;
		PROCESS_INFORMATION pi;
		ZeroMemory(&si, sizeof(si));
		si.cb = sizeof(si);
		ZeroMemory(&pi, sizeof(pi));
		char szCmd[255]; char szName[32]; char szFile[32];
		ZString strName = mp.strGameName;
		ZString strFile = mp.szIGCStaticFile;
		si.lpTitle = mp.strGameName;
		Strcpy(szName, (PCC)strName);
		Strcpy(szFile, (PCC)strFile);
		sprintf(szCmd, "AllSrv.exe \"%s\" %s %x", szName, szFile, pfmCreateMissionReq->dwCookie);

		// Create a NULL dacl to give "everyone" access
		SECURITY_DESCRIPTOR sd;
		SECURITY_ATTRIBUTES sa = { sizeof(sa), &sd, false };
		InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
		SetSecurityDescriptorDacl(&sd, true, NULL, FALSE);

		if (!CreateProcess(
			NULL,                   // No module name (use command line). 
			szCmd,
			NULL,
			NULL,
			FALSE,                  // Set handle inheritance to FALSE. 
			CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE, // we're destined to do amazing things
			NULL,                   // Use parent's environment block. 
			NULL,                   // Use parent's starting directory. 
			&si,                    // Pointer to STARTUPINFO structure.
			&pi)                   // Pointer to PROCESS_INFORMATION structure.
			)
		{
			debugf("CreateProcess failed (%d).\n", GetLastError());
		}

		// check to make sure the child is ready before restart
		char strFilename[10] = "\0";
		sprintf(strFilename, "%d.pid", pi.dwProcessId);
		HANDLE hFile = (HANDLE)CreateFile(strFilename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
		DWORD dwError = GetLastError();
		int i = 0;
		while (hFile == INVALID_HANDLE_VALUE || dwError == ERROR_FILE_NOT_FOUND) {
			if (i >= 14) //30s
				break;

			Sleep(2500);
			hFile = (HANDLE)CreateFile(strFilename, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
			dwError = GetLastError();
			i++;
		}
		_Module.AddPID(pi.dwProcessId);
		CloseHandle(hFile);
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
		g.bRestarting = true;
		PostQuitMessage(0);

#endif 

#if !defined(SRV_CHILD)
#if !defined(SRV_PARENT)
		// pkk 2011-07-24 - Create games only with IGCs from cores.txt
		bool ValidCore = false;
		for (int i = 0; i < g.cStaticCoreInfo; i++)
		{
			if (!strcmpi(mp.szIGCStaticFile, g.vStaticCoreInfo[i].cbIGCFile))
			{
				ValidCore = true;
				break; // quit loop
			}
		}
		if (ValidCore == true)
		{
			//Imago - start the mission in this thread as usual 
			FedSrvSite * psiteFedSrv = new FedSrvSite();
			CFSMission * pfsMissionNew = new CFSMission(mp, "", psiteFedSrv, psiteFedSrv, NULL, NULL);
			pfsMissionNew->SetCookie(pfmCreateMissionReq->dwCookie);
		}
		else
		{
			debugf("Lobby sent invalid core information %s, ignoring message\n", mp.szIGCStaticFile);
		}
		// pkk end
#endif
#endif
	} //Imago 6/22/08
	break;
	//#endif -- reactivate create mission

	case FM_L_NEW_MISSION_ACK:
	{
		CASTPFM(pfmNewMissionAck, L, NEW_MISSION_ACK, pfm);
		CFSMission * pfsm = CFSMission::GetMissionFromIGCMissionID(pfmNewMissionAck->dwIGCMissionID);
		if (pfsm)
		{
			pfsm->SetCookie(pfmNewMissionAck->dwCookie);
			// If we already have players (e.g. reconnect), tell the lobby who's in the game
			const ShipListIGC * plistShip = pfsm->GetIGCMission()->GetShips();
			for (ShipLinkIGC * plinkShip = plistShip->first(); plinkShip; plinkShip = plinkShip->next())
			{
				IshipIGC * pShip = plinkShip->data();
				CFSShip * pfsShip = GETFSSHIP(pShip);
				if (pfsShip->IsPlayer() && !pShip->IsGhost())
				{
					CFSPlayer* pfsPlayer = pfsShip->GetPlayer();
					BEGIN_PFM_CREATE(g.fmLobby, pfmPlayerJoined, S, PLAYER_JOINED)
						FM_VAR_PARM(pfsPlayer->GetName(), CB_ZTS)
						END_PFM_CREATE
						pfmPlayerJoined->dwMissionCookie = pfsm->GetCookie();
				}
			}
			HRESULT hr = pthis->SendMessages(pthis->GetServerConnection(), FM_GUARANTEED, FM_FLUSH);
		}
	}
	break;

	case FM_L_TOKEN:
	{
		CASTPFM(pfmToken, L, TOKEN, pfm);
		Strcpy(g.m_szToken, FM_VAR_REF(pfmToken, Token));
	}
	break;

	case FM_L_REMOVE_PLAYER:
	{
		CASTPFM(pfmRemovePlayer, L, REMOVE_PLAYER, pfm);
		CFSMission * pfsMission = CFSMission::GetMission(pfmRemovePlayer->dwMissionCookie);
		const char* szCharacterName = FM_VAR_REF(pfmRemovePlayer, szCharacterName);
		const char* szMessageParam = FM_VAR_REF(pfmRemovePlayer, szMessageParam);

		// try to find the player in question
		if (!pfsMission)
		{
			debugf("Asked to boot character %s from mission %x by lobby, "
				"but the mission was not found.\n",
				szCharacterName, pfmRemovePlayer->dwMissionCookie);
		}
		else if (!pfsMission->RemovePlayerByName(szCharacterName,
			(pfmRemovePlayer->reason == RPR_duplicateCDKey) ? QSR_DuplicateCDKey : QSR_DuplicateRemoteLogon,
			szMessageParam))
		{
			debugf("Asked to boot character %s from mission %x by lobby, "
				"but the character was not found.\n",
				szCharacterName, pfmRemovePlayer->dwMissionCookie);
		}
	}
	break;

	case FM_L_LOGON_SERVER_NACK:
	{
		char * szReason;

		CASTPFM(pfmLogonNack, L, LOGON_SERVER_NACK, pfm);

		szReason = FM_VAR_REF(pfmLogonNack, Reason);

		OnMessageBox(pthis, szReason ? szReason : "Error while try to log onto server.", "Allegiance Server Error", MB_SERVICE_NOTIFICATION);
		// TODO: consider firing out an event message
		PostQuitMessage(-1);
	}

	// BT - 12/21/2010 ACSS - The lobby server will relay the rank details back to the game server.
	case FM_LS_PLAYER_RANK:
	{
		CQLogonStats * pquery = new CQLogonStats(GotLogonDetails);
		CQLogonStatsData * pqd = pquery->GetData();

		CASTPFM(pfmPlayerRank, LS, PLAYER_RANK, pfm);

		Strcpy(pqd->szCDKey, FM_VAR_REF(pfmPlayerRank, szCDKey));
		Strcpy(pqd->szCharacterName, FM_VAR_REF(pfmPlayerRank, szCharacterName));
		Strcpy(pqd->szPassword, FM_VAR_REF(pfmPlayerRank, szPassword));
		Strcpy(pqd->szReason, FM_VAR_REF(pfmPlayerRank, szReason));

		pqd->characterID = pfmPlayerRank->characterID;
		pqd->fCanCheat = pfmPlayerRank->fCanCheat;
		pqd->fRetry = pfmPlayerRank->fRetry;
		pqd->dwCookie = pfmPlayerRank->dwCookie;
		pqd->fValid = pfmPlayerRank->fValid;
		pqd->dwConnectionID = pfmPlayerRank->dwConnectionID;

		pqd->rank = pfmPlayerRank->rank;
		pqd->sigma = pfmPlayerRank->sigma;
		pqd->mu = pfmPlayerRank->mu;
		pqd->commandRank = pfmPlayerRank->commandRank;
		pqd->commandSigma = pfmPlayerRank->commandSigma;
		pqd->commandMu = pfmPlayerRank->commandMu;

		PostThreadMessage(g.idReceiveThread, wm_sql_querydone, (WPARAM)NULL, (LPARAM)pquery);
		break;
	}

	break;
	}

	timerOnAppMessage.Stop("...for message type %s\n", g_rgszMsgNames[pfm->fmid]);
	return hr;
}