统计
1. 概述
统计是一项帮助您存储和跟踪玩家或全局统计数据的服务。默认情况下,统计也是 Leaderboard 服务的主要数据源。
阅读本章,您将了解关键机制以及如何设置和使用统计。
2. 关键概念
2.1 Stat
Stat本质上是一个用于存储统计数据的数据映射。其中的每个数据项都包含以下关键字段:
- Key:这是一个用于标识数据项的唯一字符串。Key 的具体设置取决于您的场景。例如,您可以将其设置为 PlayerID 来跟踪玩家的击杀数,或者将其设置为 TeamID 来跟踪团队的得分。
- Value:该数据项的值是 double 类型,默认值为 0。
- Secondary Value:这是一个可选的数据项值,也是 double 类型,默认值为 0。它用于 Leaderboard 服务中的多值排序。如果您不需要多值排序,可以忽略此字段。
- Tags:可以为数据项添加标签。此字段用于在 Leaderboard 服务中配置和构建子排行榜。您还可以使用它来存储任意字符串来标记数据项。
- custom_data: data item可以添加 custom_data 字段,用于存储附加信息。
您可以使用特定的聚合类型更新 Stat 中的数据项。下表概述了此机制:
Aggregate Type | Value | Secondary Value | Tags |
---|---|---|---|
Override | Overwrite | Overwrite | Overwrite |
Sum | 新值与现有值之和 | Overwrite | Overwrite |
Max | 如果新值大于现有值,则Overwrite | 如果值更新则Overwrite | 如果值更新则Overwrite |
Min | 如果新值小于现有值,则Overwrite | 如果值更新则Overwrite | 如果值更新则Overwrite |
2.2 周期
您可以使用“周期”功能来跟踪特定时间段内的统计数据。当您将属性绑定到周期后,PGOS 后端会在您更新Stat数据时自动更新周期数据。周期结束后,数据将被重置,例如,允许玩家开始新的比赛。例如,游戏可以跟踪每日击杀数或赛季最佳游戏会话得分。
您可以选择不同的周期类型,包括每日、每周、每月和季度(自定义)。您可以确定每种周期类型的重置时间。对于季度周期,您可以为每个周期定义重置时间,例如,为持续 90 天的游戏赛季定义 90 天的重置时间。
一个Stat可以绑定多个Cycle,一个Cycle也可以绑定多个Stat。
请注意,如果在绑定后将数据更新到 Cycle,则绑定之前的已存在的 Stat 数据将不会再传输到 Cycle。。
Stat 不与 Cycle 绑定:其中只有一个持久数据图,如下图所示:
Stat 与 Cycle 绑定:每个绑定的 Cycle 都有一个额外的 Cycle 数据映射。每个 Cycle 数据与持久数据分开存储,如下图所示:
3. 在门户网站上管理
3.1 统计信息
3.1.1 添加新统计信息
登录 Web 门户,进入控制台,然后前往Statistics > Stats:
字段说明:
- Stat名称:新统计的名称。它只能包含字母、数字和下划线,并且必须以字母开头。
- 最小值(可选):统计项值的最小值。如果需要限制项值的最小值,请启用并指定限制值。
- 最大值(可选):统计项值的最大值。如果需要限制项值的最大值,请启用并指定限制值。
- 描述(可选):统计项的描述。
如果一切正常,您将获得一条新统计:
3.1.2 编辑统计数据
如果您想编辑某个统计数据,请点击统计数据列表中的编辑链接按钮:
对最大限制和最小限制的修改仅影响后续的更新操作,不会改变现有数据。
3.1.3 删除统计数据
如果您想移除某个统计数据,请点击统计数据列表中的删除链接按钮:
一旦统计数据被删除,其数据将无法再通过“PgosSDK”或 HTTP API 访问。
3.1.4 管理统计项
点击Stat Name即可开始管理统计项:
点击Stat Name后,您将看到最近更新的统计项列表:
如果要搜索特定项,请输入Item key,然后单击搜索按钮:
如果您想同时搜索多个项,请启用multi-keys复选框,并在搜索框中输入多个item key。
如果您想添加/更新统计项,请点击添加/更新数据按钮:
填写所有字段并点击确定按钮,然后:
- 如果 item key存在,则更新该项目。
- 如果 item key不存在,则添加该项目。
3.2 周期
3.2.1 添加新周期
登录 Web 门户,进入控制台,然后前往Statistics > Cycle:
字段说明:
- 名称:新周期的名称。名称只能包含字母、数字和下划线,且必须以字母开头。
- 类型:周期类型,表示数据重置的周期,包括每日、每周、每月和季节性(自定义)。
- 重置时间:重置周期数据的时间。
- 开始日期时间:周期开始执行的时间。
- 结束日期时间(可选):此时间表示Cycle停止运行的时间。
- 锁定时间跨度(可选):在Cycle的最后几秒锁定数据,以防止新的提交。默认为 0。
- 描述(可选):周期的描述。
如果一切顺利,您将获得一个新的周期:
3.2.2 编辑周期
如果您想编辑周期,请点击周期列表中的编辑链接按钮:
3.2.3 删除周期
如果您想移除某个周期,请点击周期列表中的删除按钮:
3.2.4 将统计信息绑定到周期
如果您希望某个统计信息包含周期数据,则需要将该统计信息绑定到周期。在周期列表中,点击要绑定的cycle name:
点击cycle name 后,你将会看到以下信息:
点击 Bind Stat button, 你可以绑定stats到周期:
您可以选择要绑定到周期的统计。绑定后,您选择的统计将出现在已绑定统计列表中:
如果要从周期中解除绑定某个统计数据,请点击绑定统计数据列表中的删除链接按钮:
3.2.5 查看周期数据
将Stats绑定到周期后,您将能够在以后更新Stats Item数据时同时获取相应的周期数据。如果您想在控制台中查看周期数据,请进入Manage stat items页面,点击物品键旁边的下拉箭头,即可查看周期数据:
4. Cycle机制
Statistics服务持久化统计数据时,其逻辑如下:
- 基本持久化 无论统计数据是否与Cycle关联,都会始终存储一条永久的“持久化”统计数据记录。除非开发者通过移除统计数据定义明确删除,否则这些数据将无限期地保留。
- Cycle绑定的数据处理
对于与Cycle绑定的统计数据:
- 服务为每个绑定Cycle维护独立存储
- cycle重置机制:
- 每次“cycle”完成时,触发重置
- 上一cycle的数据将被存档
- 后续cycle的数据将被持久化
Cycle排序
- 每个cycle维护一个“cycle序列”计数器
- 初始化为 1(表示cycle中的第一轮)
- 按顺序递增(cycle序列 = n 表示第 n 轮迭代)
- 达到cycle配置的结束日期时间时,排序停止
锁定时间的执行
在每个cycle的最后 N 秒(可通过“锁定时间跨度”参数配置):
拒绝新的数据更新请求
默认禁用锁定(设置锁定时间跨度 = 0 表示禁用)
例如,在游戏 A 的运营事件配置中:
- 每周晚上 8:00 发布顶级矿工排名,并将奖励分发给前 100 名玩家。
- 为了在晚上 8:00 之前完成排名,服务器需要时间:
- 提取排行榜结果
- 验证数据完整性(例如,进行漏洞/黑客攻击的反作弊检查)
- 为了在晚上 8:00 之前完成排名,服务器需要时间:
如果重置时间设置为晚上 8:00,则必须预留缓冲期来完成这些操作。这可以通过配置锁定时间跨度参数来实现。
关键约束:
- 配置的锁定时间跨度不得超过一轮的总时长。
5. 边界情况
使用 Stat 和 Cycle 时,可能会遇到以下边界情况,请注意。
5.1 Stat 的最小/最大限制
在配置 Stat 的最小或最大限制时,如果使用以下聚合类型的值的结果可能超出最小或最大限制,PGOS 将按下表所示进行处理。
Aggregate Type | Value Result |
---|---|
Override | 大于最大限制的值将被设置为最大限制本身,而小于最小限制的值将被设置为最小限制本身。 |
Sum | 如果值的总和超过了最大限制,则该值将被设置为最大限制本身。如果值的总和小于最小限制,则该值将被设置为最小限制本身。 |
Max | 将当前值与大于最大限制的值进行比较时,该值将被设置为最大限制本身。 |
Min | 将当前值与小于最小限制的值进行比较时,该值将被设置为最小限制本身。 |
让我们以“最小值:0 最大值:100”限制为例:
Aggregate Type | Old Value | Value In Request | Result Value |
---|---|---|---|
Override | 75 | 150 | 100 |
Override | 75 | -100 | 0 |
Sum | 75 | 30 | 100 |
Sum | 75 | -100 | 0 |
Max | 75 | 150 | 100 |
Min | 75 | -100 | 0 |
5.2 周期首次重置时间
在某些情况下,周期的首次重置时间可能短于预设的重置时间。以下示例可能会出现这种情况:
每日周期
Cycle Type | Reset Time | Start Date |
---|---|---|
Daily | 10:00 | 2023-09-01 00:00:00 |
首次重置时间为 2023-09-01 10:00:00,即周期开始后 10 小时,而非 24 小时。下次重置时间为 2023-09-02 10:00:00,之后的重置时间亦如此。
每周周期
Cycle Type | Reset Time | Reset Weekday | Start Date |
---|---|---|---|
Weekly | 10:00 | Tuesday | 2023-01-01 00:00:00 (Let's assume this day is Monday) |
第一次重置时间为 2023-01-02 10:00(星期二),下次重置时间为 2023-01-09 10:00,之后每次重置时间均相同。
月周期
Cycle Type | Reset Time | Reset Monthday | Start Date |
---|---|---|---|
Monthly | 10:00 | 5 | 2023-01-01 00:00:00 |
第一次重置时间为 2023 年 1 月 5 日 10:00(星期二),下一次重置时间为 2023 年 2 月 5 日 10:00,之后的重置时间也一样。
如您所见,在上述场景中,第一次重置的时间周期通常小于Cycle Type中配置的时间周期。如果出现这种情况,请注意,这是符合预期的。
5.3 周期每月重置边界案例
使用月周期时,如果重置日期超过当月的最大天数,则默认为当月最后一天。
Cycle Type | Reset Time | Reset Monthday | Start Date |
---|---|---|---|
Monthly | 10:00 | 31 | 2024-02-01 00:00:00 |
第一次重置时间为2024-02-28 10:00:00,即该月的最后一天。
6. 通过 SDK 访问
6.1 客户端
游戏可以通过 PgosSDK
在游戏客户端查询统计数据。
API | 描述 |
---|---|
GetStatPersistentInfo | 查询指定stat item的持久信息。 |
BatchGetStatPersistentInfo | 批量查询指定Stat name和key的stat item的持久信息。 |
GetStatCycleInfo | 查询当前周期轮次中指定stat item的周期信息。 |
BatchGetStatCycleInfo | 批量查询当前周期轮次中指定 stat names 和 keys的周期信息。 |
BatchGetStatCycleRoundInfo | 批量查询当前周期的轮次信息 |
6.1.1 GetStatPersistentInfo 客户端 API
查询指定统计项的持久化信息。
接口原型:
/**
* Query the persistent info of the specified stat item.
*
* @param Params Request structure for querying persistent info.
*/
void GetStatPersistentInfo(
const FGetStatPersistentInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FStatItem* Data)> Callback) const;
struct FGetStatPersistentInfoParams {
/** Stat name. */
FString stat_name;
/** Stat item key. */
FString key;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FGetStatPersistentInfoParams Params;
Params.stat_name = TEXT("EnemyKills");
Params.key = TEXT("p456792");
Statistics->GetStatPersistentInfo(Params, [](const FPgosResult& Ret, const FStatItem* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStatPersistentInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStatPersistentInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.1.2 BatchGetStatPersistentInfo 客户端 API
批量查询指定stat name和key的持久化信息。
接口原型:
/**
* Query item persistent info with specified stat names and keys in batches.
* For example: stat_names=["s1", "s2"], keys=["k1", "k2"],
* then you will get a batch of items:[("s1", "k1"), ("s1", "k2"), "s2", "k1"), ("s2", "k2")]
* It will ignore non-existing (stat_name + key) combination items.
*
* @param Params Request structure for querying item persistent infos.
*/
void BatchGetStatPersistentInfo(
const FBatchGetStatPersistentInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatPersistentInfoResult* Data)> Callback) const;
struct FBatchGetStatPersistentInfoParams
{
/** Stat names. */
TArray<FString> stat_names;
/** Stat item keys. */
TArray<FString> keys;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FBatchGetStatPersistentInfoParams Params;
Params.stat_names.Add(TEXT("EnemyKills"));
Params.stat_names.Add(TEXT("PlayerDeaths"));
Params.keys.Add(TEXT("p456791"));
Params.keys.Add(TEXT("p456792"));
Statistics->BatchGetStatPersistentInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatPersistentInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatPersistentInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatPersistentInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.1.3 GetStatCycleInfo 客户端 API
查询当前周期轮次中指定stat item的周期信息。
接口原型:
/**
* Query the cycle info of the specified stat item for the current cycle round.
*
* @param Params Request structure for querying the cycle info.
*/
void GetStatCycleInfo(
const FGetStatCycleInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FGetStatCycleInfoResult* Data)> Callback) const;
struct FGetStatCycleInfoParams
{
/** The stat name. */
FString stat_name;
/** The stat item key. */
FString key;
/** The stat cycle name. */
FString cycle_name;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FGetStatCycleInfoParams Params;
Params.stat_name = TEXT("EnemyKills");
Params.key = TEXT("p456792");
Params.cycle_name = TEXT("Daily");
Statistics->GetStatCycleInfo(Params, [](const FPgosResult& Ret, const FGetStatCycleInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStatCycleInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.1.4 BatchGetStatCycleInfo 客户端 API
批量查询当前周期轮次中指定 stat names 和 keys的周期信息。
接口原型:
/**
* Query cycle info with specified stat names and keys for the current cycle round in batches.
* For example: stat_names=["s1", "s2"], keys=["k1", "k2"],
* then you will get a batch of items:[("s1", "k1"), ("s1", "k2"), "s2", "k1"), ("s2", "k2")]
* It will ignore non-existing (stat_name + key) combination items.
*
* @param Params Request structure for querying item cycle infos.
*/
void BatchGetStatCycleInfo(
const FBatchGetStatCycleInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatCycleInfoResult* Data)> Callback) const;
struct FBatchGetStatCycleInfoParams
{
/** The stat names. */
TArray<FString> stat_names;
/** The stat item keys. */
TArray<FString> keys;
/** The stat cycle name. */
FString cycle_name;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FBatchGetStatCycleInfoParams Params;
Params.stat_names.Add(TEXT("EnemyKills"));
Params.stat_names.Add(TEXT("PlayerDeaths"));
Params.keys.Add(TEXT("p456791"));
Params.keys.Add(TEXT("p456792"));
Params.cycle_name = TEXT("Daily");
Statistics->BatchGetStatCycleInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatCycleInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.1.5 BatchGetStatCycleRoundInfo 客户端 API
批量查询周期的当前轮次信息。
接口原型:
/**
* Query the current round infos of cycles in batches.
*
* @param Params Request structure for querying current round infos.
*/
void BatchGetStatCycleRoundInfo(
const FBatchGetStatCycleRoundInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatCycleRoundInfoResult* Data)> Callback) const;
struct FBatchGetStatCycleRoundInfoParams
{
/** The stat cycle names. */
TArray<FString> cycle_names;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetClientStatisticsAPI();
if (Statistics)
{
FBatchGetStatCycleRoundInfoParams Params;
Params.cycle_names.Add(TEXT("Daily"));
Params.cycle_names.Add(TEXT("Weekly"));
Statistics->BatchGetStatCycleRoundInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatCycleRoundInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleRoundInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.2 服务器端
游戏可以通过 PgosSDK
在游戏服务器上查询和更新统计数据。
API | 描述 |
---|---|
GetStatPersistentInfo | 查询指定stat item的持久信息 |
BatchGetStatPersistentInfo | 批量查询指定stat item 和key的stat item的持久信息 |
GetStatCycleInfo | 查询当前周期轮次中指定stat item的周期信息。 |
BatchGetStatCycleInfo | 批量查询当前周期轮次中指定 stat names 和 keys的周期信息。 |
UpdateStatItem | 更新指定stat items. |
BatchUpdateStatItem | 批量更新指定stat items |
BatchGetStatCycleRoundInfo | 批量查询周期的当前轮次信息。 |
6.2.1 GetStatPersistentInfo Server API
查询指定stat item的持久信息
接口原型:
/**
* Query the persistent info of the specified stat item.
*
* @param Params Request structure for querying persistent info.
*/
void GetStatPersistentInfo(
const FGetStatPersistentInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FStatItem* Data)> Callback) const;
struct FGetStatPersistentInfoParams {
/** Stat name. */
FString stat_name;
/** Stat item key. */
FString key;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FGetStatPersistentInfoParams Params;
Params.stat_name = TEXT("EnemyKills");
Params.key = TEXT("p456792");
Statistics->GetStatPersistentInfo(Params, [](const FPgosResult& Ret, const FStatItem* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStatPersistentInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStatPersistentInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.2.2 BatchGetStatPersistentInfo Server API
批量查询指定stat item 和key的stat item的持久信息。
接口原型:
/**
* Query item persistent infos with specified stat names and keys in batches.
* For example: stat_names=["s1", "s2"], keys=["k1", "k2"],
* then you will get a batch of items:[("s1", "k1"), ("s1", "k2"), "s2", "k1"), ("s2", "k2")]
* It will ignore non-existing (stat_name + key) combination items.
*
* @param Params Request structure for querying item persistent infos.
*/
void BatchGetStatPersistentInfo(
const FBatchGetStatPersistentInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatPersistentInfoResult* Data)> Callback) const;
struct FBatchGetStatPersistentInfoParams
{
/** Stat names. */
TArray<FString> stat_names;
/** Stat item keys. */
TArray<FString> keys;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FBatchGetStatPersistentInfoParams Params;
Params.stat_names.Add(TEXT("EnemyKills"));
Params.stat_names.Add(TEXT("PlayerDeaths"));
Params.keys.Add(TEXT("p456791"));
Params.keys.Add(TEXT("p456792"));
Statistics->BatchGetStatPersistentInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatPersistentInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatPersistentInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatPersistentInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.2.3 GetStatCycleInfo Server API
查询当前周期轮次中指定stat item的周期信息。
接口原型:
/**
* Query the cycle info of the specified stat item for the current cycle round.
*
* @param Params Request structure for querying the cycle info.
*/
void GetStatCycleInfo(
const FGetStatCycleInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FGetStatCycleInfoResult* Data)> Callback) const;
struct FGetStatCycleInfoParams
{
/** The stat name. */
FString stat_name;
/** The stat item key. */
FString key;
/** The stat cycle name. */
FString cycle_name;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FGetStatCycleInfoParams Params;
Params.stat_name = TEXT("EnemyKills");
Params.key = TEXT("p456792");
Params.cycle_name = TEXT("Daily");
Statistics->GetStatCycleInfo(Params, [](const FPgosResult& Ret, const FGetStatCycleInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetStatCycleInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.2.4 BatchGetStatCycleInfo Server API
批量查询当前周期轮次中指定 stat names 和 keys的周期信息。
接口原型:
/**
* Query cycle infos with specified stat names and keys for the current cycle round in batches.
* For example: stat_names=["s1", "s2"], keys=["k1", "k2"],
* then you will get a batch of items:[("s1", "k1"), ("s1", "k2"), "s2", "k1"), ("s2", "k2")]
* It will ignore non-existing (stat_name + key) combination items.
*
* @param Params Request structure for querying item cycle infos.
*/
void BatchGetStatCycleInfo(
const FBatchGetStatCycleInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatCycleInfoResult* Data)> Callback) const;
struct FBatchGetStatCycleInfoParams
{
/** The stat names. */
TArray<FString> stat_names;
/** The stat item keys. */
TArray<FString> keys;
/** The stat cycle name. */
FString cycle_name;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FBatchGetStatCycleInfoParams Params;
Params.stat_names.Add(TEXT("EnemyKills"));
Params.stat_names.Add(TEXT("PlayerDeaths"));
Params.keys.Add(TEXT("p456791"));
Params.keys.Add(TEXT("p456792"));
Params.cycle_name = TEXT("Daily");
Statistics->BatchGetStatCycleInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatCycleInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.2.5 UpdateStatItem Server API
更新指定的stat item。
接口原型:
/**
* Update the specified stat item.
*
* @param Params Request structure for updating the specified stat item.
*/
void UpdateStatItem(
const FServerUpdateStatItemParams& Params,
TFunction<void(const FPgosResult& Ret, const FServerStatItemAfterUpdate* Data)> Callback) const;
struct FServerUpdateStatItemParams
{
/** The stat item to update. */
FStatItem item;
/** Whether update custom data. It won't overwrite the old one when updated if this is true. */
bool ignore_custom_data = false;
/** Whether update tags. It won't overwrite the old one when updated if this is true. */
bool ignore_tags = false;
};
struct FStatItem
{
/** Stat name. */
FString stat_name;
/** Stat item key. */
FString key;
/**
* The meaning of the value varies in different scenarios:
* 1. Get stat item persistent value: it is item persistent value.
* 2. Get stat item cycle value: it is item cycle value.
* 3. Update stat item value: it is the value to be aggregated into the stat item.
*/
double value = 0.0;
/** Stat item secondary value. It will overwrite the old one when updated. */
double secondary_value = 0.0;
/** Stat item tags. It will overwrite the old one when updated if 'ignore_tags' is false. Max 10 values, each value limited to 64 bytes(in a narrow-character string) */
TArray<FString> tags;
/** Used to store additional information. It will overwrite the old one when updated if 'ignore_custom_data' is false. Limited to 512 bytes(in a narrow-character string) */
FString custom_data;
/** The method to aggregate. */
EPgosAggregateType aggregate_type = EPgosAggregateType::Overwrite;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FServerUpdateStatItemParams Params;
Params.item.stat_name = TEXT("EnemyKills");
Params.item.key = TEXT("p456792");
Params.item.value = 2;
Params.item.aggregate_type = EAggregateType::Sum;
Statistics->UpdateStatItem(Params, [](const FPgosResult& Ret, const FServerStatItemAfterUpdate* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("UpdateStatItem Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("UpdateStatItem Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.2.6 BatchUpdateStatItem Server API
批量更新stat items。
接口原型:
/**
* Update the stat items in batches.
*
* @param Params Request structure for updating the stat items in batches.
*/
void BatchUpdateStatItem(
const FServerBatchUpdateStatItemParams& Params,
TFunction<void(const FPgosResult& Ret, const FServerBatchUpdateStatItemResult* Data)> Callback) const;
struct FServerBatchUpdateStatItemParams
{
/** The stat items to update. */
TArray<FStatItem> items;
/** Whether update custom data. It won't overwrite the old one when updated if this is true. */
bool ignore_custom_data = false;
/** Whether update tags. It won't overwrite the old one when updated if this is true. */
bool ignore_tags = false;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FStatItem item1;
item1.stat_name = TEXT("EnemyKills");
item1.key = TEXT("p600001");
item1.value = 2;
item1.aggregate_type = EAggregateType::Sum;
FStatItem item2;
item2.stat_name = TEXT("EnemyKills");
item2.key = TEXT("p600002");
item2.value = 5;
item2.aggregate_type = EAggregateType::Sum;
FServerBatchUpdateStatItemParams Params;
Params.items.Add(item1);
Params.items.Add(item2);
Statistics->BatchUpdateStatItem(Params, [](const FPgosResult& Ret, const FServerBatchUpdateStatItemResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchUpdateStatItem Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchUpdateStatItem Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.2.7 BatchGetStatCycleRoundInfo Server API
批量查询周期的当前轮次信息。
接口原型:
/**
* Query the current round infos of cycles in batches.
*
* @param Params Request structure for querying current round infos.
*/
void BatchGetStatCycleRoundInfo(
const FBatchGetStatCycleRoundInfoParams& Params,
TFunction<void(const FPgosResult& Ret, const FBatchGetStatCycleRoundInfoResult* Data)> Callback) const;
struct FBatchGetStatCycleRoundInfoParams
{
/** The stat cycle names. */
TArray<FString> cycle_names;
};
代码示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto Statistics = IPgosSDKCpp::Get().GetServerStatisticsAPI();
if (Statistics)
{
FBatchGetStatCycleRoundInfoParams Params;
Params.cycle_names.Add(TEXT("Daily"));
Params.cycle_names.Add(TEXT("Weekly"));
Statistics->BatchGetStatCycleRoundInfo(Params, [](const FPgosResult& Ret, const FBatchGetStatCycleRoundInfoResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetStatCycleRoundInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
6.3 关键错误处理
错误码 | 相关API | Handling Suggestion |
---|---|---|
kBackendStatItemMissingCriticalFields | GetStatPersistentInfo Client API BatchGetStatPersistentInfo Client API GetStatCycleInfo Client API BatchGetStatCycleInfo Client API GetStatPersistentInfo Server API BatchGetStatPersistentInfo Server API GetStatCycleInfo Server API BatchGetStatCycleInfo Server API UpdateStatItem Server API BatchUpdateStatItem Server API | 缺失关键字段,如 stat_name,key。 |
kBackendStatKeysNoData | GetStatPersistentInfo Client API BatchGetStatPersistentInfo Client API GetStatCycleInfo Client API BatchGetStatCycleInfo Client API GetStatPersistentInfo Server API BatchGetStatPersistentInfo Server API GetStatCycleInfo Server API BatchGetStatCycleInfo Server API | 未找到指定stat 和周期的数据 |
kSdkNetworkError | All Network API | 网络错误, 检查错误日志,获取更多细节 |