GS2-Schedule SDK for Game Engine API 레퍼런스
모델
EzTrigger
트리거
상대 이벤트 스케줄링의 기점을 정의하여 플레이어별 이벤트 기간을 구현합니다.
플레이어에게 트리거가 발동되면 유효 기간(expiresAt)이 설정됩니다.
“relative” 스케줄 타입으로 설정된 이벤트는 트리거를 이름으로 참조하며, 해당 플레이어의 이벤트 기간은 트리거가 발동된 시각부터 유효 기간까지 지속됩니다.
트리거는 갱신할 수 있으며, 유효 기간이 지나면 TTL에 의해 자동으로 정리됩니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| triggerId | string | ※ | ~ 1024자 | 트리거 GRN
※ 서버가 자동으로 설정 | ||
| name | string | ✓ | ~ 128자 | 트리거 이름 트리거 고유 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| triggeredAt | long | ※ | 현재 시각 | 트리거 발동 일시 이 트리거가 발동된 타임스탬프입니다. 상대 이벤트 스케줄링의 기준 시작점 역할을 합니다. 명시적으로 지정하지 않으면 현재 시각이 자동으로 설정됩니다. UNIX 시간(밀리초)으로 표현됩니다. | ||
| expiresAt | long | ✓ | 유효 기간 이 트리거가 만료되어 상대 이벤트 기간이 종료되는 타임스탬프입니다. 이 시각 이후 트리거는 만료된 것으로 간주되며(IsExpire가 true를 반환), 해당 플레이어에 대한 관련 상대 이벤트는 더 이상 유효하지 않습니다. 트리거 데이터는 만료 후 DynamoDB TTL에 의해 자동으로 정리됩니다. UNIX 시간(밀리초)으로 표현됩니다. |
EzEvent
이벤트
이벤트의 기간에는 절대 기간과 상대 기간의 2가지 종류가 있습니다.
절대 기간은 예를 들어 YYYY년 MM월 DD일 00:00(UTC) ~ YYYY년 MM월 DD일 23:59(UTC)와 같은 고정된 기간이며,
상대 기간은 트리거를 당긴 시점부터 24시간과 같이 게임 플레이어마다 다른 기간을 이벤트 기간으로 하는 것입니다.
이벤트에는 개최 기간뿐만 아니라 반복도 설정할 수 있게 되어 있어
이벤트 기간 중 월요일 10:00 ~ 11:00만을 이벤트 기간으로 하는 설정도 가능합니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | string | ✓ | ~ 128자 | 이벤트 이름 이벤트 고유의 이름. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. | ||||||||
| metadata | string | ~ 2048자 | 메타데이터 메타데이터에는 임의의 값을 설정할 수 있습니다. 이 값들은 GS2의 동작에는 영향을 주지 않으므로, 게임 내에서 사용하는 정보를 저장하는 용도로 사용할 수 있습니다. | |||||||||
| scheduleType | 문자열 열거형 enum { “absolute”, “relative” } | ✓ | 스케줄 타입 이벤트 기간을 정의하는 방식을 결정합니다. “absolute"는 모든 플레이어에게 동일하게 적용되는 고정된 시작/종료 타임스탬프를 사용합니다. “relative"는 플레이어별 트리거를 기점으로 사용하여, 개인화된 이벤트 기간을 구현합니다(예: 각 플레이어가 처음 로그인한 시점부터 24시간).
| |||||||||
| absoluteBegin | long | 절대 시작 일시 절대 스케줄링에서 이벤트 기간의 고정 시작 시각입니다. 모든 플레이어가 동일한 시작 시각을 공유합니다. 절대 이벤트에서 설정하지 않으면 이벤트는 과거부터 시작된 것으로 취급됩니다. UNIX 시간(밀리초)으로 표현됩니다. | ||||||||||
| absoluteEnd | long | 절대 종료 일시 절대 스케줄링에서 이벤트 기간의 고정 종료 시각입니다. 모든 플레이어가 동일한 종료 시각을 공유합니다. 절대 이벤트에서 설정하지 않으면 이벤트는 종료되지 않는 것으로 취급됩니다. UNIX 시간(밀리초)으로 표현됩니다. | ||||||||||
| relativeTriggerName | string | {scheduleType} == “relative” | ✓※ | ~ 128자 | 이벤트 시작 트리거 이름 게임 플레이어별로 이벤트 기간을 설정하는( relative) 경우, 이벤트 시작의 기점이 되는 트리거의 이름을 지정합니다.영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. ※ scheduleType이(가) “relative” 이면 필수 |
EzRepeatSchedule
반복 스케줄 상태
특정 시점에서의 이벤트 반복 사이클의 현재 상태를 나타냅니다.
반복 횟수(사이클이 발생한 횟수), 현재 활성 윈도우의 시작·종료 시각,
전회 완료된 윈도우의 종료 시각, 그리고 다음 윈도우의 시작 시각을 포함합니다.
이 정보는 이벤트의 반복 설정과 현재 시각을 토대로 동적으로 계산됩니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| repeatCount | int | ✓ | 0 ~ 2147483646 | 반복 횟수 현재 시각까지 완료된 반복 사이클의 횟수. 반복 윈도우가 종료될 때마다 증가합니다. 시즌제나 정기 이벤트의 사이클 진행 상황을 추적하는 데 사용할 수 있습니다. | ||
| currentRepeatStartAt | long | 현재 반복 시작 일시 현재 활성 상태인 반복 윈도우의 시작 시각. 이벤트가 현재 활성 상태인 반복 윈도우에 있지 않은 경우 null 입니다. UNIX 시간(밀리초)으로 표현됩니다. | ||||
| currentRepeatEndAt | long | 현재 반복 종료 일시 현재 활성 상태인 반복 윈도우의 종료 시각. 이벤트가 현재 활성 상태인 반복 윈도우에 있지 않은 경우 null 입니다. UNIX 시간(밀리초)으로 표현됩니다. | ||||
| lastRepeatEndAt | long | 직전 반복 종료 일시 가장 최근에 완료된 반복 윈도우의 종료 시각. 아직 반복 윈도우가 종료되지 않은 경우 null 입니다. UNIX 시간(밀리초)으로 표현됩니다. | ||||
| nextRepeatStartAt | long | 다음 반복 시작 일시 다음 반복 윈도우의 시작 시각. 이벤트 기간 내에 다음 반복 윈도우가 없는 경우 null 입니다. UNIX 시간(밀리초)으로 표현됩니다. |
메서드
getTrigger
특정 트리거의 상태 조회
이름을 지정하여 특정 트리거를 조회하고, 언제 활성화되었는지, 언제 만료되는지를 확인할 수 있습니다.
특정 트리거의 상태를 확인하는 데 사용합니다. 예를 들어 “first_login” 트리거가 아직 유효한지, 만료까지 남은 시간은 얼마인지 확인하여 “초보자 보너스 종료까지 남은 3일 12시간"과 같이 관련 이벤트의 카운트다운을 표시하는 경우에 유용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| triggerName | string | ✓ | ~ 128자 | 트리거 이름 트리거 고유 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzTrigger | 트리거 |
구현 예제
var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Trigger(
triggerName: "trigger1"
);
var item = await domain.ModelAsync(); var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Trigger(
triggerName: "trigger1"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Schedule->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Trigger(
"trigger1" // triggerName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.schedule.namespace_(
"namespace-0001"
).me(game_session).trigger(
"trigger1"
)
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.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Trigger(
triggerName: "trigger1"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Trigger(
triggerName: "trigger1"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Schedule->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Trigger(
"trigger1" // triggerName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Schedule::Model::FTrigger> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.schedule.namespace_(
"namespace-0001"
).me(game_session).trigger(
"trigger1"
)
# 이벤트 핸들링 시작
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의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listTriggers
플레이어의 유효한 트리거 목록 조회
플레이어에 대해 현재 유효한 모든 트리거를 조회합니다.
트리거는 상대 스케줄 이벤트를 활성화하기 위한 플레이어별 타이머입니다. 트리거가 “당겨지면”(활성화되면) 카운트다운이 시작되고, 해당 트리거에 연결된 이벤트가 플레이어에 대해 활성화됩니다.
예를 들어 “first_login” 트리거가 “7일간 초보자 보너스” 이벤트를 활성화하거나, “first_purchase” 트리거가 “24시간 감사 세일” 이벤트를 활성화할 수 있습니다.
각 트리거에는 유효 기간이 있으며, 기간이 만료되면 해당 플레이어에 대한 관련 이벤트도 종료됩니다.
플레이어에게 현재 어떤 트리거가 유효한지 확인하는 데 사용합니다. 예를 들어 상태 화면에서 “초보자 보너스: 유효(남은 5일 후 만료)“와 같이 표시하는 경우에 유용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzTrigger> | 트리거 목록 |
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰 |
구현 예제
var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.TriggersAsync(
).ToListAsync(); var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Triggers(
);
List<EzTrigger> items = new List<EzTrigger>();
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->Schedule->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->Triggers(
);
TArray<Gs2::UE5::Schedule::Model::FEzTriggerPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeTriggers(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeTriggers(callbackId); var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeTriggers(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeTriggers(callbackId); const auto Domain = Gs2->Schedule->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeTriggers(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeTriggers(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
getEvent
특정 이벤트의 스케줄 상태 조회
이름을 지정하여 특정 이벤트를 플레이어에 대한 현재 스케줄 상태와 함께 조회합니다.
응답에는 이벤트가 현재 개최 중인지(inSchedule), 시작·종료 시각, 해당하는 경우 반복 스케줄 정보가 포함됩니다.
상대 스케줄 이벤트의 경우, 종료 시각은 플레이어의 트리거를 기반으로 계산되므로, 같은 이벤트라도 플레이어에 따라 종료 시각이 다를 수 있습니다.
특정 이벤트가 개최 중인지 확인하고 남은 시간을 표시하는 데 사용합니다. 예를 들어 “여름 이벤트: 남은 3일”, “초보자 보너스: 남은 12시간"과 같이 카운트다운 타이머와 함께 표시하는 데 유용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| eventName | string | ✓ | ~ 128자 | 이벤트 이름 이벤트 고유의 이름. 영숫자 및 -(하이픈), _(언더스코어), .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzEvent | 이벤트 |
| inSchedule | bool | 현재 이벤트 기간 중인지 여부 |
| scheduleStartAt | long | 이벤트 기간 시작 시각 |
| scheduleEndAt | long | 이벤트 기간 종료 시각 이벤트 종류가 absolute 인 경우 EventModel 의 absoluteEnd 가 저장됩니다. 이벤트 종류가 relative 인 경우 scheduleEndAt 에는 트리거의 유효 기간 또는 EventModel 의 absoluteEnd 중 더 빨리 종료되는 쪽이 저장됩니다. |
| repeatSchedule | EzRepeatSchedule | 반복 정보 |
| isGlobalSchedule | bool | 이벤트가 글로벌 스케줄인지 여부 |
구현 예제
var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Event(
eventName: "event-0001"
);
var item = await domain.ModelAsync(); var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Event(
eventName: "event-0001"
);
var future = domain.ModelFuture();
yield return future;
var item = future.Result; const auto Domain = Gs2->Schedule->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Event(
"event-0001" // eventName
);
const auto Future = Domain->Model();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}var domain = ez.schedule.namespace_(
"namespace-0001"
).me(game_session).event(
"event-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.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Event(
eventName: "event-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).Event(
eventName: "event-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.Subscribe(
value => {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
domain.Unsubscribe(callbackId); const auto Domain = Gs2->Schedule->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->Event(
"event-0001" // eventName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->Subscribe(
[](TSharedPtr<Gs2::Schedule::Model::FEvent> value) {
// 값이 변화했을 때 호출됨
// value에는 변경 후의 값이 전달됨
}
);
// 이벤트 핸들링 정지
Domain->Unsubscribe(CallbackId);var domain = ez.schedule.namespace_(
"namespace-0001"
).me(game_session).event(
"event-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의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
listEvents
플레이어의 현재 개최 중인 이벤트 목록 조회
이 플레이어에 대해 현재 개최 중인 모든 이벤트를 조회합니다.
이벤트에는 2가지 종류가 있습니다:
- 절대 스케줄 이벤트: 모든 플레이어에게 공통되는 고정 일시 이벤트 (예: “크리스마스 이벤트: 12월 24일
25일”, “여름 세일: 7월 1일31일”) - 상대 스케줄 이벤트: 트리거가 활성화된 시점부터 플레이어별로 시작되는 이벤트 (예: 최초 로그인부터 시작되는 “7일간 초보자 보너스”, 레벨 10 도달부터 시작되는 “24시간 한정 플래시 세일”)
현재 개최 기간 중인 이벤트만 반환됩니다.
지금 어떤 이벤트가 개최 중인지 플레이어에게 표시할 때 사용합니다. 예를 들어 홈 화면에 이벤트 배너를 표시하거나 이벤트 전용 UI 요소를 활성화하는 경우 등에 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzEvent> | 이벤트 목록 |
구현 예제
var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.EventsAsync(
).ToListAsync(); var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.Events(
);
List<EzEvent> items = new List<EzEvent>();
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->Schedule->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->Events(
);
TArray<Gs2::UE5::Schedule::Model::FEzEventPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeEvents(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeEvents(callbackId); var domain = gs2.Schedule.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeEvents(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeEvents(callbackId); const auto Domain = Gs2->Schedule->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeEvents(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeEvents(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.