# PC SDK Cocos2d-x 연동 가이드

# 소개

STOVE 플랫폼은 인디게임을 위한 게임 배포 및 판매, 커뮤니티, 지표분석 등을 포함한, 게임 출시의 모든 과정을 원스탑으로 처리할 수 있는 통합 서비스를 제공합니다.
PC SDK를 사용하면 Stove 플랫폼이 제공하는 서비스를 게임에 쉽게 통합할 수 있습니다.

여기서는 PC SDK를 Cocos2dx에 연동하는 방법에 대해 설명합니다.

confirm PC SDK 연동이 처음이라면, PC SDK Cocos2d-x 따라하기를 먼저 읽어보기 바랍니다.

# 사전준비

  • 스토브 가입 계정과 출시 게임용 App key, App secret, Game Id를 STOVE Studio (opens new window)에서 발급받았는지 확인합니다.
  • 비주얼 스튜디오 2015 업데이트 3 이상의 컴파일러가 설치되어 있는지 확인합니다.
  • PC SDK 다운로드 페이지에서, 최신 버전의 Native(C/C++) 배포 파일(이하 StovePCSDK로 표기)을 다운로드 합니다.

# StovePCSDK 배포 파일 구성

# 1) include 폴더

StovePCSDK를 다운로드하고 압축을 풀면 include 폴더에 아래 파일들이 포함되어 있습니다.

  • StovePCDefine.h
    게임과 PC SDK 간의 커뮤니케이션을 위해 사용되는 API 호출결과(StovePCResult), 에러결과 구조체(StovePCError), 콜백 함수, API 구조체 파라미터 등이 선언되어 있습니다.

  • StovePCSDK.h
    게임과 PC SDK 간의 커뮤니케이션을 위해 사용되는 API 함수 프로토타입이 선언되어 있습니다.

# 2) bin 폴더

bin 폴더 하위에는 플랫폼(Win32/x64) 및 구성(Debug/Release)별로 필요한 바이너리가 포함되어 있습니다.

  • concrt140.dll
  • msvcp100.dll
  • msvcp140.dll
  • msvcr100.dll
  • sgup_api(64).dll
  • StovePCSDK.dll
  • vcruntime140.dll

confirm StovePCSDK.lib을 제외한 위 목록의 Dll 파일들은 게임 클라이언트를 최종 사용자에게 배포할 때, 반드시 포함되어야 합니다.

# 3) sample 폴더

sample 폴더 하위에는 StovePCSDK의 동작을 확인해 볼 수 있는 StovePCSDKTestMfc.exe GUI 애플리케이션이 각 플랫폼(Win32/x64)마다 Release 빌드로 포함되어 있습니다.
먼저, StovePCConfig.MFC.ini 파일에 App key, App secret등을 입력한 다음, StovePCSDKTestMfc.exe를 실행합니다. 또한 StovePCSDKTestMfc를 직접 실행해서 Setting UI에 AppKey, SecretKey 등을 직접 입력할 수 있습니다.

# StovePCSDK 빌드 환경 구성하기

빌드 환경 구성은 PC SDK Cocos2d-x 따라하기프로젝트 환경 구성하기 항목을 참고하세요.

# 연동하기

# 1) Config, Callback 설정

PC SDK를 초기화하기 위해서는, 먼저 StovePCConfigStovePCCallback 구조체에 값을 채운 뒤, StovePC_Init 함수를 호출합니다.
아래 코드를 참고하여 StovePCConfig 구조체의 각 필드 값을 채웁니다.

StovePCConfig config{"live",
                    "YOUR_APP_KEY",
                    "YOUR_SECRET_KEY",
                    "YOUR_GAME_ID",
                    StovePCLogLevel::STOVE_PC_LOG_LEVEL_DEBUG,
                    ""};
1
2
3
4
5
6

StovePCConfig 구조체에 대한 설명은 StovePCDefine.h 파일을 참고하세요.

게임과 PC SDK간의 커뮤니케이션은 StovePCCallback 구조체와 연결된 콜백함수들을 사용합니다.
게임 코드에서는 아래 StovePCCallback 구조체의 콜백 포인터에 연결할 함수 포인터를 사전에 정의하고 정의된 함수의 포인터를 연결시켜 줘야해야 합니다.

struct StovePCCallback
{
    /// StovePCSDK 에서 에러발생시 호출되는 콜백
    void(*OnError)(const StovePCError error);

    /// PC SDK 초기화가 완료됐을 때 호출되는 콜백
    void(*OnInitComplete)();

    /// GetToken 처리가 완료됐을 때 호출되는 콜백
    void(*OnToken)(const StovePCToken token);

    /// GetUser 처리가 완료됐을 때 호출되는 콜백
    void(*OnUser)(const StovePCUser user);

    /// GetOwnership 처리가 완료됐을 때 호출되는 콜백
    void(*OnOwnership)(int size, StovePCOwnership* ownership);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

StovePCCallback 구조체의 instance는 사용하기 전에 반드시 NULL 초기화가 필요합니다.

/* StovePCCallback 구조체 instance 생성*/
StovePCCallback callback;
/* 모든 함수 포인터를 NULL로 초기화*/
memset(&callback, 0, sizeof(StovePCCallback));
/* 구현한 함수 포인터를 연결*/
callback.OnError = OnMyErrorCallback;
callback.OnInitComplete = OnMyInitCompleteCallback;
callback.OnToken = OnMyTokenCallback;
callback.OnUser = OnMyUserInfoCallback;
callback.OnOwnership = OnMyOwnershipCallback;
1
2
3
4
5
6
7
8
9
10

필수적으로 연동해야 하는 OnError, OnInitComplete, OnOwnership 콜백함수 외의 나머지 콜백함수는 필요 시에만 연동을 하면 됩니다. 예를 들어, 소유권(Ownership) 기능만 사용하는 경우, 아래와 같이 연결하면 됩니다.

/*소유권(Ownership) 기능만 사용하는 경우는,
필수 구현 콜백인 OnError, OnInitcomplte외에
OnOwnership 콜백만 추가로 구현해서 연결합니다.*/
callback.OnError = OnMyErrorCallback;
callback.OnInitComplete = OnMyInitCompleteCallback;
callback.OnOwnership = OnMyOwnershipCallback;
1
2
3
4
5
6

# 2) SDK 초기화

StovePCConfig와 StovePCCallback 구조체 초기화 및 콜백함수 연결이 완료되었으면 PC SDK를 초기화하기 위해 StovePC_Init 함수를 호출합니다.

StovePCResult result = StovePC_Init(config, callback);
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*StovePCSDK init 성공
    타이머 등을 이용해서 일정 주기로 StovePC_RunCallback 함수 호출*/

}
1
2
3
4
5
6
7

StovePC_Init 함수는 config와 callback의 유효성 여부만 확인한 후, 즉시 StovePCResult enum 타입 값을 반환합니다.
성공한 경우, STOVE_PC_NO_ERROR 값이 반환됩니다. 실패한 경우는 해당 에러 코드를 반환하며 게임 종료를 처리해야 합니다. 전체 에러 코드 목록은 StovePCDefine.h 파일의 StovePCResult enum을 확인하면 됩니다.

반환값이 STOVE_PC_NO_ERROR, 즉 '성공'인 경우, StovePC_RunCallback 함수를 주기적으로 호출해 줍니다.
StovePC_RunCallback 함수를 주기적으로 호출해야만, 연결된 콜백이 정상적으로 호출됩니다.
호출 주기가 길면 콜백의 응답 속도도 느려지게 되므로, 적당한 호출 주기를 유지하는 것이 좋습니다. 본 가이드의 예제 코드는 호출 주기를 1초로 설정했습니다.

confirm PC SDK에 연결된 콜백은 StovePC_RunCallback 함수를 호출한 스레드에서만 호출됩니다.

Cocos2dx에서는 schedule 함수 (opens new window)를 사용해서 일정 주기마다 필요한 작업을 처리할 수 있습니다.
아래는 1초마다 StovePC_RunCallback 함수를 호출하는 예시 코드입니다.

...
StovePCResult result = StovePC_Init(config, callback);
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*PC SDK 초기화가 성공했으면, 1초마다 updateTimer 함수를 호출하도록 스케쥴러 실행*/
    schedule(schedule_selector(StartScene::updateTimer), 1.0f);
}
...

void StartScene::updateTimer(float time)
{
    StovePC_RunCallback();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14

StovePC_Init 함수는 config와 callback 유효성 확인을 제외한, 그 외의 작업을 비동기로 처리합니다.
비동기 작업이 성공적으로 완료된 경우, OnInitComplete 콜백이 호출되며, 에러가 발생한 경우는 OnError 콜백이 호출됩니다.
에러가 발생한 경우, OnError 콜백으로 전달된 StovePCError 구조체를 통해 에러 코드, 메시지 등을 확인할 수 있습니다.

void OnInitComplete()
{
    printf("pc sdk init success");
}

void OnError(const StovePCError error)
{
	switch (Error.functionType)
	{
	case STOVE_PC_INIT:
	case STOVE_PC_GET_USER:
	case STOVE_PC_GET_OWNERSHIP:
		QuitApplicationDueToError();
		break;
	}
}

void QuitApplicationDueToError()
{
	// 어쩌면 당신은 즉시 앱을 중단하기보다는 사용자에게 앱 중단에 대한 메시지를 보여준 후
	// 사용자 액션(e.g. 종료 버튼 클릭)에 따라 앱을 중단하고 싶어 할지도 모릅니다.
	// 그렇다면 여기에 QuitApplication을 지우고 당신만의 로직을 구현하십시오.
	// 권장하는 필수 사전 작업 오류에 대한 메시지는 아래와 같습니다.
	// 한국어 : 필수 사전 작업이 실패하여 게임을 종료합니다.
	// 그 외 언어 : The required pre-task fails and exits the game.
	OnStoveLog("QuitApplicationDueToError");
	exit(0)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 3) SDK 연동시 주의사항

confirm StovePCConfig 구조체의 로그레벨 설정시 테스트 시에는 StovePCLogLevel::STOVE_PC_LOG_LEVEL_DEBUG 값으로 설정하고, 정식 출시 시에는 StovePCLogLevel::STOVE_PC_LOG_LEVEL_ERROR 값으로 설정하기 바랍니다.

confirm 초기화가 완료되기 전에 GetToken, GetUser, GetOwnership 메서드를 호출하면 정상적으로 결과를 받지 못할 수 있습니다. 즉, OnInitComplete 콜백이 정상적으로 수신된 이후에 GetToken, GetUser, GetOwnership 메서드를 호출해야 정상적으로 결과를 받을 수 있습니다.

# 4) SDK 종료

PC SDK 사용이 끝난 뒤에 StovePC_UnInit 함수를 호출하여 사용중인 리소스를 정리합니다.

StovePCResult result = StovePC_UnInit();
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*성공 처리*/
}
...
1
2
3
4
5
6

# 5) 사용자 정보 얻기

StovePC_GetUser 함수로 STOVE 런처에 로그인한 사용자 정보를 조회합니다.

StovePCResult result = StovePC_GetUser();
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*성공 처리*/
}
1
2
3
4
5

StovePC_GetUser 함수가 정상적으로 처리되면 OnUser 콜백이 호출됩니다.
콜백에 전달되는 StovePCUser 구조체를 통해 사용자의 멤버넘버, 닉네임, 게임사용자아이디 정보들을 알 수 있습니다. StovePCUser 구조체에 대한 설명은 StovePCDefine.h 파일에 설명되어 있습니다.

void OnUser(const StovePCUser user)
{
    /*사용자 정보 출력*/
    printf("User Info(memberNo = %I64d, nickname = %S, gameUserId = %s)",
                      user.memberNo, user.nickname, user.gameUserId);
}
1
2
3
4
5
6

# 6) 토큰 정보 얻기

StovePC_GetToken 함수로 STOVE 런처에 로그인한 사용자의 토큰 정보를 확인 할 수 있습니다.

StovePCResult result = StovePC_GetToken();
if (result == StovePCResult::STOVE_PC_NO_ERROR)
{
    /*성공 처리*/
}
1
2
3
4
5

StovePC_GetToken 함수가 정상적으로 처리되면 OnToken 콜백이 호출됩니다.
콜백에 전달되는 StovePCToken 구조체에는 토큰 문자열이 포함되어 있습니다.

void OnToken(const StovePCToken token)
{
    /*토큰 정보 출력*/
    printf("Token : %s", token.accessToken);
}
1
2
3
4
5

confirm 토큰이란? STOVE 런처에 로그인된 사용자의 엑세스토큰(Access Token)으로 게임서버가 이 엑세스토큰을 스토브 인증서버로 전달해서 로그인한 사용자의 유효성 검증을 수행할 수 있습니다. 엑세스토큰에 대한 상세한 설명은 스토브 인디팀에 문의하기 로 기술지원을 받으시길 바랍니다

# 7) 소유권 정보 얻기

StovePC_GetOwnership 함수로 로그인한 사용자가 해당 게임을 구매해서 소유하고 있는지 여부를 확인 할 수 있습니다.


StovePCResult result = StovePC_GetOwnership();
if (result == STOVE_PC_NO_ERROR)
{
    /*성공 처리*/
    /*소유권에 관한 정보는 OnOwnership 콜백으로 전달됩니다.*/ 
}
1
2
3
4
5
6
7

StovePC_GetOwnership 함수가 정상적으로 처리되면 OnOwnership 콜백이 호출됩니다.
OnOwnership 콜백의 파라미터인 StovePCOwnership 구조체에 대한 세부 정보는 StovePCDefine.h 파일을 참고하세요.

아래는 OnOwnership 콜백에서 게임 구매 여부를 판단하는 예시 코드입니다.
DLC가 없는 패키지게임인 경우, 20~23 line의 확인 코드는 불필요합니다.

void OnOwnership(int size, StovePCOwnership* ownership)
{
    bool owned = false;
 
    StovePCOwnership* data = ownership;
    for (int i = 0; i < size; i++, data++)
    {
        if ((data->memberNo != LOGIN_USER_MEMBER_NO /*StovePCUser 구조체의 memberNo*/)
            || (data->ownershipCode != 1 /*1:소유권 획득, 2:소유권 해제(구매 취소한 경우)*/))
        {
            continue;
        }
 
        if (0 == wcscmp(L"YOUR_GAME_ID", data->gameId) && data->gameCode == 3 /* 3: 인디게임*/)
        {
            owned = true; // 소유권 확인 변수 true로 설정
        }
 
        /*DLC를 판매하는 인디게임일 때만 필요*/
        if (0 == wcscmp(L"YOUR_DLC_ID", data->gameId) && data->gameCode == 5 /* 5: DLC*/)
        {
            // YOUR_DLC_ID(DLC) 소유권이 있기에 DLC 플레이 허용
        }
    }
 
    if(owned)
    {
        // 소유권 검증이 정상적으로 완료된 이후 게임진입 로직 작성
    }
    else
    {
        // 소유권 검증실패 후 게임을 종료하고 에러메세지 표출 로직 작성
    }
     
     
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  • 게임을 구매한 계정(소유권 보유)으로 STOVE 런처에 로그인한 후 게임을 플레이를 할 수 있습니다.
  • 게임 소유권이 없는 계정으로 STOVE 런처에 로그인한 후 exe 실행 시 아래 안내 메시지(예시)를 출력한 후 게임을 종료합니다.
    • 한국어 외의 OS : Please log in to STOVE Client with the account that has purchased the game.
    • 한국어 : 게임을 구매한 계정으로 STOVE 클라이언트에 로그인하시기 바랍니다.

# 에러 확인

PC SDK 사용 중 발생하는 에러는 크게 두 가지 경우로 구분해서 확인할 수 있습니다.

# 함수 호출 후 반환되는 StovePCResult enum 값

PC SDK의 모든 함수는 호출 직후, 호출이 성공했는지 여부를 나타내는 StovePCResult enum 값을 반환합니다.
전체값은 PC SDK 오류 코드 페이지에서 확인 할 수 있습니다.

# OnError 콜백을 통해 전달되는 StovePCError 구조체

PC SDK 함수 중, 비동기로 동작하는 코드블럭에서 에러가 발생한 경우는 OnError 콜백이 호출되며, 에러에 대한 설명이 포함된 StovePCError 구조체가 전달됩니다.

/*OnError 콜백이 호출될 때 전달 됩니다.*/
struct StovePCError
{
    /*호출된 함수를 나타내는 enum 값*/
    StovePCFunctionType functionType;

    /*발생한 에러 유형을 나타내는 enum 값*/
    StovePCResult result;

    /*발생한 에러 메시지*/
    char* message;

    /*외부 에러(http 에러, 외부 모듈 에러)가 발생한 경우, 해당하는 에러 코드*/
    int externalError; 
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Last Updated: 2023. 8. 22. 오전 1:49:10