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"); } } }
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(); }
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; }
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(); } }