> For the complete documentation index, see [llms.txt](/llms.txt)

# GS2-Account SDK for Game Engine API 레퍼런스

게임 엔진용 GS2-Account SDK의 모델 사양과 API 레퍼런스



## 모델

### EzAccount

게임 플레이어 계정<br>

게임 플레이어를 식별하는 ID 정보 엔티티입니다.<br>
게임 플레이어 계정은 익명 계정이며 사용자ID(UUID)와 비밀번호(무작위 32자 문자열)로 구성되므로, 게임 플레이어는 이메일 주소 등의 정보를 입력할 필요가 없습니다.<br>

발급된 게임 플레이어 계정은 디바이스의 로컬 스토리지에 저장해 두고, 다음번 로그인부터 사용합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ | UUID |  ~ 128자 | 사용자ID |
| password | string |  | ✓ |  |  ~ 128자 | 비밀번호<br>계정의 보안을 확보하기 위한 비밀번호를 저장합니다.<br>비밀번호는 최대 128자 길이를 가지며, 계정 보호에 중요한 역할을 합니다. |
| createdAt | long |  | ※ | 현재 시각 |  | 생성일시<br>UNIX 시간・밀리초<br>※ 서버가 자동으로 설정 |

**관련 메서드:**
authentication - 계정에 로그인합니다
create - 새로운 계정을 생성합니다
doTakeOver - 계정 인계를 실행합니다
doTakeOverOpenIdConnect - OpenID Connect를 사용하여 계정 인계를 실행합니다


---

### EzTakeOver

인계 정보<br>

인계 정보란 디바이스 기종 변경이나 플랫폼 간 계정 이동·공유 시에 사용하는 정보입니다.<br>
개인을 식별하는 고유한 문자열과 비밀번호로 구성되며, 올바른 조합을 입력함으로써 Account(익명 계정)를 취득할 수 있습니다.<br>

하나의 Account에 대해 여러 개의 인계 정보를 설정할 수 있습니다.<br>
여러 개의 인계 정보를 설정하려면 각각 다른 슬롯을 지정해야 합니다.<br>
슬롯에는 0~1024를 지정할 수 있으므로, 최대 1,025종류의 인계 정보를 설정할 수 있습니다.<br>

구체적인 예시로는 0에는 Sign in with Apple의 계정 정보를, 1에는 Google의 계정 정보를 저장하는 방식이 예상됩니다.<br>
어디까지나 이 인계 정보는 데이터 홀더일 뿐이며, 소셜 계정과의 인증 구조는 별도로 준비해야 합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128자 | 사용자ID |
| type | int |  | ✓ |  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |
| userIdentifier | string |  | ✓ |  |  ~ 1024자 | 인계용 사용자 ID<br>계정을 인계할 때 사용되는 개인을 식별하기 위한 고유 키입니다.<br>서로 다른 계정에서 동일한 userIdentifier를 지정한 경우, 나중에 설정한 값이 우선됩니다. |
| createdAt | long |  | ※ | 현재 시각 |  | 생성일시<br>UNIX 시간・밀리초<br>※ 서버가 자동으로 설정 |

**관련 메서드:**
addTakeOverSetting - 인계 정보를 등록합니다
addTakeOverSettingOpenIdConnect - OpenID Connect를 사용하여 인계 정보를 등록합니다
deleteTakeOverSetting - 인계 정보를 삭제합니다
get - 지정한 타입의 인계 정보를 조회합니다
listTakeOverSettings - 등록된 인계 정보 목록을 조회합니다
updateTakeOverSetting - 인계용 비밀번호를 변경합니다


---

### EzPlatformId

외부 플랫폼 계정 ID<br>

X, Instagram, Facebook 등 외부 서비스의 사용자 식별자를 보유합니다.<br>
다른 플레이어는 외부 플랫폼 계정 정보를 사용하여 GS2-Account 사용자 ID를 검색할 수 있습니다.<br>

Instagram의 팔로워나 Facebook의 친구를 게임 내 친구로 임포트할 때, GS2-Account의 계정을 특정하기 위해 사용합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| type | int |  | ✓ |  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 외부 플랫폼의 종류를 식별하는 데 사용합니다. |
| userIdentifier | string |  | ✓ |  |  ~ 1024자 | 외부 플랫폼 사용자 ID<br>외부 플랫폼에서의 사용자 고유 식별자(예: 소셜 미디어의 사용자 ID나 이메일 주소)입니다. `type`(슬롯 번호)과 조합하여 특정 플랫폼 계정을 식별하는 데 사용됩니다. |
| userId | string |  | ✓ |  |  ~ 128자 | GS2-Account 사용자 ID<br>이 외부 플랫폼 계정 ID에 연결된 GS2-Account의 사용자 ID입니다. 외부 플랫폼의 ID와 GS2-Account의 익명 계정을 대응시키는 데 사용됩니다. |
| createdAt | long |  | ※ | 현재 시각 |  | 생성일시<br>UNIX 시간・밀리초<br>※ 서버가 자동으로 설정 |

**관련 메서드:**
addPlatformIdSetting - 외부 플랫폼 계정 ID를 등록합니다
deletePlatformIdSetting - 외부 플랫폼 계정 ID를 삭제합니다
getPlatformId - 지정한 슬롯 번호의 외부 플랫폼 계정 ID를 조회합니다
listPlatformIdSettings - 등록된 외부 플랫폼 계정 ID 목록을 조회합니다


---

### EzPlatformUser

외부 플랫폼 사용자 정보<br>

외부 플랫폼에서의 사용자 정보를 보유합니다. 플랫폼 고유의 사용자 식별자와 대응하는 GS2-Account 사용자 ID의 매핑을 포함하며, 외부 플랫폼의 계정 ID를 이용한 플레이어 검색에 사용됩니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| type | int |  | ✓ |  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 외부 플랫폼의 종류를 식별하는 데 사용합니다. |
| userIdentifier | string |  | ✓ |  |  ~ 1024자 | 외부 플랫폼 사용자 ID<br>외부 플랫폼에서의 사용자 고유 식별자(예: 소셜 미디어의 사용자 ID나 이메일 주소)입니다. `type`(슬롯 번호)과 조합하여 특정 플랫폼 계정을 식별하는 데 사용됩니다. |
| userId | string |  | ✓ |  |  ~ 128자 | GS2-Account 사용자 ID<br>이 플랫폼 사용자에게 연결된 GS2-Account의 사용자 ID입니다. 외부 플랫폼의 ID와 GS2-Account의 익명 계정을 대응시키는 데 사용됩니다. |

**관련 메서드:**
findPlatformUser - 슬롯 번호와 외부 플랫폼 계정 ID로 GS2-Account 사용자 ID를 검색합니다


---

### EzBanStatus

계정 BAN 상태<br>

게임 플레이어 계정에 적용된 BAN(접근 금지) 상태에 관한 정보를 나타냅니다.<br>
이 타입은 BAN이 적용된 이유, BAN의 명칭, 그리고 BAN 해제 예정 일시 등의 상세 정보를 포함합니다.<br>
BAN 상태는 부정 행위나 이용 약관 위반 등 다양한 이유로 계정에 적용될 수 있으며, 이 타입은 그 상태를 관리하는 데 도움이 됩니다.<br>
시스템은 이 정보를 바탕으로 계정의 접근 권한을 제어하고, 필요에 따라 접근을 제한하거나 해제합니다.

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ | UUID |  ~ 36자 | BAN 상태 이름<br>BAN 상태의 고유한 이름을 보유합니다. 이름에는 임의의 값을 설정할 수 있습니다.<br>생략할 경우 UUID(Universally Unique Identifier) 형식으로 자동 생성되어 각 BAN 상태를 식별하는 데 사용됩니다.<br>이 ID를 통해 여러 개의 BAN 상태를 쉽게 추적할 수 있습니다. |
| reason | string |  | ✓ |  |  ~ 256자 | 계정이 BAN된 이유<br>계정이 BAN된 구체적인 이유를 설명합니다.<br>최대 256자 길이로, 계정 BAN의 원인을 명확히 하는 데 도움이 됩니다.<br>이 정보는 계정 관리자나 운영팀이 참조할 뿐만 아니라, 게임 클라이언트로의 응답값에도 포함됩니다. |
| releaseTimestamp | long |  | ✓ |  |  | BAN이 해제되는 일시<br>계정 BAN이 해제될 예정 일시를 나타냅니다.<br>이 일시가 지나면 계정은 자동으로 BAN 해제 상태가 되어 정상적인 접근이 가능해집니다. |

**관련 메서드:**
authentication - 계정에 로그인합니다


---

## 메서드

### authentication

계정에 로그인합니다<br>

계정 생성 시 발급받은 사용자 ID와 비밀번호를 사용하여 게임 플레이어의 로그인 처리를 수행합니다.<br>
로그인에 성공하면 `계정 인증 정보`와 `서명`이 발급됩니다.<br>
이를 [GS2-Auth::Login](../../auth/game_engine/#login)에 전달하면 GS2의 각 서비스를 이용하기 위한 `액세스 토큰`을 얻을 수 있습니다.<br>

일반적으로는 GS2-Profile::Login을 사용하여 이 처리와 [GS2-Auth::Login](../../auth/game_engine/#login)을 한 번에 실행할 수 있습니다.<br>
자세한 내용은 "시작하기"의 샘플 프로그램을 참조하십시오.<br>

`계정 인증 정보`와 `서명`의 유효 기간은 1시간입니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| userId | string |  | ✓|  |  ~ 128자 | 사용자ID |
| keyId | string |  | | "grn:gs2:{region}:{ownerId}:key:default:key:default" |  ~ 1024자 | 암호화 키 GRN |
| password | string |  | ✓|  |  ~ 128자 | 비밀번호<br>계정의 보안을 확보하기 위한 비밀번호를 저장합니다.<br>비밀번호는 최대 128자 길이를 가지며, 계정 보호에 중요한 역할을 합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzAccount](#ezaccount) | 게임 플레이어 계정|
| banStatuses | [List&lt;EzBanStatus&gt;](#ezbanstatus) | BAN 상태 리스트|
| body | string | 서명 대상 계정 인증 정보|
| signature | string | 서명|

#### Error

이 API에는 특별한 예외가 정의되어 있습니다.<br>
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.<br>
일반적인 에러의 종류와 핸들링 방법은 [여기]() 문서를 참고해 주세요.

| 타입 | 베이스 클래스 | 설명 |
| --- | --- | --- |
| PasswordIncorrectException | UnauthorizedException | 비밀번호 지정이 올바르지 않습니다 |
| BannedInfinityException | UnauthorizedException | 계정이 이용 정지되었습니다 |

#### 구현 예제




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Account(
        userId: "user-0001"
    );
    var result = await domain.AuthenticationAsync(
        password: "password-0001",
        keyId: "grn:gs2:ap-northeast-1:owner_id:key:namespace-0001:key:key-0001"
    );
    var item = await result.ModelAsync();
    var banStatuses = result.BanStatuses;
    var body = result.Body;
    var signature = result.Signature;
} catch(Gs2.Gs2Account.Exception.PasswordIncorrectException e) {
    // Incorrect password specified.
} catch(Gs2.Gs2Account.Exception.BannedInfinityException e) {
    // Account has been suspended.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Account(
        userId: "user-0001"
    );
    var future = domain.AuthenticationFuture(
        password: "password-0001",
        keyId: "grn:gs2:ap-northeast-1:owner_id:key:namespace-0001:key:key-0001"
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Account.Exception.PasswordIncorrectException)
        {
            // Incorrect password specified.
        }
        if (future.Error is Gs2.Gs2Account.Exception.BannedInfinityException)
        {
            // Account has been suspended.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;
    var banStatuses = future.Result.BanStatuses;
    var body = future.Result.Body;
    var signature = future.Result.Signature;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Account(
        "user-0001" // userId
    );
    const auto Future = Domain->Authentication(
        "password-0001", // password
        "grn:gs2:ap-northeast-1:owner_id:key:namespace-0001:key:key-0001" // keyId
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Account::Error::FPasswordIncorrectError::Class))
        {
            // Incorrect password specified.
        }
        if (e->IsChildOf(Gs2::Account::Error::FBannedInfinityError::Class))
        {
            // Account has been suspended.
        }
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();
    const auto BanStatuses = Result->BanStatuses;
    const auto Body = Result->Body;
    const auto Signature = Result->Signature;

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).account(
        "user-0001"
    )

var async_result = await domain.authentication(
    "password-0001", # password
    "grn:gs2:ap-northeast-1:owner_id:key:namespace-0001:key:key-0001" # key_id
)
if async_result.error != null:
    if async_result.error is Gs2AccountPasswordIncorrectException:
        # 비밀번호 지정이 올바르지 않습니다
        pass
    if async_result.error is Gs2AccountBannedInfinityException:
        # 계정이 이용 정지되었습니다
        pass
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### create

새로운 계정을 생성합니다<br>

게임을 처음 실행했을 때 호출하여 플레이어의 계정을 생성합니다.<br>
생성에 성공하면 사용자 ID와 비밀번호가 반환됩니다.<br>
이 두 값은 게임 데이터의 저장 영역(PlayerPrefs나 로컬 세이브 등)에 저장하여 다음 로그인에 사용하십시오.<br>

비밀번호는 자동으로 무작위 생성되므로 플레이어가 임의로 설정할 수 없습니다.<br>
플레이어가 알기 쉬운 ID(이메일 주소나 SNS 계정 등)로 계정을 인계하고자 하는 경우에는 별도로 `인계 정보`를 등록하십시오.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzAccount](#ezaccount) | 작성한 게임 플레이어 계정|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    );
    var result = await domain.CreateAsync(
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    );
    var future = domain.CreateFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto Future = Domain->Create(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    )

var async_result = await domain.create(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### addTakeOverSetting

인계 정보를 등록합니다<br>

스마트폰 기종 변경이나 앱 재설치 시에 계정을 복원할 수 있도록 하기 위한 설정입니다.<br>
`인계용 사용자 ID`(이메일 주소 등)와 `인계용 비밀번호`를 등록해 두면,<br>
해당 조합을 입력하여 다른 단말기에서 계정을 인계할 수 있습니다.<br>

하나의 계정에 대해 여러 개의 인계 방법을 설정할 수 있습니다.<br>
`슬롯 번호`를 나누어 예를 들어 슬롯 0에는 이메일 주소, 슬롯 1에는 SNS 계정 정보를 저장하는 등의 방식으로 사용할 수 있습니다.<br>
슬롯 번호는 0~1024 범위에서 지정할 수 있습니다.<br>

주의: 이 기능은 데이터 저장만을 수행합니다. SNS 계정과의 인증 연동(OAuth 등)은 게임 측에서 별도로 구현해야 합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |
| userIdentifier | string |  | ✓|  |  ~ 1024자 | 인계용 사용자 ID<br>계정을 인계할 때 사용되는 개인을 식별하기 위한 고유 키입니다.<br>서로 다른 계정에서 동일한 userIdentifier를 지정한 경우, 나중에 설정한 값이 우선됩니다. |
| password | string |  | ✓|  |  ~ 128자 | 비밀번호<br>보안을 고려하여 이 비밀번호는 기밀 정보로 취급되며, 해시 값만 저장되어 API 응답에는 값이 포함되지 않습니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzTakeOver](#eztakeover) | 작성한 인계 정보|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    var result = await domain.AddTakeOverSettingAsync(
        userIdentifier: "user-0001@gs2.io",
        password: "password-0001"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    var future = domain.AddTakeOverSettingFuture(
        userIdentifier: "user-0001@gs2.io",
        password: "password-0001"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->TakeOver(
        0, // type
    );
    const auto Future = Domain->AddTakeOverSetting(
        "user-0001@gs2.io", // userIdentifier
        "password-0001" // password
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).take_over(
        0
    )

var async_result = await domain.add_take_over_setting(
    "password-0001" # password
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### addTakeOverSettingOpenIdConnect

OpenID Connect를 사용하여 인계 정보를 등록합니다<br>

Google이나 Apple 등의 외부 로그인 서비스(OpenID Connect)의 인증 결과를 사용하여 인계 정보를 등록합니다.<br>
이 방법에서는 비밀번호 설정이 필요하지 않습니다.<br>

이 기능을 사용하려면 사전에 마스터 데이터에서 `슬롯 번호`와 인증 서비스의 대응 관계를 설정해 두어야 합니다.<br>
OpenID Connect 연동 설정이 완료된 슬롯에서는 일반적인 "사용자 ID + 비밀번호" 방식의 인계 설정을 사용할 수 없게 됩니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |
| idToken | string |  | ✓|  |  ~ 10240자 | OpenID Connect ID Token |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzTakeOver](#eztakeover) | 작성한 인계 정보|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    var result = await domain.AddTakeOverSettingOpenIdConnectAsync(
        idToken: "0123456789"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    var future = domain.AddTakeOverSettingOpenIdConnectFuture(
        idToken: "0123456789"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->TakeOver(
        0, // type
    );
    const auto Future = Domain->AddTakeOverSettingOpenIdConnect(
        "0123456789" // idToken
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).take_over(
        0
    )

var async_result = await domain.add_take_over_setting_open_id_connect(
    "0123456789" # id_token
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### deleteTakeOverSetting

인계 정보를 삭제합니다<br>

등록된 인계 정보를 삭제합니다.<br>
삭제 후에는 해당 인계 정보를 이용한 계정 복원이 불가능해집니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzTakeOver](#eztakeover) | 삭제한 인계 정보|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var result = await domain.DeleteTakeOverSettingAsync(
        type: 0
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var future = domain.DeleteTakeOverSettingFuture(
        type: 0
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto Future = Domain->DeleteTakeOverSetting(
        0 // type
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session)

var async_result = await domain.delete_take_over_setting(
    null # type
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### doTakeOver

계정 인계를 실행합니다<br>

`인계용 사용자 ID`와 `인계용 비밀번호`를 입력하여 계정을 인계합니다.<br>
입력한 정보가 일치하면 연결된 계정의 `사용자 ID`와 `비밀번호`가 반환됩니다.<br>
반환된 사용자 ID와 비밀번호를 세이브 데이터에 저장하여 다음 로그인부터 사용하십시오.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |
| userIdentifier | string |  | ✓|  |  ~ 1024자 | 인계용 사용자 ID<br>계정을 인계할 때 사용되는 개인을 식별하기 위한 고유 키입니다.<br>서로 다른 계정에서 동일한 userIdentifier를 지정한 경우, 나중에 설정한 값이 우선됩니다. |
| password | string |  | ✓|  |  ~ 128자 | 비밀번호<br>보안을 고려하여 이 비밀번호는 기밀 정보로 취급되며, 해시 값만 저장되어 API 응답에는 값이 포함되지 않습니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzAccount](#ezaccount) | 게임 플레이어 계정|

#### Error

이 API에는 특별한 예외가 정의되어 있습니다.<br>
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.<br>
일반적인 에러의 종류와 핸들링 방법은 [여기]() 문서를 참고해 주세요.

| 타입 | 베이스 클래스 | 설명 |
| --- | --- | --- |
| PasswordIncorrectException | UnauthorizedException | 비밀번호 지정이 올바르지 않습니다 |

#### 구현 예제




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    );
    var result = await domain.DoTakeOverAsync(
        type: 0,
        userIdentifier: "user-0001@gs2.io",
        password: "password-0001"
    );
    var item = await result.ModelAsync();
} catch(Gs2.Gs2Account.Exception.PasswordIncorrectException e) {
    // Incorrect password specified.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    );
    var future = domain.DoTakeOverFuture(
        type: 0,
        userIdentifier: "user-0001@gs2.io",
        password: "password-0001"
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Account.Exception.PasswordIncorrectException)
        {
            // Incorrect password specified.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto Future = Domain->DoTakeOver(
        0, // type
        "user-0001@gs2.io", // userIdentifier
        "password-0001" // password
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Account::Error::FPasswordIncorrectError::Class))
        {
            // Incorrect password specified.
        }
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    )

var async_result = await domain.do_take_over(
    null, # type
    "user-0001@gs2.io", # user_identifier
    "password-0001" # password
)
if async_result.error != null:
    if async_result.error is Gs2AccountPasswordIncorrectException:
        # 비밀번호 지정이 올바르지 않습니다
        pass
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### doTakeOverOpenIdConnect

OpenID Connect를 사용하여 계정 인계를 실행합니다<br>

Google이나 Apple 등의 로그인 서비스(OpenID Connect)의 인증 정보를 사용하여 계정을 인계합니다.<br>
인증 정보에 연결된 계정의 `사용자 ID`와 `비밀번호`가 반환됩니다.<br>
반환된 사용자 ID와 비밀번호를 세이브 데이터에 저장하여 다음 로그인부터 사용하십시오.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |
| idToken | string |  | ✓|  |  ~ 10240자 | OpenID Connect ID Token |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzAccount](#ezaccount) | 게임 플레이어 계정|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    );
    var result = await domain.DoTakeOverOpenIdConnectAsync(
        type: 0,
        idToken: "0123456789"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    );
    var future = domain.DoTakeOverOpenIdConnectFuture(
        type: 0,
        idToken: "0123456789"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto Future = Domain->DoTakeOverOpenIdConnect(
        0, // type
        "0123456789" // idToken
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    )

var async_result = await domain.do_take_over_open_id_connect(
    null, # type
    "0123456789" # id_token
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### get

지정한 타입의 인계 정보를 조회합니다<br>

슬롯 번호(타입)를 지정하여 등록된 인계 정보를 1건 조회합니다.<br>
어떤 인계 방법이 설정되어 있는지 확인할 때 사용합니다.<br>
보안을 위해 인계용 비밀번호는 응답에 포함되지 않습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzTakeOver](#eztakeover) | 인계 정보|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->TakeOver(
        0, // type
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).take_over(
        0
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->TakeOver(
        0, // type
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Account::Model::FTakeOver> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).take_over(
        0
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### getAuthorizationUrl

OpenID Connect 인증 URL을 조회합니다<br>

Google이나 Apple 등의 외부 로그인 서비스의 인증 페이지로 리다이렉트하기 위한 URL을 조회합니다.<br>
이 URL로 플레이어를 안내하면 OpenID Connect를 사용한 인계 정보 등록이나 계정 인계 실행을 시작할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| authorizationUrl | string | 인증URL|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    );
    var result = await domain.GetAuthorizationUrlAsync(
        type: 0
    );
    var authorizationUrl = result.AuthorizationUrl;

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    );
    var future = domain.GetAuthorizationUrlFuture(
        type: 0
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var authorizationUrl = future.Result.AuthorizationUrl;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto Future = Domain->GetAuthorizationUrl(
        0 // type
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();
    const auto AuthorizationUrl = Result->AuthorizationUrl;

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).account(
        "userId-0001"
    ).take_over(
        0
    )

var async_result = await domain.get_authorization_url(
    null # type
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### listTakeOverSettings

등록된 인계 정보 목록을 조회합니다<br>

이 플레이어에게 설정되어 있는 인계 정보 목록을 조회합니다.<br>
보안을 위해 인계용 비밀번호는 응답에 포함되지 않습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzTakeOver&gt;](#eztakeover) | 인계 정보의 리스트|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.TakeOversAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.TakeOvers(
    );
    List<EzTakeOver> items = new List<EzTakeOver>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->TakeOvers(
    );
    TArray<Gs2::UE5::Account::Model::FEzTakeOverPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeTakeOvers(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeTakeOvers(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribeTakeOvers(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribeTakeOvers(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribeTakeOvers(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribeTakeOvers(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### updateTakeOverSetting

인계용 비밀번호를 변경합니다<br>

인계 정보의 비밀번호를 변경합니다.<br>
변경하려면 현재 설정되어 있는 기존 비밀번호를 입력해야 합니다.<br>

주의: 이 API를 사용하여 안전한 비밀번호 변경을 구현하려는 경우에는,<br>
`인계 정보 삭제` API에 대한 접근 권한을 비활성화하십시오.<br>
삭제 시에는 비밀번호 인증이 필요하지 않으므로, 삭제 후 재생성하면 사실상 비밀번호를 변경할 수 있게 되기 때문입니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 서로 다른 인계 정보를 구분합니다. |
| oldPassword | string |  | ✓|  |  ~ 128자 | 이전 비밀번호 |
| password | string |  | ✓|  |  ~ 128자 | 비밀번호<br>보안을 고려하여 이 비밀번호는 기밀 정보로 취급되며, 해시 값만 저장되어 API 응답에는 값이 포함되지 않습니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzTakeOver](#eztakeover) | 갱신한 인계 정보|

#### Error

이 API에는 특별한 예외가 정의되어 있습니다.<br>
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.<br>
일반적인 에러의 종류와 핸들링 방법은 [여기]() 문서를 참고해 주세요.

| 타입 | 베이스 클래스 | 설명 |
| --- | --- | --- |
| PasswordIncorrectException | UnauthorizedException | 비밀번호 지정이 올바르지 않습니다 |

#### 구현 예제




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    var result = await domain.UpdateTakeOverSettingAsync(
        oldPassword: "password-0001",
        password: "password-1001"
    );
    var item = await result.ModelAsync();
} catch(Gs2.Gs2Account.Exception.PasswordIncorrectException e) {
    // Incorrect password specified.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).TakeOver(
        type: 0,
    );
    var future = domain.UpdateTakeOverSettingFuture(
        oldPassword: "password-0001",
        password: "password-1001"
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Account.Exception.PasswordIncorrectException)
        {
            // Incorrect password specified.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->TakeOver(
        0, // type
    );
    const auto Future = Domain->UpdateTakeOverSetting(
        "password-0001", // oldPassword
        "password-1001" // password
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Account::Error::FPasswordIncorrectError::Class))
        {
            // Incorrect password specified.
        }
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).take_over(
        0
    )

var async_result = await domain.update_take_over_setting(
    "password-0001", # old_password
    "password-1001" # password
)
if async_result.error != null:
    if async_result.error is Gs2AccountPasswordIncorrectException:
        # 비밀번호 지정이 올바르지 않습니다
        pass
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### addPlatformIdSetting

외부 플랫폼 계정 ID를 등록합니다<br>

X(구 Twitter), Instagram, Facebook 등의 외부 서비스 사용자 ID를 GS2 게임 플레이어 계정에 연결하여 저장합니다.<br>

`type`에는 0~1024 범위의 숫자를 지정하여 플랫폼 종류를 구분합니다.<br>
`userIdentifier`에는 각 플랫폼의 사용자 ID를 지정합니다.<br>

다른 플레이어는 type과 userIdentifier를 지정하여 해당 플레이어를 검색할 수 있습니다.<br>
예를 들어 SNS 친구를 게임 내 친구로 추가하는 기능을 구현할 때 사용할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession<br>이 외부 플랫폼 계정 ID에 연결된 GS2-Account의 사용자 ID를 포함하는 GameSession 객체입니다. 외부 플랫폼의 ID와 GS2-Account의 익명 계정을 대응시키기 위해 사용됩니다. |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 외부 플랫폼의 종류를 식별하는 데 사용합니다. |
| userIdentifier | string |  | ✓|  |  ~ 1024자 | 외부 플랫폼 사용자 ID<br>외부 플랫폼에서의 사용자 고유 식별자(예: 소셜 미디어의 사용자 ID나 이메일 주소)입니다. `type`(슬롯 번호)과 조합하여 특정 플랫폼 계정을 식별하는 데 사용됩니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPlatformId](#ezplatformid) | 생성한 외부 플랫폼의 계정ID|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    var result = await domain.AddPlatformIdSettingAsync(
        userIdentifier: "user-0001@gs2.io"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    var future = domain.AddPlatformIdSettingFuture(
        userIdentifier: "user-0001@gs2.io"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PlatformId(
        0, // type
    );
    const auto Future = Domain->AddPlatformIdSetting(
        "user-0001@gs2.io" // userIdentifier
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).platform_id(
        0
    )

var async_result = await domain.add_platform_id_setting(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### deletePlatformIdSetting

외부 플랫폼 계정 ID를 삭제합니다<br>

등록된 외부 플랫폼 계정 ID를 삭제합니다.<br>
삭제 후에는 해당 외부 플랫폼 계정 ID를 이용한 플레이어 검색이 불가능해집니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession<br>이 외부 플랫폼 계정 ID에 연결된 GS2-Account의 사용자 ID를 포함하는 GameSession 객체입니다. 외부 플랫폼의 ID와 GS2-Account의 익명 계정을 대응시키기 위해 사용됩니다. |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 외부 플랫폼의 종류를 식별하는 데 사용합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPlatformId](#ezplatformid) | 삭제한 외부 플랫폼의 계정ID|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    var result = await domain.DeletePlatformIdSettingAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    var future = domain.DeletePlatformIdSettingFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PlatformId(
        0, // type
    );
    const auto Future = Domain->DeletePlatformIdSetting(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).platform_id(
        0
    )

var async_result = await domain.delete_platform_id_setting(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### findPlatformUser

슬롯 번호와 외부 플랫폼 계정 ID로 GS2-Account 사용자 ID를 검색합니다<br>

`type`(슬롯 번호)과 `userIdentifier`(외부 플랫폼의 사용자 ID)를 지정하여 해당 외부 플랫폼 계정 ID에 연결된 게임 플레이어를 검색합니다.<br>
예를 들어 SNS 친구 목록에서 게임 내 플레이어를 찾는 데 이용할 수 있습니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession<br>이 외부 플랫폼 계정 ID에 연결된 GS2-Account의 사용자 ID를 포함하는 GameSession 객체입니다. 외부 플랫폼의 ID와 GS2-Account의 익명 계정을 대응시키기 위해 사용됩니다. |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 외부 플랫폼의 종류를 식별하는 데 사용합니다. |
| userIdentifier | string |  | ✓|  |  ~ 1024자 | 외부 플랫폼 사용자 ID<br>외부 플랫폼에서의 사용자 고유 식별자(예: 소셜 미디어의 사용자 ID나 이메일 주소)입니다. `type`(슬롯 번호)과 조합하여 특정 플랫폼 계정을 식별하는 데 사용됩니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPlatformUser](#ezplatformuser) | 외부 플랫폼의 사용자 정보|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    var result = await domain.FindPlatformUserAsync(
        userIdentifier: "user-0001@gs2.io"
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    var future = domain.FindPlatformUserFuture(
        userIdentifier: "user-0001@gs2.io"
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PlatformId(
        0, // type
    );
    const auto Future = Domain->FindPlatformUser(
        "user-0001@gs2.io" // userIdentifier
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // 변경된 값 / 결과 값을 취득
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).platform_id(
        0
    )

var async_result = await domain.find_platform_user(
)
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


---

### getPlatformId

지정한 슬롯 번호의 외부 플랫폼 계정 ID를 조회합니다<br>

`type`(슬롯 번호)을 지정하여 등록된 외부 서비스 계정을 1건 조회합니다.<br>
특정 플랫폼에 어떤 사용자 ID가 연결되어 있는지 확인할 때 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession<br>이 외부 플랫폼 계정 ID에 연결된 GS2-Account의 사용자 ID를 포함하는 GameSession 객체입니다. 외부 플랫폼의 ID와 GS2-Account의 익명 계정을 대응시키기 위해 사용됩니다. |
| type | int |  | ✓|  | 0 ~ 1024 | 슬롯 번호<br>0에서 1024까지의 범위로 지정되며, 외부 플랫폼의 종류를 식별하는 데 사용합니다. |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| item | [EzPlatformId](#ezplatformid) | 외부 플랫폼의 계정ID|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PlatformId(
        0, // type
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).platform_id(
        0
    )

var async_result = await domain.model()
if async_result.error != null:
    push_error(str(async_result.error))
    return

var result = async_result.result

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).PlatformId(
        type: 0,
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.Subscribe(
        value => {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->PlatformId(
        0, // type
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Account::Model::FPlatformId> value) {
            // 값이 변화했을 때 호출됨
            // value에는 변경 후의 값이 전달됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->Unsubscribe(CallbackId);

```

**Godot**
```gdscript

var domain = ez.account.namespace_(
        "namespace-0001"
    ).me(game_session).platform_id(
        0
    )

# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
    # 값이 변화했을 때 호출됨
    # value에는 변경 후의 값이 전달됩니다
    pass
)

# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---

### listPlatformIdSettings

등록된 외부 플랫폼 계정 ID 목록을 조회합니다<br>

이 플레이어에게 연결된 외부 서비스 ID 정보 목록을 조회합니다.<br>
어떤 플랫폼의 ID가 등록되어 있는지 확인할 때 사용합니다.

#### Request

|  | 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128자 | 네임스페이스 이름<br>네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
| limit | int |  | | 30 | 1 ~ 1000 | 취득할 데이터 건수 |

#### Result

|  | 타입 | 설명 |
| --- | --- | --- |
| items | [List&lt;EzPlatformId&gt;](#ezplatformid) | 외부 플랫폼 계정ID 목록|
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰|

#### 구현 예제




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.PlatformIdsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.PlatformIds(
    );
    List<EzPlatformId> items = new List<EzPlatformId>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->PlatformIds(
    );
    TArray<Gs2::UE5::Account::Model::FEzPlatformIdPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 값 변경 이벤트 핸들링




**Unity (UniTask)**
```csharp
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribePlatformIds(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribePlatformIds(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Account.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // 이벤트 핸들링 시작
    var callbackId = domain.SubscribePlatformIds(
        () => {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    domain.UnsubscribePlatformIds(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Account->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    
    // 이벤트 핸들링 시작
    const auto CallbackId = Domain->SubscribePlatformIds(
        []() {
            // 리스트의 요소가 변화했을 때 호출됨
        }
    );

    // 이벤트 핸들링 정지
    Domain->UnsubscribePlatformIds(CallbackId);

```


**⚠️ Warning**

이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.

로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.

따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.

---



