샘플 코드 전문
계정 발급~로그인까지를 구현하는 샘플 코드
여기서는 GS2 SDK를 사용하여 계정 생성과 로그인을 수행하는 최소한의 구현 방법을 설명합니다.
각 플랫폼별 전체 코드는 샘플 코드 전문을 확인해 주세요.
Unity SDK에서는 비동기 처리에 Coroutine을 사용합니다. 아래 코드 예시는 Coroutine 내부(IEnumerator를 반환하는 메서드 내부)에서 실행하는 것을 상정하고 있습니다.
// 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)먼저 4개의 변수를 정의하고 있습니다.
| 변수 이름 | 용도 | 취득처 |
|---|---|---|
| clientId | GS2에 접근하기 위한 인증 정보 | 크리덴셜(API 키) 생성에서 생성한 값 |
| clientSecret | GS2에 접근하기 위한 인증 정보 | 크리덴셜(API 키) 생성에서 생성한 값 |
| accountNamespaceName | 이용할 GS2-Account의 네임스페이스 이름 | 로그인 처리에 필요한 리소스 준비에서 생성한 값 |
| accountEncryptionKeyId | 계정 인증에 사용하는 암호 키의 GRN | 로그인 처리에 필요한 리소스 준비에서 생성한 스택의 KeyAccountAuthenticationKeyId 출력 값 |
Gs2Client.CreateFuture(UniTask 사용 시 Gs2Client.CreateAsync)로 GS2 클라이언트를 생성합니다.
clientId나 clientSecret이 올바르지 않은 경우 여기서 오류가 반환됩니다.
Godot에서는 Gs2Connection을 생성하고, 게임 엔진용 Ez 레이어를 이용하기 위해 Gs2EzDomain을 초기화합니다. 각 서비스는 ez.account나 ez.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을 전달하여 사용하게 됩니다.
// 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을 전달하여 로그인 중인 게임 플레이어에게 설정된 인계 설정 목록을 취득할 수 있습니다.
// 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를 사용하면 그 밖에 어떤 것을 구현할 수 있는지 알아봅시다
계정 발급~로그인까지를 구현하는 샘플 코드