Implementation

Let’s implement from account issuance to login

Initialize GS2 SDK

    // Setup variables

    var clientId = "YourClientId";
    var clientSecret = "YourClientSecret";
    var accountNamespaceName = "game-0001";
    var accountEncryptionKeyId = "grn:gs2:{region}:{ownerId}:key:account-encryption-key-namespace:key:account-encryption-key";
    
    // Setup general setting
    var profile = new Profile(
        clientId,
        clientSecret,
        reopener: new Gs2BasicReopener()
    );

    // Create GS2 client
    var initializeFuture = profile.InitializeFuture();
    yield return initializeFuture;
    if (initializeFuture.Error ! = null) {
        throw initializeFuture.Error;
    }
    var gs2 = initializeFuture.Result;
	// Setup variables

	const auto ClientId = "YourClientId";
	const auto ClientSecret = "YourClientSecret";
	const auto AccountNamespaceName = "game-0001";
	const auto AccountEncryptionKeyId = "grn:gs2:{region}:{ownerId}:key:account-encryption-key-namespace:key:account-encryption-key";
	
	// Setup general setting
	
	const auto Profile = MakeShared<Gs2::UE5::Util::FProfile>(
		ClientId,
		ClientSecret,
		Gs2::Core::Model::ERegion::ApNorthEast1,
		MakeShareable<Gs2::UE5::Util::IReOpener>(new Gs2::UE5::Util::FGs2BasicReOpener()
	);

	// Create GS2 client
    const auto InitializeFuture = Profile->Initialize();
    InitializeFuture->StartSynchronousTask();
    if (InitializeFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(InitializeFuture->GetTask().Error()->String())));
        return InitializeFuture->GetTask().Error();
    }
    const auto Gs2 = InitializeFuture->GetTask().Result();

Setup variables

First, four variables are defined.

Variable nameUsageSource of acquisition
clientIdauthentication information to access GS2value created in Create credential (API key)
clientSecretauthentication information for accessing GS2value created by create credential (API key)
accountNamespaceNamethe namespace name of the GS2-Account to be usedthe value created in Prepare resources required for login process
accountEncryptionKeyIdthe encryption key ID of the GS2-Key to be used in the authentication processthe value created in Prepare resources required for login process

Setup general setting

Create a Profile object. The Profile object is a utility class that wraps the general process of starting to use GS2 in an easy-to-handle manner.

In the reopener object, set up a handler to reconnect the communication. In this example, we set Gs2BasicReopener, which is provided in the library.

Create GS2 client

Initialize a GS2 client. If clientId or clientSecret is incorrect, an error will be returned here.

Create new anonymous account.

    // Create an anonymous account
    
    Debug.Log("Create anonymous account");
    
    var createFuture = gs2.Account.Namespace(
        AccountNamespaceName
    ).Create();
    Create(); var createFuture = gs2.Account.Namespace( accountNamespaceName );
    if (createFuture.Error ! = null)
    {
        throw createFuture.Error;
    }
	// Create an anonymous account
	
    UE_LOG(GameLog, Display, TEXT("Create anonymous account"));

    const auto CreateFuture = Gs2->Account->Namespace(
        AccountNamespaceName
    )->Create();
    CreateFuture->StartSynchronousTask();
    if (CreateFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(CreateFuture->GetTask().Error()->String())));
        return CreateFuture->GetTask().Error();
    }

Here we are creating an account to identify the game player. The accountNamespaceName is the name of the namespace to which the account will be added.

In this sample, a new account is logged in on every startup, but normally an account is created only on the first startup of the application. In the actual application, this response account information is saved in local storage, etc., and from the second time onward, the created account information retrieved from local storage, etc., is used to log in as an existing game player.

Get contents of created anonymous account

    // Load created account
    
    var loadFuture = createFuture.Result.Model();
    yield return loadFuture;
    if (loadFuture.Error != null)
    {
        throw loadFuture.Error;
    }
    var account = loadFuture.Result;

    // Dump anonymous account
    
    Debug.Log($"UserId: {account.UserId}");
    Debug.Log($"Password: {account.Password}");
	// Load created account

    const auto LoadFuture = CreateFuture->GetTask().Result()->Model();
    LoadFuture->StartSynchronousTask();
    if (LoadFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(LoadFuture->GetTask().Error()->String()));
        return LoadFuture->GetTask().Error();
    }
    const auto Account = LoadFuture->GetTask().Result();

    // Dump anonymous account

    UE_LOG(GameLog, Display, TEXT("UserId: %s"), ToCStr(*Account->GetUserId()));
    UE_LOG(GameLog, Display, TEXT("Password: %s"), ToCStr(*Account->GetPassword()));

Get the contents of the created anonymous account.

Login process

    // Log-in created anonymous account

    var loginFuture = profile.LoginFuture(
        new Gs2AccountAuthenticator(
            profile.Gs2RestSession,
            accountNamespaceName,
            accountEncryptionKeyId,
            account.UserId,
            account.Password
        )
    );
    yield return loginFuture;
    if (loginFuture.Error != null)
    {
        throw loginFuture.Error;
    }
    var gameSession = loginFuture.Result;
	// Log-in created anonymous account

	const auto LoginFuture = Profile->Login(
		MakeShareable<Gs2::UE5::Util::IAuthenticator>(
			new Gs2::UE5::Util::FGs2AccountAuthenticator(
				AccountNamespaceName,
				AccountEncryptionKeyId
			)
		),
		*Account->GetUserId(),
		*Account->GetPassword()
	);
    LoginFuture->StartSynchronousTask();
    if (LoginFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(LoginFuture->GetTask().Error()->String()));
        return LoginFuture->GetTask().Error();
    }
    const auto GameSession = LoginFuture->GetTask().Result();

Next is the GS2 login process. In accountNamespaceName, specify the name of the namespace in which the created account exists, and in keyId, specify the encryption key used to calculate the signature to be given to the account authentication result. In addition, userId password specifies the user ID and password of the created account.

Result returns a GameSession object that represents the login status. From now on, when calling GS2 APIs, pass GameSession as an argument for APIs that can only be called if the user is logged in.

Calling APIs that can be called after login

    // Load TakeOver settings
    
    var it = gs2.Account.Namespace(
        accountNamespaceName
    ).Me(
        gameSession
    ).TakeOvers();

    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            throw it.Error;
        }
        if (it.Current != null)
        {
            // Dump TakeOver setting
            Debug.Log($"Type: {it.Current.Type}");
            Debug.Log($"Identifier: {it.Current.UserIdentifier}");
        }
    }
	// Load TakeOver settings

	const auto It = Gs2->Account->Namespace(
		AccountNamespaceName
	)->Me(
		GameSession
	)->TakeOvers();
	for (const auto TakeOver : *It)
	{
		UE_LOG(GameLog, Display, TEXT("Type: %s"), *TakeOver->GetType());
		UE_LOG(GameLog, Display, TEXT("Identifier: %s"), *TakeOver->GetUserIdentifier());
	}

As an example of an API that can only be used while logged in, we call the API to get a list of takeover settings. You can pass GameSession to get a list of handover settings set for the currently logged-in game player.

GS2 SDK termination process

    // Finalize GS2-SDK

    yield return profile.Finalize();
	// Finalize GS2-SDK
	
    const auto FinalizeFuture = Profile->Finalize();
    FinalizeFuture->StartSynchronousTask();
    if (FinalizeFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(FinalizeFuture->GetTask().Error()->String()));
        return FinalizeFuture->GetTask().Error();
    }

Terminate the connection with GS2.

Have you completed the tutorial?

[Check out our YouTube channel for guidance on how to use GS2!] (/en/articles/sample/youtube/)

[We also provide more practical examples] (/en/articles/sample/project/)

find out what else you can achieve with GS2

learn about the development workflow using GS2


Full sample code

Full text of sample code