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; }
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; }