# PC SDK Native对接指南

# 介绍

独立游戏的STOVE平台提供包括游戏发行及销售、社区、指标分析等在内的游戏上市所有过程一站式处理综合服务。 使用PC SDK(Native)可以轻松地将Stove平台提供的服务整合到游戏中。

这里说明如何对接PC SDK(Native)。

confirm 如果第一次对接PC SDK(Native),请先阅读[PCSDK Native](../Getting Started/tutorial_native.md)。

# 事先准备

  • 确认是否在STOVE Studio (opens new window)上获得了加入stove的账户和游戏上线用Appkey、App secret、Game Id。
  • 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

confirmStovePCSDK.lib 外,以上列表中的 Dll 文件必须包含在游戏客户端发布到最终用户 。

# 3) sample 文件夹

sample文件夹下方, 包含对应相关平台(Win32/x64)的Release Build,可通过StovePCSDKTestMfc.exe GUI 应用程序确认StovePCSDK流程。 首先在StovePCConfig.在MFC.ini文件输入Appkey、App secret等,然后运行StovePCSDKTestMfc.exe。 另外,可直接运行StovePCSDKTestMfc,在Setting UI中直接输入AppKey、SecretKey等。

# 构建StovePCSDK包环境

包构建环境请参考[PCSDK Native示例](../Getting Started/tutorial_native.md)的构建项目环境项目。

# 对接

# 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

除了必须对接的OnErrorOnInit CompleteOnOwnership回调函数外,其余回调函数可在必要时对接。 例如,仅使用所有权(Ownership)功能时,可对接如下。

/*只使用所有权(Ownership)功能时,
除了必须进行回拨的OnError、OnInitcomplte
添加OnOwnership进行连接 。*/
callback.OnError = OnMyErrorCallback;
callback.OnInitComplete = OnMyInitCompleteCallback;
callback.OnOwnership = OnMyOwnershipCallback;
1
2
3
4
5
6

# 2) SDK 初始化

StovePCConfig和StovePCCallback结构体初始化和回传函数连接完成后,调用`StovePC_Init' 函数以初始化 PCSDK 。

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 文件中的 StovePCResultenum 。

返回值为STOVE_PC_NO_ERROR,即<span style=color:red>成功时,可定期调用StovePC_RunCallback 函数。
只有定期调用StovePC_RunCallback 函数,连接的回拨才能正常调用。
如果呼叫周期长,回拨的响应速度也会变慢,因此最好保持适当的呼叫周期。 本指南的实例代码将调用周期设定为 0.5 秒。

confirm 连接到 PCSDK 的返回函数请在调用StovePC_RunCallback 函数的线程中调用。

除了确认 config 和 callback 有效性之外, StovePC_Init 函数将其它任务处理为异步 。
异步操作成功时, 调用 OnInitComplete 回拨; 发生错误时, 调用 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

如果需要在 OnInitComplete 回调之前查找 PC SDK 的初始化状态值,可以使用 StovePC_GetInitState 函数。

/*StovePC_Init 호출 후...*/
while(StovePC_GetInitState()
        == StovePCInitState::STOVE_PC_INIT_PENDING)
{
    sleep(500ms);
    StovePC_RunCallback();
}

if (StovePC_GetInitState()
            == StovePCInitState::STOVE_PC_INIT_COMPLETE)
{
    /*초기화 완료
    OnInitComplete 콜백이 호출됨*/
}
else
{
    /*초기화 실패
    OnError 콜백이 호출됨*/
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 3) 对接SDK时的注意事项

confirm StovePCCConfig结构体设置日志级别时,测试时请设置StovePCLogLevel:::STOVE_PC_LOG_LEVEL_DEBUG值,正式上市时请设置StovePCLogLevel::: STOVE_LOG_ERROR值。

confirm 在 PCSDK 初始化之前调用GetToken,GetUser,GetOwnership 函数可能无法正常获得结果。 也就是说,在正常接收到OnInit Complete回拨后,必须调用GetTokenGetUserGetOwnership函数才能正常接收到结果。

# 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 回拨。
通过Callback上传达的StovePCUser结构体,可以了解用户的会员号、昵称、游戏用户ID信息。 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 Launcher的用户的Access Token,游戏服务器可以将该Access Token传达给Stove认证服务器,进行登录用户的有效性验证。 有关Access Token的详细说明,请咨询store.support@smilegate.com获得技术支援。

# 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行的确认代码可以去掉。

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->ownership Code!=1/*1:所有权获得,2:所有权解除(取消购买时)*/))
        {
            continue;
        }
 
        if(0== wcscmp(L`YOUR_GAME_ID`, data->gameId) &&amp; data->gameCode==3/*3:BASIC, 4: DEMO*/)
        {
            设置为 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时显示以下提示信息(示例)后终止游戏。
    • 韩语以外的操作系统 : Please log in to STOVE Client with the account that has purchased the game.
    • 韩语:게임을 구매한 계정으로 STOVE 클라이언트에 로그인하시기 바랍니다.

confirm 即使没有拥有游戏所有权的账号,也可以测试所有权功能,详细方法请确认FAQ

# 确认错误

PC SDK使用过程中发生的错误大致可分为两种情况。

# 调用函数后返回的StovePCResultenum值

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/12/14 14:24:57