void UAdvancedSessionsLibrary::IsPlayerInSession(const FBPUniqueNetId &PlayerToCheck, bool &bIsInSession) { IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(); if (!SessionInterface.IsValid()) { UE_LOG(AdvancedSessionsLog, Warning, TEXT("IsPlayerInSession couldn't get the session interface!")); bIsInSession = false; return; } bIsInSession = SessionInterface->IsPlayerInSession(GameSessionName, *PlayerToCheck.GetUniqueNetId()); }
void APartyBeaconHost::Tick(float DeltaTime) { IOnlineSessionPtr SessionsInt = Online::GetSessionInterface(); if (SessionsInt.IsValid()) { FNamedOnlineSession* Session = SessionsInt->GetNamedSession(SessionName); if (Session) { TArray< TSharedPtr<FUniqueNetId> > PlayersToLogout; for (int32 ResIdx=0; ResIdx < Reservations.Num(); ResIdx++) { FPartyReservation& PartyRes = Reservations[ResIdx]; // Determine if we have a client connection for the reservation bool bIsConnectedReservation = false; for (int32 ClientIdx=0; ClientIdx < ClientActors.Num(); ClientIdx++) { APartyBeaconClient* Client = Cast<APartyBeaconClient>(ClientActors[ClientIdx]); if (Client) { const FPartyReservation& ClientRes = Client->GetPendingReservation(); if (ClientRes.PartyLeader == PartyRes.PartyLeader) { bIsConnectedReservation = true; break; } } else { UE_LOG(LogBeacon, Error, TEXT("Missing PartyBeaconClient found in ClientActors array")); ClientActors.RemoveAtSwap(ClientIdx); ClientIdx--; } } // Don't update clients that are still connected if (bIsConnectedReservation) { for (int32 PlayerIdx=0; PlayerIdx < PartyRes.PartyMembers.Num(); PlayerIdx++) { FPlayerReservation& PlayerEntry = PartyRes.PartyMembers[PlayerIdx]; PlayerEntry.ElapsedTime = 0.0f; } } // Once a client disconnects, update the elapsed time since they were found as a registrant in the game session else { for (int32 PlayerIdx=0; PlayerIdx < PartyRes.PartyMembers.Num(); PlayerIdx++) { FPlayerReservation& PlayerEntry = PartyRes.PartyMembers[PlayerIdx]; // Determine if the player is the owner of the session const bool bIsSessionOwner = Session->OwningUserId.IsValid() && (*Session->OwningUserId == *PlayerEntry.UniqueId); // Determine if the player member is registered in the game session if (SessionsInt->IsPlayerInSession(SessionName, *PlayerEntry.UniqueId) || // Never timeout the session owner bIsSessionOwner) { FUniqueNetIdMatcher PlayerMatch(*PlayerEntry.UniqueId); int32 FoundIdx = PlayersPendingJoin.FindMatch(PlayerMatch); if (FoundIdx != INDEX_NONE) { UE_LOG(LogBeacon, Display, TEXT("Beacon (%s): pending player %s found in session (%s)."), *GetName(), *PlayerEntry.UniqueId->ToDebugString(), *SessionName.ToString()); // reset elapsed time since found PlayerEntry.ElapsedTime = 0.0f; // also remove from pending join list PlayersPendingJoin.RemoveAtSwap(FoundIdx); } } else { // update elapsed time PlayerEntry.ElapsedTime += DeltaTime; // if the player is pending it's initial join then check against TravelSessionTimeoutSecs instead FUniqueNetIdMatcher PlayerMatch(*PlayerEntry.UniqueId); int32 FoundIdx = PlayersPendingJoin.FindMatch(PlayerMatch); const bool bIsPlayerPendingJoin = FoundIdx != INDEX_NONE; // if the timeout has been exceeded then add to list of players // that need to be logged out from the beacon if ((bIsPlayerPendingJoin && PlayerEntry.ElapsedTime > TravelSessionTimeoutSecs) || (!bIsPlayerPendingJoin && PlayerEntry.ElapsedTime > SessionTimeoutSecs)) { PlayersToLogout.AddUnique(PlayerEntry.UniqueId.GetUniqueNetId()); } } } } } // Logout any players that timed out for (int32 LogoutIdx=0; LogoutIdx < PlayersToLogout.Num(); LogoutIdx++) { bool bFound = false; const TSharedPtr<FUniqueNetId>& UniqueId = PlayersToLogout[LogoutIdx]; float ElapsedSessionTime = 0.f; for (int32 ResIdx=0; ResIdx < Reservations.Num(); ResIdx++) { FPartyReservation& PartyRes = Reservations[ResIdx]; for (int32 PlayerIdx=0; PlayerIdx < PartyRes.PartyMembers.Num(); PlayerIdx++) { FPlayerReservation& PlayerEntry = PartyRes.PartyMembers[PlayerIdx]; if (*PlayerEntry.UniqueId == *UniqueId) { ElapsedSessionTime = PlayerEntry.ElapsedTime; bFound = true; break; } } if (bFound) { break; } } UE_LOG(LogBeacon, Display, TEXT("Beacon (%s): player logout due to timeout for %s, elapsed time = %0.3f"), *GetName(), *UniqueId->ToDebugString(), ElapsedSessionTime); // Also remove from pending join list PlayersPendingJoin.RemoveSingleSwap(UniqueId); // let the beacon handle the logout and notifications/delegates FUniqueNetIdRepl RemovedId(UniqueId); HandlePlayerLogout(RemovedId); } } } }