202 lines
7.1 KiB
C++
202 lines
7.1 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "MultiplayerSessionsSubsystem.h"
|
|
|
|
#include "OnlineSubsystem.h"
|
|
#include "OnlineSessionSettings.h"
|
|
|
|
UMultiplayerSessionsSubsystem::UMultiplayerSessionsSubsystem():
|
|
CreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCreateSessionComplete)),
|
|
FindSessionsCompleteDelegate(FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnFindSessionsComplete)),
|
|
JoinSessionCompleteDelegate(FOnJoinSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnJoinSessionComplete)),
|
|
DestroySessionCompleteDelegate(FOnDestroySessionCompleteDelegate::CreateUObject(this, &ThisClass::OnDestroySessionComplete)),
|
|
StartSessionCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnStartSessionComplete))
|
|
{
|
|
IOnlineSubsystem* Subsystem = IOnlineSubsystem::Get();
|
|
if (Subsystem)
|
|
{
|
|
SessionInterface = Subsystem->GetSessionInterface();
|
|
}
|
|
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::CreateSession(int32 NumPublicConnections, FString MatchType)
|
|
{
|
|
if (!SessionInterface.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto ExistingSession = SessionInterface->GetNamedSession(NAME_GameSession);
|
|
if (ExistingSession != nullptr)
|
|
{
|
|
bCreateSessionOnDestroy = true;
|
|
LastNumPublicConnections = NumPublicConnections;
|
|
LastMatchType = MatchType;
|
|
|
|
DestroySession();
|
|
}
|
|
|
|
// Store the delegate in a FDelegateHandle so we can later remove it from the delegate list
|
|
CreateSessionCompleteDelegateHandle = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate);
|
|
|
|
LastSessionSettings = MakeShareable(new FOnlineSessionSettings());
|
|
LastSessionSettings->bIsLANMatch = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true : false;
|
|
LastSessionSettings->NumPublicConnections = NumPublicConnections;
|
|
LastSessionSettings->bAllowJoinInProgress = true;
|
|
LastSessionSettings->bAllowJoinViaPresence = true;
|
|
LastSessionSettings->bShouldAdvertise = true;
|
|
LastSessionSettings->bUsesPresence = true;
|
|
LastSessionSettings->bUseLobbiesIfAvailable = true; // For UE5 when not finding sessions
|
|
LastSessionSettings->Set(FName("MatchType"), FString(MatchType), EOnlineDataAdvertisementType::ViaOnlineServiceAndPing);
|
|
LastSessionSettings->BuildUniqueId = 1;
|
|
|
|
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
|
if (!SessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *LastSessionSettings))
|
|
{
|
|
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
|
|
|
|
// Broadcast our own custom delegate
|
|
MultiplayerOnCreateSessionComplete.Broadcast(false);
|
|
}
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::FindSessions(int32 MaxSearchResults)
|
|
{
|
|
if (!SessionInterface.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
FindSessionCompleteDelegateHandle = SessionInterface->AddOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegate);
|
|
|
|
LastSessionSearch = MakeShareable(new FOnlineSessionSearch);
|
|
LastSessionSearch->MaxSearchResults = MaxSearchResults;
|
|
LastSessionSearch->bIsLanQuery = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true : false;
|
|
LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
|
|
|
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
|
if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), LastSessionSearch.ToSharedRef()))
|
|
{
|
|
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionCompleteDelegateHandle);
|
|
|
|
MultiplayerOnFindSessionsComplete.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
|
|
}
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionResult)
|
|
{
|
|
if (!SessionInterface.IsValid())
|
|
{
|
|
MultiplayerOnJoinSessionComplete.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
|
return;
|
|
}
|
|
|
|
JoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegate);
|
|
|
|
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
|
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, SessionResult))
|
|
{
|
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
|
|
|
|
MultiplayerOnJoinSessionComplete.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
|
}
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::DestroySession()
|
|
{
|
|
if (!SessionInterface.IsValid())
|
|
{
|
|
MultiplayerOnDestroySessionComplete.Broadcast(false);
|
|
return;
|
|
}
|
|
|
|
DestroySessionCompleteDelegateHandle = SessionInterface->AddOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegate);
|
|
|
|
if (!SessionInterface->DestroySession(NAME_GameSession))
|
|
{
|
|
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegateHandle);
|
|
MultiplayerOnDestroySessionComplete.Broadcast(false);
|
|
}
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::StartSession()
|
|
{
|
|
if (!SessionInterface.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
StartSessionCompleteDelegateHandle = SessionInterface->AddOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegate);
|
|
|
|
if (!SessionInterface->StartSession(NAME_GameSession))
|
|
{
|
|
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegateHandle);
|
|
|
|
MultiplayerOnStartSessionComplete.Broadcast(false);
|
|
}
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
|
|
{
|
|
if (SessionInterface)
|
|
{
|
|
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
|
|
}
|
|
|
|
MultiplayerOnCreateSessionComplete.Broadcast(bWasSuccessful);
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::OnFindSessionsComplete(bool bWasSuccessful)
|
|
{
|
|
if (SessionInterface)
|
|
{
|
|
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionCompleteDelegateHandle);
|
|
}
|
|
|
|
if (LastSessionSearch->SearchResults.Num() <= 0)
|
|
{
|
|
MultiplayerOnFindSessionsComplete.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
|
|
return;
|
|
}
|
|
|
|
MultiplayerOnFindSessionsComplete.Broadcast(LastSessionSearch->SearchResults, bWasSuccessful);
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
|
|
{
|
|
if (SessionInterface)
|
|
{
|
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
|
|
}
|
|
|
|
MultiplayerOnJoinSessionComplete.Broadcast(Result);
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::OnDestroySessionComplete(FName SessionName, bool bWasSuccessful)
|
|
{
|
|
if (SessionInterface)
|
|
{
|
|
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegateHandle);
|
|
}
|
|
|
|
if (bWasSuccessful && bCreateSessionOnDestroy)
|
|
{
|
|
bCreateSessionOnDestroy = false;
|
|
CreateSession(LastNumPublicConnections, LastMatchType);
|
|
}
|
|
|
|
MultiplayerOnDestroySessionComplete.Broadcast(bWasSuccessful);
|
|
}
|
|
|
|
void UMultiplayerSessionsSubsystem::OnStartSessionComplete(FName SessionNAme, bool bWasSuccessful)
|
|
{
|
|
if (SessionInterface)
|
|
{
|
|
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegateHandle);
|
|
}
|
|
|
|
MultiplayerOnStartSessionComplete.Broadcast(bWasSuccessful);
|
|
}
|