diff --git a/Source/TurnBasedTutorial/MyGameInstanceSubsystem.cpp b/Source/TurnBasedTutorial/MyGameInstanceSubsystem.cpp index a7c3930..e0b684f 100644 --- a/Source/TurnBasedTutorial/MyGameInstanceSubsystem.cpp +++ b/Source/TurnBasedTutorial/MyGameInstanceSubsystem.cpp @@ -5,7 +5,26 @@ #include "OnlineSubsystemUtils.h" UMyGameInstanceSubsystem::UMyGameInstanceSubsystem() : CreateSessionCompleteDelegate( - FOnCreateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCreateSessionCompleted)) + 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)) { } @@ -50,7 +69,7 @@ void UMyGameInstanceSubsystem::CreateSession(int32 NumPublicConnections, bool bI void UMyGameInstanceSubsystem::OnCreateSessionCompleted(FName SessionName, bool bSuccessful) { const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld()); - if (SessionInterface) + if (SessionInterface.IsValid()) { SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle); } @@ -92,10 +111,209 @@ void UMyGameInstanceSubsystem::UpdateSession() void UMyGameInstanceSubsystem::OnUpdateSessionCompleted(FName SessionName, bool bSuccessful) { const IOnlineSessionPtr sessionInterface = Online::GetSessionInterface(GetWorld()); - if (sessionInterface) + 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; +} diff --git a/Source/TurnBasedTutorial/MyGameInstanceSubsystem.h b/Source/TurnBasedTutorial/MyGameInstanceSubsystem.h index 3fd413d..7ad7735 100644 --- a/Source/TurnBasedTutorial/MyGameInstanceSubsystem.h +++ b/Source/TurnBasedTutorial/MyGameInstanceSubsystem.h @@ -3,14 +3,26 @@ #pragma once #include "CoreMinimal.h" +#include "OnlineSessionSettings.h" #include "Interfaces/OnlineSessionInterface.h" #include "Subsystems/GameInstanceSubsystem.h" #include "MyGameInstanceSubsystem.generated.h" -DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnCreateSessionComplete, bool, Successful); -DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnUpdateSessionComplete, bool, Successful); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnCreateSessionComplete, bool, bSuccessful); +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnUpdateSessionComplete, bool, bSuccessful); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnStartSessionCompete, bool, bSuccessful); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnEndSessionComplete, bool, bSuccessful); + +DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnDestroySessionComplete, bool, bSuccessful); + +DECLARE_MULTICAST_DELEGATE_TwoParams(FMyOnFindSessionsComplete, + const TArray& SessionResults, bool bSuccessful); + +DECLARE_MULTICAST_DELEGATE_OneParam(FMyOnJoinSessionCompele, EOnJoinSessionCompleteResult::Type Result); /** * */ @@ -25,15 +37,42 @@ public: void CreateSession(int32 NumPublicConnections, bool bIsLANMatch); void UpdateSession(); - + + void StartSession(); + + void EndSession(); + + void DestroySession(); + + void FindSessions(int32 MaxSearchResults, bool bIsLANQuery); + + void JoinSession(const FOnlineSessionSearchResult& SessionSearchResult); + FMyOnCreateSessionComplete OnCreateSessionCompleteEvent; FMyOnUpdateSessionComplete OnUpdateSessionCompleteEvent; - + FMyOnStartSessionCompete OnStartSessionCompleteEvent; + FMyOnEndSessionComplete OnEndSessionCompleteEvent; + FMyOnDestroySessionComplete OnDestroySessionCompleteEvent; + FMyOnFindSessionsComplete OnFindSessionsCompleteEvent; + FMyOnJoinSessionCompele OnJoinSessionCompleteEvent; + protected: void OnCreateSessionCompleted(FName SessionName, bool bSuccessful); void OnUpdateSessionCompleted(FName SessionName, bool bSuccessful); - + + void OnStartSessionCompleted(FName SessionName, bool bSuccessful); + + void OnEndSessionCompleted(FName SessionName, bool bSuccessful); + + void OnDestroySessionCompleted(FName SessionName, bool bSuccessful); + + void OnFindSessionsCompleted(bool bSuccessful); + + void OnJoinSessionCompleted(FName SessionName, EOnJoinSessionCompleteResult::Type Result); + + bool TryConnectToCurrentSession() const; + private: FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate; FDelegateHandle CreateSessionCompleteDelegateHandle; @@ -41,4 +80,20 @@ private: FOnUpdateSessionCompleteDelegate UpdateSessionCompleteDelegate; FDelegateHandle UpdateSessionCompleteDelegateHandle; + + FOnStartSessionCompleteDelegate StartSessionCompleteDelegate; + FDelegateHandle StartSessionCompleteDelegateHandle; + + FOnEndSessionCompleteDelegate EndSessionCompleteDelegate; + FDelegateHandle EndSessionCompleteDelegateHandle; + + FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate; + FDelegateHandle DestroySessionCompleteDelegateHandle; + + FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate; + FDelegateHandle FindSessionsCompleteDelegateHandle; + TSharedPtr LastSessionSearch; + + FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate; + FDelegateHandle JoinSessionCompleteDelegateHandle; };