Documentation index for AI agents

구현

계정 발급부터 로그인까지 구현해 봅시다

여기서는 GS2 SDK를 사용하여 계정 생성과 로그인을 수행하는 최소한의 구현 방법을 설명합니다.

각 플랫폼별 전체 코드는 샘플 코드 전문을 확인해 주세요.

GS2 SDK 초기화

    // Setup variables

    var clientId = "YourClientId";
    var clientSecret = "YourClientSecret";
    var accountNamespaceName = "game-0001";

    // Setup general setting
    Gs2Domain gs2;
    {
        var future = Gs2Client.CreateFuture(
            new BasicGs2Credential(
                clientId,
                clientSecret
            ),
            Region.ApNortheast1
        );
        yield return future;
        if (future.Error != null) {
            throw future.Error;
        }
        gs2 = future.Result;
    }
	// Setup variables

	const auto ClientId = "YourClientId";
	const auto ClientSecret = "YourClientSecret";
	const auto AccountNamespaceName = "game-0001";

    // Create GS2 client

    const auto InitializeFuture = Gs2::UE5::Core::FGs2Client::Create(
        MakeShared<Gs2::Core::Model::FBasicGs2Credential>(
            ClientId,
            ClientSecret
        ),
        Gs2::Core::Model::ApNorthEast1
    );
    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

    var client_id = "YourClientId"
    var client_secret = "YourClientSecret"
    var account_namespace_name = "game-0001"
    var account_encryption_key_id = "grn:gs2:{region}:{ownerId}:key:account-encryption-key-namespace:key:account-encryption-key"

    # Initialize GS2 SDK

    var credential = Gs2BasicCredential.new(client_id, client_secret)
    var connection = Gs2Connection.new(credential, Gs2Region.AP_NORTHEAST_1)
    var ez = Gs2EzDomain.new(connection)

Setup variables

먼저 4개의 변수를 정의하고 있습니다.

변수 이름용도취득처
clientIdGS2에 접근하기 위한 인증 정보크리덴셜(API 키) 생성에서 생성한 값
clientSecretGS2에 접근하기 위한 인증 정보크리덴셜(API 키) 생성에서 생성한 값
accountNamespaceName이용할 GS2-Account의 네임스페이스 이름로그인 처리에 필요한 리소스 준비에서 생성한 값
accountEncryptionKeyId계정 인증에 사용하는 암호 키의 GRN로그인 처리에 필요한 리소스 준비에서 생성한 스택의 KeyAccountAuthenticationKeyId 출력 값

Setup general setting

Gs2Client.CreateFuture(UniTask 사용 시 Gs2Client.CreateAsync)로 GS2 클라이언트를 생성합니다. clientIdclientSecret이 올바르지 않은 경우 여기서 오류가 반환됩니다. Godot에서는 Gs2Connection을 생성하고, 게임 엔진용 Ez 레이어를 이용하기 위해 Gs2EzDomain을 초기화합니다. 각 서비스는 ez.accountez.inventory와 같은 서비스 프로퍼티를 통해 접근합니다.

익명 계정 신규 생성

    // define GS2-Account namespace
    var gs2Account = gs2.Account.Namespace(
        accountNamespaceName
    );

    // Create an anonymous account
    EzAccount account;
    {
        Debug.Log("Create an anonymous account");
        var future = gs2Account.CreateFuture();
        yield return future;
        if (future.Error != null) {
            throw future.Error;
        }
        var future2 = future.Result.ModelFuture();
        yield return future2;
        if (future2.Error != null) {
            throw future2.Error;
        }
        account = future2.Result;
    }
	// 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();
    }

	// 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()));
    # Define the GS2-Account namespace
    var gs2_account = ez.account.namespace_(
        account_namespace_name
    )

    # Create an anonymous account
    var create_result = await gs2_account.create()
    if create_result.error != null:
        push_error(str(create_result.error))
        return

    var model_result = await create_result.result.model()
    if model_result.error != null:
        push_error(str(model_result.error))
        return

    var account = model_result.result
    print("UserId: ", account.user_id)
    print("Password: ", account.password)

여기서는 게임 플레이어를 식별하기 위한 계정 생성을 하고 있습니다. accountNamespaceName에는 계정을 추가할 네임스페이스 이름을 지정합니다.

또한 이 샘플에서는 실행할 때마다 신규 계정으로 로그인하는 동작으로 되어 있지만, 일반적으로 계정 생성은 애플리케이션의 최초 실행 시에만 수행합니다. 실제 애플리케이션에서는 이 응답의 계정 정보를 로컬 스토리지 등에 저장하고, 두 번째 실행부터는 로컬 스토리지 등에서 취득한 생성된 계정 정보로 기존 게임 플레이어로서 로그인을 수행합니다.

로그인 처리

    // Log-in created anonymous account
    GameSession gameSession;
    {
        var future = gs2.LoginFuture(
            new Gs2AccountAuthenticator(
                accountSetting: new AccountSetting {
                    accountNamespaceName = accountNamespaceName,
                }
            ),
            account.UserId,
            account.Password
        );
        yield return future;
        if (future.Error != null) {
            throw future.Error;
        }
        gameSession = future.Result;
    }
    // Log-in created anonymous account

    const auto LoginFuture = Gs2->Login(
        MakeShareable<Gs2::UE5::Util::IAuthenticator>(
            new Gs2::UE5::Util::FGs2AccountAuthenticator(
                MakeShared<Gs2::UE5::Util::FAccountSetting>(
                    AccountNamespaceName
                )
            )
        ),
        *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();
    # Log in with the created anonymous account
    var authenticator = Gs2AccountAuthenticator.new(
        account_namespace_name,
        account_encryption_key_id
    )
    var game_session = Gs2GameSession.new(
        authenticator,
        connection,
        account.user_id,
        account.password
    )
    var login_result = await game_session.login()
    if login_result.error != null:
        push_error(str(login_result.error))
        return

이어서 GS2에 로그인하는 처리입니다. Gs2AccountAuthenticator에 계정 인증에 관한 정보를 지정합니다. 구체적으로는 로그인에 사용할 GS2-Account의 네임스페이스 이름을 지정하고 있습니다. Godot에서는 이와 함께 계정 인증에 사용하는 암호 키의 GRN을 지정합니다. 또한 userId, password에는 생성한 계정의 사용자ID와 비밀번호를 지정합니다.

결과적으로 GameSession 객체가 반환됩니다. 이후 GS2의 API를 호출할 때 로그인 상태가 아니면 호출할 수 없는 API의 인수에는 GameSession을 전달하여 사용하게 됩니다.

로그인 후 호출 가능한 API 호출

    // Load TakeOver settings
    {
        var it = gs2Account.Me(
            gameSession
        ).TakeOvers();
        while (it.HasNext()) {
            yield return it.Next();
            if (it.Error != null)
            {
                throw it.Error;
            }
            if (it.Current != null)
            {
                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());
	}
    # Load TakeOver settings
    var load_result = await gs2_account.me(
        game_session
    ).take_overs().load()
    if load_result.error != null:
        push_error(str(load_result.error))
        return

    for take_over in load_result.result:
        print("Type: ", take_over.type)
        print("Identifier: ", take_over.user_identifier)

로그인 상태가 아니면 사용할 수 없는 API의 예시로, 인계 설정 목록을 취득하는 API를 호출하고 있습니다. GameSession을 전달하여 로그인 중인 게임 플레이어에게 설정된 인계 설정 목록을 취득할 수 있습니다.

GS2 SDK 종료 처리

    // Finalize GS2-SDK
    {
        var future = gs2.DisconnectFuture();
        yield return future;
        if (future.Error != null) {
            throw future.Error;
        }
    }
	// Finalize GS2-SDK

    const auto FinalizeFuture = Gs2->Disconnect();
    FinalizeFuture->StartSynchronousTask();
    if (FinalizeFuture->GetTask().IsError())
    {
        UE_LOG(GameLog, Error, TEXT("%s"), ToCStr(FinalizeFuture->GetTask().Error()->String()));
        return FinalizeFuture->GetTask().Error();
    }
    # Finalize GS2 SDK
    connection.disconnect_session()

GS2와의 연결을 종료합니다.

튜토리얼을 마치셨나요?

GS2 사용법에 대해 안내하는 YouTube 채널을 확인해 보세요!

보다 실전적인 샘플도 제공하고 있습니다.

GS2를 사용하면 그 밖에 어떤 것을 구현할 수 있는지 알아봅시다

GS2를 사용한 개발 워크플로우에 대해 배워봅시다


샘플 코드 전문

계정 발급~로그인까지를 구현하는 샘플 코드