/**
	 * 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);
			}
		}
	}
Example #3
0
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);
			}
		}
	}
}