GS2-Datastore SDK for Game Engine API 레퍼런스
모델
EzDataObject
데이터 오브젝트
데이터 오브젝트는 게임 플레이어가 업로드한 데이터입니다.
데이터는 세대 관리되며, 30일분의 과거 데이터도 보관됩니다.
데이터에는 접근 권한을 설정할 수 있습니다.
스코프에는 3종류가 있으며,
- 누구나 접근할 수 있는
public - 지정한 사용자 ID의 게임 플레이어만 접근할 수 있는
protected - 본인만 접근할 수 있는
private
가 있습니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| dataObjectId | string | ※ | ~ 1024자 | 데이터 오브젝트 GRN
※ 서버가 자동으로 설정 | ||||||||||
| name | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 데이터 오브젝트를 식별하는 고유한 이름입니다. 기본적으로 UUID 형식으로 자동 생성됩니다. 네임스페이스 내에서 업로드된 데이터를 참조·관리하는 데 사용됩니다. | |||||||||
| userId | string | ✓ | ~ 128자 | 사용자ID | ||||||||||
| scope | 문자열 열거형 enum { “public”, “protected”, “private” } | “private” | 파일 접근 권한 이 데이터 오브젝트에 접근할 수 있는 사용자를 제어합니다. public은 누구나 접근 가능, protected는 allowUserIds에 지정된 사용자 ID만 접근 가능, private은 오너 본인만 접근 가능합니다.
| |||||||||||
| allowUserIds | List<string> | {scope} == “protected” | [] | 0 ~ 100 items | 공개할 사용자 ID 목록 스코프가 protected로 설정되어 있는 경우, 이 데이터 오브젝트에 접근할 수 있는 사용자를 지정합니다. 이 목록에 포함된 사용자 ID를 가진 사용자만 읽기 접근이 허용됩니다.※ scope이(가) “protected” 이면 활성화 | |||||||||
| status | 문자열 열거형 enum { “ACTIVE”, “UPLOADING”, “DELETED” } | ✓ | 상태 데이터 오브젝트의 현재 라이프사이클 상태입니다. ACTIVE는 데이터에 접근 가능함을 나타내고, UPLOADING은 새로운 버전이 업로드 중임을 나타내며, DELETED는 삭제 예정으로 표시된 상태임을 나타냅니다(실제 삭제는 30일 후에 이루어집니다).
| |||||||||||
| generation | string | ~ 128자 | 데이터의 세대 업로드된 데이터의 현재 버전을 나타내는 식별자입니다. 데이터가 재업로드될 때마다 새로운 세대 ID가 할당됩니다. | |||||||||||
| createdAt | long | ※ | 현재 시각 | 생성일시 UNIX 시간·밀리초 ※ 서버가 자동으로 설정 | ||||||||||
| updatedAt | long | ※ | 현재 시각 | 최종 갱신일시 UNIX 시간·밀리초 ※ 서버가 자동으로 설정 |
EzDataObjectHistory
데이터 오브젝트 이력
데이터 오브젝트의 업데이트 이력을 확인할 수 있습니다.
데이터 오브젝트가 재업로드될 때마다 세대 ID와 파일 크기를 포함한 이력 레코드가 생성됩니다. 이력 데이터는 30일간 보관되며, 이전 버전으로의 롤백 및 감사가 가능합니다.
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| dataObjectHistoryId | string | ※ | ~ 1024자 | 데이터 오브젝트 이력 GRN
※ 서버가 자동으로 설정 | ||
| generation | string | ✓ | ~ 128자 | 세대 ID 업로드 시점의 데이터 오브젝트의 특정 버전을 나타내는 고유 식별자입니다. DataObject 의 generation 필드에 해당하며, PrepareDownloadByGeneration 에서 이 특정 버전을 다운로드할 때 사용할 수 있습니다. | ||
| contentLength | long | ✓ | 0 ~ 10485760 | 데이터 크기 이 세대의 업로드 데이터 크기(바이트 단위)입니다. 최대 파일 크기는 10 MB(10,485,760 바이트)입니다. | ||
| createdAt | long | ※ | 현재 시각 | 생성일시 UNIX 시간·밀리초 ※ 서버가 자동으로 설정 |
메서드
deleteDataObject
업로드한 파일 삭제
지정한 데이터 오브젝트를 삭제 예정으로 표시합니다. 실제 파일은 30일 후에 삭제됩니다.
플레이어가 더 이상 필요하지 않은 세이브 데이터나 업로드한 콘텐츠를 삭제할 때 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 데이터 오브젝트를 식별하는 고유한 이름입니다. 기본적으로 UUID 형식으로 자동 생성됩니다. 네임스페이스 내에서 업로드된 데이터를 참조·관리하는 데 사용됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
Error
이 API에는 특별한 예외가 정의되어 있습니다.
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.
일반적인 에러의 종류와 핸들링 방법은 여기 문서를 참고해 주세요.
| 타입 | 베이스 클래스 | 설명 |
|---|---|---|
| InvalidStatusException | BadRequestException | DataObject가 조작 가능한 상태가 아닙니다 |
구현 예제
try {
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.DeleteDataObjectAsync(
);
var item = await result.ModelAsync();
} catch(Gs2.Gs2Datastore.Exception.InvalidStatusException e) {
// DataObject is not in operable state.
} var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.DeleteDataObjectFuture(
);
yield return future;
if (future.Error != null)
{
if (future.Error is Gs2.Gs2Datastore.Exception.InvalidStatusException)
{
// DataObject is not in operable state.
}
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; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->DeleteDataObject(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
auto e = Future->GetTask().Error();
if (e->IsChildOf(Gs2::Datastore::Error::FInvalidStatusError::Class))
{
// DataObject is not in operable state.
}
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();var domain = ez.datastore.namespace_(
"namespace-0001"
).me(game_session).data_object(
"dataObject-0001"
)
var async_result = await domain.delete_data_object(
)
if async_result.error != null:
if async_result.error is Gs2DatastoreInvalidStatusException:
# DataObject가 조작 가능한 상태가 아닙니다
pass
push_error(str(async_result.error))
return
var result = async_result.resultdoneUpload
파일 업로드 확정
PrepareUpload 또는 PrepareReUpload로 취득한 URL로의 파일 업로드가 완료된 후에 호출합니다.
업로드를 확정하여 데이터 오브젝트를 다운로드 가능한 상태(상태 ACTIVE)로 만듭니다.
이 호출을 하지 않으면 데이터 오브젝트는 UPLOADING 상태인 채로 남아 다운로드할 수 없습니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 데이터 오브젝트를 식별하는 고유한 이름입니다. 기본적으로 UUID 형식으로 자동 생성됩니다. 네임스페이스 내에서 업로드된 데이터를 참조·관리하는 데 사용됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
Error
이 API에는 특별한 예외가 정의되어 있습니다.
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.
일반적인 에러의 종류와 핸들링 방법은 여기 문서를 참고해 주세요.
| 타입 | 베이스 클래스 | 설명 |
|---|---|---|
| InvalidStatusException | BadRequestException | DataObject가 조작 가능한 상태가 아닙니다 |
| NotUploadedException | BadRequestException | DataObject가 업로드되지 않았습니다 |
구현 예제
try {
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.DoneUploadAsync(
);
var item = await result.ModelAsync();
} catch(Gs2.Gs2Datastore.Exception.InvalidStatusException e) {
// DataObject is not in operable state.
} catch(Gs2.Gs2Datastore.Exception.NotUploadedException e) {
// DataObject is not uploaded.
} var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.DoneUploadFuture(
);
yield return future;
if (future.Error != null)
{
if (future.Error is Gs2.Gs2Datastore.Exception.InvalidStatusException)
{
// DataObject is not in operable state.
}
if (future.Error is Gs2.Gs2Datastore.Exception.NotUploadedException)
{
// DataObject is not uploaded.
}
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; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->DoneUpload(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
auto e = Future->GetTask().Error();
if (e->IsChildOf(Gs2::Datastore::Error::FInvalidStatusError::Class))
{
// DataObject is not in operable state.
}
if (e->IsChildOf(Gs2::Datastore::Error::FNotUploadedError::Class))
{
// DataObject is not uploaded.
}
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();var domain = ez.datastore.namespace_(
"namespace-0001"
).me(game_session).data_object(
"dataObject-0001"
)
var async_result = await domain.done_upload(
)
if async_result.error != null:
if async_result.error is Gs2DatastoreInvalidStatusException:
# DataObject가 조작 가능한 상태가 아닙니다
pass
if async_result.error is Gs2DatastoreNotUploadedException:
# DataObject가 업로드되지 않았습니다
pass
push_error(str(async_result.error))
return
var result = async_result.resultlistMyDataObjects
플레이어가 업로드한 데이터 목록 조회
플레이어가 업로드한 데이터 오브젝트(파일)의 목록을 조회합니다.
상태별로 필터링할 수 있습니다: ACTIVE(다운로드 가능), UPLOADING(업로드 중), DELETED(삭제 예정).
세이브 데이터 목록 화면을 표시하거나, 플레이어가 현재 저장하고 있는 파일을 확인할 때 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||||||||||
| gameSession | GameSession | ✓ | GameSession | |||||||||||
| status | 문자열 열거형 enum { “ACTIVE”, “UPLOADING”, “DELETED” } | 상태
| ||||||||||||
| pageToken | string | ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 | |||||||||||
| limit | int | 30 | 1 ~ 1000 | 취득할 데이터 건수 |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzDataObject> | 데이터 오브젝트 목록 |
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var items = await domain.DataObjectsAsync(
status: "ACTIVE"
).ToListAsync(); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var it = domain.DataObjects(
status: "ACTIVE"
);
List<EzDataObject> items = new List<EzDataObject>();
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->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto It = Domain->DataObjects(
"ACTIVE" // status
);
TArray<Gs2::UE5::Datastore::Model::FEzDataObjectPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeDataObjects(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeDataObjects(callbackId); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeDataObjects(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeDataObjects(callbackId); const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeDataObjects(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeDataObjects(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.
prepareDownload
파일의 다운로드 URL 취득(데이터 오브젝트 ID로 지정)
지정한 데이터 오브젝트의 일시적인 다운로드 URL을 반환합니다.
데이터 오브젝트는 ID(GRN)로 지정합니다. 접근 제어가 적용되어 파일의 오너 또는 허용 목록에 등록된 사용자만 다운로드할 수 있습니다.
반환된 URL에 HTTP GET으로 접근하여 파일을 다운로드합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| dataObjectId | string | ✓ | ~ 1024자 | 데이터 오브젝트 GRN | ||
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
| fileUrl | string | 파일을 다운로드하기 위한 URL |
| contentLength | long | 파일 용량 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var result = await domain.PrepareDownloadAsync(
dataObjectId: "grn:gs2:ap-northeast-1:YourOwnerId:datastore:namespace-0001:user:user-0001:data:dataObject-0001"
);
var item = await result.ModelAsync();
var fileUrl = result.FileUrl;
var contentLength = result.ContentLength; var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var future = domain.PrepareDownloadFuture(
dataObjectId: "grn:gs2:ap-northeast-1:YourOwnerId:datastore:namespace-0001:user:user-0001:data:dataObject-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;
var fileUrl = future.Result.FileUrl;
var contentLength = future.Result.ContentLength; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto Future = Domain->PrepareDownload(
"grn:gs2:ap-northeast-1:YourOwnerId:datastore:namespace-0001:user:user-0001:data:dataObject-0001" // dataObjectId
);
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();
const auto FileUrl = Result->FileUrl;
const auto ContentLength = Result->ContentLength;var domain = ez.datastore.namespace_(
"namespace-0001"
).me(game_session)
var async_result = await domain.prepare_download(
"grn:gs2:ap-northeast-1:YourOwnerId:datastore:namespace-0001:user:user-0001:data:dataObject-0001" # data_object_id
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultprepareDownloadByUserIdAndDataObjectName
다른 플레이어의 파일 다운로드 URL 취득(사용자 ID와 이름으로 지정)
다른 플레이어의 데이터를 사용자 ID와 데이터 오브젝트 이름을 지정하여 다운로드합니다.
접근 제어가 적용됩니다. 데이터가 public이거나, 요청한 플레이어가 오너의 허용 목록에 포함되어 있어야 합니다.
커스텀 레벨이나 리플레이 데이터 등, 플레이어끼리 데이터를 공유할 때 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| userId | string | ✓ | ~ 128자 | 사용자ID | ||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 데이터 오브젝트를 식별하는 고유한 이름입니다. 기본적으로 UUID 형식으로 자동 생성됩니다. 네임스페이스 내에서 업로드된 데이터를 참조·관리하는 데 사용됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
| fileUrl | string | 파일을 다운로드하기 위한 URL |
| contentLength | long | 파일 용량 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).User(
userId: "user-0001"
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.PrepareDownloadByUserIdAndDataObjectNameAsync(
);
var item = await result.ModelAsync();
var fileUrl = result.FileUrl;
var contentLength = result.ContentLength; var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).User(
userId: "user-0001"
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.PrepareDownloadByUserIdAndDataObjectNameFuture(
);
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;
var fileUrl = future.Result.FileUrl;
var contentLength = future.Result.ContentLength; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->User(
"user-0001" // userId
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->PrepareDownloadByUserIdAndDataObjectName(
);
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();
const auto FileUrl = Result->FileUrl;
const auto ContentLength = Result->ContentLength;var domain = ez.datastore.namespace_(
"namespace-0001"
).user(
"user-0001"
).data_object(
"dataObject-0001"
)
var async_result = await domain.prepare_download_by_user_id_and_data_object_name(
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultprepareDownloadOwnData
플레이어 자신의 파일 다운로드 URL 취득(이름으로 지정)
ID 대신 데이터 오브젝트 이름을 지정하여 플레이어 자신의 데이터를 다운로드하기 위한 편리한 방법입니다.
플레이어가 자신의 세이브 데이터나 업로드한 콘텐츠를 불러올 때 사용합니다.
일시적인 다운로드 URL과 파일 크기가 반환됩니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 데이터 오브젝트를 식별하는 고유한 이름입니다. 기본적으로 UUID 형식으로 자동 생성됩니다. 네임스페이스 내에서 업로드된 데이터를 참조·관리하는 데 사용됩니다. | |
| gameSession | GameSession | ✓ | GameSession |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
| fileUrl | string | 파일을 다운로드하기 위한 URL |
| contentLength | long | 파일 용량 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.PrepareDownloadOwnDataAsync(
);
var item = await result.ModelAsync();
var fileUrl = result.FileUrl;
var contentLength = result.ContentLength; var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.PrepareDownloadOwnDataFuture(
);
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;
var fileUrl = future.Result.FileUrl;
var contentLength = future.Result.ContentLength; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->PrepareDownloadOwnData(
);
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();
const auto FileUrl = Result->FileUrl;
const auto ContentLength = Result->ContentLength;var domain = ez.datastore.namespace_(
"namespace-0001"
).me(game_session).data_object(
"dataObject-0001"
)
var async_result = await domain.prepare_download_own_data(
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultDownload
데이터 다운로드
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | byte 배열 | 바이너리 데이터 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var result = await domain.DownloadAsync(
dataObjectName: "dataObject-0001"
); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.DownloadFuture();
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
var result = future.Result; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->Download();
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();DownloadByUserIdAndDataObjectName
사용자ID와 데이터 이름을 지정하여 데이터를 다운로드
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| userId | string | ✓ | ~ 128자 | 사용자ID | ||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | byte 배열 | 바이너리 데이터 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).User(
userId: "user-0001"
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.DownloadByUserIdAndDataObjectNameAsync(
); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).User(
userId: "user-0001"
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.DownloadByUserIdAndDataObjectNameFuture(
);
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
var result = future.Result; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->User(
"user-0001" // userId
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->DownloadByUserIdAndDataObjectName(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();DownloadOwn
자신의 데이터 다운로드
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | byte 배열 | 바이너리 데이터 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.DownloadOwnAsync(); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.DownloadOwnFuture();
yield return future;
if (future.Error != null)
{
onError.Invoke(future.Error, null);
yield break;
}
var result = future.Result; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->DownloadOwn(
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();ReUpload
재업로드
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 | |
| data | byte 배열 | 바이너리 데이터 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
| uploadUrl | string | 업로드 처리 실행에 사용하는 URL |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.ReUploadAsync(
data: binary
);
var item = await result.ModelAsync(); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.ReUploadFuture(
data: binary
);
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; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->ReUpload(
binary // Binary
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
return false;
}
// obtain changed values / result values
const auto Future2 = Future->GetTask().Result()->Model();
Future2->StartSynchronousTask();
if (Future2->GetTask().IsError())
{
return Future2->GetTask().Error();
}
const auto Result = Future2->GetTask().Result();prepareReUpload
기존 파일의 재업로드(덮어쓰기) 준비
기존 데이터 오브젝트의 내용을 교체하기 위한 새로운 업로드 URL을 반환합니다.
이전 버전의 파일은 이력에 남으므로, 세대 번호를 지정하여 이전 버전을 다운로드할 수도 있습니다.
반환된 URL에 새 파일을 업로드한 후, DoneUpload를 호출하여 확정합니다.
재업로드 흐름: PrepareReUpload → 반환된 URL에 파일 PUT → DoneUpload
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 데이터 오브젝트를 식별하는 고유한 이름입니다. 기본적으로 UUID 형식으로 자동 생성됩니다. 네임스페이스 내에서 업로드된 데이터를 참조·관리하는 데 사용됩니다. | |
| contentType | string | “application/octet-stream” | ~ 256자 | 업로드할 데이터의 MIME-Type |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
| uploadUrl | string | 업로드 처리를 실행하는 데 사용하는 URL |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.PrepareReUploadAsync(
contentType: "application/octet-stream"
);
var item = await result.ModelAsync();
var uploadUrl = result.UploadUrl; var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.PrepareReUploadFuture(
contentType: "application/octet-stream"
);
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;
var uploadUrl = future.Result.UploadUrl; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->PrepareReUpload(
"application/octet-stream" // contentType
);
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();
const auto UploadUrl = Result->UploadUrl;var domain = ez.datastore.namespace_(
"namespace-0001"
).me(game_session).data_object(
"dataObject-0001"
)
var async_result = await domain.prepare_re_upload(
"application/octet-stream" # content_type
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultprepareUpload
새 파일 업로드 준비
새로운 데이터 오브젝트를 생성하고 업로드용 URL을 반환합니다.
이 API를 호출한 후, 반환된 URL에 HTTP PUT 요청으로 파일을 업로드하고, DoneUpload를 호출하여 확정합니다.
접근 범위(public 또는 protected)를 설정하거나, 파일 다운로드를 허용할 사용자를 지정할 수 있습니다.updateIfExists를 true로 설정하면, 동일한 이름의 파일이 이미 있는 경우 오류를 반환하는 대신 기존 파일을 덮어써 업데이트합니다.
업로드 흐름: PrepareUpload → 반환된 URL에 파일 PUT → DoneUpload
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||||||||||
| gameSession | GameSession | ✓ | GameSession | |||||||||||
| name | string | ~ 128자 | 데이터 오브젝트의 이름 지정하지 않으면 자동으로 UUID가 할당됩니다. | |||||||||||
| scope | 문자열 열거형 enum { “public”, “protected”, “private” } | “private” | 파일 접근 권한 이 데이터 오브젝트에 접근할 수 있는 사용자를 제어합니다. public은 누구나 접근 가능, protected는 allowUserIds에 지정된 사용자 ID만 접근 가능, private은 오너 본인만 접근 가능합니다.
| |||||||||||
| contentType | string | “application/octet-stream” | ~ 256자 | 업로드할 데이터의 MIME-Type | ||||||||||
| allowUserIds | List<string> | {scope} == “protected” | [] | 0 ~ 100 items | 공개할 사용자 ID 목록 스코프가 protected로 설정되어 있는 경우, 이 데이터 오브젝트에 접근할 수 있는 사용자를 지정합니다. 이 목록에 포함된 사용자 ID를 가진 사용자만 읽기 접근이 허용됩니다. | |||||||||
| updateIfExists | bool | false | 이미 데이터가 존재하는 경우 오류로 처리할지, 데이터를 업데이트할지 여부 |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
| uploadUrl | string | 업로드 처리를 실행하는 데 사용하는 URL |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var result = await domain.PrepareUploadAsync(
name: "dataObject-0001",
scope: "public",
contentType: "application/octet-stream",
allowUserIds: null,
updateIfExists: null
);
var item = await result.ModelAsync();
var uploadUrl = result.UploadUrl; var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
);
var future = domain.PrepareUploadFuture(
name: "dataObject-0001",
scope: "public",
contentType: "application/octet-stream",
allowUserIds: null,
updateIfExists: null
);
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;
var uploadUrl = future.Result.UploadUrl; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
);
const auto Future = Domain->PrepareUpload(
"dataObject-0001", // name
"public", // scope
"application/octet-stream" // contentType
// allowUserIds
// updateIfExists
);
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();
const auto UploadUrl = Result->UploadUrl;var domain = ez.datastore.namespace_(
"namespace-0001"
).me(game_session)
var async_result = await domain.prepare_upload(
"dataObject-0001", # name
"public", # scope
"application/octet-stream", # content_type
null, # allow_user_ids
null # update_if_exists
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultrestoreDataObject
데이터 오브젝트의 관리 정보 복구
데이터 오브젝트의 메타데이터와 실제 파일 사이의 불일치를 수정합니다.
기록되어 있는 파일 크기나 버전 번호가 실제 파일과 일치하지 않는 경우(업로드가 중단된 경우 등), 이 API가 메타데이터를 올바르게 수정합니다.
일반적으로는 호출할 필요가 없으며, 업로드 중 문제가 발생했을 때 복구 용도로만 필요합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| dataObjectId | string | ✓ | ~ 1024자 | 데이터 오브젝트 GRN |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
Error
이 API에는 특별한 예외가 정의되어 있습니다.
GS2-SDK for Game Engine에서는 게임 내에서 핸들링이 필요할 것으로 예상되는 에러를, 일반적인 예외에서 파생된 특수화된 예외로 제공하여 다루기 쉽게 하고 있습니다.
일반적인 에러의 종류와 핸들링 방법은 여기 문서를 참고해 주세요.
| 타입 | 베이스 클래스 | 설명 |
|---|---|---|
| InvalidStatusException | BadRequestException | DataObject가 조작 가능한 상태가 아닙니다 |
구현 예제
try {
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
);
var result = await domain.RestoreDataObjectAsync(
dataObjectId: "grn:gs2:ap-northeast-1:YourOwnerId:datastore:namespace-0001:user:user-0001:data:dataObject-0001"
);
var item = await result.ModelAsync();
} catch(Gs2.Gs2Datastore.Exception.InvalidStatusException e) {
// DataObject is not in operable state.
} var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
);
var future = domain.RestoreDataObjectFuture(
dataObjectId: "grn:gs2:ap-northeast-1:YourOwnerId:datastore:namespace-0001:user:user-0001:data:dataObject-0001"
);
yield return future;
if (future.Error != null)
{
if (future.Error is Gs2.Gs2Datastore.Exception.InvalidStatusException)
{
// DataObject is not in operable state.
}
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; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
);
const auto Future = Domain->RestoreDataObject(
"grn:gs2:ap-northeast-1:YourOwnerId:datastore:namespace-0001:user:user-0001:data:dataObject-0001" // dataObjectId
);
Future->StartSynchronousTask();
if (Future->GetTask().IsError())
{
auto e = Future->GetTask().Error();
if (e->IsChildOf(Gs2::Datastore::Error::FInvalidStatusError::Class))
{
// DataObject is not in operable state.
}
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();var domain = ez.datastore.namespace_(
"namespace-0001"
)
var async_result = await domain.restore_data_object(
"grn:gs2:ap-northeast-1:YourOwnerId:datastore:namespace-0001:user:user-0001:data:dataObject-0001" # data_object_id
)
if async_result.error != null:
if async_result.error is Gs2DatastoreInvalidStatusException:
# DataObject가 조작 가능한 상태가 아닙니다
pass
push_error(str(async_result.error))
return
var result = async_result.resultupdateDataObject
데이터 오브젝트의 접근 설정 변경
업로드된 데이터 오브젝트에 접근할 수 있는 범위를 변경합니다.
스코프를 public(누구나 다운로드 가능)과 protected(지정한 사용자만 다운로드 가능) 사이에서 전환하거나,
허용할 사용자 ID 목록을 업데이트할 수 있습니다.
파일 내용 자체는 변경되지 않습니다. 파일을 업데이트하려면 대신 PrepareReUpload를 사용하세요.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||||||||||
| gameSession | GameSession | ✓ | GameSession | |||||||||||
| scope | 문자열 열거형 enum { “public”, “protected”, “private” } | “private” | 파일 접근 권한 이 데이터 오브젝트에 접근할 수 있는 사용자를 제어합니다. public은 누구나 접근 가능, protected는 allowUserIds에 지정된 사용자 ID만 접근 가능, private은 오너 본인만 접근 가능합니다.
| |||||||||||
| allowUserIds | List<string> | {scope} == “protected” | [] | 0 ~ 100 items | 공개할 사용자 ID 목록 스코프가 protected로 설정되어 있는 경우, 이 데이터 오브젝트에 접근할 수 있는 사용자를 지정합니다. 이 목록에 포함된 사용자 ID를 가진 사용자만 읽기 접근이 허용됩니다. |
Result
| 타입 | 설명 | |
|---|---|---|
| item | EzDataObject | 데이터 오브젝트 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var result = await domain.UpdateDataObjectAsync(
scope: "public",
allowUserIds: null
);
var item = await result.ModelAsync(); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var future = domain.UpdateDataObjectFuture(
scope: "public",
allowUserIds: null
);
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; const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto Future = Domain->UpdateDataObject(
"public" // scope
// allowUserIds
);
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();var domain = ez.datastore.namespace_(
"namespace-0001"
).me(game_session).data_object(
"dataObject-0001"
)
var async_result = await domain.update_data_object(
"public", # scope
null # allow_user_ids
)
if async_result.error != null:
push_error(str(async_result.error))
return
var result = async_result.resultlistDataObjectHistories
데이터 오브젝트의 버전 이력 조회
데이터 오브젝트의 과거 버전(세대) 목록을 조회합니다.
PrepareReUpload로 파일을 재업로드할 때마다 이전 버전이 이력에 저장됩니다.
각 항목에는 파일 크기와 생성 일시가 포함되어 있어, 언제 무엇이 변경되었는지 확인할 수 있습니다.
버전 이력 화면을 구성하거나, 플레이어가 이전 세이브 데이터로 되돌리는 기능을 구현할 때 사용합니다.
Request
| 타입 | 활성화 조건 | 필수 | 기본값 | 값 제한 | 설명 | |
|---|---|---|---|---|---|---|
| namespaceName | string | ✓ | ~ 128자 | 네임스페이스 이름 네임스페이스 고유의 이름입니다. 영숫자 및 -(하이픈) _(언더스코어) .(마침표)로 지정합니다. | ||
| gameSession | GameSession | ✓ | GameSession | |||
| dataObjectName | string | ✓ | UUID | ~ 128자 | 데이터 오브젝트의 이름 데이터 오브젝트를 식별하는 고유한 이름입니다. 기본적으로 UUID 형식으로 자동 생성됩니다. 네임스페이스 내에서 업로드된 데이터를 참조·관리하는 데 사용됩니다. | |
| pageToken | string | ~ 1024자 | 데이터 취득을 시작할 위치를 지정하는 토큰 | |||
| limit | int | 30 | 1 ~ 1000 | 취득할 데이터 건수 |
Result
| 타입 | 설명 | |
|---|---|---|
| items | List<EzDataObjectHistory> | 데이터 오브젝트 이력 목록 |
| nextPageToken | string | 목록의 나머지를 취득하기 위한 페이지 토큰 |
구현 예제
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var items = await domain.DataObjectHistoriesAsync(
).ToListAsync(); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
var it = domain.DataObjectHistories(
);
List<EzDataObjectHistory> items = new List<EzDataObjectHistory>();
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->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
const auto It = Domain->DataObjectHistories(
);
TArray<Gs2::UE5::Datastore::Model::FEzDataObjectHistoryPtr> Result;
for (auto Item : *It)
{
if (Item.IsError())
{
return false;
}
Result.Add(Item.Current());
}값 변경 이벤트 핸들링
var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeDataObjectHistories(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeDataObjectHistories(callbackId); var domain = gs2.Datastore.Namespace(
namespaceName: "namespace-0001"
).Me(
gameSession: GameSession
).DataObject(
dataObjectName: "dataObject-0001"
);
// 이벤트 핸들링 시작
var callbackId = domain.SubscribeDataObjectHistories(
() => {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
domain.UnsubscribeDataObjectHistories(callbackId); const auto Domain = Gs2->Datastore->Namespace(
"namespace-0001" // namespaceName
)->Me(
GameSession
)->DataObject(
"dataObject-0001" // dataObjectName
);
// 이벤트 핸들링 시작
const auto CallbackId = Domain->SubscribeDataObjectHistories(
[]() {
// 리스트의 요소가 변화했을 때 호출됨
}
);
// 이벤트 핸들링 정지
Domain->UnsubscribeDataObjectHistories(CallbackId);이 이벤트는 SDK가 가진 로컬 캐시의 값이 변경되었을 때 호출됩니다.
로컬 캐시는 SDK가 가진 API의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-Distributor를 통한 스탬프 시트의 실행, 또는 GS2-Gateway의 알림을 활성화한 GS2-JobQueue의 실행에 의해 변화한 것만이 대상이 됩니다.
따라서 이 방법 이외로 값이 변경된 경우 콜백은 호출되지 않습니다.