GS2-Exchange SDK for Game Engine API 레퍼런스
모델
EzAwait
교환 대기
보상을 받기 전에 실시간의 경과가 필요한 교환의 실행 상태를 나타냅니다. 플레이어가 await 타이밍 타입의 교환을 시작했을 때 생성되며, 보상을 사용할 수 있게 될 때까지의 대기 기간을 추적합니다. 대기 시간을 단축하거나 없애는 스킵 기능을 지원하며, 보상 취득 시의 기본 설정값을 저장합니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| userId | string | ✓ | ~ 128자 | 사용자ID | ||
| rateName | string | ✓ | ~ 128자 | 교환 레이트 모델 이름 교환 레이트 모델 종류 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| name | string | ✓ | UUID | ~ 36자 | 교환 대기의 이름 교환 대기의 고유한 이름을 보유합니다. 이름은 UUID(Universally Unique Identifier) 형식으로 자동 생성되며, 교환 대기를 식별하는 데 사용됩니다. | |
| skipSeconds | int | 0 | 0 ~ 2147483646 | 스킵 초수 대기 시간에서 차감하는 초수입니다. 스킵 초수가 적용되면 acquirableAt 타임스탬프가 이만큼 앞당겨집니다. 플레이어가 리소스를 지불하여 대기 시간을 단축하는 구조를 구현하기 위해 사용됩니다. | ||
| config | List<EzConfig> | [] | 0 ~ 32 items | 보상 취득 시 적용하는 기본 설정값 대기 완료 시 보상이 배포될 때 트랜잭션의 플레이스홀더 변수로 사용되는 키와 값의 쌍입니다. 이 값들은 교환 시작 시 설정되며, 획득 액션의 트랜잭션 파라미터에 적용됩니다. | ||
| exchangedAt | long | 교환 시간 교환이 시작되어 대기가 생성된 타임스탬프입니다. 보상이 사용 가능해지는 시각을 계산하기 위한 기준 시각으로 사용됩니다(acquirableAt = exchangedAt + lockTime - skipSeconds). | ||||
| acquirableAt | long | 보상을 받을 수 있게 되는 시간 대기 기간이 만료되어 보상을 받을 수 있게 되는 타임스탬프입니다. exchangedAt + lockTime - skipSeconds로 계산됩니다. 현재 시각이 이 타임스탬프를 지나면 플레이어는 취득 API를 호출할 수 있게 됩니다. |
EzRateModel
교환 레이트 모델
교환 레이트 모델은 리소스와 리소스를 교환할 때 사용하는 레이트를 정의하는 엔티티입니다.
즉시 교환할 수 있는 레이트뿐만 아니라, 현실 시간으로 일정 시간이 경과한 후에 교환할 수 있는 레이트도 설정할 수 있습니다.
현실 시간의 경과가 필요한 교환 레이트에는 즉시 교환을 실행하는 데 필요한 리소스를 추가로 정의할 수 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 교환 레이트 모델 이름 교환 레이트 모델 종류 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||||||||
| metadata | string | ~ 2048자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||||||||
| timingType | 문자열 열거형 enum { “immediate”, “await” } | “immediate” | 교환 종류 교환 실행 후 보상이 언제 전달되는지를 결정합니다. immediate는 교환 실행 시 즉시 보상을 전달합니다. await는 보상을 받기 전에 실시간의 경과가 필요하며, 대기 기간(예: 제작 시간)을 둡니다.
| |||||||||
| lockTime | int | {timingType} == “await” | ✓※ | 0 ~ 538214400 | 교환 실행부터 실제로 보상을 받을 수 있게 될 때까지의 대기 시간(분) timingType이 await인 경우에만 적용됩니다. 교환이 시작된 후 플레이어가 보상을 받을 수 있게 되기까지 경과해야 하는 실시간 분수를 지정합니다. 대기 시간은 스킵 기능을 사용하여 단축할 수 있습니다.※ timingType이(가) “await” 이면 필수 | |||||||
| verifyActions | List<EzVerifyAction> | [] | 0 ~ 10 items | 검증 액션 리스트 교환이 실행되기 전에 모두 통과해야 하는 사전 조건 체크입니다. 검증 액션 중 하나라도 실패하면, 리소스를 소비하지 않고 교환이 중단됩니다. 레벨 요건이나 인벤토리 용량 등의 조건을 강제하기 위해 사용됩니다. | ||||||||
| consumeActions | List<EzConsumeAction> | [] | 0 ~ 10 items | 소비 액션 리스트 이 교환을 실행하기 위해 플레이어가 지불해야 하는 리소스(코스트)를 정의합니다. 여러 개의 소비 액션을 지정할 수 있어, 골드와 아이템을 모두 필요로 하는 것과 같은 복잡한 교환 코스트를 구현할 수 있습니다. 이러한 액션은 분산 트랜잭션 내의 소비 액션으로 실행됩니다. | ||||||||
| acquireActions | List<EzAcquireAction> | [] | 0 ~ 100 items | 획득 액션 리스트 교환 완료 시 플레이어가 받는 리소스(보상)를 정의합니다. 여러 개의 획득 액션을 지정하여 다양한 리소스 타입을 동시에 지급할 수 있습니다. 이러한 액션은 분산 트랜잭션 내의 획득 액션으로 실행됩니다. |
EzIncrementalRateModel
코스트 상승형 교환 레이트 모델
일반적인 교환 레이트는 항상 일정한 레이트로 교환을 제공합니다.
상승형 교환 레이트에서는 교환 횟수에 따라 코스트가 상승하는 레이트를 정의할 수 있습니다.
예를 들어, 첫 번째 교환에서는 1:1로 교환할 수 있지만, 두 번째 교환에서는 2:1로 교환하게 되는 것과 같은 레이트를 정의할 수 있습니다.
이러한 레이트를 정의함으로써 플레이어가 게임을 진행함에 따라 얻을 수 있는 리소스의 가치를 높일 수 있습니다.
교환 횟수는 현실 시간의 경과에 따라 리셋할 수 있습니다.
이 기능을 이용하면 매일 또는 매주 교환에 필요한 코스트를 리셋할 수 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 코스트 상승형 교환 레이트 모델의 이름 코스트 상승형 교환 레이트 모델 종류 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||||||||||
| metadata | string | ~ 2048자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||||||||||
| calculateType | 문자열 열거형 enum { “linear”, “power”, “gs2_script” } | ✓ | 코스트 상승량 계산 방식 교환 횟수에 따라 코스트가 어떻게 상승하는지를 결정합니다. linear는 코스트를 baseValue +(coefficientValue × 교환 횟수)로 계산합니다. power는 코스트를 coefficientValue ×(교환 횟수 + 1)^2로 계산합니다. gs2_script는 임의의 로직을 위해 커스텀 GS2-Script에 계산을 위임합니다.
| |||||||||||
| consumeAction | EzConsumeAction | ✓ | 소비 액션 (수량/값은 자동으로 덮어써집니다) 교환 비용으로 소비되는 리소스의 종류를 정의합니다. 실제 수량은 교환 횟수와 계산 방식(선형, 거듭제곱, 스크립트)에 기반하여 동적으로 계산됩니다. 액션 종류와 대상 리소스만 지정하면 되며, 수량 필드는 자동으로 덮어써집니다. | |||||||||||
| baseValue | long | {calculateType} == “linear” | ✓※ | 0 ~ 9223372036854775805 | 베이스 값linear 계산 방식을 사용하는 경우 첫 교환 시의 기본 코스트입니다. 합계 코스트는 baseValue +(coefficientValue × 교환 횟수)로 계산됩니다.※ calculateType이(가) “linear” 이면 필수 | |||||||||
| coefficientValue | long | {calculateType} in [“linear”, “power”] | ✓※ | 0 ~ 9223372036854775805 | 계수 교환 횟수에 따라 코스트가 얼마나 빠르게 상승하는지를 제어하는 승수입니다. linear 모드에서는 각 교환마다 이 값이 코스트에 더해집니다. power 모드에서는 코스트가 coefficientValue ×(교환 횟수 + 1)^2로 계산됩니다.※ calculateType이(가) “linear”,“power"이면 필수 | |||||||||
| exchangeCountId | string | ✓ | ~ 1024자 | 교환 실행 횟수를 관리하는 GS2-Limit의 횟수 제한 모델 GRN
각 사용자가 이 코스트 상승형 교환을 몇 번 실행했는지 추적하는 GS2-Limit의 횟수 제한 모델을 참조합니다. 카운트는 상승하는 코스트 계산에 사용되며, GS2-Limit의 리셋 타이밍을 사용하여 정기적으로(예: 매일 또는 매주) 리셋할 수 있습니다. | ||||||||||
| maximumExchangeCount | int | 2147483646 | 0 ~ 2147483646 | 교환 횟수 상한 사용자가 이 코스트 상승형 교환을 실행할 수 있는 최대 횟수입니다. 교환 횟수가 이 상한에 도달하면, GS2-Limit에 의한 카운트 리셋까지 이후의 교환이 거부됩니다. | ||||||||||
| acquireActions | List<EzAcquireAction> | [] | 0 ~ 100 items | 획득 액션 리스트 코스트 상승형 교환 완료 시 플레이어가 받는 리소스(보상)를 정의합니다. 보상은 교환 횟수와 관계없이 일정하며, 코스트만 교환마다 증가합니다. |
EzConfig
컨피그 설정
트랜잭션의 변수에 적용하는 설정 값
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| key | string | ✓ | ~ 64자 | 이름 | ||
| value | string | ~ 51200자 | 값 |
EzAcquireAction
입수 액션
EzConsumeAction
소비 액션
EzVerifyAction
검증 액션
EzVerifyActionResult
검증 액션 실행 결과
EzConsumeActionResult
소비 액션 실행 결과
EzAcquireActionResult
획득 액션 실행 결과
EzTransactionResult
트랜잭션 실행 결과
서버 사이드에서 트랜잭션 자동 실행 기능을 이용하여 실행된 트랜잭션의 실행 결과
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| transactionId | string | ✓ | 36 ~ 36자 | 트랜잭션 ID | ||
| verifyResults | List<EzVerifyActionResult> | 0 ~ 10 items | 검증 액션의 실행 결과 목록 | |||
| consumeResults | List<EzConsumeActionResult> | [] | 0 ~ 10 items | 소비 액션의 실행 결과 목록 | ||
| acquireResults | List<EzAcquireActionResult> | [] | 0 ~ 100 items | 획득 액션 실행 결과 리스트 |
메서드
acquire
완료된 시간제 교환의 보상 수령
필요한 대기 시간이 경과한 시간제 교환의 보상을 수령합니다.
대기 시간이 아직 경과하지 않은 경우, 이 호출은 실패합니다. 사전에 GetAwait로 남은 시간을 확인하세요.
수령하면 대기 레코드는 소비되고, 플레이어는 레이트 모델에서 정의된 보상을 받습니다.
예를 들어 “철검” 제작으로 3시간을 기다린 후 이를 호출하면 플레이어에게 검이 지급됩니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| awaitName | string | ✓ | UUID | ~ 36자 | 교환 대기의 이름 교환 대기의 고유한 이름을 보유합니다. 이름은 UUID(Universally Unique Identifier) 형식으로 자동 생성되며, 교환 대기를 식별하는 데 사용됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzAwait | 교환 대기 |
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 보상 획득 처리 실행에 사용하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Await(
awaitName: "await-0001"
);
var result = await domain.AcquireAsync(
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Await(
awaitName: "await-0001"
);
var future = domain.AcquireFuture(
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Await(
"await-0001" // awaitName
);
const auto Future = Domain->Acquire(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.exchange.namespace_(
"namespace-0001"
).me(game_session).await_(
"await-0001"
)
var async_result = await domain.acquire(
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultdeleteAwait
대기 중인 시간제 교환 취소
대기 중인 교환 대기 레코드를 삭제하여 교환을 취소합니다.
보상은 지급되지 않으며, 교환 시작 시 지불한 리소스도 반환되지 않습니다.
플레이어가 제작 중이거나 건설 중인 주문을 취소하고 싶을 때 사용합니다. 비용이 돌아오지 않으므로 확인 대화상자를 표시하는 것을 권장합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| awaitName | string | ✓ | UUID | ~ 36자 | 교환 대기의 이름 교환 대기의 고유한 이름을 보유합니다. 이름은 UUID(Universally Unique Identifier) 형식으로 자동 생성되며, 교환 대기를 식별하는 데 사용됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzAwait | 교환 대기 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Await(
awaitName: "await-0001"
);
var result = await domain.DeleteAwaitAsync(
); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Await(
awaitName: "await-0001"
);
var future = domain.DeleteAwaitFuture(
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
} const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Await(
"await-0001" // awaitName
);
const auto Future = Domain->DeleteAwait(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
const auto Result = Future->GetTask().Result();var domain = ez.exchange.namespace_(
"namespace-0001"
).me(game_session).await_(
"await-0001"
)
var async_result = await domain.delete_await(
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultgetAwait
특정 대기 중인 시간제 교환 조회
특정 교환 대기 레코드의 상세 정보를 조회합니다.
조회할 수 있는 정보에는 교환 타입, 요청한 수량, 시작 일시, 남은 대기 시간이 포함됩니다.
특정 대기 중인 교환의 상세 화면을 표시할 때 사용합니다. 예를 들어 “철검 제작 중… 남은 시간 2시간 30분"과 같은 표시에 편리합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| awaitName | string | ✓ | UUID | ~ 36자 | 교환 대기의 이름 교환 대기의 고유한 이름을 보유합니다. 이름은 UUID(Universally Unique Identifier) 형식으로 자동 생성되며, 교환 대기를 식별하는 데 사용됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzAwait | 교환 대기 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Await(
awaitName: "await-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Await(
awaitName: "await-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Await(
"await-0001" // awaitName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.exchange.namespace_(
"namespace-0001"
).me(game_session).await_(
"await-0001"
)
var async_result = await domain.model()
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result값 변경 이벤트 핸들링
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Await(
awaitName: "await-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Await(
awaitName: "await-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Await(
"await-0001" // awaitName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Exchange::Model::FAwait> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.exchange.namespace_(
"namespace-0001"
).me(game_session).await_(
"await-0001"
)
# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
# 값이 변화했을 때 호출됨
# value에는 변경 후의 값이 전달됩니다
pass
)
# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listAwaits
대기 중인 시간제 교환 목록 조회
플레이어의 교환 대기 레코드를 조회합니다. 보상을 받기 전에 대기가 필요한 교환(제작이나 건설과 같은 구조)의 목록입니다.
레이트 이름을 지정하여 특정 교환 타입의 대기만 표시할 수도 있습니다.
“제작 중인 아이템"이나 “진행 중” 목록을 구성하는 데 사용합니다. 플레이어가 무엇을 기다리고 있고 앞으로 얼마나 걸리는지를 표시할 수 있습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| rateName | string | ~ 128자 | 교환 레이트 모델 이름 교환 레이트 모델 종류 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | |||
| gameSession | GameSession | ✓ | GameSession | |||
| pageToken | string | ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzAwait> | 교환 대기 목록 |
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.AwaitsAsync(
rateName: "material_n_to_r"
).ToListAsync(); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Awaits(
rateName: "material_n_to_r"
);
List<EzAwait> items = new List<EzAwait>();
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;
}
} const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->Awaits(
"material_n_to_r" // rateName
);
TArray<Gs2::UE5::Exchange::Model::FEzAwaitPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeAwaits(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeAwaits(callbackId); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeAwaits(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeAwaits(callbackId); const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeAwaits(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeAwaits(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
getRateModel
이름을 지정하여 교환 레이트 모델 조회
이름을 지정하여 교환 레이트 모델을 1건 조회합니다.
조회할 수 있는 정보에는 플레이어가 지불하는 것, 받는 것, 즉시 교환인지 대기가 필요한지가 포함됩니다.
특정 교환의 상세 정보를 표시할 때 사용합니다. 예를 들어 상점의 아이템 상세 화면에서 “비용: 골드 100 → 보상: 회복 포션 1개"와 같이 표시하는 데 편리합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| rateName | string | ✓ | ~ 128자 | 교환 레이트 모델 이름 교환 레이트 모델 종류 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzRateModel | 교환 레이트 모델 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).RateModel(
rateName: "character-level"
);
var item = await domain.ModelAsync(); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).RateModel(
rateName: "character-level"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->RateModel(
"character-level" // rateName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.exchange.namespace_(
"namespace-0001"
).rate_model(
"character-level"
)
var async_result = await domain.model()
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result값 변경 이벤트 핸들링
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).RateModel(
rateName: "character-level"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).RateModel(
rateName: "character-level"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->RateModel(
"character-level" // rateName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Exchange::Model::FRateModel> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.exchange.namespace_(
"namespace-0001"
).rate_model(
"character-level"
)
# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
# 값이 변화했을 때 호출됨
# value에는 변경 후의 값이 전달됩니다
pass
)
# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listRateModels
교환 레이트 모델 목록 조회
이 네임스페이스에 등록되어 있는 모든 교환 레이트 모델을 조회합니다.
레이트 모델은 교환 레시피를 정의합니다. 플레이어가 무엇을 지불하고(예: 골드 100개), 무엇을 받을지(예: 회복 포션 1개)를 설정합니다.
타이밍에는 두 가지 종류가 있습니다. “즉시” 교환은 곧바로 완료되고, “대기” 교환은 플레이어가 일정 시간을 기다린 후 보상을 받습니다(제작과 같은 구조).
상점이나 제작 UI를 구성할 때, 플레이어에게 이용 가능한 교환 옵션을 표시하는 데 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzRateModel> | 교환 레이트 모델 목록 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
);
var items = await domain.RateModelsAsync(
).ToListAsync(); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
);
var it = domain.RateModels(
);
List<EzRateModel> items = new List<EzRateModel>();
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;
}
} const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
);
const auto It = Domain->RateModels(
);
TArray<Gs2::UE5::Exchange::Model::FEzRateModelPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeRateModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeRateModels(callbackId); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeRateModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeRateModels(callbackId); const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeRateModels(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeRateModels(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
getIncrementalRateModel
이름을 지정하여 코스트 상승형 교환 레이트 모델 조회
이름을 지정하여 코스트 상승형 교환 레이트 모델을 1건 조회합니다.
조회할 수 있는 정보에는 코스트 계산 방법(선형 계산식 또는 커스텀 스크립트), 기본 코스트, 교환마다의 코스트 증가량, 최대 교환 횟수, 플레이어가 받는 것이 포함됩니다.
특정 코스트 상승형 교환의 상세 정보를 표시할 때 사용합니다. 예를 들어 상점 화면에서 “스태미나 회복: 젬 30개(오늘 3회차, 최대 5회)“와 같이 표시하는 데 편리합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| rateName | string | ✓ | ~ 128자 | 코스트 상승형 교환 레이트 모델의 이름 코스트 상승형 교환 레이트 모델 종류 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzIncrementalRateModel | 코스트 상승형 교환 레이트 모델 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).IncrementalRateModel(
rateName: "character-level"
);
var item = await domain.ModelAsync(); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).IncrementalRateModel(
rateName: "character-level"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->IncrementalRateModel(
"character-level" // rateName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.exchange.namespace_(
"namespace-0001"
).incremental_rate_model(
"character-level"
)
var async_result = await domain.model()
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result값 변경 이벤트 핸들링
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).IncrementalRateModel(
rateName: "character-level"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).IncrementalRateModel(
rateName: "character-level"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->IncrementalRateModel(
"character-level" // rateName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Exchange::Model::FIncrementalRateModel> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.exchange.namespace_(
"namespace-0001"
).incremental_rate_model(
"character-level"
)
# 이벤트 핸들링 시작
var callback_id = domain.subscribe_model(func(value):
# 값이 변화했을 때 호출됨
# value에는 변경 후의 값이 전달됩니다
pass
)
# 이벤트 핸들링 정지
domain.unsubscribe_model(callback_id)이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listIncrementalRateModels
코스트 상승형 교환 레이트 모델 목록 조회
이 네임스페이스에 등록되어 있는 모든 코스트 상승형 교환 레이트 모델을 조회합니다.
코스트 상승형 모델은 플레이어가 사용할 때마다 가격이 오르는 교환을 정의합니다. 예를 들어 스태미나 회복 1회차는 젬 10개, 2회차는 20개, 3회차는 30개…와 같은 구조입니다.
코스트 상승은 단순한 선형 계산식(기본값 + 계수 × 횟수) 또는 커스텀 스크립트로 계산할 수 있습니다.
이용 가능한 코스트 상승형 교환과 현재 코스트를 표시하는 UI를 구성하는 데 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzIncrementalRateModel> | 코스트 상승형 교환 레이트 모델 목록 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
);
var items = await domain.IncrementalRateModelsAsync(
).ToListAsync(); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
);
var it = domain.IncrementalRateModels(
);
List<EzIncrementalRateModel> items = new List<EzIncrementalRateModel>();
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;
}
} const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
);
const auto It = Domain->IncrementalRateModels(
);
TArray<Gs2::UE5::Exchange::Model::FEzIncrementalRateModelPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeIncrementalRateModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeIncrementalRateModels(callbackId); var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeIncrementalRateModels(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeIncrementalRateModels(callbackId); const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeIncrementalRateModels(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeIncrementalRateModels(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
exchange
교환 실행
지정한 교환 레이트 모델을 기반으로 리소스를 교환합니다.
플레이어는 레이트 모델에서 정의된 비용을 지불하고 보상을 받습니다. 예를 들어 골드 100개를 회복 포션 1개와 교환하는 처리입니다.
횟수를 지정하여 같은 교환을 한 번에 여러 번 실행할 수도 있습니다(예: 포션 5개를 골드 500개로 구매).
레이트 모델이 “대기” 타이밍인 경우, 즉시 완료되지 않고 시간 대기형 교환이 시작됩니다(보상 수령은 Await 계열 API를 참조하세요).
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| rateName | string | ✓ | ~ 128자 | 교환 레이트 모델 이름 교환 레이트 모델 종류 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| count | int | ✓ | 1 ~ 1073741821 | 교환 횟수 | ||
| config | List<EzConfig> | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzRateModel | 교환 레이트 모델 |
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 교환 처리 실행에 사용하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Exchange(
);
var result = await domain.ExchangeAsync(
rateName: "rate-0001",
count: 1,
config: null
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Exchange(
);
var future = domain.ExchangeFuture(
rateName: "rate-0001",
count: 1,
config: null
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Exchange(
);
const auto Future = Domain->Exchange(
"rate-0001", // rateName
1 // count
// config
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.exchange.namespace_(
"namespace-0001"
).me(game_session).exchange(
)
var async_result = await domain.exchange(
"rate-0001", # rate_name
1, # count
null # config
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultincrementalExchange
코스트 상승형 교환 실행
사용할 때마다 코스트가 오르는 레이트 모델을 사용하여 리소스를 교환합니다.
코스트는 플레이어가 지금까지 몇 번 교환했는지를 기반으로 자동 계산됩니다. 예를 들어 스태미나 회복 1회차는 젬 10개, 2회차는 20개…와 같이 올라갑니다.
횟수를 지정하여 한 번에 교환할 수도 있습니다. 이 경우 합계 비용은 각 회차 가격의 합계가 됩니다.
매일의 스태미나 회복, 횟수 한정 상점 등 반복 이용에 따라 가격을 올리고 싶은 구조에 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| rateName | string | ✓ | ~ 128자 | 코스트 상승형 교환 레이트 모델의 이름 코스트 상승형 교환 레이트 모델 종류 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| count | int | ✓ | 1 ~ 1073741821 | 교환 횟수 | ||
| config | List<EzConfig> | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzIncrementalRateModel | 코스트 상승형 교환 레이트 모델 |
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 교환 처리 실행에 사용하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Exchange(
);
var result = await domain.IncrementalExchangeAsync(
rateName: "rate-0001",
count: 1,
config: null
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.Exchange.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Exchange(
);
var future = domain.IncrementalExchangeFuture(
rateName: "rate-0001",
count: 1,
config: null
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. const auto Domain = Gs2->Exchange->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Exchange(
);
const auto Future = Domain->IncrementalExchange(
"rate-0001", // rateName
1 // count
// config
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.exchange.namespace_(
"namespace-0001"
).me(game_session).exchange(
)
var async_result = await domain.incremental_exchange(
"rate-0001", # rate_name
1, # count
null # config
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result