搬了lyra的hudlayout
This commit is contained in:
38
Plugins/CommonUser/CommonUser.uplugin
Normal file
38
Plugins/CommonUser/CommonUser.uplugin
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "CommonUser",
|
||||
"Description": "Provides gameplay code and blueprint wrappers for online and platform operations.",
|
||||
"Category": "Gameplay",
|
||||
"CreatedBy": "Epic Games, Inc.",
|
||||
"CreatedByURL": "https://www.epicgames.com",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"CanContainContent": false,
|
||||
"IsBetaVersion": false,
|
||||
"IsExperimentalVersion": false,
|
||||
"Installed": false,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "CommonUser",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
],
|
||||
"Plugins": [
|
||||
{
|
||||
"Name": "OnlineSubsystem",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Name": "OnlineSubsystemUtils",
|
||||
"Enabled": true
|
||||
},
|
||||
{
|
||||
"Name": "OnlineServices",
|
||||
"Enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Plugins/CommonUser/Resources/Icon128.png
Normal file
BIN
Plugins/CommonUser/Resources/Icon128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
70
Plugins/CommonUser/Source/CommonUser/CommonUser.Build.cs
Normal file
70
Plugins/CommonUser/Source/CommonUser/CommonUser.Build.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class CommonUser : ModuleRules
|
||||
{
|
||||
public CommonUser(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
bool bUseOnlineSubsystemV1 = true;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
"CoreOnline",
|
||||
"GameplayTags",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
if (bUseOnlineSubsystemV1)
|
||||
{
|
||||
PublicDependencyModuleNames.Add("OnlineSubsystem");
|
||||
}
|
||||
else
|
||||
{
|
||||
PublicDependencyModuleNames.Add("OnlineServicesInterface");
|
||||
}
|
||||
PrivateDependencyModuleNames.Add("OnlineSubsystemUtils");
|
||||
PublicDefinitions.Add("COMMONUSER_OSSV1=" + (bUseOnlineSubsystemV1 ? "1" : "0"));
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreOnline",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"ApplicationCore",
|
||||
"InputCore",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "AsyncAction_CommonUserInitialize.h"
|
||||
|
||||
#include "GenericPlatform/GenericPlatformInputDeviceMapper.h"
|
||||
#include "TimerManager.h"
|
||||
|
||||
#include UE_INLINE_GENERATED_CPP_BY_NAME(AsyncAction_CommonUserInitialize)
|
||||
|
||||
UAsyncAction_CommonUserInitialize* UAsyncAction_CommonUserInitialize::InitializeForLocalPlay(UCommonUserSubsystem* Target, int32 LocalPlayerIndex, FInputDeviceId PrimaryInputDevice, bool bCanUseGuestLogin)
|
||||
{
|
||||
if (!PrimaryInputDevice.IsValid())
|
||||
{
|
||||
// Set to default device
|
||||
PrimaryInputDevice = IPlatformInputDeviceMapper::Get().GetDefaultInputDevice();
|
||||
}
|
||||
|
||||
UAsyncAction_CommonUserInitialize* Action = NewObject<UAsyncAction_CommonUserInitialize>();
|
||||
|
||||
Action->RegisterWithGameInstance(Target);
|
||||
|
||||
if (Target && Action->IsRegistered())
|
||||
{
|
||||
Action->Subsystem = Target;
|
||||
|
||||
Action->Params.RequestedPrivilege = ECommonUserPrivilege::CanPlay;
|
||||
Action->Params.LocalPlayerIndex = LocalPlayerIndex;
|
||||
Action->Params.PrimaryInputDevice = PrimaryInputDevice;
|
||||
Action->Params.bCanUseGuestLogin = bCanUseGuestLogin;
|
||||
Action->Params.bCanCreateNewLocalPlayer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Action->SetReadyToDestroy();
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
UAsyncAction_CommonUserInitialize* UAsyncAction_CommonUserInitialize::LoginForOnlinePlay(UCommonUserSubsystem* Target, int32 LocalPlayerIndex)
|
||||
{
|
||||
UAsyncAction_CommonUserInitialize* Action = NewObject<UAsyncAction_CommonUserInitialize>();
|
||||
|
||||
Action->RegisterWithGameInstance(Target);
|
||||
|
||||
if (Target && Action->IsRegistered())
|
||||
{
|
||||
Action->Subsystem = Target;
|
||||
|
||||
Action->Params.RequestedPrivilege = ECommonUserPrivilege::CanPlayOnline;
|
||||
Action->Params.LocalPlayerIndex = LocalPlayerIndex;
|
||||
Action->Params.bCanCreateNewLocalPlayer = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Action->SetReadyToDestroy();
|
||||
}
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UAsyncAction_CommonUserInitialize::HandleFailure()
|
||||
{
|
||||
const UCommonUserInfo* UserInfo = nullptr;
|
||||
if (Subsystem.IsValid())
|
||||
{
|
||||
UserInfo = Subsystem->GetUserInfoForLocalPlayerIndex(Params.LocalPlayerIndex);
|
||||
}
|
||||
HandleInitializationComplete(UserInfo, false, NSLOCTEXT("CommonUser", "LoginFailedEarly", "Unable to start login process"), Params.RequestedPrivilege, Params.OnlineContext);
|
||||
}
|
||||
|
||||
void UAsyncAction_CommonUserInitialize::HandleInitializationComplete(const UCommonUserInfo* UserInfo, bool bSuccess, FText Error, ECommonUserPrivilege RequestedPrivilege, ECommonUserOnlineContext OnlineContext)
|
||||
{
|
||||
if (ShouldBroadcastDelegates())
|
||||
{
|
||||
OnInitializationComplete.Broadcast(UserInfo, bSuccess, Error, RequestedPrivilege, OnlineContext);
|
||||
}
|
||||
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
|
||||
void UAsyncAction_CommonUserInitialize::Activate()
|
||||
{
|
||||
if (Subsystem.IsValid())
|
||||
{
|
||||
Params.OnUserInitializeComplete.BindUFunction(this, GET_FUNCTION_NAME_CHECKED(UAsyncAction_CommonUserInitialize, HandleInitializationComplete));
|
||||
bool bSuccess = Subsystem->TryToInitializeUser(Params);
|
||||
|
||||
if (!bSuccess)
|
||||
{
|
||||
// Call failure next frame
|
||||
FTimerManager* TimerManager = GetTimerManager();
|
||||
|
||||
if (TimerManager)
|
||||
{
|
||||
TimerManager->SetTimerForNextTick(FTimerDelegate::CreateUObject(this, &UAsyncAction_CommonUserInitialize::HandleFailure));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetReadyToDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "CommonUserModule.h"
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FCommonUserModule"
|
||||
|
||||
void FCommonUserModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
}
|
||||
|
||||
void FCommonUserModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FCommonUserModule, CommonUser)
|
||||
2640
Plugins/CommonUser/Source/CommonUser/Private/CommonUserSubsystem.cpp
Normal file
2640
Plugins/CommonUser/Source/CommonUser/Private/CommonUserSubsystem.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "CommonUserTypes.h"
|
||||
#include "OnlineError.h"
|
||||
|
||||
void FOnlineResultInformation::FromOnlineError(const FOnlineErrorType& InOnlineError)
|
||||
{
|
||||
#if COMMONUSER_OSSV1
|
||||
bWasSuccessful = InOnlineError.WasSuccessful();
|
||||
ErrorId = InOnlineError.GetErrorCode();
|
||||
ErrorText = InOnlineError.GetErrorMessage();
|
||||
#else
|
||||
bWasSuccessful = InOnlineError != UE::Online::Errors::Success();
|
||||
ErrorId = InOnlineError.GetErrorId();
|
||||
ErrorText = InOnlineError.GetText();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CommonUserSubsystem.h"
|
||||
#include "Engine/CancellableAsyncAction.h"
|
||||
|
||||
#include "AsyncAction_CommonUserInitialize.generated.h"
|
||||
|
||||
enum class ECommonUserOnlineContext : uint8;
|
||||
enum class ECommonUserPrivilege : uint8;
|
||||
struct FInputDeviceId;
|
||||
|
||||
class FText;
|
||||
class UObject;
|
||||
struct FFrame;
|
||||
|
||||
/**
|
||||
* Async action to handle different functions for initializing users
|
||||
*/
|
||||
UCLASS()
|
||||
class COMMONUSER_API UAsyncAction_CommonUserInitialize : public UCancellableAsyncAction
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes a local player with the common user system, which includes doing platform-specific login and privilege checks.
|
||||
* When the process has succeeded or failed, it will broadcast the OnInitializationComplete delegate.
|
||||
*
|
||||
* @param LocalPlayerIndex Desired index of ULocalPlayer in Game Instance, 0 will be primary player and 1+ for local multiplayer
|
||||
* @param PrimaryInputDevice Primary input device for the user, if invalid will use the system default
|
||||
* @param bCanUseGuestLogin If true, this player can be a guest without a real system net id
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser, meta = (BlueprintInternalUseOnly = "true"))
|
||||
static UAsyncAction_CommonUserInitialize* InitializeForLocalPlay(UCommonUserSubsystem* Target, int32 LocalPlayerIndex, FInputDeviceId PrimaryInputDevice, bool bCanUseGuestLogin);
|
||||
|
||||
/**
|
||||
* Attempts to log an existing user into the platform-specific online backend to enable full online play
|
||||
* When the process has succeeded or failed, it will broadcast the OnInitializationComplete delegate.
|
||||
*
|
||||
* @param LocalPlayerIndex Index of existing LocalPlayer in Game Instance
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser, meta = (BlueprintInternalUseOnly = "true"))
|
||||
static UAsyncAction_CommonUserInitialize* LoginForOnlinePlay(UCommonUserSubsystem* Target, int32 LocalPlayerIndex);
|
||||
|
||||
/** Call when initialization succeeds or fails */
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FCommonUserOnInitializeCompleteMulticast OnInitializationComplete;
|
||||
|
||||
/** Fail and send callbacks if needed */
|
||||
void HandleFailure();
|
||||
|
||||
/** Wrapper delegate, will pass on to OnInitializationComplete if appropriate */
|
||||
UFUNCTION()
|
||||
virtual void HandleInitializationComplete(const UCommonUserInfo* UserInfo, bool bSuccess, FText Error, ECommonUserPrivilege RequestedPrivilege, ECommonUserOnlineContext OnlineContext);
|
||||
|
||||
protected:
|
||||
/** Actually start the initialization */
|
||||
virtual void Activate() override;
|
||||
|
||||
TWeakObjectPtr<UCommonUserSubsystem> Subsystem;
|
||||
FCommonUserInitializeParams Params;
|
||||
};
|
||||
@@ -0,0 +1,382 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CommonUserTypes.h"
|
||||
#include "Subsystems/GameInstanceSubsystem.h"
|
||||
#include "UObject/ObjectPtr.h"
|
||||
#include "UObject/StrongObjectPtr.h"
|
||||
#include "UObject/PrimaryAssetId.h"
|
||||
#include "UObject/WeakObjectPtr.h"
|
||||
|
||||
class APlayerController;
|
||||
class ULocalPlayer;
|
||||
namespace ETravelFailure { enum Type : int; }
|
||||
struct FOnlineResultInformation;
|
||||
|
||||
#if COMMONUSER_OSSV1
|
||||
#include "Interfaces/OnlineSessionInterface.h"
|
||||
#include "Public/OnlineSessionSettings.h"
|
||||
#else
|
||||
#include "Online/Lobbies.h"
|
||||
#endif // COMMONUSER_OSSV1
|
||||
|
||||
#include "CommonSessionSubsystem.generated.h"
|
||||
|
||||
class UWorld;
|
||||
class FCommonSession_OnlineSessionSettings;
|
||||
|
||||
#if COMMONUSER_OSSV1
|
||||
class FCommonOnlineSearchSettingsOSSv1;
|
||||
using FCommonOnlineSearchSettings = FCommonOnlineSearchSettingsOSSv1;
|
||||
#else
|
||||
class FCommonOnlineSearchSettingsOSSv2;
|
||||
using FCommonOnlineSearchSettings = FCommonOnlineSearchSettingsOSSv2;
|
||||
#endif // COMMONUSER_OSSV1
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// UCommonSession_HostSessionRequest
|
||||
|
||||
/** Specifies the online features and connectivity that should be used for a game session */
|
||||
UENUM(BlueprintType)
|
||||
enum class ECommonSessionOnlineMode : uint8
|
||||
{
|
||||
Offline,
|
||||
LAN,
|
||||
Online
|
||||
};
|
||||
|
||||
/** A request object that stores the parameters used when hosting a gameplay session */
|
||||
UCLASS(BlueprintType)
|
||||
class COMMONUSER_API UCommonSession_HostSessionRequest : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Indicates if the session is a full online session or a different type */
|
||||
UPROPERTY(BlueprintReadWrite, Category=Session)
|
||||
ECommonSessionOnlineMode OnlineMode;
|
||||
|
||||
/** True if this request should create a player-hosted lobbies if available */
|
||||
UPROPERTY(BlueprintReadWrite, Category = Session)
|
||||
bool bUseLobbies;
|
||||
|
||||
/** String used during matchmaking to specify what type of game mode this is */
|
||||
UPROPERTY(BlueprintReadWrite, Category=Session)
|
||||
FString ModeNameForAdvertisement;
|
||||
|
||||
/** The map that will be loaded at the start of gameplay, this needs to be a valid Primary Asset top-level map */
|
||||
UPROPERTY(BlueprintReadWrite, Category=Session, meta=(AllowedTypes="World"))
|
||||
FPrimaryAssetId MapID;
|
||||
|
||||
/** Extra arguments passed as URL options to the game */
|
||||
UPROPERTY(BlueprintReadWrite, Category=Session)
|
||||
TMap<FString, FString> ExtraArgs;
|
||||
|
||||
/** Maximum players allowed per gameplay session */
|
||||
UPROPERTY(BlueprintReadWrite, Category=Session)
|
||||
int32 MaxPlayerCount = 16;
|
||||
|
||||
public:
|
||||
/** Returns the maximum players that should actually be used, could be overridden in child classes */
|
||||
virtual int32 GetMaxPlayers() const;
|
||||
|
||||
/** Returns the full map name that will be used during gameplay */
|
||||
virtual FString GetMapName() const;
|
||||
|
||||
/** Constructs the full URL that will be passed to ServerTravel */
|
||||
virtual FString ConstructTravelURL() const;
|
||||
|
||||
/** Returns true if this request is valid, returns false and logs errors if it is not */
|
||||
virtual bool ValidateAndLogErrors(FText& OutError) const;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// UCommonSession_SearchResult
|
||||
|
||||
/** A result object returned from the online system that describes a joinable game session */
|
||||
UCLASS(BlueprintType)
|
||||
class COMMONUSER_API UCommonSession_SearchResult : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Returns an internal description of the session, not meant to be human readable */
|
||||
UFUNCTION(BlueprintCallable, Category=Session)
|
||||
FString GetDescription() const;
|
||||
|
||||
/** Gets an arbitrary string setting, bFoundValue will be false if the setting does not exist */
|
||||
UFUNCTION(BlueprintPure, Category=Sessions)
|
||||
void GetStringSetting(FName Key, FString& Value, bool& bFoundValue) const;
|
||||
|
||||
/** Gets an arbitrary integer setting, bFoundValue will be false if the setting does not exist */
|
||||
UFUNCTION(BlueprintPure, Category = Sessions)
|
||||
void GetIntSetting(FName Key, int32& Value, bool& bFoundValue) const;
|
||||
|
||||
/** The number of private connections that are available */
|
||||
UFUNCTION(BlueprintPure, Category=Sessions)
|
||||
int32 GetNumOpenPrivateConnections() const;
|
||||
|
||||
/** The number of publicly available connections that are available */
|
||||
UFUNCTION(BlueprintPure, Category=Sessions)
|
||||
int32 GetNumOpenPublicConnections() const;
|
||||
|
||||
/** The maximum number of publicly available connections that could be available, including already filled connections */
|
||||
UFUNCTION(BlueprintPure, Category = Sessions)
|
||||
int32 GetMaxPublicConnections() const;
|
||||
|
||||
/** Ping to the search result, MAX_QUERY_PING is unreachable */
|
||||
UFUNCTION(BlueprintPure, Category=Sessions)
|
||||
int32 GetPingInMs() const;
|
||||
|
||||
public:
|
||||
/** Pointer to the platform-specific implementation */
|
||||
#if COMMONUSER_OSSV1
|
||||
FOnlineSessionSearchResult Result;
|
||||
#else
|
||||
TSharedPtr<const UE::Online::FLobby> Lobby;
|
||||
#endif // COMMONUSER_OSSV1
|
||||
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// UCommonSession_SearchSessionRequest
|
||||
|
||||
/** Delegates called when a session search completes */
|
||||
DECLARE_MULTICAST_DELEGATE_TwoParams(FCommonSession_FindSessionsFinished, bool bSucceeded, const FText& ErrorMessage);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FCommonSession_FindSessionsFinishedDynamic, bool, bSucceeded, FText, ErrorMessage);
|
||||
|
||||
/** Request object describing a session search, this object will be updated once the search has completed */
|
||||
UCLASS(BlueprintType)
|
||||
class COMMONUSER_API UCommonSession_SearchSessionRequest : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Indicates if the this is looking for full online games or a different type like LAN */
|
||||
UPROPERTY(BlueprintReadWrite, Category = Session)
|
||||
ECommonSessionOnlineMode OnlineMode;
|
||||
|
||||
/** True if this request should look for player-hosted lobbies if they are available, false will only search for registered server sessions */
|
||||
UPROPERTY(BlueprintReadWrite, Category = Session)
|
||||
bool bUseLobbies;
|
||||
|
||||
/** List of all found sessions, will be valid when OnSearchFinished is called */
|
||||
UPROPERTY(BlueprintReadOnly, Category=Session)
|
||||
TArray<TObjectPtr<UCommonSession_SearchResult>> Results;
|
||||
|
||||
/** Native Delegate called when a session search completes */
|
||||
FCommonSession_FindSessionsFinished OnSearchFinished;
|
||||
|
||||
/** Called by subsystem to execute finished delegates */
|
||||
void NotifySearchFinished(bool bSucceeded, const FText& ErrorMessage);
|
||||
|
||||
private:
|
||||
/** Delegate called when a session search completes */
|
||||
UPROPERTY(BlueprintAssignable, Category = "Events", meta = (DisplayName = "On Search Finished", AllowPrivateAccess = true))
|
||||
FCommonSession_FindSessionsFinishedDynamic K2_OnSearchFinished;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CommonSessionSubsystem Events
|
||||
|
||||
/**
|
||||
* Event triggered when the local user has requested to join a session from an external source, for example from a platform overlay.
|
||||
* Generally, the game should transition the player into the session.
|
||||
* @param LocalPlatformUserId the local user id that accepted the invitation. This is a platform user id because the user might not be signed in yet.
|
||||
* @param RequestedSession the requested session. Can be null if there was an error processing the request.
|
||||
* @param RequestedSessionResult result of the requested session processing
|
||||
*/
|
||||
DECLARE_MULTICAST_DELEGATE_ThreeParams(FCommonSessionOnUserRequestedSession, const FPlatformUserId& /*LocalPlatformUserId*/, UCommonSession_SearchResult* /*RequestedSession*/, const FOnlineResultInformation& /*RequestedSessionResult*/);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FCommonSessionOnUserRequestedSession_Dynamic, const FPlatformUserId&, LocalPlatformUserId, UCommonSession_SearchResult*, RequestedSession, const FOnlineResultInformation&, RequestedSessionResult);
|
||||
|
||||
/**
|
||||
* Event triggered when a session join has completed, after joining the underlying session and before traveling to the server if it was successful.
|
||||
* The event parameters indicate if this was successful, or if there was an error that will stop it from traveling.
|
||||
* @param Result result of the session join
|
||||
*/
|
||||
DECLARE_MULTICAST_DELEGATE_OneParam(FCommonSessionOnJoinSessionComplete, const FOnlineResultInformation& /*Result*/);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCommonSessionOnJoinSessionComplete_Dynamic, const FOnlineResultInformation&, Result);
|
||||
|
||||
/**
|
||||
* Event triggered when a session creation for hosting has completed, right before it travels to the map.
|
||||
* The event parameters indicate if this was successful, or if there was an error that will stop it from traveling.
|
||||
* @param Result result of the session join
|
||||
*/
|
||||
DECLARE_MULTICAST_DELEGATE_OneParam(FCommonSessionOnCreateSessionComplete, const FOnlineResultInformation& /*Result*/);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCommonSessionOnCreateSessionComplete_Dynamic, const FOnlineResultInformation&, Result);
|
||||
|
||||
/**
|
||||
* Event triggered when a session join has completed, after resolving the connect string and prior to the client traveling.
|
||||
* @param URL resolved connection string for the session with any additional arguments
|
||||
*/
|
||||
DECLARE_MULTICAST_DELEGATE_OneParam(FCommonSessionOnPreClientTravel, FString& /*URL*/);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// UCommonSessionSubsystem
|
||||
|
||||
/**
|
||||
* Game subsystem that handles requests for hosting and joining online games.
|
||||
* One subsystem is created for each game instance and can be accessed from blueprints or C++ code.
|
||||
* If a game-specific subclass exists, this base subsystem will not be created.
|
||||
*/
|
||||
UCLASS()
|
||||
class COMMONUSER_API UCommonSessionSubsystem : public UGameInstanceSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCommonSessionSubsystem() { }
|
||||
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
|
||||
|
||||
/** Creates a host session request with default options for online games, this can be modified after creation */
|
||||
UFUNCTION(BlueprintCallable, Category = Session)
|
||||
virtual UCommonSession_HostSessionRequest* CreateOnlineHostSessionRequest();
|
||||
|
||||
/** Creates a session search object with default options to look for default online games, this can be modified after creation */
|
||||
UFUNCTION(BlueprintCallable, Category = Session)
|
||||
virtual UCommonSession_SearchSessionRequest* CreateOnlineSearchSessionRequest();
|
||||
|
||||
/** Creates a new online game using the session request information, if successful this will start a hard map transfer */
|
||||
UFUNCTION(BlueprintCallable, Category=Session)
|
||||
virtual void HostSession(APlayerController* HostingPlayer, UCommonSession_HostSessionRequest* Request);
|
||||
|
||||
/** Starts a process to look for existing sessions or create a new one if no viable sessions are found */
|
||||
UFUNCTION(BlueprintCallable, Category=Session)
|
||||
virtual void QuickPlaySession(APlayerController* JoiningOrHostingPlayer, UCommonSession_HostSessionRequest* Request);
|
||||
|
||||
/** Starts process to join an existing session, if successful this will connect to the specified server */
|
||||
UFUNCTION(BlueprintCallable, Category=Session)
|
||||
virtual void JoinSession(APlayerController* JoiningPlayer, UCommonSession_SearchResult* Request);
|
||||
|
||||
/** Queries online system for the list of joinable sessions matching the search request */
|
||||
UFUNCTION(BlueprintCallable, Category=Session)
|
||||
virtual void FindSessions(APlayerController* SearchingPlayer, UCommonSession_SearchSessionRequest* Request);
|
||||
|
||||
/** Clean up any active sessions, called from cases like returning to the main menu */
|
||||
UFUNCTION(BlueprintCallable, Category=Session)
|
||||
virtual void CleanUpSessions();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Events
|
||||
|
||||
/** Native Delegate when a local user has accepted an invite */
|
||||
FCommonSessionOnUserRequestedSession OnUserRequestedSessionEvent;
|
||||
/** Event broadcast when a local user has accepted an invite */
|
||||
UPROPERTY(BlueprintAssignable, Category = "Events", meta = (DisplayName = "On User Requested Session"))
|
||||
FCommonSessionOnUserRequestedSession_Dynamic K2_OnUserRequestedSessionEvent;
|
||||
|
||||
/** Native Delegate when a JoinSession call has completed */
|
||||
FCommonSessionOnJoinSessionComplete OnJoinSessionCompleteEvent;
|
||||
/** Event broadcast when a JoinSession call has completed */
|
||||
UPROPERTY(BlueprintAssignable, Category = "Events", meta = (DisplayName = "On Join Session Complete"))
|
||||
FCommonSessionOnJoinSessionComplete_Dynamic K2_OnJoinSessionCompleteEvent;
|
||||
|
||||
/** Native Delegate when a CreateSession call has completed */
|
||||
FCommonSessionOnCreateSessionComplete OnCreateSessionCompleteEvent;
|
||||
/** Event broadcast when a CreateSession call has completed */
|
||||
UPROPERTY(BlueprintAssignable, Category = "Events", meta = (DisplayName = "On Create Session Complete"))
|
||||
FCommonSessionOnCreateSessionComplete_Dynamic K2_OnCreateSessionCompleteEvent;
|
||||
|
||||
/** Native Delegate for modifying the connect URL prior to a client travel */
|
||||
FCommonSessionOnPreClientTravel OnPreClientTravelEvent;
|
||||
|
||||
protected:
|
||||
// Functions called during the process of creating or joining a session, these can be overidden for game-specific behavior
|
||||
|
||||
/** Called to fill in a session request from quick play host settings, can be overridden for game-specific behavior */
|
||||
virtual TSharedRef<FCommonOnlineSearchSettings> CreateQuickPlaySearchSettings(UCommonSession_HostSessionRequest* Request, UCommonSession_SearchSessionRequest* QuickPlayRequest);
|
||||
|
||||
/** Called when a quick play search finishes, can be overridden for game-specific behavior */
|
||||
virtual void HandleQuickPlaySearchFinished(bool bSucceeded, const FText& ErrorMessage, TWeakObjectPtr<APlayerController> JoiningOrHostingPlayer, TStrongObjectPtr<UCommonSession_HostSessionRequest> HostRequest);
|
||||
|
||||
/** Called when traveling to a session fails */
|
||||
virtual void TravelLocalSessionFailure(UWorld* World, ETravelFailure::Type FailureType, const FString& ReasonString);
|
||||
|
||||
/** Called when a new session is either created or fails to be created */
|
||||
virtual void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);
|
||||
|
||||
/** Called to finalize session creation */
|
||||
virtual void FinishSessionCreation(bool bWasSuccessful);
|
||||
|
||||
/** Called after traveling to the new hosted session map */
|
||||
virtual void HandlePostLoadMap(UWorld* World);
|
||||
|
||||
protected:
|
||||
// Internal functions for initializing and handling results from the online systems
|
||||
|
||||
void BindOnlineDelegates();
|
||||
void CreateOnlineSessionInternal(ULocalPlayer* LocalPlayer, UCommonSession_HostSessionRequest* Request);
|
||||
void FindSessionsInternal(APlayerController* SearchingPlayer, const TSharedRef<FCommonOnlineSearchSettings>& InSearchSettings);
|
||||
void JoinSessionInternal(ULocalPlayer* LocalPlayer, UCommonSession_SearchResult* Request);
|
||||
void InternalTravelToSession(const FName SessionName);
|
||||
void NotifyUserRequestedSession(const FPlatformUserId& PlatformUserId, UCommonSession_SearchResult* RequestedSession, const FOnlineResultInformation& RequestedSessionResult);
|
||||
void NotifyJoinSessionComplete(const FOnlineResultInformation& Result);
|
||||
void NotifyCreateSessionComplete(const FOnlineResultInformation& Result);
|
||||
void SetCreateSessionError(const FText& ErrorText);
|
||||
|
||||
#if COMMONUSER_OSSV1
|
||||
void BindOnlineDelegatesOSSv1();
|
||||
void CreateOnlineSessionInternalOSSv1(ULocalPlayer* LocalPlayer, UCommonSession_HostSessionRequest* Request);
|
||||
void FindSessionsInternalOSSv1(ULocalPlayer* LocalPlayer);
|
||||
void JoinSessionInternalOSSv1(ULocalPlayer* LocalPlayer, UCommonSession_SearchResult* Request);
|
||||
TSharedRef<FCommonOnlineSearchSettings> CreateQuickPlaySearchSettingsOSSv1(UCommonSession_HostSessionRequest* Request, UCommonSession_SearchSessionRequest* QuickPlayRequest);
|
||||
void CleanUpSessionsOSSv1();
|
||||
|
||||
void HandleSessionFailure(const FUniqueNetId& NetId, ESessionFailure::Type FailureType);
|
||||
void HandleSessionUserInviteAccepted(const bool bWasSuccessful, const int32 LocalUserIndex, FUniqueNetIdPtr AcceptingUserId, const FOnlineSessionSearchResult& SearchResult);
|
||||
void OnStartSessionComplete(FName SessionName, bool bWasSuccessful);
|
||||
void OnRegisterLocalPlayerComplete_CreateSession(const FUniqueNetId& PlayerId, EOnJoinSessionCompleteResult::Type Result);
|
||||
void OnUpdateSessionComplete(FName SessionName, bool bWasSuccessful);
|
||||
void OnEndSessionComplete(FName SessionName, bool bWasSuccessful);
|
||||
void OnDestroySessionComplete(FName SessionName, bool bWasSuccessful);
|
||||
void OnFindSessionsComplete(bool bWasSuccessful);
|
||||
void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);
|
||||
void OnRegisterJoiningLocalPlayerComplete(const FUniqueNetId& PlayerId, EOnJoinSessionCompleteResult::Type Result);
|
||||
void FinishJoinSession(EOnJoinSessionCompleteResult::Type Result);
|
||||
|
||||
#else
|
||||
void BindOnlineDelegatesOSSv2();
|
||||
void CreateOnlineSessionInternalOSSv2(ULocalPlayer* LocalPlayer, UCommonSession_HostSessionRequest* Request);
|
||||
void FindSessionsInternalOSSv2(ULocalPlayer* LocalPlayer);
|
||||
void JoinSessionInternalOSSv2(ULocalPlayer* LocalPlayer, UCommonSession_SearchResult* Request);
|
||||
TSharedRef<FCommonOnlineSearchSettings> CreateQuickPlaySearchSettingsOSSv2(UCommonSession_HostSessionRequest* HostRequest, UCommonSession_SearchSessionRequest* SearchRequest);
|
||||
void CleanUpSessionsOSSv2();
|
||||
|
||||
/** Process a join request originating from the online service */
|
||||
void OnSessionJoinRequested(const UE::Online::FUILobbyJoinRequested& EventParams);
|
||||
|
||||
/** Get the local user id for a given controller */
|
||||
UE::Online::FAccountId GetAccountId(APlayerController* PlayerController) const;
|
||||
/** Get the lobby id for a given session name */
|
||||
UE::Online::FLobbyId GetLobbyId(const FName SessionName) const;
|
||||
/** Event handle for UI lobby join requested */
|
||||
UE::Online::FOnlineEventDelegateHandle LobbyJoinRequestedHandle;
|
||||
#endif // COMMONUSER_OSSV1
|
||||
|
||||
protected:
|
||||
/** The travel URL that will be used after session operations are complete */
|
||||
FString PendingTravelURL;
|
||||
|
||||
/** Most recent result information for a session creation attempt, stored here to allow storing error codes for later */
|
||||
FOnlineResultInformation CreateSessionResult;
|
||||
|
||||
/** True if we want to cancel the session after it is created */
|
||||
bool bWantToDestroyPendingSession = false;
|
||||
|
||||
/** True if this is a dedicated server, which doesn't require a LocalPlayer to create a session */
|
||||
bool bIsDedicatedServer = false;
|
||||
|
||||
/** Settings for the current search */
|
||||
TSharedPtr<FCommonOnlineSearchSettings> SearchSettings;
|
||||
|
||||
/** Settings for the current host request */
|
||||
TSharedPtr<FCommonSession_OnlineSessionSettings> HostSettings;
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleInterface.h"
|
||||
|
||||
class FCommonUserModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,635 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CommonUserTypes.h"
|
||||
#include "Engine/GameViewportClient.h"
|
||||
#include "GameFramework/OnlineReplStructs.h"
|
||||
#include "Subsystems/GameInstanceSubsystem.h"
|
||||
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "Interfaces/OnlineIdentityInterface.h"
|
||||
#include "OnlineError.h"
|
||||
#include "UObject/WeakObjectPtr.h"
|
||||
#include "CommonUserSubsystem.generated.h"
|
||||
|
||||
class FNativeGameplayTag;
|
||||
class IOnlineSubsystem;
|
||||
|
||||
/** List of tags used by the common user subsystem */
|
||||
struct COMMONUSER_API FCommonUserTags
|
||||
{
|
||||
// General severity levels and specific system messages
|
||||
|
||||
static FNativeGameplayTag SystemMessage_Error; // SystemMessage.Error
|
||||
static FNativeGameplayTag SystemMessage_Warning; // SystemMessage.Warning
|
||||
static FNativeGameplayTag SystemMessage_Display; // SystemMessage.Display
|
||||
|
||||
/** All attempts to initialize a player failed, user has to do something before trying again */
|
||||
static FNativeGameplayTag SystemMessage_Error_InitializeLocalPlayerFailed; // SystemMessage.Error.InitializeLocalPlayerFailed
|
||||
|
||||
|
||||
// Platform trait tags, it is expected that the game instance or other system calls SetTraitTags with these tags for the appropriate platform
|
||||
|
||||
/** This tag means it is a console platform that directly maps controller IDs to different system users. If false, the same user can have multiple controllers */
|
||||
static FNativeGameplayTag Platform_Trait_RequiresStrictControllerMapping; // Platform.Trait.RequiresStrictControllerMapping
|
||||
|
||||
/** This tag means the platform has a single online user and all players use index 0 */
|
||||
static FNativeGameplayTag Platform_Trait_SingleOnlineUser; // Platform.Trait.SingleOnlineUser
|
||||
};
|
||||
|
||||
/** Logical representation of an individual user, one of these will exist for all initialized local players */
|
||||
UCLASS(BlueprintType)
|
||||
class COMMONUSER_API UCommonUserInfo : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Primary controller input device for this user, they could also have additional secondary devices */
|
||||
UPROPERTY(BlueprintReadOnly, Category = UserInfo)
|
||||
FInputDeviceId PrimaryInputDevice;
|
||||
|
||||
/** Specifies the logical user on the local platform, guest users will point to the primary user */
|
||||
UPROPERTY(BlueprintReadOnly, Category = UserInfo)
|
||||
FPlatformUserId PlatformUser;
|
||||
|
||||
/** If this user is assigned a LocalPlayer, this will match the index in the GameInstance localplayers array once it is fully created */
|
||||
UPROPERTY(BlueprintReadOnly, Category = UserInfo)
|
||||
int32 LocalPlayerIndex = -1;
|
||||
|
||||
/** If true, this user is allowed to be a guest */
|
||||
UPROPERTY(BlueprintReadOnly, Category = UserInfo)
|
||||
bool bCanBeGuest = false;
|
||||
|
||||
/** If true, this is a guest user attached to primary user 0 */
|
||||
UPROPERTY(BlueprintReadOnly, Category = UserInfo)
|
||||
bool bIsGuest = false;
|
||||
|
||||
/** Overall state of the user's initialization process */
|
||||
UPROPERTY(BlueprintReadOnly, Category = UserInfo)
|
||||
ECommonUserInitializationState InitializationState = ECommonUserInitializationState::Invalid;
|
||||
|
||||
/** Returns true if this user has successfully logged in */
|
||||
UFUNCTION(BlueprintCallable, Category = UserInfo)
|
||||
bool IsLoggedIn() const;
|
||||
|
||||
/** Returns true if this user is in the middle of logging in */
|
||||
UFUNCTION(BlueprintCallable, Category = UserInfo)
|
||||
bool IsDoingLogin() const;
|
||||
|
||||
/** Returns the most recently queries result for a specific privilege, will return unknown if never queried */
|
||||
UFUNCTION(BlueprintCallable, Category = UserInfo)
|
||||
ECommonUserPrivilegeResult GetCachedPrivilegeResult(ECommonUserPrivilege Privilege, ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Ask about the general availability of a feature, this combines cached results with state */
|
||||
UFUNCTION(BlueprintCallable, Category = UserInfo)
|
||||
ECommonUserAvailability GetPrivilegeAvailability(ECommonUserPrivilege Privilege) const;
|
||||
|
||||
/** Returns the net id for the given context */
|
||||
UFUNCTION(BlueprintCallable, Category = UserInfo)
|
||||
FUniqueNetIdRepl GetNetId(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Returns the user's human readable nickname */
|
||||
UFUNCTION(BlueprintCallable, Category = UserInfo)
|
||||
FString GetNickname() const;
|
||||
|
||||
/** Returns an internal debug string for this player */
|
||||
UFUNCTION(BlueprintCallable, Category = UserInfo)
|
||||
FString GetDebugString() const;
|
||||
|
||||
/** Accessor for platform user id */
|
||||
FPlatformUserId GetPlatformUserId() const;
|
||||
|
||||
/** Gets the platform user index for older functions expecting an integer */
|
||||
int32 GetPlatformUserIndex() const;
|
||||
|
||||
// Internal data, only intended to be accessed by online subsystems
|
||||
|
||||
/** Cached data for each online system */
|
||||
struct FCachedData
|
||||
{
|
||||
/** Cached net id per system */
|
||||
FUniqueNetIdRepl CachedNetId;
|
||||
|
||||
/** Cached values of various user privileges */
|
||||
TMap<ECommonUserPrivilege, ECommonUserPrivilegeResult> CachedPrivileges;
|
||||
};
|
||||
|
||||
/** Per context cache, game will always exist but others may not */
|
||||
TMap<ECommonUserOnlineContext, FCachedData> CachedDataMap;
|
||||
|
||||
/** Looks up cached data using resolution rules */
|
||||
FCachedData* GetCachedData(ECommonUserOnlineContext Context);
|
||||
const FCachedData* GetCachedData(ECommonUserOnlineContext Context) const;
|
||||
|
||||
/** Updates cached privilege results, will propagate to game if needed */
|
||||
void UpdateCachedPrivilegeResult(ECommonUserPrivilege Privilege, ECommonUserPrivilegeResult Result, ECommonUserOnlineContext Context);
|
||||
|
||||
/** Updates cached privilege results, will propagate to game if needed */
|
||||
void UpdateCachedNetId(const FUniqueNetIdRepl& NewId, ECommonUserOnlineContext Context);
|
||||
|
||||
/** Return the subsystem this is owned by */
|
||||
class UCommonUserSubsystem* GetSubsystem() const;
|
||||
};
|
||||
|
||||
|
||||
/** Delegates when initialization processes succeed or fail */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams(FCommonUserOnInitializeCompleteMulticast, const UCommonUserInfo*, UserInfo, bool, bSuccess, FText, Error, ECommonUserPrivilege, RequestedPrivilege, ECommonUserOnlineContext, OnlineContext);
|
||||
DECLARE_DYNAMIC_DELEGATE_FiveParams(FCommonUserOnInitializeComplete, const UCommonUserInfo*, UserInfo, bool, bSuccess, FText, Error, ECommonUserPrivilege, RequestedPrivilege, ECommonUserOnlineContext, OnlineContext);
|
||||
|
||||
/** Delegate when a system error message is sent, the game can choose to display it to the user using the type tag */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FCommonUserHandleSystemMessageDelegate, FGameplayTag, MessageType, FText, TitleText, FText, BodyText);
|
||||
|
||||
/** Delegate when a privilege changes, this can be bound to see if online status/etc changes during gameplay */
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FCommonUserAvailabilityChangedDelegate, const UCommonUserInfo*, UserInfo, ECommonUserPrivilege, Privilege, ECommonUserAvailability, OldAvailability, ECommonUserAvailability, NewAvailability);
|
||||
|
||||
|
||||
/** Parameter struct for initialize functions, this would normally be filled in by wrapper functions like async nodes */
|
||||
USTRUCT(BlueprintType)
|
||||
struct COMMONUSER_API FCommonUserInitializeParams
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** What local player index to use, can specify one above current if can create player is enabled */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Default)
|
||||
int32 LocalPlayerIndex = 0;
|
||||
|
||||
/** Deprecated method of selecting platform user and input device */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Default)
|
||||
int32 ControllerId = -1;
|
||||
|
||||
/** Primary controller input device for this user, they could also have additional secondary devices */
|
||||
UPROPERTY(BlueprintReadOnly, Category = UserInfo)
|
||||
FInputDeviceId PrimaryInputDevice;
|
||||
|
||||
/** Specifies the logical user on the local platform */
|
||||
UPROPERTY(BlueprintReadOnly, Category = UserInfo)
|
||||
FPlatformUserId PlatformUser;
|
||||
|
||||
/** Generally either CanPlay or CanPlayOnline, specifies what level of privilege is required */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Default)
|
||||
ECommonUserPrivilege RequestedPrivilege = ECommonUserPrivilege::CanPlay;
|
||||
|
||||
/** What specific online context to log in to, game means to login to all relevant ones */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Default)
|
||||
ECommonUserOnlineContext OnlineContext = ECommonUserOnlineContext::Game;
|
||||
|
||||
/** True if this is allowed to create a new local player for initial login */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Default)
|
||||
bool bCanCreateNewLocalPlayer = false;
|
||||
|
||||
/** True if this player can be a guest user without an actual online presence */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Default)
|
||||
bool bCanUseGuestLogin = false;
|
||||
|
||||
/** True if we should not show login errors, the game will be responsible for displaying them */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Default)
|
||||
bool bSuppressLoginErrors = false;
|
||||
|
||||
/** If bound, call this dynamic delegate at completion of login */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Default)
|
||||
FCommonUserOnInitializeComplete OnUserInitializeComplete;
|
||||
};
|
||||
|
||||
/**
|
||||
* Game subsystem that handles queries and changes to user identity and login status.
|
||||
* One subsystem is created for each game instance and can be accessed from blueprints or C++ code.
|
||||
* If a game-specific subclass exists, this base subsystem will not be created.
|
||||
*/
|
||||
UCLASS(BlueprintType, Config=Game)
|
||||
class COMMONUSER_API UCommonUserSubsystem : public UGameInstanceSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UCommonUserSubsystem() { }
|
||||
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
virtual bool ShouldCreateSubsystem(UObject* Outer) const override;
|
||||
|
||||
|
||||
/** BP delegate called when any requested initialization request completes */
|
||||
UPROPERTY(BlueprintAssignable, Category = CommonUser)
|
||||
FCommonUserOnInitializeCompleteMulticast OnUserInitializeComplete;
|
||||
|
||||
/** BP delegate called when the system sends an error/warning message */
|
||||
UPROPERTY(BlueprintAssignable, Category = CommonUser)
|
||||
FCommonUserHandleSystemMessageDelegate OnHandleSystemMessage;
|
||||
|
||||
/** BP delegate called when privilege availability changes for a user */
|
||||
UPROPERTY(BlueprintAssignable, Category = CommonUser)
|
||||
FCommonUserAvailabilityChangedDelegate OnUserPrivilegeChanged;
|
||||
|
||||
/** Send a system message via OnHandleSystemMessage */
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual void SendSystemMessage(FGameplayTag MessageType, FText TitleText, FText BodyText);
|
||||
|
||||
/** Sets the maximum number of local players, will not destroy existing ones */
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual void SetMaxLocalPlayers(int32 InMaxLocalPLayers);
|
||||
|
||||
/** Gets the maximum number of local players */
|
||||
UFUNCTION(BlueprintPure, Category = CommonUser)
|
||||
int32 GetMaxLocalPlayers() const;
|
||||
|
||||
/** Gets the current number of local players, will always be at least 1 */
|
||||
UFUNCTION(BlueprintPure, Category = CommonUser)
|
||||
int32 GetNumLocalPlayers() const;
|
||||
|
||||
/** Returns the state of initializing the specified local player */
|
||||
UFUNCTION(BlueprintPure, Category = CommonUser)
|
||||
ECommonUserInitializationState GetLocalPlayerInitializationState(int32 LocalPlayerIndex) const;
|
||||
|
||||
/** Returns the user info for a given local player index in game instance, 0 is always valid in a running game */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure = False, Category = CommonUser)
|
||||
const UCommonUserInfo* GetUserInfoForLocalPlayerIndex(int32 LocalPlayerIndex) const;
|
||||
|
||||
/** Deprecated, use PlatformUserId when available */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure = False, Category = CommonUser)
|
||||
const UCommonUserInfo* GetUserInfoForPlatformUserIndex(int32 PlatformUserIndex) const;
|
||||
|
||||
/** Returns the primary user info for a given platform user index. Can return null */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure = False, Category = CommonUser)
|
||||
const UCommonUserInfo* GetUserInfoForPlatformUser(FPlatformUserId PlatformUser) const;
|
||||
|
||||
/** Returns the user info for a unique net id. Can return null */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure = False, Category = CommonUser)
|
||||
const UCommonUserInfo* GetUserInfoForUniqueNetId(const FUniqueNetIdRepl& NetId) const;
|
||||
|
||||
/** Deprecated, use InputDeviceId when available */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure = False, Category = CommonUser)
|
||||
const UCommonUserInfo* GetUserInfoForControllerId(int32 ControllerId) const;
|
||||
|
||||
/** Returns the user info for a given input device. Can return null */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure = False, Category = CommonUser)
|
||||
const UCommonUserInfo* GetUserInfoForInputDevice(FInputDeviceId InputDevice) const;
|
||||
|
||||
/**
|
||||
* Tries to start the process of creating or updating a local player, including logging in and creating a player controller.
|
||||
* When the process has succeeded or failed, it will broadcast the OnUserInitializeComplete delegate.
|
||||
*
|
||||
* @param LocalPlayerIndex Desired index of LocalPlayer in Game Instance, 0 will be primary player and 1+ for local multiplayer
|
||||
* @param PrimaryInputDevice The physical controller that should be mapped to this user, will use the default device if invalid
|
||||
* @param bCanUseGuestLogin If true, this player can be a guest without a real Unique Net Id
|
||||
*
|
||||
* @returns true if the process was started, false if it failed before properly starting
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual bool TryToInitializeForLocalPlay(int32 LocalPlayerIndex, FInputDeviceId PrimaryInputDevice, bool bCanUseGuestLogin);
|
||||
|
||||
/**
|
||||
* Starts the process of taking a locally logged in user and doing a full online login including account permission checks.
|
||||
* When the process has succeeded or failed, it will broadcast the OnUserInitializeComplete delegate.
|
||||
*
|
||||
* @param LocalPlayerIndex Index of existing LocalPlayer in Game Instance
|
||||
*
|
||||
* @returns true if the process was started, false if it failed before properly starting
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual bool TryToLoginForOnlinePlay(int32 LocalPlayerIndex);
|
||||
|
||||
/**
|
||||
* Starts a general user login and initialization process, using the params structure to determine what to log in to.
|
||||
* When the process has succeeded or failed, it will broadcast the OnUserInitializeComplete delegate.
|
||||
* AsyncAction_CommonUserInitialize provides several wrapper functions for using this in an Event graph.
|
||||
*
|
||||
* @returns true if the process was started, false if it failed before properly starting
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual bool TryToInitializeUser(FCommonUserInitializeParams Params);
|
||||
|
||||
/**
|
||||
* Starts the process of listening for user input for new and existing controllers and logging them.
|
||||
* This will insert a key input handler on the active GameViewportClient and is turned off by calling again with empty key arrays.
|
||||
*
|
||||
* @param AnyUserKeys Listen for these keys for any user, even the default user. Set this for an initial press start screen or empty to disable
|
||||
* @param NewUserKeys Listen for these keys for a new user without a player controller. Set this for splitscreen/local multiplayer or empty to disable
|
||||
* @param Params Params passed to TryToInitializeUser after detecting key input
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual void ListenForLoginKeyInput(TArray<FKey> AnyUserKeys, TArray<FKey> NewUserKeys, FCommonUserInitializeParams Params);
|
||||
|
||||
/** Attempts to cancel an in-progress initialization attempt, this may not work on all platforms but will disable callbacks */
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual bool CancelUserInitialization(int32 LocalPlayerIndex);
|
||||
|
||||
/** Logs a player out of any online systems, and optionally destroys the player entirely if it's not the first one */
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual bool TryToLogOutUser(int32 LocalPlayerIndex, bool bDestroyPlayer = false);
|
||||
|
||||
/** Resets the login and initialization state when returning to the main menu after an error */
|
||||
UFUNCTION(BlueprintCallable, Category = CommonUser)
|
||||
virtual void ResetUserState();
|
||||
|
||||
/** Returns true if this this could be a real platform user with a valid identity (even if not currently logged in) */
|
||||
virtual bool IsRealPlatformUserIndex(int32 PlatformUserIndex) const;
|
||||
|
||||
/** Returns true if this this could be a real platform user with a valid identity (even if not currently logged in) */
|
||||
virtual bool IsRealPlatformUser(FPlatformUserId PlatformUser) const;
|
||||
|
||||
/** Converts index to id */
|
||||
virtual FPlatformUserId GetPlatformUserIdForIndex(int32 PlatformUserIndex) const;
|
||||
|
||||
/** Converts id to index */
|
||||
virtual int32 GetPlatformUserIndexForId(FPlatformUserId PlatformUser) const;
|
||||
|
||||
/** Gets the user for an input device */
|
||||
virtual FPlatformUserId GetPlatformUserIdForInputDevice(FInputDeviceId InputDevice) const;
|
||||
|
||||
/** Gets a user's primary input device id */
|
||||
virtual FInputDeviceId GetPrimaryInputDeviceForPlatformUser(FPlatformUserId PlatformUser) const;
|
||||
|
||||
/** Call from game code to set the cached trait tags when platform state or options changes */
|
||||
virtual void SetTraitTags(const FGameplayTagContainer& InTags);
|
||||
|
||||
/** Gets the current tags that affect feature avialability */
|
||||
const FGameplayTagContainer& GetTraitTags() const { return CachedTraitTags; }
|
||||
|
||||
/** Checks if a specific platform/feature tag is enabled */
|
||||
UFUNCTION(BlueprintPure, Category=CommonUser)
|
||||
bool HasTraitTag(const FGameplayTag TraitTag) const { return CachedTraitTags.HasTag(TraitTag); }
|
||||
|
||||
/** Checks to see if we should display a press start/input confirmation screen at startup. Games can call this or check the trait tags directly */
|
||||
UFUNCTION(BlueprintPure, BlueprintPure, Category=CommonUser)
|
||||
virtual bool ShouldWaitForStartInput() const;
|
||||
|
||||
|
||||
// Functions for accessing low-level online system information
|
||||
|
||||
#if COMMONUSER_OSSV1
|
||||
/** Returns OSS interface of specific type, will return null if there is no type */
|
||||
IOnlineSubsystem* GetOnlineSubsystem(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Returns identity interface of specific type, will return null if there is no type */
|
||||
IOnlineIdentity* GetOnlineIdentity(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Returns human readable name of OSS system */
|
||||
FName GetOnlineSubsystemName(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Returns the current online connection status */
|
||||
EOnlineServerConnectionStatus::Type GetConnectionStatus(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
#else
|
||||
/** Get the services provider type, or None if there isn't one. */
|
||||
UE::Online::EOnlineServices GetOnlineServicesProvider(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Returns auth interface of specific type, will return null if there is no type */
|
||||
UE::Online::IAuthPtr GetOnlineAuth(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Returns the current online connection status */
|
||||
UE::Online::EOnlineServicesConnectionStatus GetConnectionStatus(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
#endif
|
||||
|
||||
/** Returns true if we are currently connected to backend servers */
|
||||
bool HasOnlineConnection(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Returns the current login status for a player on the specified online system, only works for real platform users */
|
||||
ELoginStatusType GetLocalUserLoginStatus(FPlatformUserId PlatformUser, ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Returns the unique net id for a local platform user */
|
||||
FUniqueNetIdRepl GetLocalUserNetId(FPlatformUserId PlatformUser, ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
|
||||
/** Convert a user id to a debug string */
|
||||
FString PlatformUserIdToString(FPlatformUserId UserId);
|
||||
|
||||
/** Convert a context to a debug string */
|
||||
FString ECommonUserOnlineContextToString(ECommonUserOnlineContext Context);
|
||||
|
||||
/** Returns human readable string for privilege checks */
|
||||
virtual FText GetPrivilegeDescription(ECommonUserPrivilege Privilege) const;
|
||||
virtual FText GetPrivilegeResultDescription(ECommonUserPrivilegeResult Result) const;
|
||||
|
||||
/**
|
||||
* Starts the process of login for an existing local user, will return false if callback was not scheduled
|
||||
* This activates the low level state machine and does not modify the initialization state on user info
|
||||
*/
|
||||
DECLARE_DELEGATE_FiveParams(FOnLocalUserLoginCompleteDelegate, const UCommonUserInfo* /*UserInfo*/, ELoginStatusType /*NewStatus*/, FUniqueNetIdRepl /*NetId*/, const TOptional<FOnlineErrorType>& /*Error*/, ECommonUserOnlineContext /*Type*/);
|
||||
virtual bool LoginLocalUser(const UCommonUserInfo* UserInfo, ECommonUserPrivilege RequestedPrivilege, ECommonUserOnlineContext Context, FOnLocalUserLoginCompleteDelegate OnComplete);
|
||||
|
||||
/** Assign a local player to a specific local user and call callbacks as needed */
|
||||
virtual void SetLocalPlayerUserInfo(ULocalPlayer* LocalPlayer, const UCommonUserInfo* UserInfo);
|
||||
|
||||
/** Resolves a context that has default behavior into a specific context */
|
||||
ECommonUserOnlineContext ResolveOnlineContext(ECommonUserOnlineContext Context) const;
|
||||
|
||||
/** True if there is a separate platform and service interface */
|
||||
bool HasSeparatePlatformContext() const;
|
||||
|
||||
protected:
|
||||
/** Internal structure that caches status and pointers for each online context */
|
||||
struct FOnlineContextCache
|
||||
{
|
||||
#if COMMONUSER_OSSV1
|
||||
/** Pointer to base subsystem, will stay valid as long as game instance does */
|
||||
IOnlineSubsystem* OnlineSubsystem = nullptr;
|
||||
|
||||
/** Cached identity system, this will always be valid */
|
||||
IOnlineIdentityPtr IdentityInterface;
|
||||
|
||||
/** Last connection status that was passed into the HandleNetworkConnectionStatusChanged hander */
|
||||
EOnlineServerConnectionStatus::Type CurrentConnectionStatus = EOnlineServerConnectionStatus::Normal;
|
||||
#else
|
||||
/** Online services, accessor to specific services */
|
||||
UE::Online::IOnlineServicesPtr OnlineServices;
|
||||
/** Cached auth service */
|
||||
UE::Online::IAuthPtr AuthService;
|
||||
/** Login status changed event handle */
|
||||
UE::Online::FOnlineEventDelegateHandle LoginStatusChangedHandle;
|
||||
/** Connection status changed event handle */
|
||||
UE::Online::FOnlineEventDelegateHandle ConnectionStatusChangedHandle;
|
||||
/** Last connection status that was passed into the HandleNetworkConnectionStatusChanged hander */
|
||||
UE::Online::EOnlineServicesConnectionStatus CurrentConnectionStatus = UE::Online::EOnlineServicesConnectionStatus::NotConnected;
|
||||
#endif
|
||||
|
||||
/** Resets state, important to clear all shared ptrs */
|
||||
void Reset()
|
||||
{
|
||||
#if COMMONUSER_OSSV1
|
||||
OnlineSubsystem = nullptr;
|
||||
IdentityInterface.Reset();
|
||||
CurrentConnectionStatus = EOnlineServerConnectionStatus::Normal;
|
||||
#else
|
||||
OnlineServices.Reset();
|
||||
AuthService.Reset();
|
||||
CurrentConnectionStatus = UE::Online::EOnlineServicesConnectionStatus::NotConnected;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/** Internal structure to represent an in-progress login request */
|
||||
struct FUserLoginRequest : public TSharedFromThis<FUserLoginRequest>
|
||||
{
|
||||
FUserLoginRequest(UCommonUserInfo* InUserInfo, ECommonUserPrivilege InPrivilege, ECommonUserOnlineContext InContext, FOnLocalUserLoginCompleteDelegate&& InDelegate)
|
||||
: UserInfo(TWeakObjectPtr<UCommonUserInfo>(InUserInfo))
|
||||
, DesiredPrivilege(InPrivilege)
|
||||
, DesiredContext(InContext)
|
||||
, Delegate(MoveTemp(InDelegate))
|
||||
{}
|
||||
|
||||
/** Which local user is trying to log on */
|
||||
TWeakObjectPtr<UCommonUserInfo> UserInfo;
|
||||
|
||||
/** Overall state of login request, could come from many sources */
|
||||
ECommonUserAsyncTaskState OverallLoginState = ECommonUserAsyncTaskState::NotStarted;
|
||||
|
||||
/** State of attempt to use platform auth. When started, this immediately transitions to Failed for OSSv1, as we do not support platform auth there. */
|
||||
ECommonUserAsyncTaskState TransferPlatformAuthState = ECommonUserAsyncTaskState::NotStarted;
|
||||
|
||||
/** State of attempt to use AutoLogin */
|
||||
ECommonUserAsyncTaskState AutoLoginState = ECommonUserAsyncTaskState::NotStarted;
|
||||
|
||||
/** State of attempt to use external login UI */
|
||||
ECommonUserAsyncTaskState LoginUIState = ECommonUserAsyncTaskState::NotStarted;
|
||||
|
||||
/** Final privilege to that is requested */
|
||||
ECommonUserPrivilege DesiredPrivilege = ECommonUserPrivilege::Invalid_Count;
|
||||
|
||||
/** State of attempt to request the relevant privilege */
|
||||
ECommonUserAsyncTaskState PrivilegeCheckState = ECommonUserAsyncTaskState::NotStarted;
|
||||
|
||||
/** The final context to log into */
|
||||
ECommonUserOnlineContext DesiredContext = ECommonUserOnlineContext::Invalid;
|
||||
|
||||
/** What online system we are currently logging into */
|
||||
ECommonUserOnlineContext CurrentContext = ECommonUserOnlineContext::Invalid;
|
||||
|
||||
/** User callback for completion */
|
||||
FOnLocalUserLoginCompleteDelegate Delegate;
|
||||
|
||||
/** Most recent/relevant error to display to user */
|
||||
TOptional<FOnlineErrorType> Error;
|
||||
};
|
||||
|
||||
|
||||
/** Create a new user info object */
|
||||
virtual UCommonUserInfo* CreateLocalUserInfo(int32 LocalPlayerIndex);
|
||||
|
||||
/** Deconst wrapper for const getters */
|
||||
FORCEINLINE UCommonUserInfo* ModifyInfo(const UCommonUserInfo* Info) { return const_cast<UCommonUserInfo*>(Info); }
|
||||
|
||||
/** Refresh user info from OSS */
|
||||
virtual void RefreshLocalUserInfo(UCommonUserInfo* UserInfo);
|
||||
|
||||
/** Possibly send privilege availability notification, compares current value to cached old value */
|
||||
virtual void HandleChangedAvailability(UCommonUserInfo* UserInfo, ECommonUserPrivilege Privilege, ECommonUserAvailability OldAvailability);
|
||||
|
||||
/** Updates the cached privilege on a user and notifies delegate */
|
||||
virtual void UpdateUserPrivilegeResult(UCommonUserInfo* UserInfo, ECommonUserPrivilege Privilege, ECommonUserPrivilegeResult Result, ECommonUserOnlineContext Context);
|
||||
|
||||
/** Gets internal data for a type of online system, can return null for service */
|
||||
const FOnlineContextCache* GetContextCache(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game) const;
|
||||
FOnlineContextCache* GetContextCache(ECommonUserOnlineContext Context = ECommonUserOnlineContext::Game);
|
||||
|
||||
/** Create and set up system objects before delegates are bound */
|
||||
virtual void CreateOnlineContexts();
|
||||
virtual void DestroyOnlineContexts();
|
||||
|
||||
/** Bind online delegates */
|
||||
virtual void BindOnlineDelegates();
|
||||
|
||||
/** Forcibly logs out and deinitializes a single user */
|
||||
virtual void LogOutLocalUser(FPlatformUserId PlatformUser);
|
||||
|
||||
/** Performs the next step of a login request, which could include completing it. Returns true if it's done */
|
||||
virtual void ProcessLoginRequest(TSharedRef<FUserLoginRequest> Request);
|
||||
|
||||
/** Call login on OSS, with platform auth from the platform OSS. Return true if AutoLogin started */
|
||||
virtual bool TransferPlatformAuth(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
|
||||
/** Call AutoLogin on OSS. Return true if AutoLogin started. */
|
||||
virtual bool AutoLogin(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
|
||||
/** Call ShowLoginUI on OSS. Return true if ShowLoginUI started. */
|
||||
virtual bool ShowLoginUI(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
|
||||
/** Call QueryUserPrivilege on OSS. Return true if QueryUserPrivilege started. */
|
||||
virtual bool QueryUserPrivilege(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
|
||||
/** OSS-specific functions */
|
||||
#if COMMONUSER_OSSV1
|
||||
virtual ECommonUserPrivilege ConvertOSSPrivilege(EUserPrivileges::Type Privilege) const;
|
||||
virtual EUserPrivileges::Type ConvertOSSPrivilege(ECommonUserPrivilege Privilege) const;
|
||||
virtual ECommonUserPrivilegeResult ConvertOSSPrivilegeResult(EUserPrivileges::Type Privilege, uint32 Results) const;
|
||||
|
||||
void BindOnlineDelegatesOSSv1();
|
||||
bool AutoLoginOSSv1(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
bool ShowLoginUIOSSv1(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
bool QueryUserPrivilegeOSSv1(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
#else
|
||||
virtual ECommonUserPrivilege ConvertOnlineServicesPrivilege(UE::Online::EUserPrivileges Privilege) const;
|
||||
virtual UE::Online::EUserPrivileges ConvertOnlineServicesPrivilege(ECommonUserPrivilege Privilege) const;
|
||||
virtual ECommonUserPrivilegeResult ConvertOnlineServicesPrivilegeResult(UE::Online::EUserPrivileges Privilege, UE::Online::EPrivilegeResults Results) const;
|
||||
|
||||
void BindOnlineDelegatesOSSv2();
|
||||
void CacheConnectionStatus(ECommonUserOnlineContext Context);
|
||||
bool TransferPlatformAuthOSSv2(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
bool AutoLoginOSSv2(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
bool ShowLoginUIOSSv2(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
bool QueryUserPrivilegeOSSv2(FOnlineContextCache* System, TSharedRef<FUserLoginRequest> Request, FPlatformUserId PlatformUser);
|
||||
TSharedPtr<UE::Online::FAccountInfo> GetOnlineServiceAccountInfo(UE::Online::IAuthPtr AuthService, FPlatformUserId InUserId) const;
|
||||
#endif
|
||||
|
||||
/** Callbacks for OSS functions */
|
||||
#if COMMONUSER_OSSV1
|
||||
virtual void HandleIdentityLoginStatusChanged(int32 PlatformUserIndex, ELoginStatus::Type OldStatus, ELoginStatus::Type NewStatus, const FUniqueNetId& NewId, ECommonUserOnlineContext Context);
|
||||
virtual void HandleUserLoginCompleted(int32 PlatformUserIndex, bool bWasSuccessful, const FUniqueNetId& NetId, const FString& Error, ECommonUserOnlineContext Context);
|
||||
virtual void HandleControllerPairingChanged(int32 PlatformUserIndex, FControllerPairingChangedUserInfo PreviousUser, FControllerPairingChangedUserInfo NewUser);
|
||||
virtual void HandleNetworkConnectionStatusChanged(const FString& ServiceName, EOnlineServerConnectionStatus::Type LastConnectionStatus, EOnlineServerConnectionStatus::Type ConnectionStatus, ECommonUserOnlineContext Context);
|
||||
virtual void HandleOnLoginUIClosed(TSharedPtr<const FUniqueNetId> LoggedInNetId, const int PlatformUserIndex, const FOnlineError& Error, ECommonUserOnlineContext Context);
|
||||
virtual void HandleCheckPrivilegesComplete(const FUniqueNetId& UserId, EUserPrivileges::Type Privilege, uint32 PrivilegeResults, ECommonUserPrivilege RequestedPrivilege, TWeakObjectPtr<UCommonUserInfo> CommonUserInfo, ECommonUserOnlineContext Context);
|
||||
#else
|
||||
virtual void HandleAuthLoginStatusChanged(const UE::Online::FAuthLoginStatusChanged& EventParameters, ECommonUserOnlineContext Context);
|
||||
virtual void HandleUserLoginCompletedV2(const UE::Online::TOnlineResult<UE::Online::FAuthLogin>& Result, FPlatformUserId PlatformUser, ECommonUserOnlineContext Context);
|
||||
virtual void HandleOnLoginUIClosedV2(const UE::Online::TOnlineResult<UE::Online::FExternalUIShowLoginUI>& Result, FPlatformUserId PlatformUser, ECommonUserOnlineContext Context);
|
||||
virtual void HandleNetworkConnectionStatusChanged(const UE::Online::FConnectionStatusChanged& EventParameters, ECommonUserOnlineContext Context);
|
||||
virtual void HandleCheckPrivilegesComplete(const UE::Online::TOnlineResult<UE::Online::FQueryUserPrivilege>& Result, TWeakObjectPtr<UCommonUserInfo> CommonUserInfo, UE::Online::EUserPrivileges DesiredPrivilege, ECommonUserOnlineContext Context);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Callback for when an input device (i.e. a gamepad) has been connected or disconnected.
|
||||
*/
|
||||
virtual void HandleInputDeviceConnectionChanged(EInputDeviceConnectionState NewConnectionState, FPlatformUserId PlatformUserId, FInputDeviceId InputDeviceId);
|
||||
|
||||
virtual void HandleLoginForUserInitialize(const UCommonUserInfo* UserInfo, ELoginStatusType NewStatus, FUniqueNetIdRepl NetId, const TOptional<FOnlineErrorType>& Error, ECommonUserOnlineContext Context, FCommonUserInitializeParams Params);
|
||||
virtual void HandleUserInitializeFailed(FCommonUserInitializeParams Params, FText Error);
|
||||
virtual void HandleUserInitializeSucceeded(FCommonUserInitializeParams Params);
|
||||
|
||||
/** Callback for handling press start/login logic */
|
||||
virtual bool OverrideInputKeyForLogin(FInputKeyEventArgs& EventArgs);
|
||||
|
||||
|
||||
/** Previous override handler, will restore on cancel */
|
||||
FOverrideInputKeyHandler WrappedInputKeyHandler;
|
||||
|
||||
/** List of keys to listen for from any user */
|
||||
TArray<FKey> LoginKeysForAnyUser;
|
||||
|
||||
/** List of keys to listen for a new unmapped user */
|
||||
TArray<FKey> LoginKeysForNewUser;
|
||||
|
||||
/** Params to use for a key-triggered login */
|
||||
FCommonUserInitializeParams ParamsForLoginKey;
|
||||
|
||||
/** Maximum number of local players */
|
||||
int32 MaxNumberOfLocalPlayers = 0;
|
||||
|
||||
/** True if this is a dedicated server, which doesn't require a LocalPlayer */
|
||||
bool bIsDedicatedServer = false;
|
||||
|
||||
/** List of current in progress login requests */
|
||||
TArray<TSharedRef<FUserLoginRequest>> ActiveLoginRequests;
|
||||
|
||||
/** Information about each local user, from local player index to user */
|
||||
UPROPERTY()
|
||||
TMap<int32, TObjectPtr<UCommonUserInfo>> LocalUserInfos;
|
||||
|
||||
/** Cached platform/mode trait tags */
|
||||
FGameplayTagContainer CachedTraitTags;
|
||||
|
||||
/** Do not access this outside of initialization */
|
||||
FOnlineContextCache* DefaultContextInternal = nullptr;
|
||||
FOnlineContextCache* ServiceContextInternal = nullptr;
|
||||
FOnlineContextCache* PlatformContextInternal = nullptr;
|
||||
|
||||
friend UCommonUserInfo;
|
||||
};
|
||||
218
Plugins/CommonUser/Source/CommonUser/Public/CommonUserTypes.h
Normal file
218
Plugins/CommonUser/Source/CommonUser/Public/CommonUserTypes.h
Normal file
@@ -0,0 +1,218 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#if COMMONUSER_OSSV1
|
||||
|
||||
// Online Subsystem (OSS v1) includes and forward declares
|
||||
#include "OnlineSubsystemTypes.h"
|
||||
class IOnlineSubsystem;
|
||||
struct FOnlineError;
|
||||
using FOnlineErrorType = FOnlineError;
|
||||
using ELoginStatusType = ELoginStatus::Type;
|
||||
|
||||
#else
|
||||
|
||||
// Online Services (OSS v2) includes and forward declares
|
||||
#include "Online/Connectivity.h"
|
||||
#include "Online/OnlineError.h"
|
||||
namespace UE::Online
|
||||
{
|
||||
enum class ELoginStatus : uint8;
|
||||
enum class EPrivilegeResults : uint32;
|
||||
enum class EUserPrivileges : uint8;
|
||||
using IAuthPtr = TSharedPtr<class IAuth>;
|
||||
using IOnlineServicesPtr = TSharedPtr<class IOnlineServices>;
|
||||
template <typename OpType>
|
||||
class TOnlineResult;
|
||||
struct FAuthLogin;
|
||||
struct FConnectionStatusChanged;
|
||||
struct FExternalUIShowLoginUI;
|
||||
struct FAuthLoginStatusChanged;
|
||||
struct FQueryUserPrivilege;
|
||||
struct FAccountInfo;
|
||||
}
|
||||
using FOnlineErrorType = UE::Online::FOnlineError;
|
||||
using ELoginStatusType = UE::Online::ELoginStatus;
|
||||
|
||||
#endif
|
||||
|
||||
#include "CommonUserTypes.generated.h"
|
||||
|
||||
|
||||
/** Enum specifying where and how to run online queries */
|
||||
UENUM(BlueprintType)
|
||||
enum class ECommonUserOnlineContext : uint8
|
||||
{
|
||||
/** Called from game code, this uses the default system but with special handling that could merge results from multiple contexts */
|
||||
Game,
|
||||
|
||||
/** The default engine online system, this will always exist and will be the same as either Service or Platform */
|
||||
Default,
|
||||
|
||||
/** Explicitly ask for the external service, which may not exist */
|
||||
Service,
|
||||
|
||||
/** Looks for external service first, then falls back to default */
|
||||
ServiceOrDefault,
|
||||
|
||||
/** Explicitly ask for the platform system, which may not exist */
|
||||
Platform,
|
||||
|
||||
/** Looks for platform system first, then falls back to default */
|
||||
PlatformOrDefault,
|
||||
|
||||
/** Invalid system */
|
||||
Invalid
|
||||
};
|
||||
|
||||
/** Enum describing the state of initialization for a specific user */
|
||||
UENUM(BlueprintType)
|
||||
enum class ECommonUserInitializationState : uint8
|
||||
{
|
||||
/** User has not started login process */
|
||||
Unknown,
|
||||
|
||||
/** Player is in the process of acquiring a user id with local login */
|
||||
DoingInitialLogin,
|
||||
|
||||
/** Player is performing the network login, they have already logged in locally */
|
||||
DoingNetworkLogin,
|
||||
|
||||
/** Player failed to log in at all */
|
||||
FailedtoLogin,
|
||||
|
||||
|
||||
/** Player is logged in and has access to online functionality */
|
||||
LoggedInOnline,
|
||||
|
||||
/** Player is logged in locally (either guest or real user), but cannot perform online actions */
|
||||
LoggedInLocalOnly,
|
||||
|
||||
|
||||
/** Invalid state or user */
|
||||
Invalid,
|
||||
};
|
||||
|
||||
/** Enum specifying different privileges and capabilities available to a user */
|
||||
UENUM(BlueprintType)
|
||||
enum class ECommonUserPrivilege : uint8
|
||||
{
|
||||
/** Whether the user can play at all, online or offline */
|
||||
CanPlay,
|
||||
|
||||
/** Whether the user can play in online modes */
|
||||
CanPlayOnline,
|
||||
|
||||
/** Whether the user can use text chat */
|
||||
CanCommunicateViaTextOnline,
|
||||
|
||||
/** Whether the user can use voice chat */
|
||||
CanCommunicateViaVoiceOnline,
|
||||
|
||||
/** Whether the user can access content generated by other users */
|
||||
CanUseUserGeneratedContent,
|
||||
|
||||
/** Whether the user can ever participate in cross-play */
|
||||
CanUseCrossPlay,
|
||||
|
||||
/** Invalid privilege (also the count of valid ones) */
|
||||
Invalid_Count UMETA(Hidden)
|
||||
};
|
||||
|
||||
/** Enum specifying the general availability of a feature or privilege, this combines information from multiple sources */
|
||||
UENUM(BlueprintType)
|
||||
enum class ECommonUserAvailability : uint8
|
||||
{
|
||||
/** State is completely unknown and needs to be queried */
|
||||
Unknown,
|
||||
|
||||
/** This feature is fully available for use right now */
|
||||
NowAvailable,
|
||||
|
||||
/** This might be available after the completion of normal login procedures */
|
||||
PossiblyAvailable,
|
||||
|
||||
/** This feature is not available now because of something like network connectivity but may be available in the future */
|
||||
CurrentlyUnavailable,
|
||||
|
||||
/** This feature will never be available for the rest of this session due to hard account or platform restrictions */
|
||||
AlwaysUnavailable,
|
||||
|
||||
/** Invalid feature */
|
||||
Invalid,
|
||||
};
|
||||
|
||||
/** Enum giving specific reasons why a user may or may not use a certain privilege */
|
||||
UENUM(BlueprintType)
|
||||
enum class ECommonUserPrivilegeResult : uint8
|
||||
{
|
||||
/** State is unknown and needs to be queried */
|
||||
Unknown,
|
||||
|
||||
/** This privilege is fully available for use */
|
||||
Available,
|
||||
|
||||
/** User has not fully logged in */
|
||||
UserNotLoggedIn,
|
||||
|
||||
/** User does not own the game or content */
|
||||
LicenseInvalid,
|
||||
|
||||
/** The game needs to be updated or patched before this will be available */
|
||||
VersionOutdated,
|
||||
|
||||
/** No network connection, this may be resolved by reconnecting */
|
||||
NetworkConnectionUnavailable,
|
||||
|
||||
/** Parental control failure */
|
||||
AgeRestricted,
|
||||
|
||||
/** Account does not have a required subscription or account type */
|
||||
AccountTypeRestricted,
|
||||
|
||||
/** Another account/user restriction such as being banned by the service */
|
||||
AccountUseRestricted,
|
||||
|
||||
/** Other platform-specific failure */
|
||||
PlatformFailure,
|
||||
};
|
||||
|
||||
/** Used to track the progress of different asynchronous operations */
|
||||
enum class ECommonUserAsyncTaskState : uint8
|
||||
{
|
||||
/** The task has not been started */
|
||||
NotStarted,
|
||||
/** The task is currently being processed */
|
||||
InProgress,
|
||||
/** The task has completed successfully */
|
||||
Done,
|
||||
/** The task failed to complete */
|
||||
Failed
|
||||
};
|
||||
|
||||
/** Detailed information about the online error. Effectively a wrapper for FOnlineError. */
|
||||
USTRUCT(BlueprintType)
|
||||
struct FOnlineResultInformation
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
/** Whether the operation was successful or not. If it was successful, the error fields of this struct will not contain extra information. */
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
bool bWasSuccessful = true;
|
||||
|
||||
/** The unique error id. Can be used to compare against specific handled errors. */
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FString ErrorId;
|
||||
|
||||
/** Error text to display to the user. */
|
||||
UPROPERTY(BlueprintReadOnly)
|
||||
FText ErrorText;
|
||||
|
||||
/**
|
||||
* Initialize this from an FOnlineErrorType
|
||||
* @param InOnlineError the online error to initialize from
|
||||
*/
|
||||
void COMMONUSER_API FromOnlineError(const FOnlineErrorType& InOnlineError);
|
||||
};
|
||||
Reference in New Issue
Block a user