/** * Give the async task a chance to marshal its data back to the game thread * Can only be called on the game thread by the async task manager */ virtual void Finalize() override { IOnlineSessionPtr SessionInt = Subsystem->GetSessionInterface(); FNamedOnlineSession* Session = SessionInt->GetNamedSession(SessionName); if (Session) { Session->SessionState = EOnlineSessionState::Ended; } }
/** * Give the async task a chance to marshal its data back to the game thread * Can only be called on the game thread by the async task manager */ virtual void Finalize() override { IOnlineSessionPtr SessionInt = Subsystem->GetSessionInterface(); if (SessionInt.IsValid()) { FNamedOnlineSession* Session = SessionInt->GetNamedSession(SessionName); if (Session) { SessionInt->RemoveNamedSession(SessionName); } } }
bool AQosBeaconHost::DoesSessionMatch(const FString& SessionId) const { UWorld* World = GetWorld(); IOnlineSessionPtr SessionInt = Online::GetSessionInterface(World); FNamedOnlineSession* Session = SessionInt.IsValid() ? SessionInt->GetNamedSession(SessionName) : NULL; if (Session && Session->SessionInfo.IsValid() && !SessionId.IsEmpty() && Session->SessionInfo->GetSessionId().ToString() == SessionId) { return true; } return false; }
void UOnlineSessionClient::EndOnlineSession(FName SessionName) { IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (SessionInterface.IsValid()) { FNamedOnlineSession* Session = SessionInterface->GetNamedSession(SessionName); if (Session && Session->SessionState == EOnlineSessionState::InProgress) { EndSessionCompleteHandle = SessionInterface->AddOnEndSessionCompleteDelegate_Handle(FOnStartSessionCompleteDelegate::CreateUObject(this, &UOnlineSessionClient::OnEndSessionComplete)); SessionInterface->EndSession(SessionName); } } }
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); } } } }