GS2-Showcase SDK for Game Engine API 레퍼런스
모델
EzShowcase
진열대
진열대에는 진열할 상품을 정의할 수 있습니다.
또한 진열대의 상품 판매 기간을 설정할 수 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 진열대 이름 진열대 고유의 이름. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. | ||
| metadata | string | ~ 2048자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||
| displayItems | List<EzDisplayItem> | [] | 1 ~ 1000 items | 진열할 상품 리스트 이 진열대에 진열되는 상품의 리스트입니다. 각 진열 상품은 단일 상품 또는 상품 그룹 중 하나입니다. 판매 기간 이벤트가 종료되었거나 유효하지 않은 상품은 진열대 조회 시 자동으로 필터링됩니다. | ||
| salesPeriodEventId | string | ~ 1024자 | 진열대의 판매 기간을 설정한 GS2-Schedule 이벤트 GRN
이 진열대 전체의 판매 기간을 제어합니다. 지정한 경우, 연관된 GS2-Schedule 이벤트 기간 중에만 진열대를 이용할 수 있습니다. 이벤트가 유효하지 않은 경우, 진열대는 비어 있는 상태로 반환됩니다. |
EzDisplayItem
진열 상품
진열대에 표시되는 상품입니다. 단일 상품 또는 상품 그룹 중 하나를 참조할 수 있습니다. 각 진열 상품에는 진열대 전체의 판매 기간과는 독립적으로 GS2-Schedule 이벤트에 의한 개별 판매 기간을 설정할 수 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| displayItemId | string | ✓ | UUID | ~ 128자 | 진열 상품 ID 진열 상품의 고유한 이름을 유지합니다. 생략하면 시스템에 의해 UUID(Universally Unique Identifier) 형식으로 자동 할당됩니다. | |||||||
| type | 문자열 열거형 enum { “salesItem”, “salesItemGroup” } | ✓ | 종류 표시할 상품의 종류입니다. “salesItem"은 고정된 대가와 보상을 가진 단일 상품입니다. “salesItemGroup"은 여러 상품을 순서대로 평가하는 상품 그룹으로, 단계별 가격 인상이나 초회 한정 할인 등에 사용됩니다.
| |||||||||
| salesItem | EzSalesItem | {type} == “salesItem” | ✓※ | 상품 ※ type이(가) “salesItem” 이면 필수 | ||||||||
| salesItemGroup | EzSalesItemGroup | {type} == “salesItemGroup” | ✓※ | 상품 그룹 ※ type이(가) “salesItemGroup” 이면 필수 |
EzRandomDisplayItem
랜덤 진열대에 진열된 상품
특정 사용자에게 랜덤 진열대에서 추첨·표시된 상품을 나타냅니다. 현재 로테이션 기간에서의 상품 대가, 보상 및 구매 횟수 추적 정보를 포함합니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| name | string | ✓ | UUID | ~ 128자 | 랜덤 진열 상품명 랜덤 진열 상품의 고유한 이름을 유지합니다. 생략하면 시스템에 의해 UUID(Universally Unique Identifier) 형식으로 자동 할당됩니다. | |
| metadata | string | ~ 2048자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||
| verifyActions | List<EzVerifyAction> | [] | 0 ~ 10 items | 검증 액션 목록 | ||
| consumeActions | List<EzConsumeAction> | [] | 0 ~ 10 items | 소비 액션 목록 | ||
| acquireActions | List<EzAcquireAction> | [] | 1 ~ 100 items | 입수 액션 목록 | ||
| currentPurchaseCount | int | ✓ | 1 ~ 2147483646 | 현재 구매 횟수 현재 로테이션 기간 중에 이 상품이 구매된 횟수입니다. 구매할 때마다 증가하며, 로테이션 기간이 종료되면 리셋됩니다. | ||
| maximumPurchaseCount | int | ✓ | 1 ~ 2147483646 | 최대 구매 횟수 현재 로테이션 기간 중에 이 상품을 구매할 수 있는 최대 횟수입니다. currentPurchaseCount가 이 값에 도달하면 다음 로테이션까지 구매할 수 없게 됩니다. |
EzSalesItem
상품
상품을 구매하기 위해 필요한 대가와, 상품을 구매했을 때 얻을 수 있는 보상을 설정합니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 상품 이름 상품 고유의 이름. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. | ||
| metadata | string | ~ 2048자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||
| verifyActions | List<EzVerifyAction> | [] | 0 ~ 10 items | 검증 액션 리스트 구매 전에 실행되는 전제 조건 체크입니다. 모든 검증 액션이 성공한 후에 소비·획득 액션이 처리됩니다. 구매 자격 조건 체크에 사용할 수 있습니다. | ||
| consumeActions | List<EzConsumeAction> | [] | 0 ~ 10 items | 소비 액션 리스트 구매 대가로 리소스를 소비하는 액션입니다. 상품 그룹의 구매 횟수 제어를 위해 GS2-Limit의 CountUp 액션을 포함할 수 있습니다. | ||
| acquireActions | List<EzAcquireAction> | [] | 1 ~ 100 items | 획득 액션 리스트 구매 보상으로 리소스를 부여하는 액션입니다. 모든 소비 액션이 정상적으로 완료된 후에 실행됩니다. |
EzSalesItemGroup
상품 그룹
상품 그룹은 진열대에 진열하기 위한 엔티티입니다.
상품 그룹에는 여러 상품을 소속시킬 수 있으며, 소속된 상품의 앞에서부터 순서대로 구매 가능한지를 판정하여 가장 먼저 구매 가능하다고 판정된 상품이 실제로 진열됩니다.
최초 1회만 할인되는 상품이나, 스텝업 가챠처럼 구매 횟수에 따라 상품 내용이 변화하는 구조에 사용할 수 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 상품 그룹 이름 상품 그룹 고유의 이름. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. | ||
| metadata | string | ~ 2048자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||
| salesItems | List<EzSalesItem> | [] | 2 ~ 10 items | 상품 그룹에 포함할 상품 이 그룹 내 상품의 순서가 지정된 리스트입니다. GS2-Limit 카운터를 사용하여 앞에서부터 순서대로 구매 가능한지를 판정하고, 가장 먼저 구매 가능하다고 판정된 상품이 표시됩니다. 어느 것도 해당하지 않는 경우, 리스트의 마지막 상품이 폴백으로 사용됩니다. |
EzConfig
컨피그 설정
트랜잭션의 변수에 적용하는 설정 값
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| key | string | ✓ | ~ 64자 | 이름 트랜잭션 템플릿에서 치환되는 변수명입니다. 획득 액션 파라미터 내의 플레이스홀더에 대응합니다. | ||
| value | string | ~ 51200자 | 값 트랜잭션 템플릿 내의 대응하는 변수명에 치환되는 값입니다. |
EzConsumeAction
소비 액션
EzVerifyAction
검증 액션
EzAcquireAction
입수 액션
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 | 획득 액션 실행 결과 리스트 |
메서드
buy
쇼케이스의 상품 구매하기
쇼케이스에서 특정 상품을 구매합니다.
플레이어가 상품을 구매하면 시스템이 구매 흐름 전체를 자동으로 처리합니다. 조건 확인(예: 플레이어 레벨), 비용 소비(예: 젬 100개), 보상 부여(예: 레어 검)가 모두 자동으로 이루어집니다.
이 모든 처리는 하나의 트랜잭션에서 이루어지므로, 결제만 이루어지고 아이템이 지급되지 않는 상황은 발생하지 않습니다.
플레이어가 상점 상품의 “구매” 버튼을 탭했을 때 사용합니다. 예를 들어 “스타터 팩"을 젬 500개로 구매하여 스태미나 포션 10개와 골드 상자 1개를 받는 처리에 유용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| showcaseName | string | ✓ | ~ 128자 | 진열대 이름 진열대 고유의 이름. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| displayItemId | string | ✓ | UUID | ~ 128자 | 진열 상품 ID 진열 상품의 고유한 이름을 유지합니다. 생략하면 시스템에 의해 UUID(Universally Unique Identifier) 형식으로 자동 할당됩니다. | |
| quantity | int | 1 | 1 ~ 1000 | 구매 수량 | ||
| config | List<EzConfig> | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzSalesItem | 상품 |
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 구매 처리를 실행하는 데 사용하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Showcase(
showcaseName: "showcase-0001"
).DisplayItem(
displayItemId: "display-item-0001"
);
var result = await domain.BuyAsync(
quantity: null,
config: null
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Showcase(
showcaseName: "showcase-0001"
).DisplayItem(
displayItemId: "display-item-0001"
);
var future = domain.BuyFuture(
quantity: null,
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->Showcase->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Showcase(
"showcase-0001" // showcaseName
)->DisplayItem(
"display-item-0001" // displayItemId
);
const auto Future = Domain->Buy(
// quantity
// config
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.showcase.namespace_(
"namespace-0001"
).me(game_session).showcase(
"showcase-0001"
).display_item(
"display-item-0001"
)
var async_result = await domain.buy(
null, # quantity
null # config
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultgetShowcase
상점 쇼케이스와 상품 가져오기
특정 쇼케이스(상점 페이지)와 해당 쇼케이스에 표시된 상품 목록을 가져옵니다.
쇼케이스는 게임 내 상점 화면과 같은 것입니다. 예를 들어 “젬 상점”, “데일리 세일”, “스페셜 오퍼” 같은 페이지에 해당합니다.
각 쇼케이스에는 상품이 진열되어 있으며, 각 상품에는 플레이어가 지불하는 것(비용)과 받는 것(보상)이 정의되어 있습니다.
쇼케이스는 스케줄 이벤트와 연결하여 특정 기간에만 표시되게 할 수도 있습니다. 예를 들어 크리스마스 기간에만 표시되는 “홀리데이 상점” 같은 방식으로 사용할 수 있습니다.
상점 UI를 구축할 때 사용합니다. 예를 들어 플레이어가 상점 화면을 열었을 때 상품 목록을 가격과 “구매” 버튼과 함께 표시하는 데 유용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| showcaseName | string | ✓ | ~ 128자 | 진열대 이름 진열대 고유의 이름. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzShowcase | 진열대 |
구현 예제
var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Showcase(
showcaseName: "showcase-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Showcase(
showcaseName: "showcase-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Showcase->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Showcase(
"showcase-0001" // showcaseName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.showcase.namespace_(
"namespace-0001"
).me(game_session).showcase(
"showcase-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.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Showcase(
showcaseName: "showcase-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Showcase(
showcaseName: "showcase-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Showcase->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Showcase(
"showcase-0001" // showcaseName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Showcase::Model::FShowcase> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.showcase.namespace_(
"namespace-0001"
).me(game_session).showcase(
"showcase-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의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
getRandomShowcaseDisplayItem
랜덤 진열대의 특정 상품 조회
랜덤 진열대에 현재 표시되고 있는 특정 상품의 상세 정보를 조회합니다.
플레이어가 랜덤 상점의 특정 상품을 탭했을 때 상세 화면을 표시하는 데 사용합니다. 예를 들어, 상세 팝업에서 아이템의 설명, 가격, “구매” 버튼을 표시하는 데 유용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| showcaseName | string | ✓ | ~ 128자 | 랜덤 진열대 이름 랜덤 진열대 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| displayItemName | string | ✓ | UUID | ~ 128자 | 랜덤 진열 상품명 랜덤 진열 상품의 고유한 이름을 유지합니다. 생략하면 시스템에 의해 UUID(Universally Unique Identifier) 형식으로 자동 할당됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzRandomDisplayItem | 상품 |
구현 예제
var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
).RandomDisplayItem(
displayItemName: "display-item-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
).RandomDisplayItem(
displayItemName: "display-item-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Showcase->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RandomShowcase(
"showcase-0001" // showcaseName
)->RandomDisplayItem(
"display-item-0001" // displayItemName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.showcase.namespace_(
"namespace-0001"
).me(game_session).random_showcase(
"showcase-0001"
).random_display_item(
"display-item-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.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
).RandomDisplayItem(
displayItemName: "display-item-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
).RandomDisplayItem(
displayItemName: "display-item-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Showcase->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RandomShowcase(
"showcase-0001" // showcaseName
)->RandomDisplayItem(
"display-item-0001" // displayItemName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Showcase::Model::FRandomDisplayItem> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.showcase.namespace_(
"namespace-0001"
).me(game_session).random_showcase(
"showcase-0001"
).random_display_item(
"display-item-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의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listRandomShowcaseDisplayItems
랜덤 쇼케이스에 현재 표시되고 있는 상품 목록 가져오기
플레이어를 대상으로 랜덤 쇼케이스에 현재 표시되고 있는 상품을 가져옵니다.
랜덤 쇼케이스는 상품 풀에서 무작위로 선택된 상품이 표시되는 상점입니다. “데일리 세일"이나 “미스터리 상점"처럼 플레이어마다 다른 상품이 표시되거나 주기적으로 라인업이 갱신됩니다.
예를 들어 50종류의 상품 풀에서 매일 5개가 무작위로 선택되어 자정에 리프레시되는 방식입니다.
표시되는 상품은 플레이어마다 다르며, 같은 시점이라도 다른 플레이어에게는 다른 상품이 표시될 수 있습니다.
랜덤 상점 UI 구축에 사용합니다. 예를 들어 “오늘의 세일"로 5개의 랜덤 상품과 다음 리프레시까지의 카운트다운 타이머를 표시하는 데 유용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| showcaseName | string | ✓ | ~ 128자 | 랜덤 진열대 이름 랜덤 진열대 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzRandomDisplayItem> | 랜덤 쇼케이스의 상품 목록 |
구현 예제
var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
);
var items = await domain.RandomDisplayItemsAsync(
).ToListAsync(); var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
);
var it = domain.RandomDisplayItems(
);
List<EzRandomDisplayItem> items = new List<EzRandomDisplayItem>();
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->Showcase->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RandomShowcase(
"showcase-0001" // showcaseName
);
const auto It = Domain->RandomDisplayItems(
);
TArray<Gs2::UE5::Showcase::Model::FEzRandomDisplayItemPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeRandomDisplayItems(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeRandomDisplayItems(callbackId); var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeRandomDisplayItems(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeRandomDisplayItems(callbackId); const auto Domain = Gs2->Showcase->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RandomShowcase(
"showcase-0001" // showcaseName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeRandomDisplayItems(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeRandomDisplayItems(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
randomShowcaseBuy
랜덤 진열대의 상품 구매
랜덤 진열대에서 특정 상품을 구매합니다.
일반 진열대에서의 구매와 마찬가지로 조건 확인, 비용 소비, 보상 지급이 모두 하나의 트랜잭션에서 자동으로 처리됩니다.
랜덤 진열대에서 상품을 구매하면 설정에 따라 해당 상품이 품절 상태가 되어, 다음 새로고침까지 새로운 상품이 표시되지 않을 수 있습니다.
플레이어가 랜덤 상점의 상품에서 “구매” 버튼을 탭했을 때 사용합니다. 예를 들어, 데일리 세일에서 새로고침 전에 할인된 “레전더리 무기 상자"를 구매하는 처리에 유용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| showcaseName | string | ✓ | ~ 128자 | 랜덤 진열대 이름 랜덤 진열대 고유의 이름. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| displayItemName | string | ✓ | UUID | ~ 128자 | 랜덤 진열 상품명 랜덤 진열 상품의 고유한 이름을 유지합니다. 생략하면 시스템에 의해 UUID(Universally Unique Identifier) 형식으로 자동 할당됩니다. | |
| quantity | int | 1 | 1 ~ 1000 | 구매 수량 | ||
| config | List<EzConfig> | [] | 0 ~ 32 items | 트랜잭션 변수에 적용할 설정값 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzRandomDisplayItem | 구매한 상품 |
| transactionId | string | 발행된 트랜잭션 ID |
| stampSheet | string | 구매 처리를 실행하는 데 사용하는 스탬프 시트 |
| stampSheetEncryptionKeyId | string | 스탬프 시트의 서명 계산에 사용한 암호화 키 GRN |
| autoRunStampSheet | bool | 트랜잭션 자동 실행이 활성화되어 있는지 여부 |
| atomicCommit | bool | 트랜잭션을 원자적으로 커밋할지 여부 |
| transaction | string | 발행된 트랜잭션 |
| transactionResult | EzTransactionResult | 트랜잭션 실행 결과 |
구현 예제
var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
).RandomDisplayItem(
displayItemName: "display-item-0001"
);
var result = await domain.RandomShowcaseBuyAsync(
quantity: 1,
config: null
);
// New Experience에서는 스탬프 시트가 SDK 레벨에서 자동으로 실행됩니다.
// 에러가 발생하면 TransactionException이 발생합니다.
// TransactionException::Retry()로 재시도할 수 있습니다. var domain = gs2.Showcase.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).RandomShowcase(
showcaseName: "showcase-0001"
).RandomDisplayItem(
displayItemName: "display-item-0001"
);
var future = domain.RandomShowcaseBuyFuture(
quantity: 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->Showcase->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->RandomShowcase(
"showcase-0001" // showcaseName
)->RandomDisplayItem(
"display-item-0001" // displayItemName
);
const auto Future = Domain->RandomShowcaseBuy(
1 // quantity
// config
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.showcase.namespace_(
"namespace-0001"
).me(game_session).random_showcase(
"showcase-0001"
).random_display_item(
"display-item-0001"
)
var async_result = await domain.random_showcase_buy(
1, # quantity
null # config
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.result