Authenticating with Discord #
In this section, we’ll log into the platform with Discord. This method is appropriate for use in production. A Discord account is required to complete this section.
Complete Setting Up the Unreal SDK and Logging Into the Platform before starting this section.
Discord Developer Portal Setup #
- Log into the Discord Developer Portal.
- Click on the Applications tab, then click the New Application button.
If the application has already been created, then you can click on it under My Applications.
- Name your application, then click the Create button.
- After your application has been created, click on the Bot section in the left sidebar, then click the Add Bot button. Confirm that you wish to create a bot.
- Click on OAuth2 in the left sidebar, then click the Add Redirect button. Paste the following URL:
http://localhost:11000/v1/account/discord-redirect
. Click the Save Changes button.
- In the left sidebar, click URL Generator which is nested under OAuth2. Tick the
identify
andemail
boxes, then choosehttp://localhost:11000/v1/account/discord-redirect
under the Select Redirect URL dropdown.
Configure the Pragma Platform Discord Identity Provider #
- Obtain your
clientSecret
andclientId
from the OAuth2 General tab of your application in the Discord Developer Portal. If you have not yet been issued a Client Secret, click the Reset Secret button.
Be sure to securely record your Client Secret, as it will not be shown again.
Navigate to the
pragma-engine/platform/5-ext/config
directory and openLocalConfig.yml
.Insert the following code while making sure to edit in your
clientSecret
andclientId
:
Be sure to nestAccountService.discordIdentityProvider
underpluginConfigs
if you already have other identity providers configured.
social:
pluginConfigs:
AccountService.discordIdentityProvider:
class: "pragma.account.DiscordIdentityProviderPlugin"
config:
clientSecret: "*YOUR CLIENT SECRET"
clientId: "*YOUR CLIENT ID*"
redirectUri: "http://localhost:11000/v1/account/discord-redirect"
- Run
make run
to start Pragma Engine. Run this in a terminal withplatform
as the working directory.
Alternatively, Pragma Engine can be run from IntelliJ. From the IntelliJ toolbar in the upper right, ensure
MainKt - LocalConfigured
is selected, then click the play button.Once the engine has successfully started it prints the message
[main] INFO main - Pragma server startup complete
.
Import the Discord SDK Into Unreal #
- Download the Discord SDK from the Discord Developer site.
- Follow the directions on the Discord developer site to import the Discord SDK into your Unreal project.
Note that the code provided by the Discord guide for editing your-project-name.Build.cs
is missing trailing semicolons.
Do not copy the MyPawn
class provided by the Discord guide. Instead, continue following the instructions here.
- Click on the Content Browser, then expand C++ Classes. Click on your project. Right click in an empty area in the right-hand side of the Content Browser, then click New C++ Class.
- In the Create Parent Class window, create a new Pawn. This guide will assume that it was created with the default name of
MyPawn
.
- Open
MyPawn.cpp
with Rider and replace the contents with the following code. Be sure to replace"Discord Client Token"
with your Discord application’sclientID
, which can be obtained from the Discord Developer Portal. Replace all instances of[Project Name]
with your project’s name.
#include "MyPawn.h"
#include <string>
#include "[Project Name]GameModeBase.h"
#include "discord-files/discord.h"
discord::Core* core{};
A[Project Name]GameModeBase* gmBase;
AMyPawn::AMyPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bStartWithTickEnabled = true;
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AMyPawn::BeginPlay()
{
Super::BeginPlay();
gmBase = Cast<A[Project Name]GameModeBase>(GetWorld()->GetAuthGameMode<A[Project Name]GameModeBase>());
auto result = discord::Core::Create("Discord Client Token", DiscordCreateFlags_Default, &core);
core->ApplicationManager().GetOAuth2Token([](discord::Result result, discord::OAuth2Token token){
const char* charToken = token.GetAccessToken();
//Convert Discord's UTF-8 encoded string to something Unreal can understand
std::string test = charToken;
FString tokenString(test .c_str());
//Log into the Pragma Platform by passing in our string
gmBase->LoginViaDiscord(tokenString);
});
}
// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
::core->RunCallbacks();
}
// Called to bind functionality to input
void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
- Replace the contents of
[Project Name]GameModeBase.cpp
with the following code. Replace all instances of[Project Name]
with your project’s name.
// Copyright Epic Games, Inc. All Rights Reserved.
#include "[Project Name]GameModeBase.h"
#include "PragmaSessionLocalPlayerSubsystem.h"
#include "PragmaSession.h"
#include "GameFramework/GameMode.h"
void A[Project Name]GameModeBase::BeginPlay()
{
Init(*GetWorld()->GetFirstLocalPlayerFromController());
}
void A[Project Name]GameModeBase::Init(ULocalPlayer& InLocalPlayer)
{
LocalPlayer = &InLocalPlayer;
auto* World = GetWorld();
if (!World->IsClient())
{
return;
}
auto* SessionSubsystem = LocalPlayer->GetSubsystem<UPragmaSessionLocalPlayerSubsystem>();
if (!ensure(SessionSubsystem))
{
return;
}
Session = &SessionSubsystem->Session();
Session->Connection()->OnConnected.AddUObject(this, &A[Project Name]GameModeBase::HandleConnected);
Session->Connection()->OnDisconnectedV2.AddUObject(this, &A[Project Name]GameModeBase::HandleDisconnected);
}
void A[Project Name]GameModeBase::LogIn(const FString& Username)
{
UPragmaAccountService::FLoggedInDelegate OnLoggedIn;
OnLoggedIn.AddUObject(this, &A[Project Name]GameModeBase::HandleLoggedIn);
Session->Account().LogIn(EPragma_Account_IdProvider::UNSAFE, Username, OnLoggedIn);
}
void A[Project Name]GameModeBase::LoginViaDiscord(const FString& DiscoToken)
{
UPragmaAccountService::FLoggedInDelegate OnLoggedIn;
OnLoggedIn.AddUObject(this, &A[Project Name]GameModeBase::HandleLoggedIn);
Session->Account().LogIn(EPragma_Account_IdProvider::DISCORD, DiscoToken, OnLoggedIn);
}
void A[Project Name]GameModeBase::HandleConnected()
{
UE_LOG(LogTemp, Warning, TEXT("Pragma Connected") );
}
void A[Project Name]GameModeBase::HandleDisconnected(TOptional<UPragmaConnection::FConnectionError> Error)
{
UE_LOG(LogTemp, Warning, TEXT("Pragma Disconnected") );
}
void A[Project Name]GameModeBase::HandleLoggedIn(const TPragmaResult<FString>& Result)
{
if (Result.IsSuccessful())
{
UE_LOG(LogTemp, Warning, TEXT("Pragma Logged in! Player Id: %s:"), *Session->Account().GetPragmaId());
}
else
{
// Note you can access platform/sdk error enums in Result as well.
UE_LOG(LogTemp, Warning, TEXT("Pragma Disconnected") );
}
}
- Add the following code to
[Project Name]GameModeBase.h
nested underpublic:
:
void LoginViaDiscord(const FString& DiscoToken);
Compile the project using the green hammer icon at the top of the Rider window.
In Unreal Editor, drag
MyPawn
from the Content Browser into the game.
Click the Play button to log into Discord via Unreal.
Navigate to your local Pragma Platform portal and sign in via Pragma Unsafe using the
test04
account.Confirm that you see both the
test04
account and your Discord account’s display name in the list of logged-in players.Click on the Discord account’s display name. Under the Identity providers section, verify that the account’s identity provider is Discord.