// Fill out your copyright notice in the Description page of Project Settings. #include "MyGameInstanceSubsystem.h" #include "OnlineSubsystemUtils.h" UMyGameInstanceSubsystem::UMyGameInstanceSubsystem() : CreateSessionCompleteDelegate( FOnCreateSessionCompleteDelegate::CreateUObject( this, &ThisClass::OnCreateSessionCompleted)), UpdateSessionCompleteDelegate( FOnUpdateSessionCompleteDelegate::CreateUObject( this, &ThisClass::OnUpdateSessionCompleted)), StartSessionCompleteDelegate( FOnStartSessionCompleteDelegate::CreateUObject( this, &ThisClass::OnStartSessionCompleted)), EndSessionCompleteDelegate( FOnEndSessionCompleteDelegate::CreateUObject( this, &ThisClass::OnEndSessionCompleted)), DestroySessionCompleteDelegate( FOnDestroySessionCompleteDelegate::CreateUObject( this, &ThisClass::OnDestroySessionCompleted)), FindSessionsCompleteDelegate( FOnFindSessionsCompleteDelegate::CreateUObject( this, &ThisClass::OnFindSessionsCompleted)), JoinSessionCompleteDelegate( FOnJoinSessionCompleteDelegate::CreateUObject( this, &ThisClass::OnJoinSessionCompleted)) { } void UMyGameInstanceSubsystem::CreateSession(int32 NumPublicConnections, bool bIsLANMatch) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (!SessionInterface.IsValid()) { OnCreateSessionCompleteEvent.Broadcast(false); return; } LastSessionSettings = MakeShareable(new FOnlineSessionSettings()); LastSessionSettings->NumPrivateConnections = 0; LastSessionSettings->NumPublicConnections = NumPublicConnections; LastSessionSettings->bAllowInvites = true; LastSessionSettings->bAllowJoinInProgress = true; LastSessionSettings->bAllowJoinViaPresence = true; LastSessionSettings->bAllowJoinViaPresenceFriendsOnly = true; LastSessionSettings->bIsDedicated = false; LastSessionSettings->bUsesPresence = true; LastSessionSettings->bIsLANMatch = bIsLANMatch; LastSessionSettings->bShouldAdvertise = true; LastSessionSettings->Set(SETTING_MAPNAME, FString("Your Level Name"), EOnlineDataAdvertisementType::ViaOnlineService); CreateSessionCompleteDelegateHandle = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle( CreateSessionCompleteDelegate); const ULocalPlayer* localPlayer = GetWorld()->GetFirstLocalPlayerFromController(); if (!SessionInterface->CreateSession(*localPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *LastSessionSettings)) { SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle); OnCreateSessionCompleteEvent.Broadcast(false); } } void UMyGameInstanceSubsystem::OnCreateSessionCompleted(FName SessionName, bool bSuccessful) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (SessionInterface.IsValid()) { SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle); } OnCreateSessionCompleteEvent.Broadcast(bSuccessful); } void UMyGameInstanceSubsystem::UpdateSession() { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (!SessionInterface.IsValid()) { OnCreateSessionCompleteEvent.Broadcast(false); return; } const TSharedPtr UpdatedSessionSettings = MakeShareable( new FOnlineSessionSettings(*LastSessionSettings)); // Here we can insert any changes we want UpdatedSessionSettings->Set(SETTING_MAPNAME, FString("Updated Level Name"), EOnlineDataAdvertisementType::ViaOnlineService); UpdateSessionCompleteDelegateHandle = SessionInterface->AddOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegate); if (!SessionInterface->UpdateSession(NAME_GameSession, *UpdatedSessionSettings)) { SessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegateHandle); OnUpdateSessionCompleteEvent.Broadcast(false); } else { LastSessionSettings = UpdatedSessionSettings; } } void UMyGameInstanceSubsystem::OnUpdateSessionCompleted(FName SessionName, bool bSuccessful) { const IOnlineSessionPtr sessionInterface = Online::GetSessionInterface(GetWorld()); if (sessionInterface.IsValid()) { sessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegateHandle); } OnUpdateSessionCompleteEvent.Broadcast(bSuccessful); } void UMyGameInstanceSubsystem::StartSession() { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (!SessionInterface.IsValid()) { OnCreateSessionCompleteEvent.Broadcast(false); return; } StartSessionCompleteDelegateHandle = SessionInterface->AddOnStartSessionCompleteDelegate_Handle( StartSessionCompleteDelegate); if (!SessionInterface->StartSession(NAME_GameSession)) { SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegateHandle); OnStartSessionCompleteEvent.Broadcast(false); } } void UMyGameInstanceSubsystem::OnStartSessionCompleted(FName SessionName, bool bSuccessful) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (SessionInterface.IsValid()) { SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegateHandle); } OnStartSessionCompleteEvent.Broadcast(bSuccessful); } void UMyGameInstanceSubsystem::EndSession() { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (!SessionInterface.IsValid()) { OnCreateSessionCompleteEvent.Broadcast(false); return; } EndSessionCompleteDelegateHandle = SessionInterface->AddOnEndSessionCompleteDelegate_Handle( EndSessionCompleteDelegate); if (!SessionInterface->EndSession(NAME_GameSession)) { SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle); OnEndSessionCompleteEvent.Broadcast(false); } } void UMyGameInstanceSubsystem::OnEndSessionCompleted(FName SessionName, bool bSuccessful) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (SessionInterface.IsValid()) { SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle); } OnEndSessionCompleteEvent.Broadcast(bSuccessful); } void UMyGameInstanceSubsystem::DestroySession() { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (!SessionInterface.IsValid()) { OnDestroySessionCompleteEvent.Broadcast(false); return; } DestroySessionCompleteDelegateHandle = SessionInterface->AddOnDestroySessionCompleteDelegate_Handle( DestroySessionCompleteDelegate); if (!SessionInterface->DestroySession(NAME_GameSession)) { SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle); OnDestroySessionCompleteEvent.Broadcast(false); } } void UMyGameInstanceSubsystem::OnDestroySessionCompleted(FName SessionName, bool bSuccessful) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (SessionInterface.IsValid()) { SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegateHandle); } OnDestroySessionCompleteEvent.Broadcast(bSuccessful); } void UMyGameInstanceSubsystem::FindSessions(int32 MaxSearchResults, bool bIsLANQuery) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (!SessionInterface.IsValid()) { OnFindSessionsCompleteEvent.Broadcast(TArray(), false); return; } FindSessionsCompleteDelegateHandle = SessionInterface->AddOnFindSessionsCompleteDelegate_Handle( FindSessionsCompleteDelegate); LastSessionSearch = MakeShareable(new FOnlineSessionSearch()); LastSessionSearch->MaxSearchResults = MaxSearchResults; LastSessionSearch->bIsLanQuery = bIsLANQuery; // Disable dedicated server search (maybe enable later, when dedicated server is implemented) LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals); const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), LastSessionSearch.ToSharedRef()) { SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle); OnFindSessionsCompleteEvent.Broadcast(TArray(), false); } } void UMyGameInstanceSubsystem::OnFindSessionsCompleted(bool bSuccessful) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (SessionInterface.IsValid()) { SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle); } if (LastSessionSearch->SearchResults.Num() <= 0) { OnFindSessionsCompleteEvent.Broadcast(TArray(), bSuccessful); return; } OnFindSessionsCompleteEvent.Broadcast(LastSessionSearch->SearchResults, bSuccessful); } void UMyGameInstanceSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionSearchResult) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (!SessionInterface.IsValid()) { OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError); return; } JoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle( JoinSessionCompleteDelegate); const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, SessionSearchResult)) { SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle); OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError); } } void UMyGameInstanceSubsystem::OnJoinSessionCompleted(FName SessionName, EOnJoinSessionCompleteResult::Type Result) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (SessionInterface.IsValid()) { SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle); } OnJoinSessionCompleteEvent.Broadcast(Result); } bool UMyGameInstanceSubsystem::TryConnectToCurrentSession() const { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); if (!SessionInterface.IsValid()) { return false; } FString ConnectString; if (!SessionInterface->GetResolvedConnectString(NAME_GameSession, ConnectString)) { return false; } APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); PlayerController->ClientTravel(ConnectString, TRAVEL_Absolute); return true; }