Skip to content

Commit 2c798eb

Browse files
committed
feat: Added APIs for Passport in Blueprint and C++, with samples
1 parent 495c73c commit 2c798eb

40 files changed

+2309
-1
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,9 @@ Plugins/*/Intermediate/*
7272

7373
# Cache files for the editor to use
7474
DerivedDataCache/*
75+
76+
.vsconfig
77+
78+
.idea/
79+
80+
node_modules/
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Content/PassportBlueprintSample.umap

58.2 KB
Binary file not shown.

Content/index.html

+18
Large diffs are not rendered by default.

Immutable.uplugin

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"FileVersion": 3,
3+
"Version": 1,
4+
"VersionName": "1.0",
5+
"FriendlyName": "Immutable",
6+
"Description": "",
7+
"Category": "Other",
8+
"CreatedBy": "",
9+
"CreatedByURL": "",
10+
"DocsURL": "",
11+
"MarketplaceURL": "",
12+
"SupportURL": "",
13+
"CanContainContent": true,
14+
"IsBetaVersion": true,
15+
"IsExperimentalVersion": true,
16+
"Installed": true,
17+
"EnabledByDefault": true,
18+
"Modules": [
19+
{
20+
"Name": "Immutable",
21+
"Type": "Runtime",
22+
"LoadingPhase": "Default"
23+
}
24+
],
25+
"Plugins": [
26+
{
27+
"Name": "WebBrowserWidget",
28+
"Enabled": true
29+
}
30+
]
31+
}

README.md

+45-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,45 @@
1-
# ImmutableSDK-Unreal
1+
# Immutable SDK for Unreal
2+
3+
## User Guide
4+
5+
### Installation
6+
7+
To install the plugin download it into your project's `Plugins` folder, e.g.: `MyGame/Plugins/unreal-immutable-sdk`.
8+
9+
### Setup
10+
11+
#### Blueprint
12+
13+
See the included sample widgets in `All`->`Plugins`->`Immutable Content` in the Unreal Editor content browser for examples of how to use the plugin in Blueprint. If you don't see a `Plugins` folder under `All` you may need to enable `Show Plugin Content` in the content browser's `Settings` menu.
14+
15+
#### C++
16+
17+
See `ImmutablePassport.h` for the C++ Passport API. Follow the same sequence of steps as the Blueprint widget example to initialise and connect Passport and retrieve account data.
18+
19+
20+
## Plugin Maintainers' Guide
21+
22+
### Getting Started
23+
24+
See user docs to install the plugin, with one caveat: If you want to open the project and plugin in an IDE you'll need to create your Unreal project as a C++ project. If you've already accidentally created your Unreal project as BluePrint-only you can convert it to a BluePrint-and-C++ project by adding any C++ class from the `Add New C++ Class` option in the Unreal Editor's `File` menu.
25+
26+
### Debugging the Embedded Browser
27+
28+
#### Embedded Browser Logs
29+
30+
See `Saved/Logs/cef3.log` in your Unreal project.
31+
32+
#### JS Console Output
33+
34+
In Unreal Engine 5.1+ the project is set up so that `console.log()` will pass all the way through to the Unreal console. This isn't available in UE5.0 and earlier but you can still use Chromium's remote debugging (see below).
35+
36+
#### Remote Debugging
37+
38+
To set up Chromium remote debugging, edit project build/launch configurations in your IDE to add the following program command line argument to the appropriate configurations: `cefdebug=9222`
39+
40+
Next, launch the game and then open a separate Chrome/Chromium browser and navigate to `chrome://inspect` where your app should be listed, sometimes intermittently or after a delay, under the `Remote Target #localhost` section. Click `inspect` to launch the remote debugging session.
41+
42+
#### Displaying the Browser
43+
44+
**TODO**
45+

Resources/Icon128.png

12.4 KB
Loading

Source/Immutable/Immutable.Build.cs

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright Epic Games, Inc. All Rights Reserved.
2+
3+
using UnrealBuildTool;
4+
5+
public class Immutable : ModuleRules
6+
{
7+
public Immutable(ReadOnlyTargetRules Target) : base(Target)
8+
{
9+
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
10+
11+
PublicIncludePaths.AddRange(
12+
new string[]
13+
{
14+
// ... add public include paths required here ...
15+
}
16+
);
17+
18+
19+
PrivateIncludePaths.AddRange(
20+
new string[]
21+
{
22+
// ... add other private include paths required here ...
23+
}
24+
);
25+
26+
27+
PublicDependencyModuleNames.AddRange(
28+
new string[]
29+
{
30+
"Core",
31+
"WebBrowserWidget",
32+
// ... add other public dependencies that you statically link with here ...
33+
}
34+
);
35+
36+
37+
PrivateDependencyModuleNames.AddRange(
38+
new string[]
39+
{
40+
"CoreUObject",
41+
"Engine",
42+
"Slate",
43+
"SlateCore",
44+
"Json",
45+
"JsonUtilities",
46+
"WebBrowser",
47+
"UMG",
48+
"Projects",
49+
// ... add private dependencies that you statically link with here ...
50+
}
51+
);
52+
53+
54+
DynamicallyLoadedModuleNames.AddRange(
55+
new string[]
56+
{
57+
// ... add any modules that your module loads dynamically here ...
58+
}
59+
);
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Fill out your copyright notice in the Description page of Project Settings.
2+
3+
4+
#include "Actions/ImtblBlueprintAsyncAction.h"
5+
6+
7+
UImmutableSubsystem* UImtblBlueprintAsyncAction::GetSubsystem() const
8+
{
9+
if (!WorldContextObject || !WorldContextObject->GetWorld())
10+
return nullptr;
11+
return WorldContextObject->GetWorld()->GetGameInstance()->GetSubsystem<UImmutableSubsystem>();
12+
}
13+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Fill out your copyright notice in the Description page of Project Settings.
2+
3+
4+
#include "Actions/ImtblPassportConfirmCodeAsyncAction.h"
5+
6+
#include "ImmutablePassport.h"
7+
#include "ImmutableSubsystem.h"
8+
#include "ImtblLogging.h"
9+
10+
11+
UImtblPassportConfirmCodeAsyncAction* UImtblPassportConfirmCodeAsyncAction::ConfirmCode(UObject* WorldContextObject, const FString& DeviceCode)
12+
{
13+
UImtblPassportConfirmCodeAsyncAction* BlueprintNode = NewObject<UImtblPassportConfirmCodeAsyncAction>();
14+
BlueprintNode->WorldContextObject = WorldContextObject;
15+
BlueprintNode->DeviceCode = DeviceCode;
16+
return BlueprintNode;
17+
}
18+
19+
20+
void UImtblPassportConfirmCodeAsyncAction::Activate()
21+
{
22+
if (!WorldContextObject || !WorldContextObject->GetWorld())
23+
{
24+
FString Err = "ConfirmCode failed due to missing world or world context object.";
25+
IMTBL_WARN("%s", *Err)
26+
Failed.Broadcast(Err);
27+
return;
28+
}
29+
30+
GetSubsystem()->WhenReady(this, &UImtblPassportConfirmCodeAsyncAction::DoConfirmCode);//, /* timoutSec */ 15.0f);
31+
}
32+
33+
34+
void UImtblPassportConfirmCodeAsyncAction::DoConfirmCode(TWeakObjectPtr<UImtblJSConnector> JSConfirmConnector)
35+
{
36+
// Get Passport
37+
auto Passport = GetSubsystem()->GetPassport();
38+
// Run ConfirmCode
39+
Passport->ConfirmCode(DeviceCode, UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportConfirmCodeAsyncAction::OnConfirmCodeCodeResponse));
40+
}
41+
42+
43+
void UImtblPassportConfirmCodeAsyncAction::OnConfirmCodeCodeResponse(FImmutablePassportResult Result)
44+
{
45+
if (Result.Success)
46+
{
47+
CodeConfirmed.Broadcast(TEXT(""));
48+
}
49+
else
50+
{
51+
Failed.Broadcast(Result.Message);
52+
}
53+
}
54+
55+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Fill out your copyright notice in the Description page of Project Settings.
2+
3+
4+
#include "Actions/ImtblPassportConnectAsyncAction.h"
5+
6+
#include "ImmutablePassport.h"
7+
#include "ImmutableSubsystem.h"
8+
#include "ImtblLogging.h"
9+
10+
11+
UImtblPassportConnectAsyncAction* UImtblPassportConnectAsyncAction::Connect(UObject* WorldContextObject)
12+
{
13+
UImtblPassportConnectAsyncAction* PassportInitBlueprintNode = NewObject<UImtblPassportConnectAsyncAction>();
14+
PassportInitBlueprintNode->WorldContextObject = WorldContextObject;
15+
return PassportInitBlueprintNode;
16+
}
17+
18+
19+
void UImtblPassportConnectAsyncAction::Activate()
20+
{
21+
if (!WorldContextObject || !WorldContextObject->GetWorld())
22+
{
23+
FString Err = "Connect failed due to missing world or world context object.";
24+
IMTBL_WARN("%s", *Err)
25+
Failed.Broadcast(Err, TEXT(""), TEXT(""), TEXT(""));
26+
return;
27+
}
28+
29+
GetSubsystem()->WhenReady(this, &UImtblPassportConnectAsyncAction::DoConnect);//, /* timoutSec */ 15.0f);
30+
}
31+
32+
33+
void UImtblPassportConnectAsyncAction::DoConnect(TWeakObjectPtr<UImtblJSConnector> JSConnector)
34+
{
35+
// Get Passport
36+
auto Passport = GetSubsystem()->GetPassport();
37+
// Run Connect
38+
Passport->Connect(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportConnectAsyncAction::OnConnectCodeReady));
39+
}
40+
41+
42+
void UImtblPassportConnectAsyncAction::OnConnectCodeReady(FImmutablePassportResult Result)
43+
{
44+
if (Result.Success)
45+
{
46+
if (auto Data = FImmutablePassportConnectData::FromString(Result.Message))
47+
{
48+
ConnectData = Data.GetValue();
49+
50+
CodeReady.Broadcast(TEXT(""), ConnectData.code, ConnectData.deviceCode, ConnectData.url);
51+
}
52+
else
53+
{
54+
IMTBL_WARN("Could not deserialize connect data.")
55+
Failed.Broadcast(Result.Message, TEXT(""), TEXT(""), TEXT(""));
56+
}
57+
}
58+
else
59+
{
60+
Failed.Broadcast(Result.Message, TEXT(""), TEXT(""), TEXT(""));
61+
}
62+
}
63+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Fill out your copyright notice in the Description page of Project Settings.
2+
3+
4+
#include "Actions/ImtblPassportGetAddressAsyncAction.h"
5+
6+
#include "ImmutablePassport.h"
7+
#include "ImmutableSubsystem.h"
8+
#include "ImtblLogging.h"
9+
10+
11+
UImtblPassportGetAddressAsyncAction* UImtblPassportGetAddressAsyncAction::GetAddress(UObject* WorldContextObject)
12+
{
13+
UImtblPassportGetAddressAsyncAction* PassportInitBlueprintNode = NewObject<UImtblPassportGetAddressAsyncAction>();
14+
PassportInitBlueprintNode->WorldContextObject = WorldContextObject;
15+
return PassportInitBlueprintNode;
16+
}
17+
18+
19+
void UImtblPassportGetAddressAsyncAction::Activate()
20+
{
21+
if (!WorldContextObject || !WorldContextObject->GetWorld())
22+
{
23+
FString Err = "GetAddress failed due to missing world or world context object.";
24+
IMTBL_WARN("%s", *Err)
25+
Failed.Broadcast(Err, TEXT(""));
26+
return;
27+
}
28+
29+
GetSubsystem()->WhenReady(this, &UImtblPassportGetAddressAsyncAction::DoGetAddress);//, /* timoutSec */ 15.0f);
30+
}
31+
32+
33+
void UImtblPassportGetAddressAsyncAction::DoGetAddress(TWeakObjectPtr<UImtblJSConnector> JSConnector)
34+
{
35+
// Get Passport
36+
auto Passport = GetSubsystem()->GetPassport();
37+
// Run GetAddress
38+
Passport->GetAddress(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportGetAddressAsyncAction::OnGetAddressResponse));
39+
}
40+
41+
42+
void UImtblPassportGetAddressAsyncAction::OnGetAddressResponse(FImmutablePassportResult Result)
43+
{
44+
if (Result.Success)
45+
{
46+
GotAddress.Broadcast(TEXT(""), Result.Message);
47+
}
48+
else
49+
{
50+
Failed.Broadcast(Result.Message, TEXT(""));
51+
}
52+
}
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Fill out your copyright notice in the Description page of Project Settings.
2+
3+
4+
#include "Actions/ImtblPassportGetEmailAsyncAction.h"
5+
6+
#include "ImmutablePassport.h"
7+
#include "ImmutableSubsystem.h"
8+
#include "ImtblLogging.h"
9+
10+
11+
UImtblPassportGetEmailAsyncAction* UImtblPassportGetEmailAsyncAction::GetEmail(UObject* WorldContextObject)
12+
{
13+
UImtblPassportGetEmailAsyncAction* PassportInitBlueprintNode = NewObject<UImtblPassportGetEmailAsyncAction>();
14+
PassportInitBlueprintNode->WorldContextObject = WorldContextObject;
15+
return PassportInitBlueprintNode;
16+
}
17+
18+
19+
void UImtblPassportGetEmailAsyncAction::Activate()
20+
{
21+
if (!WorldContextObject || !WorldContextObject->GetWorld())
22+
{
23+
FString Err = "GetEmail failed due to missing world or world context object.";
24+
IMTBL_WARN("%s", *Err)
25+
Failed.Broadcast(Err, TEXT(""));
26+
return;
27+
}
28+
29+
GetSubsystem()->WhenReady(this, &UImtblPassportGetEmailAsyncAction::DoGetEmail);//, /* timoutSec */ 15.0f);
30+
}
31+
32+
33+
void UImtblPassportGetEmailAsyncAction::DoGetEmail(TWeakObjectPtr<UImtblJSConnector> JSConnector)
34+
{
35+
// Get Passport
36+
auto Passport = GetSubsystem()->GetPassport();
37+
// Run GetEmail
38+
Passport->GetEmail(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportGetEmailAsyncAction::OnGetEmailResponse));
39+
}
40+
41+
42+
void UImtblPassportGetEmailAsyncAction::OnGetEmailResponse(FImmutablePassportResult Result)
43+
{
44+
if (Result.Success)
45+
{
46+
GotEmail.Broadcast(TEXT(""), Result.Message);
47+
}
48+
else
49+
{
50+
Failed.Broadcast(Result.Message, TEXT(""));
51+
}
52+
}
53+

0 commit comments

Comments
 (0)