204 lines
6.5 KiB
C++
204 lines
6.5 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "CommonGameInstance.h"
|
|
|
|
#include "CommonLocalPlayer.h"
|
|
#include "CommonSessionSubsystem.h"
|
|
#include "CommonUISettings.h"
|
|
#include "CommonUserSubsystem.h"
|
|
#include "Containers/UnrealString.h"
|
|
#include "Delegates/Delegate.h"
|
|
#include "Engine/LocalPlayer.h"
|
|
#include "GameUIManagerSubsystem.h"
|
|
#include "GameplayTagContainer.h"
|
|
#include "ICommonUIModule.h"
|
|
#include "Internationalization/Text.h"
|
|
#include "LogCommonGame.h"
|
|
#include "Logging/LogCategory.h"
|
|
#include "Logging/LogMacros.h"
|
|
#include "Messaging/CommonGameDialog.h"
|
|
#include "Messaging/CommonMessagingSubsystem.h"
|
|
#include "Misc/AssertionMacros.h"
|
|
#include "NativeGameplayTags.h"
|
|
#include "Templates/Casts.h"
|
|
#include "Trace/Detail/Channel.h"
|
|
#include "UObject/WeakObjectPtr.h"
|
|
|
|
UCommonGameInstance::UCommonGameInstance(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
|
|
}
|
|
|
|
void UCommonGameInstance::HandleSystemMessage(FGameplayTag MessageType, FText Title, FText Message)
|
|
{
|
|
ULocalPlayer* FirstPlayer = GetFirstGamePlayer();
|
|
// Forward severe ones to the error dialog for the first player
|
|
if (FirstPlayer && MessageType.MatchesTag(FCommonUserTags::SystemMessage_Error))
|
|
{
|
|
if (UCommonMessagingSubsystem* Messaging = FirstPlayer->GetSubsystem<UCommonMessagingSubsystem>())
|
|
{
|
|
Messaging->ShowError(UCommonGameDialogDescriptor::CreateConfirmationOk(Title, Message));
|
|
}
|
|
}
|
|
}
|
|
|
|
void UCommonGameInstance::HandlePrivilegeChanged(const UCommonUserInfo* UserInfo, ECommonUserPrivilege Privilege, ECommonUserAvailability OldAvailability, ECommonUserAvailability NewAvailability)
|
|
{
|
|
// By default show errors and disconnect if play privilege for first player is lost
|
|
if (Privilege == ECommonUserPrivilege::CanPlay && OldAvailability == ECommonUserAvailability::NowAvailable && NewAvailability != ECommonUserAvailability::NowAvailable)
|
|
{
|
|
UE_LOG(LogCommonGame, Error, TEXT("HandlePrivilegeChanged: Player %d no longer has permission to play the game!"), UserInfo->LocalPlayerIndex);
|
|
// TODO: Games can do something specific in subclass
|
|
// ReturnToMainMenu();
|
|
}
|
|
}
|
|
|
|
int32 UCommonGameInstance::AddLocalPlayer(ULocalPlayer* NewPlayer, FPlatformUserId UserId)
|
|
{
|
|
int32 ReturnVal = Super::AddLocalPlayer(NewPlayer, UserId);
|
|
if (ReturnVal != INDEX_NONE)
|
|
{
|
|
if (!PrimaryPlayer.IsValid())
|
|
{
|
|
UE_LOG(LogCommonGame, Log, TEXT("AddLocalPlayer: Set %s to Primary Player"), *NewPlayer->GetName());
|
|
PrimaryPlayer = NewPlayer;
|
|
}
|
|
|
|
GetSubsystem<UGameUIManagerSubsystem>()->NotifyPlayerAdded(Cast<UCommonLocalPlayer>(NewPlayer));
|
|
}
|
|
|
|
return ReturnVal;
|
|
}
|
|
|
|
bool UCommonGameInstance::RemoveLocalPlayer(ULocalPlayer* ExistingPlayer)
|
|
{
|
|
if (PrimaryPlayer == ExistingPlayer)
|
|
{
|
|
//TODO: do we want to fall back to another player?
|
|
PrimaryPlayer.Reset();
|
|
UE_LOG(LogCommonGame, Log, TEXT("RemoveLocalPlayer: Unsetting Primary Player from %s"), *ExistingPlayer->GetName());
|
|
}
|
|
GetSubsystem<UGameUIManagerSubsystem>()->NotifyPlayerDestroyed(Cast<UCommonLocalPlayer>(ExistingPlayer));
|
|
|
|
return Super::RemoveLocalPlayer(ExistingPlayer);
|
|
}
|
|
|
|
void UCommonGameInstance::Init()
|
|
{
|
|
Super::Init();
|
|
|
|
// After subsystems are initialized, hook them together
|
|
FGameplayTagContainer PlatformTraits = ICommonUIModule::GetSettings().GetPlatformTraits();
|
|
|
|
UCommonUserSubsystem* UserSubsystem = GetSubsystem<UCommonUserSubsystem>();
|
|
if (ensure(UserSubsystem))
|
|
{
|
|
UserSubsystem->SetTraitTags(PlatformTraits);
|
|
UserSubsystem->OnHandleSystemMessage.AddDynamic(this, &UCommonGameInstance::HandleSystemMessage);
|
|
UserSubsystem->OnUserPrivilegeChanged.AddDynamic(this, &UCommonGameInstance::HandlePrivilegeChanged);
|
|
}
|
|
|
|
UCommonSessionSubsystem* SessionSubsystem = GetSubsystem<UCommonSessionSubsystem>();
|
|
if (ensure(SessionSubsystem))
|
|
{
|
|
SessionSubsystem->OnUserRequestedSessionEvent.AddUObject(this, &UCommonGameInstance::OnUserRequestedSession);
|
|
}
|
|
}
|
|
|
|
void UCommonGameInstance::ResetUserAndSessionState()
|
|
{
|
|
UCommonUserSubsystem* UserSubsystem = GetSubsystem<UCommonUserSubsystem>();
|
|
if (ensure(UserSubsystem))
|
|
{
|
|
UserSubsystem->ResetUserState();
|
|
}
|
|
|
|
UCommonSessionSubsystem* SessionSubsystem = GetSubsystem<UCommonSessionSubsystem>();
|
|
if (ensure(SessionSubsystem))
|
|
{
|
|
SessionSubsystem->CleanUpSessions();
|
|
}
|
|
}
|
|
|
|
void UCommonGameInstance::ReturnToMainMenu()
|
|
{
|
|
// By default when returning to main menu we should reset everything
|
|
ResetUserAndSessionState();
|
|
|
|
Super::ReturnToMainMenu();
|
|
}
|
|
|
|
void UCommonGameInstance::OnUserRequestedSession(const FPlatformUserId& PlatformUserId, UCommonSession_SearchResult* InRequestedSession, const FOnlineResultInformation& RequestedSessionResult)
|
|
{
|
|
if (InRequestedSession)
|
|
{
|
|
SetRequestedSession(InRequestedSession);
|
|
}
|
|
else
|
|
{
|
|
HandleSystemMessage(FCommonUserTags::SystemMessage_Error, NSLOCTEXT("CommonGame", "Warning_RequestedSessionFailed", "Requested Session Failed"), RequestedSessionResult.ErrorText);
|
|
}
|
|
}
|
|
|
|
void UCommonGameInstance::SetRequestedSession(UCommonSession_SearchResult* InRequestedSession)
|
|
{
|
|
RequestedSession = InRequestedSession;
|
|
if (RequestedSession)
|
|
{
|
|
if (CanJoinRequestedSession())
|
|
{
|
|
JoinRequestedSession();
|
|
}
|
|
else
|
|
{
|
|
ResetGameAndJoinRequestedSession();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool UCommonGameInstance::CanJoinRequestedSession() const
|
|
{
|
|
// Default behavior is always allow joining the requested session
|
|
return true;
|
|
}
|
|
|
|
void UCommonGameInstance::JoinRequestedSession()
|
|
{
|
|
if (RequestedSession)
|
|
{
|
|
if (ULocalPlayer* const FirstPlayer = GetFirstGamePlayer())
|
|
{
|
|
UCommonSessionSubsystem* SessionSubsystem = GetSubsystem<UCommonSessionSubsystem>();
|
|
if (ensure(SessionSubsystem))
|
|
{
|
|
// Clear our current requested session since we are now acting on it.
|
|
UCommonSession_SearchResult* LocalRequestedSession = RequestedSession;
|
|
RequestedSession = nullptr;
|
|
SessionSubsystem->JoinSession(FirstPlayer->PlayerController, LocalRequestedSession);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UCommonGameInstance::ResetGameAndJoinRequestedSession()
|
|
{
|
|
// Default behavior is to return to the main menu. The game must call JoinRequestedSession when the game is in a ready state.
|
|
ReturnToMainMenu();
|
|
}
|
|
|
|
|
|
//void UCommonGameInstance::OnPreLoadMap(const FString& MapName)
|
|
//{
|
|
// if (!IsDedicatedServerInstance())
|
|
// {
|
|
// if (!bWasInLoadMap)
|
|
// {
|
|
// UGameUIManagerSubsystem* UIManager = GetSubsystem<UGameUIManagerSubsystem>();
|
|
// for (ULocalPlayer* LocalPlayer : LocalPlayers)
|
|
// {
|
|
// UIManager->NotifyPlayerAdded(Cast<UCommonLocalPlayer>(LocalPlayer));
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|