//-------------------------------------------------------------------------
bool CCryLobbySessionHandler::ShouldCallMapCommand( const char *pLevelName, const char *pGameRules )
{
	bool result = false;

	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		result = pGameLobby->ShouldCallMapCommand(pLevelName, pGameRules);
		if(result)
		{
			IPlatformOS* pPlatform = gEnv->pSystem->GetPlatformOS();

			SStreamingInstallProgress progress;
			pPlatform->QueryStreamingInstallProgressForLevel(pLevelName, &progress);
			const bool bLevelReady = SStreamingInstallProgress::eState_Completed == progress.m_state;
			if(!bLevelReady)
			{
				// we can jump directly into MP from system game invitation avoiding frontend, so update streaming install priorities here
				pPlatform->SwitchStreamingInstallPriorityToLevel(pLevelName);
				gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent( ESYSTEM_EVENT_LEVEL_NOT_READY, (UINT_PTR)pLevelName, 0 );
			}
			return bLevelReady;
		}
	}

	return result;
}
Пример #2
0
void CUILobbyMP::WriteLeaderBoard()
{

	ICryLobby *Lobby = gEnv->pNetwork->GetLobby();
	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	ICryLobbyService *Service = (Lobby) ? Lobby->GetLobbyService() : NULL;
	ICryStats *Stats = (Service != NULL) ? Service->GetStats() : NULL;


	unsigned int user = g_pGame->GetPlayerProfileManager()->GetExclusiveControllerDeviceIndex();
	CryUserID userID = Service->GetUserID(user);
	ECryLobbyError Error;
	
	SCryStatsLeaderBoardWrite leaderboard;
	leaderboard.id = 0;
	leaderboard.data.numColumns = 0;
	leaderboard.data.pColumns = NULL;
	leaderboard.data.score.score = 311;
	leaderboard.data.score.id = 0;










	Error = Stats->StatsWriteLeaderBoards(pGameLobby->GetCurrentSessionHandle(), user, &leaderboard, 1, NULL, CUILobbyMP::WriteLeaderboardCallback, this);

}
Пример #3
0
int CDLCManager::GetNamesStringOfPlayersMissingDLCsForLevel(const char* pLevelName, stack_string* pPlayersString)
{
	CGameLobby*  pGameLobby = g_pGame->GetGameLobby();
	CRY_ASSERT(pGameLobby);
	CRY_ASSERT(pGameLobby->IsServer());

	int  count = 0;

	uint32  requiredDLCs = GetRequiredDLCsForLevel(pLevelName);

	const SSessionNames&  lobbySessNames = pGameLobby->GetSessionNames();

	const int  nameSize = lobbySessNames.Size();
	for (int i=0; i<nameSize; ++i)
	{
		const SSessionNames::SSessionName&  player = lobbySessNames.m_sessionNames[i];
		const uint32  loadedDLC = (uint32) player.m_userData[eLUD_LoadedDLCs];
		if (!MeetsDLCRequirements(requiredDLCs, loadedDLC))
		{
			CryLog("CDLCManager::GetNamesStringOfPlayersMissingDLCsForLevel: '%s' does not meet DLC requirements for level '%s'", player.m_name, pLevelName);
			count++;
			if (!pPlayersString->empty())
			{
				pPlayersString->append(", ");
			}
			pPlayersString->append(player.m_name);
		}
	}

	return count;
}
//-------------------------------------------------------------------------
void CCryLobbySessionHandler::JoinSessionFromConsole(CrySessionID session)
{
	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		pGameLobby->JoinServer(session, "JoinSessionFromConsole", CryMatchMakingInvalidConnectionUID, true);
	}
}
Пример #5
0
//------------------------------------------------------------------------
void CGameRules::StoreMigratingPlayer(IActor* pActor)
{
	if (pActor == NULL)
	{
		GameWarning("Invalid data for migrating player");
		return;
	}

	IEntity* pEntity = pActor->GetEntity();
	EntityId id = pEntity->GetId();
	bool registered = false;

	uint16 channelId = pActor->GetChannelId();
	CRY_ASSERT(channelId);

	bool bShouldAdd = true;

	CGameLobby *pGameLobby = g_pGame->GetGameLobby();
	CRY_ASSERT(pGameLobby);
	if (pGameLobby)
	{
		SCryMatchMakingConnectionUID conId = pGameLobby->GetConnectionUIDFromChannelID((int) channelId);
		if (pGameLobby->GetSessionNames().Find(conId) == SSessionNames::k_unableToFind)
		{
			CryLog("CGameRules::StoreMigratingPlayer() player %s (channelId=%u) has already left the game, not storing", pEntity->GetName(), channelId);
			bShouldAdd = false;
		}
	}

	if (bShouldAdd && (!m_hostMigrationCachedEntities.empty()))
	{
		if (!stl::find(m_hostMigrationCachedEntities, pActor->GetEntityId()))
		{
			bShouldAdd = false;
		}
	}

	if (bShouldAdd)
	{
		for (uint32 index = 0; index < m_migratingPlayerMaxCount; ++index)
		{
			if (!m_pMigratingPlayerInfo[index].InUse())
			{
				m_pMigratingPlayerInfo[index].SetData(pEntity->GetName(), id, GetTeam(id), pEntity->GetWorldPos(), pEntity->GetWorldAngles(), pActor->GetHealth());
				m_pMigratingPlayerInfo[index].SetChannelID(channelId);
				registered = true;
				break;
			}
		}
	}

	pEntity->Hide(true);		// Hide the player, they will be unhidden when they rejoin

	if (!registered && bShouldAdd)
	{
		GameWarning("Too many migrating players!");
	}
}
Пример #6
0
void CUILobbyMP::LeaveGame()
{
	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		pGameLobby->LeaveSession(true);
		pGameLobby->SetMatchmakingGame(false);
	}
}
Пример #7
0
void CAntiCheatManager::KickPlayer(uint16 channelId, EDisconnectionCause reason, int nConfidence)
{
	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		CryUserID userId = pGameLobby->GetUserIDFromChannelID(channelId);

		KickPlayer(userId, reason, nConfidence);
	}
}
Пример #8
0
void CUIMultiPlayer::OnSendChatMessage( const string& message )
{
    //chat to all
#if ENABLE_CHAT_MESSAGES
    CGameLobby* lobby = g_pGame->GetGameLobby();
    if(lobby)
    {
        lobby->SendChatMessage(false, message.c_str());
    }
#endif
}
//-------------------------------------------------------------------------
bool CCryLobbySessionHandler::IsGameSessionMigratable() const
{
	bool result = false;

	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		result = pGameLobby->IsSessionMigratable();
	}

	return result;
}
//-------------------------------------------------------------------------
int CCryLobbySessionHandler::GetNumberOfExpectedClients()
{
	int result = 0;

	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		result = pGameLobby->GetNumberOfExpectedClients();
	}

	return result;
}
//-------------------------------------------------------------------------
bool CCryLobbySessionHandler::ShouldMigrateNub() const
{
	bool bResult = true;

	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		bResult = pGameLobby->ShouldMigrateNub();
	}

	return bResult;
}
//-------------------------------------------------------------------------
CrySessionHandle CCryLobbySessionHandler::GetGameSessionHandle() const
{
	CrySessionHandle result = CrySessionInvalidHandle;

	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		result = pGameLobby->GetCurrentSessionHandle();
	}

	return result;
}
Пример #13
0
//-------------------------------------------------------------------------
bool CCryLobbySessionHandler::ShouldCallMapCommand( const char *pLevelName, const char *pGameRules )
{
    bool result = false;

    CGameLobby* pGameLobby = g_pGame->GetGameLobby();
    if (pGameLobby)
    {
        result = pGameLobby->ShouldCallMapCommand(pLevelName, pGameRules);
    }

    return result;
}
Пример #14
0
void CUILobbyMP::WriteLeaderboardCallback(CryLobbyTaskID TaskID, ECryLobbyError Error, void *Arg)
{
	if (Error > eCLE_SuccessContinue)
		GameWarning("CQuerySystem::WriteLeaderboardCallback: Failed to write, code: %i", Error);
	//test

	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		pGameLobby->LeaveSession(true);
		pGameLobby->SetMatchmakingGame(false);
	}
}
Пример #15
0
void CUILobbyMP::GetPlayerList()
{
	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	SSessionNames sessions = pGameLobby->GetSessionNames();
	SUIArguments players, ids;
	for (uint i = 0; i < sessions.Size(); i++)
	{
		SSessionNames::SSessionName &player = sessions.m_sessionNames[i];
		players.AddArgument( string(player.m_name) );
		ids.AddArgument(player.m_conId.m_uid);
	}
	
	PlayerListReturn(players, ids);
}
Пример #16
0
void CGameLocalizationManager::LoadTag( ELocalizationTag tag )
{
	if(gEnv->IsEditor())// in editor all loca files are loaded during level load to get the info in the log
		return;

	switch(tag)
	{
	case eLT_Init:
		{
			LoadTagInternal(tag, "init");
		}
		break;
	case eLT_GameType:
		{
			LoadTagInternal(tag, gEnv->bMultiplayer ? "multiplayer" : "singleplayer");
		}
		break;
	case eLT_Level:
		{
			if(gEnv->bMultiplayer)
			{
				CGameLobby *pGameLobby = g_pGame->GetGameLobby();
				if (pGameLobby)
				{
					const char* pGameRules = pGameLobby->GetCurrentGameModeName(NULL);
					if(pGameRules)
					{
						LoadTagInternal(tag, pGameRules);
					}
				}
			}
			else
			{
				LoadTagInternal(tag, gEnv->pGame->GetIGameFramework()->GetLevelName());
			}
		}
		break;
	case eLT_Credits:
		{
			LoadTagInternal(tag, "credits");
		}
		break;
	default:
		CRY_ASSERT_MESSAGE(0, "Unknown GameLocalizationManger Tag");
		break;
	}
}
Пример #17
0
void CAntiCheatManager::BanPlayer_Internal(uint16 channelId, float timeout, int nConfidence)
{
	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		CryUserID userId = pGameLobby->GetUserIDFromChannelID(channelId);
		if (userId.IsValid())
		{
			ICryLobby *pLobby = gEnv->pNetwork->GetLobby();
			if (pLobby)
			{
				ICryMatchMaking *pMatchmaking = pLobby->GetMatchMaking();
				if (pMatchmaking)
				{
					pMatchmaking->Ban(&userId, timeout);
				}
			}
		}
	}
}
Пример #18
0
uint32 CDLCManager::GetRequiredDLCs()
{
	stack_string sCurrentLevelName;
	CGameLobby* pGameLobby = g_pGame->GetGameLobby();
	if (pGameLobby)
	{
		// This is the map currently selected in the game lobby
		sCurrentLevelName = pGameLobby->GetCurrentLevelName();
	}
	else
	{
		// This is the fallback if the lobby can't be found
		sCurrentLevelName = gEnv->pConsole->GetCVar("sv_map")->GetString();
	}
	if (strcmp(sCurrentLevelName.c_str(), m_prevLevelName.c_str()) != 0)
	{
		m_prevLevelName = sCurrentLevelName.c_str();
		m_requiredDLCs = GetRequiredDLCsForLevel(sCurrentLevelName.c_str());
	}
	return m_requiredDLCs;
}
Пример #19
0
void CUILobbyMP::JoinGame(int sessionID)
{
	bool result = false;

	CGameLobby *pGameLobby = g_pGame->GetGameLobby();
	CGameLobbyManager *pGameLobbyMgr = g_pGame->GetGameLobbyManager();
	CSquadManager *pSquadMgr = g_pGame->GetSquadManager();

	if(pGameLobbyMgr)
	{
		pGameLobbyMgr->SetMultiplayer(true);
	}

	if(pSquadMgr)
	{
		pSquadMgr->SetMultiplayer(true);
	}

	if(pGameLobby && m_FoundServers.size() > sessionID)
		result = pGameLobby->JoinServer(m_FoundServers[sessionID].m_id, m_FoundServers[sessionID].m_data.m_name, CryMatchMakingInvalidConnectionUID, false);
	return;
}
Пример #20
0
//------------------------------------------------------------------------
void CPlaylistActivityTracker::Update( float dt )
{
    //update downloadable resources
    for( int i = 0; i < eRTT_MaxCount; i++ )
    {
        if( m_downloadableResources[ i ] != NULL )
        {
            m_downloadableResources[ i ]->DispatchCallbacks();
        }
    }

    if( m_state != eATS_Idle )
    {
        //check conditions
        if( m_state == eATS_OnPlaylist )
        {
            CGameLobby* pLobby = g_pGame->GetGameLobby();

            if( !pLobby || pLobby->GetState() == eLS_None )
            {
                //game lobby isn't active so this must be the wrong state we're in
                //set us back to get activity because we're still in multiplayer
                m_state = eATS_GetActivity;
                //small delay on next poll in case other things are going on
                m_timeUntilNextAction = 10.0f;
            }
        }

        m_timeUntilNextAction -= dt;

        if( m_timeUntilNextAction <= 0.0f )
        {
            switch( m_state )
            {
            case eATS_GetActivity:
            {
                //we're in some state where we want a regular update of the playlist activity
                //e.g. on the multiplayer menus, ask for the data again
                RequestCurrentActivity();
                m_timeUntilNextAction = k_activityUpdateFrequency;

                break;
            }
            case eATS_OnPlaylist:
            {
                //re-send the on a playlist info
                CPlaylistManager* pPlaylists = g_pGame->GetPlaylistManager();

                if( const SPlaylist* pCurrentPlaylist = pPlaylists->GetCurrentPlaylist() )
                {
                    int variantIndex = pPlaylists->GetActiveVariantIndex();
                    JoinedPlaylist( pCurrentPlaylist->id, variantIndex );
                }

                m_timeUntilNextAction = k_onPlaylistUpdateFrequency;

                break;
            }
            }
        }

    }

}
Пример #21
0
//------------------------------------------------------------------------
void CMatchMakingHandler::OnSearchResult( SCrySessionSearchResult* pSession )
{
	//session will expire at the end of the callback
	//so copy it into a results structure (we need lots of details to pass to the matchmaking part
	//store it in a map (indexed via sessionID?)
	//pass the index to the lua


	CGameLobbyManager* pLobbyManager = g_pGame->GetGameLobbyManager();
	if( pLobbyManager )
	{
		CGameLobby* pLobby = pLobbyManager->GetGameLobby();
		
		//first check if this result refers to a lobby we're in/hosting
		if( pLobby->IsCurrentSessionId( pSession->m_id ) )
		{
			//this is the session for the lobby we are in, early out
			return;
		}
		//also check secondary lobby
		if( CGameLobby* pSecondaryLobby = pLobbyManager->GetNextGameLobby() )	
		{
			if( ( pSecondaryLobby->IsCurrentSessionId( pSession->m_id ) ) )
			{
				//this is the session for the lobby we are going to, early out
				return;
			}
		}
		
		const CGameLobby::EActiveStatus activeStatus = (CGameLobby::EActiveStatus) GameLobbyData::GetSearchResultsData( pSession, LID_MATCHDATA_ACTIVE );
		bool bIsBadServer = pLobby->IsBadServer( pSession->m_id );
		const int skillRank = pLobby->CalculateAverageSkill();
		const int sessionSkillRank = GameLobbyData::GetSearchResultsData( pSession, LID_MATCHDATA_SKILL );
		const int sessionLanguageId = GameLobbyData::GetSearchResultsData( pSession, LID_MATCHDATA_LANGUAGE );

		float sessionScore = LegacyC2MatchMakingScore( pSession, pLobby, false );

		int32 region = 0;
#if GAMELOBBY_USE_COUNTRY_FILTERING
		region = GameLobbyData::GetSearchResultsData( pSession, LID_MATCHDATA_COUNTRY );
#endif //GAMELOBBY_USE_COUNTRY_FILTERING

#if defined(TRACK_MATCHMAKING)
		if( CMatchmakingTelemetry* pMMTel = g_pGame->GetMatchMakingTelemetry() )
		{
			pMMTel->AddEvent( SMMFoundSessionEvent( pSession, activeStatus, skillRank - sessionSkillRank, region, sessionLanguageId, bIsBadServer, sessionScore ) );
		}
#endif //defined(TRACK_MATCHMAKING)

		HSCRIPTFUNCTION scriptFunction;

		if( m_pScript->GetValue( "OnSearchResult", scriptFunction ) )  
		{
			//Make a table to hold the search result
			SmartScriptTable result( gEnv->pScriptSystem );

			SessionDetails newSession;
			newSession.m_id = pSession->m_id;
			cry_strcpy( newSession.m_name, pSession->m_data.m_name );

			//capture the session ID in a map
			std::pair< TSessionIdMap::iterator, bool > insertResult = m_sessionIdMap.insert( std::make_pair( m_sessionIdIndex++, newSession ) );

			if( insertResult.second )
			{
				CryLog( "MMLua: Adding a server with parameters ping %d, status %d, avSkill %d", pSession->m_ping, activeStatus, sessionSkillRank );

				result->SetValue( "SessionId", insertResult.first->first );
				result->SetValue( "SearchId", s_currentMMSearchID );

				float timeSinceStarted = gEnv->pTimer->GetFrameStartTime().GetSeconds() - m_startTime;
				result->SetValue( "TimeFound", timeSinceStarted );
				
				//make a sub table to hold all the known session parameters	
				SmartScriptTable parameters( gEnv->pScriptSystem );
				result->SetValue( "Parameters", parameters );

				parameters->SetValue( "ActiveStatus", activeStatus );
				parameters->SetValue( "ServerAvSkill", sessionSkillRank );
				parameters->SetValue( "Region", region );
				parameters->SetValue( "Language", sessionLanguageId );
				parameters->SetValue( "BadServer", bIsBadServer );
				parameters->SetValue( "Ping", pSession->m_ping );
				parameters->SetValue( "FilledSlots", pSession->m_numFilledSlots );

				Script::Call( gEnv->pScriptSystem, scriptFunction, m_pScript, result );
				gEnv->pScriptSystem->ReleaseFunc( scriptFunction );
			}
		}
	}
}
Пример #22
0
//-------------------------------------------------------------------------
void CGameRulesStandardState::Update( float frameTime )
{
	if (gEnv->bServer)
	{
		if(m_state == EGRS_Intro)
		{
			// We assume there is an intro, if we reach this point and an intro hasnt been registered, we know there isn't one. Onwards and upwards. 
			if(!m_pGameRules->IsIntroSequenceRegistered())
			{
				ChangeState(EGRS_PreGame); 
			}
		}

		if (m_state == EGRS_PreGame)
		{
			if (m_isStarting)
			{
				const float remainingTime = m_pGameRules->GetRemainingStartTimer();
				if (remainingTime <= 0.f)
				{
					CryLog("CGameRulesStandardState::Update(), starting game");

					ChangeState(EGRS_InGame);
				}
			}
			else
			{
				bool bOk = true;
				CGameLobby* pGameLobby = g_pGame->GetGameLobby();
				const int numPlayers = m_pGameRules->GetPlayerCount(true);

				if (pGameLobby)
				{
					if (m_isWaitingForOverrideTimer)
					{
						//-- test override timer
						m_startTimerOverrideWait -= frameTime;
						bOk = (m_startTimerOverrideWait <= 0.0f);

						if (!bOk)
						{
							bOk = true;

							//-- testing min player count doesn't apply to private games
							const bool publicGame = !pGameLobby->IsPrivateGame();
							const bool onlineGame = pGameLobby->IsOnlineGame();
							if (publicGame && onlineGame)
							{
								// Start only when we have enough players
								if (m_pGameRules->GetTeamCount() > 1)
								{
									//-- team game, insist at least 1 player per team
									const int numPlayersPerTeamMin = g_pGameCVars->g_gameRules_startTimerMinPlayersPerTeam;
									const int numPlayersTeam1 = m_pGameRules->GetTeamPlayerCount(1, true);
									const int numPlayersTeam2 = m_pGameRules->GetTeamPlayerCount(2, true);

									bOk = ((numPlayersTeam1 >= numPlayersPerTeamMin) && (numPlayersTeam2 >= numPlayersPerTeamMin));
								}
								else
								{
									//-- not a team game, so just insist on minimum 2 players
									const int numPlayersMin = g_pGameCVars->g_gameRules_startTimerMinPlayers;
									bOk = (numPlayers >= numPlayersMin);
								}
								const int numPlayersInLobby = pGameLobby->GetSessionNames().Size();
								bOk |= (numPlayersInLobby == numPlayers);
							}

							if (bOk)
							{
								//-- Enforce a percentage of lobby players in game before starting countdown
								bOk = (!gEnv->IsClient() || (g_pGame->GetClientActorId() != 0)) && CheckInitialChannelPlayers();
							}
						}
					}
					else
					{
						bOk = false;

						if (numPlayers)
						{
							//-- Start the override timer. 
							m_startTimerOverrideWait = g_pGameCVars->g_gameRules_startTimerOverrideWait;
							m_isWaitingForOverrideTimer = true;
						}
					}
				}

				if (bOk)
				{
					CryLog("CGameRulesStandardState::Update(), we have %i players, starting the game", numPlayers);
					float startTimeLength = 
#if !defined(_RELEASE)
						g_pGameCVars->g_gameRules_skipStartTimer ? 0.0f : 
#endif
						g_pGameCVars->g_gameRules_startTimerLength;

#if USE_PC_PREMATCH
					bool bDoPCPrematch = false;

					CGameRules::EPrematchState prematchState = m_pGameRules->GetPrematchState();
					if (prematchState==CGameRules::ePS_Prematch)
					{
						int numRequiredPlayers = g_pGameCVars->g_minPlayersForRankedGame - m_pGameRules->GetPlayerCount(true);
						if ((numRequiredPlayers > 0) || (pGameLobby && pGameLobby->UseLobbyTeamBalancing() && !pGameLobby->IsGameBalanced()))
						{
							bDoPCPrematch = true;

							CPlaylistManager *pPlaylistManager = g_pGame->GetPlaylistManager();
							if (pGameLobby && pPlaylistManager)
							{
								if (!pGameLobby->IsRankedGame() || pPlaylistManager->IsUsingCustomVariant())
								{
									// Private games don't do prematch
									bDoPCPrematch = false;
								}
							}

							if (bDoPCPrematch)
							{
								// If we are waiting for players on pc, spawn ingame and set a prematch state which waits for players.
								m_pGameRules->StartPrematch();
								startTimeLength = 0.f;
							}
						}

						if (!bDoPCPrematch)
						{
							m_pGameRules->SkipPrematch();
						}
					}
#endif

					m_pGameRules->ResetGameStartTimer(startTimeLength);
					StartCountdown(true);
				}
			}
		}
		else if (m_state == EGRS_PostGame)
		{
			const float prevUpdateStamp = m_timeInPostGame;
			const float timeInPost = (prevUpdateStamp + frameTime);

			const float timeToShowHUDMessage = g_pGameCVars->g_gameRules_postGame_HUDMessageTime;
			const float timeToShowTop3 = g_pGameCVars->g_gameRules_postGame_Top3Time;
			const float timeToShowScoreboard = g_pGameCVars->g_gameRules_postGame_ScoreboardTime;
			float killcamLength = m_pGameRules->GameEndedByWinningKill() ? g_pGameCVars->kc_length : 0.f;
			if (g_pGameCVars->kc_showHighlightsAtEndOfGame)
			{
				CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem();
				if(pRecordingSystem)
				{
					killcamLength += pRecordingSystem->GetHighlightsReelLength();
					killcamLength = min(killcamLength, 20.f);
				}
			}

			const float totalPostGameTime = timeToShowHUDMessage + timeToShowTop3 + timeToShowScoreboard + killcamLength;

			if (timeInPost > totalPostGameTime)
			{
				CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem();
				if (!pRecordingSystem || (!pRecordingSystem->IsPlaybackQueued() && !pRecordingSystem->IsPlayingBack()))
				{
					CGameLobby *pGameLobby = g_pGame->GetGameLobby();
					if (pGameLobby)
					{
						CryLog("[GameRules] Server trying to return to lobby");
						pGameLobby->SvFinishedGame(frameTime);
					}
				}
				else if(pRecordingSystem)
				{
					pRecordingSystem->StopHighlightReel();
				}
			}

			m_timeInPostGame = timeInPost;
		}
	}

	CPlayer * pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor());
	if((pPlayer && pPlayer->ShouldPlayIntro() || gEnv->bServer) && m_pGameRules->IsIntroSequenceRegistered() && !m_bHaveNotifiedIntroListeners)
	{
		// All flowgraph nodes that want to listen, should be created at this point
		OnIntroStart_NotifyListeners();
	}
	

#ifndef _RELEASE
	if(g_pGameCVars->g_hud_postgame_debug)
	{
		const char* stateName = "";
		switch(m_state)
		{
		case EGRS_Reset: { stateName = "EGRS_Reset"; break;}
		case EGRS_Intro: { stateName = "EGRS_Intro"; break;}
		case EGRS_PreGame: { stateName = "EGRS_PreGame"; break;}
		case EGRS_InGame: { stateName = "EGRS_InGame"; break;}
		case EGRS_PostGame: { stateName = "EGRS_PostGame"; break;}
		case EGRS_MAX: { stateName = "EGRS_MAX"; break;}
		}
		CryWatch("GameRulesStandardState - State = %s", stateName);

		if(m_state == EGRS_PostGame)
		{
			const char* postGameStateName = "";
			switch(m_postGameState)
			{
			case ePGS_Unknown: { postGameStateName = "ePGS_Unknown"; break; }
			case ePGS_Starting: { postGameStateName = "ePGS_Starting"; break; }
			case ePGS_HudMessage: { postGameStateName = "ePGS_HudMessage"; break; }
			case ePGS_FinalKillcam: { postGameStateName = "ePGS_FinalKillcam"; break; }
			case ePGS_HighlightReel: { postGameStateName = "ePGS_HighlightReel"; break; }
			case ePGS_Top3: { postGameStateName = "ePGS_Top3"; break; }
			case ePGS_Scoreboard: { postGameStateName = "ePGS_Scoreboard"; break; }
			}
			CryWatch("GameRulesStandardState -PostGameState = %s", postGameStateName);

		}
	}
#endif

	if (gEnv->IsClient())
	{
		if (m_state == EGRS_PreGame)
		{
			if( !gEnv->IsDedicated() )
			{
				if (m_isStarting)
				{
					const float timeTillStartInSeconds = m_pGameRules->GetRemainingStartTimer();
					SHUDEventWrapper::UpdateGameStartCountdown( ePreGameCountdown_MatchStarting, timeTillStartInSeconds );
				}
				else
				{
					SHUDEventWrapper::UpdateGameStartCountdown( ePreGameCountdown_WaitingForPlayers, 0.0f );
				}
			}
		}
		else if (m_state == EGRS_InGame && !gEnv->IsDedicated() )
		{
			if (m_introMessageShown == false)	// Show only once
			{
				CGameRules *pGameRules = g_pGame->GetGameRules();
				if (pGameRules && pGameRules->HasGameActuallyStarted())
				{
					if (EntityId localPlayerId = g_pGame->GetIGameFramework()->GetClientActorId())
					{
						int teamId = g_pGame->GetGameRules()->GetTeam(localPlayerId);
						bool bTeamGame = (pGameRules->GetTeamCount() > 1);

						IActor *pActor = g_pGame->GetIGameFramework()->GetClientActor();
						if (pActor->GetSpectatorMode()==CActor::eASM_None && !pActor->IsDead() && (!bTeamGame || teamId!=0))
						{
							if (IGameRulesPlayerStatsModule *statsModule = pGameRules->GetPlayerStatsModule())
							{
								const SGameRulesPlayerStat *stats = statsModule->GetPlayerStats(localPlayerId);
								if (stats->deaths <= 0) // Not died ever
								{
									if (m_startMatchString.empty() == false)
									{
										const char* gamemodeName = g_pGame->GetGameRules()->GetEntity()->GetClass()->GetName();

										CryFixedStringT<32> strSignalName;
										strSignalName.Format("StartGame%s", gamemodeName);
										TAudioSignalID signalId = g_pGame->GetGameAudio()->GetSignalID(strSignalName);

										CryFixedStringT<64> localisedStartString = CHUDUtils::LocalizeString( m_startMatchString.c_str() );

										if (bTeamGame)
										{
											CryFixedStringT<16> strTeamName;
											strTeamName.Format("@ui_hud_team_%d", teamId);
											
											SHUDEventWrapper::TeamMessage(strTeamName.c_str(), teamId, SHUDEventWrapper::SMsgAudio(signalId), false, true);
											SHUDEventWrapper::SimpleBannerMessage(localisedStartString.c_str(), SHUDEventWrapper::kMsgAudioNULL);
										}
										else
										{
											SHUDEventWrapper::RoundMessageNotify(localisedStartString.c_str(), SHUDEventWrapper::SMsgAudio(signalId));
										}
									}
								}
							}

							m_introMessageShown = true; // Or not if has already died, but don't check again anyway.
						}
					}
				}
			}
		}
		else if(m_state == EGRS_PostGame && !gEnv->IsDedicated())
		{
			if (!gEnv->bServer)
			{
				m_timeInPostGame += frameTime;
			}

			m_timeInCurrentPostGameState += frameTime;

			switch (m_postGameState)
			{
				case ePGS_Starting:
				{
					CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem();
					if (pRecordingSystem != NULL && (pRecordingSystem->IsPlayingBack() || pRecordingSystem->IsPlaybackQueued()))
					{
						// Currently showing a killcam, skip to the killcam stage of the postgame flow
						EnterPostGameState(ePGS_FinalKillcam);
					}
					else
					{
						if (m_pGameRules->GetRoundsModule())
						{
							EnterPostGameState(ePGS_Top3);
						}
						else
						{
							EnterPostGameState(ePGS_HudMessage);
						}
					}
					break;
				}
				case ePGS_HudMessage:
				{
					if (m_timeInCurrentPostGameState > g_pGameCVars->g_gameRules_postGame_HUDMessageTime)
					{
						EnterPostGameState(ePGS_FinalKillcam);
					}
					break;
				}
				case ePGS_FinalKillcam:
				{
					CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem();
					if (!pRecordingSystem || !(pRecordingSystem->IsPlayingBack() || (pRecordingSystem->IsPlaybackQueued() && pRecordingSystem->HasWinningKillcam())))
					{
						EnterPostGameState(ePGS_Top3);
					}
#ifndef _RELEASE
					else if(g_pGameCVars->g_hud_postgame_debug && pRecordingSystem)
					{
						CryWatch("PostGameState - Waiting for final killcam to end:"); 
						CryWatch("IsPlaybackQueued: %s, IsPlayingBack: %s", 
							pRecordingSystem->IsPlaybackQueued() ? "True" : "False", pRecordingSystem->IsPlayingBack() ? "True" : "False");
					}
#endif
					break;
				}
				case ePGS_HighlightReel:
				{
					CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem();
					if (!pRecordingSystem || (!pRecordingSystem->IsPlaybackQueued() && !pRecordingSystem->IsPlayingBack()))
					{
						CGameLobby *pGameLobby = g_pGame->GetGameLobby();
						if (pGameLobby)
						{
							CryLog("[GameRules] Client trying to return to lobby");
							pGameLobby->SvFinishedGame(frameTime);
							EnterPostGameState(ePGS_LeavingGame);
						}
					}
#ifndef _RELEASE
					else if(g_pGameCVars->g_hud_postgame_debug && pRecordingSystem)
					{
						CryWatch("PostGameState - Waiting for highlight reel to end:");
						CryWatch("IsPlaybackQueued: %s, IsPlayingBack: %s, IsPlayingHighlightsReel: %s", 
							pRecordingSystem->IsPlaybackQueued() ? "True" : "False", pRecordingSystem->IsPlayingBack() ? "True" : "False", pRecordingSystem->IsPlayingHighlightsReel() ? "True" : "False");
					}
#endif
					break;
				}
				case ePGS_Top3:
				{
					if (m_timeInCurrentPostGameState > g_pGameCVars->g_gameRules_postGame_Top3Time)
					{
						EnterPostGameState(ePGS_Scoreboard);
					}
					break;
				}
				case ePGS_Scoreboard:
				{
					if(m_timeInCurrentPostGameState > g_pGameCVars->g_gameRules_postGame_ScoreboardTime)
					{
						if(!m_bHasShownHighlightReel && g_pGameCVars->kc_showHighlightsAtEndOfGame)
						{
							EnterPostGameState(ePGS_HighlightReel);
						}
						else
						{
							CGameLobby *pGameLobby = g_pGame->GetGameLobby();
							if (pGameLobby)
							{
								CryLog("[GameRules] Client trying to return to lobby [No highlight reel]");
								pGameLobby->SvFinishedGame(frameTime);
							}
						}
					}
					break;
				}
			}
		}
	}
}
Пример #23
0
//-------------------------------------------------------------------------
void CGameRulesStandardState::ChangeState( EGR_GameState newState )
{
	if (gEnv->bServer)
	{
		if (newState == EGRS_InGame)
		{
			CCCPOINT(GameRulesStandardState_EnterInGame);

#if !defined(_RELEASE) || defined(PERFORMANCE_BUILD)
			if (m_state != EGRS_InGame)
			{
				if (g_pGameCVars->g_gameRules_startCmd[0] != '\0')
				{
					gEnv->pConsole->ExecuteString(g_pGameCVars->g_gameRules_startCmd, false, true);
				}
			}
#endif // #if !defined(_RELEASE) || defined(PERFORMANCE_BUILD)

			m_pGameRules->ResetGameTime();
			IGameRulesStatsRecording	*st=m_pGameRules->GetStatsRecordingModule();
			if (st)
			{
				st->OnInGameBegin();
			}
		}
		else if (newState == EGRS_PostGame)
		{
			m_timeInPostGame = 0.0f;
			IGameRulesStatsRecording	*st=m_pGameRules->GetStatsRecordingModule();
			if (st)
			{
				st->OnPostGameBegin();
			}
#if defined(DEDICATED_SERVER) 
      if ( gEnv->bMultiplayer )
      {
        // Stop cvar probes.
        CGameRules::TPlayers players;
        m_pGameRules->GetPlayers(players);
        const int numPlayers = players.size();
        for (int i = 0; i < numPlayers; ++ i)
        {
          const EntityId playerId = players[i];
          IActor * pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(playerId);
          if ( pActor )
          {

            IGameObject * pGameObject = NULL;
            INetChannel * pNetChannel = NULL;
            IDefenceContext * pDefenceContext = NULL;

            if ( (pGameObject = pActor->GetGameObject()) )
            {
              if ( (pNetChannel = pGameObject->GetNetChannel()) )
              {
                if ( (pDefenceContext = pNetChannel->GetDefenceContext()) )
                {
                  pDefenceContext->EndCvarRequests();
                }
              }
            }
          }
        }
      }
#endif

			CGameLobby *pGameLobby = g_pGame->GetGameLobby();
			if (pGameLobby)
			{
				CryLog("[GameRules] GameFinished, telling clients");
				pGameLobby->SvFinishedGame(0.0f);
			}
		}
	}

	const bool bIsClient = gEnv->IsClient();
	if (bIsClient)
	{
		if (newState == EGRS_PostGame)
		{
			m_timeInPostGame = 0.0f;

			EnterPostGameState(ePGS_Starting);
		}
		else if (newState == EGRS_InGame)
		{
			CHUDEventDispatcher::CallEvent( SHUDEvent(eHUDEvent_OnGameStart) );
		}
		else if (newState == EGRS_Reset)
		{
			m_introMessageShown = false;
		}

		ClientChangeStateFeedback(newState);
	}

	m_state = newState;

	OnStateEntered_NotifyListeners(); 

	if (newState == EGRS_PostGame)
	{
		m_pGameRules->FreezeInput(true);
		g_pGame->GetUI()->ActivateDefaultState();	// must be after settings newState to pick endgame
	
		OnGameEnd_NotifyListeners();
	}
	else if (newState == EGRS_InGame)
	{
		OnGameStart_NotifyListeners();

		if (bIsClient && g_pGameCVars->g_gameRules_preGame_StartSpawnedFrozen)
		{
			g_pGameActions->FilterMPPreGameFreeze()->Enable(false);
			g_pGame->GetUI()->ActivateDefaultState();	// must be after settings newState
		}

		// Have to explicitly call the spawning module, can't use the listener since that would make the modules
		// dependent on the initialisation order - which comes from xml
		IGameRulesSpawningModule *pSpawningModule = m_pGameRules->GetSpawningModule();
		if (pSpawningModule)
		{
			pSpawningModule->OnInGameBegin();
		}
	}

	if (gEnv->bServer)
	{
		CHANGED_NETWORK_STATE(m_pGameRules, STANDARD_STATE_ASPECT);

		if (m_state == EGRS_InGame)
		{
			// Revive players - has to be done after setting m_state since we don't revive players in PreGame
			IGameRulesSpawningModule *pSpawningModule = m_pGameRules->GetSpawningModule();
			if (pSpawningModule)
			{
				const bool bOnlyIfDead = (g_pGameCVars->g_gameRules_preGame_StartSpawnedFrozen!=0);
				pSpawningModule->ReviveAllPlayers(false, bOnlyIfDead);
			}
		}
	}
}
Пример #24
0
//------------------------------------------------------------------------
bool CGameRules::OnPromoteToServer(SHostMigrationInfo& hostMigrationInfo, uint32& state)
{
	if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session))
	{
		return true;
	}

	CryLogAlways("[Host Migration]: CGameRules::OnPromoteToServer() started");

	// Server time will change after we migrate (change from old server time to new server time)
	m_gameStartedTime.SetValue(m_gameStartedTime.GetValue() - m_cachedServerTime.GetValue());
	m_gameStartTime.SetValue(m_gameStartTime.GetValue() - m_cachedServerTime.GetValue());

	// If this migration has reset (we're not the original anticipated host, remove any entities from the first attempt
	if (!m_hostMigrationCachedEntities.empty())
	{
		HostMigrationRemoveDuplicateDynamicEntities();
	}

	// Now we know we're the server, remove the actors for anyone we know isn't going to migrate
	CGameLobby *pGameLobby = g_pGame->GetGameLobby();
	CRY_ASSERT(pGameLobby);
	if (pGameLobby)
	{
		TPlayers playersToRemove;

		IActorSystem *pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();

		playersToRemove.reserve(pActorSystem->GetActorCount());

		IActorIteratorPtr actorIt = pActorSystem->CreateActorIterator();
		IActor *pActor;
		while (pActor = actorIt->Next())
		{
			if (pActor->IsPlayer())
			{
				CRY_ASSERT(pActor->GetChannelId());
				SCryMatchMakingConnectionUID conId = pGameLobby->GetConnectionUIDFromChannelID((int) pActor->GetChannelId());
				if (pGameLobby->GetSessionNames().Find(conId) == SSessionNames::k_unableToFind)
				{
					CryLog("  player '%s' has not got a corresponding CGameLobby entry, removing actor", pActor->GetEntity()->GetName());
					playersToRemove.push_back(pActor->GetEntityId());
				}
			}
		}

		const int numPlayersToRemove = playersToRemove.size();
		for (int i = 0; i < numPlayersToRemove; ++ i)
		{
			FakeDisconnectPlayer(playersToRemove[i]);
		}
	}

	for (uint32 i = 0; i < MAX_PLAYERS; ++ i)
	{
		m_migratedPlayerChannels[i] = 0;
	}

	IItemSystem *pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem();

	IEntityItPtr it = gEnv->pEntitySystem->GetEntityIterator();
	it->MoveFirst();

	for (uint32 i = 0; i < m_hostMigrationItemMaxCount; ++ i)
	{
		m_pHostMigrationItemInfo[i].Reset();
	}
	uint32 itemIndex = 0;

	IEntity *pEntity = NULL;
	while (pEntity = it->Next())
	{
		IItem *pItem = pItemSystem->GetItem(pEntity->GetId());
		if (pItem)
		{
			if (pItem->GetOwnerId())
			{
				IEntity *pOwner = gEnv->pEntitySystem->GetEntity(pItem->GetOwnerId());
				if (pOwner)
				{
					EntityId currentItemId = 0;

					IActor *pOwnerActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pOwner->GetId());
					if (pOwnerActor)
					{
						IItem *pCurrentItem = pOwnerActor->GetCurrentItem();
						currentItemId = pCurrentItem ? pCurrentItem->GetEntityId() : 0;
					}

					CryLog("[CG] Item '%s' is owned by '%s'", pEntity->GetName(), pOwner->GetName());
					//m_pHostMigrationItemInfo[itemIndex].Set(pEntity->GetId(), pOwner->GetId(), pItem->IsUsed(), (pItem->GetEntityId() == currentItemId));
					itemIndex ++;
					if (itemIndex >= m_hostMigrationItemMaxCount)
					{
						CRY_ASSERT(itemIndex < m_hostMigrationItemMaxCount);
						break;
					}
				}
			}
		}
		// Tell entities that we're host migrating
		// - Currently only used by ForbiddenArea but may well be needed for other entities later
		// - Currently only called on the new server, add to OnDemoteToClient if we need to use this on a client
		IScriptTable *pScript = pEntity->GetScriptTable();
		if (pScript != NULL && pScript->GetValueType("OnHostMigration") == svtFunction)
		{
			m_pScriptSystem->BeginCall(pScript, "OnHostMigration");
			m_pScriptSystem->PushFuncParam(pScript);
			m_pScriptSystem->PushFuncParam(true);
			m_pScriptSystem->EndCall();
		}
	}

	// This needs initialising on the new server otherwise the respawn timer will be counting down
	// from uninitialised data.  Likewise for the pre-round timer.
	ResetReviveCycleTime();

	const int numRespawnParams = m_respawndata.size();
	for (int i = 0; i < numRespawnParams; ++ i)
	{
		SEntityRespawnData *pData = &m_respawndata[i];
		pEntity = gEnv->pEntitySystem->GetEntity(pData->m_currentEntityId);
		if (pEntity == NULL)
		{
			CryLog("  detected respawn entity (id=%u) is not present, scheduling for respawn", pData->m_currentEntityId);
			ScheduleEntityRespawn(pData->m_currentEntityId, false, g_pGameCVars->g_defaultItemRespawnTimer);
		}
	}

	CryLog("[Host Migration]: CGameRules::OnPromoteToServer() finished");

	CCCPOINT(HostMigration_OnPromoteToServer);
	return true;
}