玩家 KV 数据
1. 概述
玩家key-value数据是与玩家关联的一组数据。具体来说,它是一系列在网页控制台中定义的key-value键值对,通常与游戏玩法相关并由游戏本身配置,例如玩家等级和角色攻击力。
完成本教程后,您将了解以下内容:
- 如何在控制台中自定义玩家kv data模板并查看玩家kv data。
- 如何在代码中查询和更新玩家kv data。
2. 自定义 KVData 模板
在访问玩家数据之前,游戏必须在网页控制台上自定义其专属的玩家数据模板。
登录网页控制台,进入您的游戏区服,然后前往玩家 > KVData 模板:
上述截图展示了一个示例。该数据模板包含4个键值,意味着游戏中的每个玩家都将独立拥有这4个数据项。游戏可以根据其玩法需求自定义这些数据项。
2.1 添加/删除 KV 数据项
使用"添加项目"按钮创建新的数据项,然后填写以下详细信息:
键名:数据项的键名,由字母、数字和下划线组成。必须以字母开头,且不能超过128个字符。键名区分大小写,这意味着"KEY_NAME"和"key_name"将被视为相同的键。
类型:数据项的类型,可以是字符串、整数(支持Int64)或浮点数(支持float64)。
默认值:在游戏中更新之前,玩家数据项的值。
使用"删除项目"按钮删除选定的数据项。一旦数据项被删除,通过PGOS SDK、匹配规则集等方式访问该项目将会失败。请确保同时修改相关的代码逻辑。
可创建的KV数据项数量上限为1000个。
2.2 KV Data 数据项访问权限
访问权限具有三个并行属性:
仅服务器:当为 true 时,该数据项只能由游戏服务器访问。
客户端可写:当为 true 时,该数据项可以由数据所有者更新。
客户端公开:当为 true 时,该数据项可以被其他玩家查看。
通常情况下:
- 游戏服务器(DS或VS)有权限访问所有玩家的数据项。
- 游戏客户端可以更新当前玩家的客户端可写数据项。它无法更新其他玩家的数据项。
下图中的数据模板示例说明了具体的玩家数据访问权限:
- 数据项
experience
: - 游戏服务器可读写。
- 数据所属玩家可读但不可写。
- 其他玩家不可见(不可读写)。
- 数据项
level
: - 游戏服务器可读写。
- 数据所属玩家可读但不可写。
- 其他玩家可读但不可写。
- 数据项
mood
: - 游戏服务器可读写。
- 数据所属玩家可读写。
- 其他玩家可读但不可写。
- 数据项
mmr
: - 游戏服务器可读写。
- 数据所属玩家不可见(不可读写)。
- 其他玩家不可见(不可读写)。
2.3 KVData Item 版本控制
versioned 属性指定键是否需要严格的版本控制。它适用于需要基于最新原始值进行严格更新的键值。例如,在游戏中,玩家的 Buff 通过玩家 KV Data 保存。当玩家满足特定条件时,Buff 会在当前值的基础上增加 10%,而这种增加可能会在多个地方(云函数、DS)触发。为了防止在多个地方同时更新 Buff 可能导致的数据错误,需要将 Buff 标记为 versioned,并调用 Set*VersionedKVData
API 来更新它。每个玩家的 KV Data versioned key都有一个版本号,该版本号仅在 versioned key更新时才会增加。versioned key只能使用 Incr*KVData
或 Set*VersionedKVData
API 进行更新。以下是 versioned key和非 versioned key相关 API 的可用性:
SDK | API | Versioned Key | Non-versioned Key | Versioned Key + Non-versioned Key |
---|---|---|---|---|
Client SDK | IncrOneOfMyKVData | Available | Available | No multi-key support |
Client SDK | IncrMyKVData | Available | Available | Available |
Client SDK | SetMyVersionedKVData | Available | Not available | Available |
Client SDK | GetMyVersionedKVData | Available | Not available | Available |
Server SDK | IncrOneOfPlayerKVData | Available | Available | No multi-key support |
Server SDK | BatchIncrOneOfPlayerKVData | Available | Available | Available |
Server SDK | IncrPlayerKVData | Available | Available | Available |
Server SDK | BatchIncrPlayerKVData | Available | Available | Available |
Server SDK | SetPlayerVersionedKVData | Available | Not available | Available |
Server SDK | BatchSetPlayerVersionedKVData | Available | Not available | Available |
Server SDK | GetPlayerVersionedKVData | Available | Not available | Available |
Server SDK | BatchGetPlayerVersionedKVData | Available | Not available | Available |
通常情况下,Incr*KVData
API 既适用于带版本的key也适用于不带版本的键。SetVersionedKVData API 仅适用于至少包含一个带版本key的情况。GetVersionedKVData API 也遵循相同的规则。
一般来说,不带版本key的读写操作速度较快,而带版本key的操作相对较慢。因此,游戏应该只在必要时才将key标记为带版本。此外,在调用 Set*VersionedKVData
API 更新带版本key的值之前,需要先调用 Get*VersionedKVData
API 获取玩家带版本key的版本号。
HTTP Backend API 的行为与相应的 Server SDK API 的行为是一致的。
2.4 KV Data 分组
游戏可以直接管理和访问所有数据项。但是,当数据项较多时,这种方式会显得杂乱无序。为了让游戏能更好地管理玩家数据,我们引入了数据分组机制,如下图所示:
如您所见,游戏可以使用分组来关联多个数据项以进行统一管理和访问。下面,我们将通过一个典型场景来说明如何在游戏中使用分组机制。
分组应用的典型场景:
假设您想要渲染玩家的详细信息。除了玩家的名称和头像(可以从玩家信息中获取)之外,您还想包含玩家等级、经验值、胜场数和负场数,如下图所示:
显然,最好将这些数据项存储在玩家数据中。因此,您需要在玩家数据模板中定义这些数据,并让游戏服务器在适当的时候更新数据,如下图所示:
这些数据项分散在数据模板的各个位置,因此很难找到和管理。所以,将它们放在一个分组中是个不错的主意。
点击左侧的"Add Group"按钮添加一个名为"profile_view"的分组,如下图所示:
可创建的 KV 数据群组数量上限为 100。
如下图所示,将 level
、experience
、win_cnt
和 lost_cnt
添加到 profile_view
分组中:
然后,您可以使用分组名称在门户网站上找到该分组,如下图所示:
完成上述操作后,当您渲染玩家详细信息时,可以使用分组名称轻松在 profile_view
中找到数据项:
/**
* Query the specified group kvdata of the specified player.
*
* @param PlayerId Player to query.
* @param GroupName Name of the specified group.
*/
void GetPlayerGroupKVData(
const FString& PlayerId,
const FString& GroupName,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
需要您注意的一些信息:
在门户网站上,您可以创建和删除数据分组,但创建的分组数量不能超过100个。
分组名称只能由字母和数字组成,必须以字母开头,且不能超过64个字符。
单个数据项可以放置在多个分组中。
当游戏客户端请求分组中的数据项时,PGOS后端只会返回请求者有权限访问的数据项。
DS和云函数可以访问分组中的所有数据项。
2.5 公共 KVData
我们将对所有其他玩家可见的数据项集合(Client Public = true)称为"公共数据"。
这是一个特殊的数据集,在游戏的玩家资料界面中经常被访问。因此,我们在 PGOS Client SDK 中提供了可以直接访问它的 API:
- 获取单个玩家的公开数据:
UPgosPlayerProfileAPI::GetPlayerPublicKVData
/**
* Query all public kvdata of the specified player.
*
* @param PlayerId Player to query.
*/
void GetPlayerPublicKVData(
const FString& PlayerId,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
struct FPlayerKVDataGroup
{
/** Player to query. */
FString player_id;
/** KVData items, key: item key, value: item value. */
TMap<FString, FKVDataValue> kvdata;
};
获取多个玩家的公开数据:
UPgosPlayerProfileAPI::BatchGetPlayerPublicKVData
/**
* Query multiple players' public kvdata.
*
* @param PlayerIds Players to query.
*/
void BatchGetPlayerPublicKVData(
const TArray<FString>& PlayerIds,
TFunction<void(const FPgosResult& Ret, const FBatchGetPlayerGroupKVDataRsp* Data)> Callback) const;
struct FBatchGetPlayerGroupKVDataRsp
{
/** KVData of the players, key: player_id, value: the player's public kvdata. */
TMap<FString, FKVDataGroup> data;
/** Players who totally failed, key: player_id, value: failed reason. */
TMap<FString, FString> fail_players;
};
3. 查看玩家 KVData
登录网页门户,进入您的游戏区服,然后前往玩家 > 查询:
点击玩家的ID以查看玩家详细信息:
4. 使用玩家 KVData
4.1 KVData 结构
数据项的值被分类为不同的类型(字符串、整数或浮点数),这些值在 PlayerData API 的输入和输出中必然会用到。为了让开发者更容易引用和设置这些值,我们将它们抽象为 FKVDataValue
结构:
struct FKVDataValue
{
/** Value data: Please access with operators or As* functions. */
FString value;
/** Value type: String/Integer/Float. */
EKVDataType type;
public:
FKVDataValue() : type(EKVDataType::String){};
FKVDataValue(const FKVDataValue& o) : value(o.value), type(o.type){};
FKVDataValue(const TCHAR* vl) { Set(vl ? (vl):TEXT("")); }; // FKVDataValue v = TEXT("abc");
FKVDataValue(const FString& vl) { Set(vl); }; // FKVDataValue v = FString(TEXT("abc"));
FKVDataValue(int32 vl) { Set(vl); }; // FKVDataValue v = 123;
FKVDataValue(int64 vl) { Set(vl); }; // FKVDataValue v = (int64)123;
FKVDataValue(float vl) { Set(vl); }; // FKVDataValue v = (float)1.23;
FKVDataValue(double vl) { Set(vl); }; // FKVDataValue v = 1.23;
operator const TCHAR*() { return AsStr().GetCharArray().GetData(); }; // const TCHAR* v = FKVDataValue(TEXT("abc"));
operator FString() { return AsStr(); }; // FString v = FKVDataValue(TEXT("abc"));
operator int32() { return AsInt32(); }; // int32 v = FKVDataValue(123);
operator int64() { return AsInt64(); }; // int64 v = FKVDataValue((int64_t)123);
operator float() { return AsFloat(); }; // float v = FKVDataValue((float)1.23);
operator double() { return AsDouble(); }; // double v = FKVDataValue(1.23);
void Set(const FString& vl) { value = vl; type = EKVDataType::String; };
void Set(int32 vl) { value = FString::FromInt(vl); type = EKVDataType::Integer; };
void Set(int64 vl) { value = FString::Printf(TEXT("%lld"), vl); type = EKVDataType::Integer; };
void Set(float vl) { value = FString::SanitizeFloat(vl); type = EKVDataType::Float; };
void Set(double vl) { value = FString::Printf(TEXT("%f"), vl); type = EKVDataType::Float; };
FString AsStr() const { return value; };
int32 AsInt32() const { return FCString::Atoi(*value); };
int64 AsInt64() const { return FCString::Atoi64(*value); };
float AsFloat() const { return FCString::Atof(*value); };
double AsDouble() const { return FCString::Atod(*value); };
};
如您所见,FKVDataValue
实现了多个构造函数和重载运算符,使开发者可以直接将其他数据类型(TCHAR*/FString/int32/int64/float/double
)的值设置给 FKVDataValue
实例。同样地,开发者也可以使用 FKVDataValue
实例直接设置其他数据类型(TCHAR*/FString/int32/int64/float/double
)的值。示例代码如下:
// (TCHAR*/FString/int32/int64/float/double) to FKVDataValue
FKVDataValue v1 = TEXT("abc");
FKVDataValue v2 = FString(TEXT("abc"));
FKVDataValue v3 = 123;
FKVDataValue v4 = (int64)123;
FKVDataValue v5 = (float)1.23;
FKVDataValue v6 = 1.23;
// FKVDataValue to (TCHAR*/FString/int32/int64/float/double)
const TCHAR* str1 = FKVDataValue(TEXT("abc"));
FString str2 = FKVDataValue(TEXT("abc"));
int32 i1 = FKVDataValue(123);
int64 i2 = FKVDataValue((int64_t)123);
float f1 = FKVDataValue((float)1.23);
double f2 = FKVDataValue(1.23);
4.2 游戏客户端
4.2.1 查询玩家 KVData
获取当前玩家的数据:
API | Description |
---|---|
GetOneOfMyKVData | 获取当前玩家的指定 KV Data。 |
GetMyKVData | 获取当前玩家的特定 KV Data。 |
GetAllOfMyKVData | 获取当前玩家所有可访问的 KV Data。 |
GetMyPublicKVData | 获取当前玩家的所有公开 KV Data。 |
GetMyGroupKVData | 获取当前玩家指定群组的 KV Data。 |
GetMyVersionedKVData | 获取当前玩家的特定版本的KV Data。 |
获取其他玩家的玩家数据:
API | Description |
---|---|
GetOneOfPlayerKVData | 获取指定玩家的指定 KV Data。 |
GetPlayerKVData | 获取指定玩家的KV Data。 |
BatchGetPlayerKVData | 批量获取多个玩家的 KV Data |
GetPlayerPublicKVData | 批量指定玩家的所有公开 KV Data。 |
BatchGetPlayerPublicKVData | 批量查询多个玩家的公开 KV Data 。 |
GetPlayerGroupKVData | 获取指定玩家的指定分组的KV Data |
BatchGetPlayerGroupKVData | 批量查询多个玩家的指定分组的 KV Data。 |
API details:
4.2.1.1 GetOneOfMyKVData Client API
接口原型:
/**
* Query the specified kvdata of the current player.
*
* @param QueryKey Key to query
*/
void GetOneOfMyKVData(
const FString& QueryKey,
TFunction<void(const FPgosResult& Ret, const FOnePlayerKVData* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (playerprofile)
{
FString QueryKey = TEXT("level");
PlayerProfile->GetOneOfMyKVData(QueryKey, [](const FPgosResult& Ret, const FOnePlayerKVData* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetOneOfMyKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetOneOfMyKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.2 GetMyKVData Client API
接口原型:
/**
* Query certain kvdata of the current player.
*
* @param QueryKeys Keys to query
*/
void GetMyKVData(
const TArray<FString>& QueryKeys,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroupWithFails* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> QueryKeys = {TEXT("level"), TEXT("experience")};
PlayerProfile->GetMyKVData(QueryKeys, [](const FPgosResult& Ret, const FPlayerKVDataGroupWithFails* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetMyKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetMyKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.3 GetAllOfMyKVData Client API
接口原型:
/**
* Query all accessible kvdata of the current player.
*/
void GetAllOfMyKVData(TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
PlayerProfile->GetAllOfMyKVData([](const FPgosResult& Ret, const FPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetAllOfMyKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetAllOfMyKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.4 GetMyPublicKVData Client API
接口原型:
/**
* Query all public kvdata of the current player.
*/
void GetMyPublicKVData(TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
PlayerProfile->GetMyPublicKVData([](const FPgosResult& Ret, const FPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetMyPublicKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetMyPublicKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.5 GetMyGroupKVData Client API
接口原型:
/**
* Query the specified group kvdata of the current player.
* Keys in the group that are not accessible to the current player will be ignored.
*
* @param GroupName Name of the specified group.
*/
void GetMyGroupKVData(
const FString& GroupName,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString GroupName = TEXT("profile_view");
PlayerProfile->GetMyGroupKVData(GroupName, [](const FPgosResult& Ret, const FPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetMyGroupKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetMyGroupKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.6 GetOneOfPlayerKVData Client API
接口原型:
/**
* Query the specified kvdata of the specified player.
*
* @param PlayerId Player to query.
* @param QueryKey Key to query.
*/
void GetOneOfPlayerKVData(
const FString& PlayerId,
const FString& QueryKey,
TFunction<void(const FPgosResult& Ret, const FOnePlayerKVData* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
FString QueryKey = TEXT("level");;
PlayerProfile->GetOneOfPlayerKVData(PlayerId, QueryKey, [](const FPgosResult& Ret, const FOnePlayerKVData* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetOneOfPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetOneOfPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.7 GetPlayerKVData Client API
接口原型:
/**
* Query certain kvdata of the specified player.
*
* @param PlayerId Player to query.
* @param QueryKeys Keys to query.
*/
void GetPlayerKVData(
const FString& PlayerId,
const TArray<FString>& QueryKeys,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroupWithFails* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
TArray<FString> QueryKeys = {TEXT("level"), TEXT("experience")};
PlayerProfile->GetPlayerKVData(PlayerId, QueryKeys, [](const FPgosResult& Ret, const FPlayerKVDataGroupWithFails* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.8 BatchGetPlayerKVData Client API
接口原型:
/**
* Perform a batch query of KVData for multiple players.
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
*
* @param PlayerIds Players to query.
* @param QueryKeys Keys to query.
*/
void BatchGetPlayerKVData(
const TArray<FString>& PlayerIds,
const TArray<FString>& QueryKeys,
TFunction<void(const FPgosResult& Ret, const FBatchPlayerKVDataGroupWithFails* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {TEXT("197177"), TEXT("197178")};
TArray<FString> QueryKeys = {TEXT("level"), TEXT("experience")};
PlayerProfile->BatchGetPlayerKVData(PlayerIds, QueryKeys, [](const FPgosResult& Ret, const FBatchPlayerKVDataGroupWithFails* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.9 GetPlayerPublicKVData Client API
接口代码:
/**
* Query all public kvdata of the specified player.
*
* @param PlayerId Player to query.
*/
void GetPlayerPublicKVData(
const FString& PlayerId,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
PlayerProfile->GetPlayerPublicKVData(PlayerId, [](const FPgosResult& Ret, const FPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerPublicKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerPublicKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.10 BatchGetPlayerPublicKVData Client API
接口原型:
/**
* Perform a batch query of public KVData for multiple players.
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
*
* @param PlayerIds Players to query.
*/
void BatchGetPlayerPublicKVData(
const TArray<FString>& PlayerIds,
TFunction<void(const FPgosResult& Ret, const FBatchPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {TEXT("197177"), TEXT("197178")};
PlayerProfile->BatchGetPlayerPublicKVData(PlayerIds, [](const FPgosResult& Ret, const FBatchPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerPublicKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerPublicKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.11 GetPlayerGroupKVData Client API
接口原型:
/**
* Query the specified group kvdata of the specified player.
* Keys in the group that are not accessible to the current player will be ignored.
*
* @param PlayerId Player to query.
* @param GroupName Name of the specified group.
*/
void GetPlayerGroupKVData(
const FString& PlayerId,
const FString& GroupName,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
FString GroupName = TEXT("profile_view");
PlayerProfile->GetPlayerGroupKVData(PlayerId, GroupName, [](const FPgosResult& Ret, const FPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerGroupKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerGroupKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.12 BatchGetPlayerGroupKVData Client API
接口原型:
/**
* Perform a batch query of the specified group KVData for multiple players.
* Keys in the group that are not accessible to the current player will be ignored.
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
*
* @param PlayerIds Players to query.
* @param GroupName Name of the specified group.
*/
void BatchGetPlayerGroupKVData(
const TArray<FString>& PlayerIds,
const FString& GroupName,
TFunction<void(const FPgosResult& Ret, const FBatchPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {TEXT("197177"), TEXT("197178")};
FString GroupName = TEXT("profile_view");
PlayerProfile->BatchGetPlayerGroupKVData(PlayerIds, GroupName, [](const FPgosResult& Ret, const FBatchPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerGroupKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerGroupKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.1.13 GetMyVersionedKVData Client API
接口原型:
/**
* Query certain versioned kvdata of the current player.
* The keys to be queried must contain at least one versioned key.
* Call 'GetMyKVData' or 'GetPlayerKVData' instead if you don't need to get the 'version' field, which is only needed when updating versioned KVData.
*
* @param QueryKeys Keys to query.
*/
void GetMyVersionedKVData(
const TArray<FString>& QueryKeys,
TFunction<void(const FPgosResult& Ret, const FKVDataGroupWithVerAndFails* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> QueryKeys = {TEXT("buff"), TEXT("experience")};
PlayerProfile->GetMyVersionedKVData(QueryKeys, [](const FPgosResult& Ret, const FKVDataGroupWithVerAndFails* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetMyVersionedKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetMyVersionedKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.2 Update Player KVData
更新当前玩家的玩家数据:
API | Description |
---|---|
SetOneOfMyKVData | 更新当前玩家的指定 KVData。 |
SetMyKVData | 更新当前玩家的KVData。 |
IncrOneOfMyKVData | 对当前玩家的特定 KVData 项执行原子递增操作。 |
IncrMyKVData | 对当前玩家的多个KVData项执行原子递增操作。 |
SetMyVersionedKVData | 更新当前玩家的versioned KV Data。 |
API details:
4.2.2.1 SetOneOfMyKVData Client API
接口原型:
/**
* Update the specified kvdata of the current player.
*
* @param Key Key to update
* @param Value The new value can be set to string/int32/int64/float/double.
*/
void SetOneOfMyKVData(
const FString& Key,
const FKVDataValue& Value,
TFunction<void(const FPgosResult& Ret)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString Key = TEXT("my_lucky_num");
FKVDataValue Value = 777;
PlayerProfile->SetOneOfMyKVData(Key, Value, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetOneOfMyKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetOneOfMyKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.2.2 SetMyKVData Client API
接口原型:
/**
* Update kvdata of the current player.
* The update operation for a player's KVData will either succeed as a whole or fail as a whole.
*
* @param Kvdata KVData to update.
*/
void SetMyKVData(
const TMap<FString, FKVDataValue>& Kvdata,
TFunction<void(const FPgosResult& Ret)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
TMap<FString, FKVDataValue> Kvdata;
Kvdata.Add(TEXT("num_key"), 100);
Kvdata.Add(TEXT("string_key"), TEXT("abc"));
PlayerProfile->SetMyKVData(Kvdata, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetMyKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetMyKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.2.3 IncrOneOfMyKVData Client API
接口原型:
/**
* Perform atomic increment operation on a specific kvdata item for the current player. [Only works on Integer/Float type keys]
* If the operation is successful, the callback will return the updated data.
*
* @param Key Key to operate.
* @param Increment The increment value can be set to int32/int64/float/double.
*/
void IncrOneOfMyKVData(
const FString& Key,
const FKVDataValue& Increment,
TFunction<void(const FPgosResult& Ret, const FOnePlayerKVData* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString Key = TEXT("my_lucky_day_cnt");
FKVDataValue Increment = 1;
PlayerProfile->IncrOneOfMyKVData(Key, Increment, [](const FPgosResult& Ret, const FOnePlayerKVData* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("IncrOneOfMyKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("IncrOneOfMyKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.2.4 IncrMyKVData Client API
接口原型:
/**
* Perform atomic increment operation on multiple kvdata items for the current player. [Only works on Integer/Float type keys]
* If the operation is successful, the callback will return the updated data.
*
* @param Increments Increments to update, key: kvdata key, value: increment of the value.
*/
void IncrMyKVData(
const TMap<FString, FKVDataValue>& Increments,
TFunction<void(const FPgosResult& Ret, const FKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
TMap<FString, FKVDataValue> Increments;
Increments.Add(TEXT("win_cnt"), 1);
Increments.Add(TEXT("defeated_players_cnt"), 5);
PlayerProfile->IncrMyKVData(Increments, [](const FPgosResult& Ret, const FKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("IncrMyKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("IncrMyKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.2.2.5 SetMyVersionedKVData Client API
接口原型:
/**
* Update versioned kvdata for the current player.
* The KVData of the player to be updated must contain at least one versioned key.
* The 'version' needs to pass in can be obtained from the 'GetMyVersionedKVData' API call.
* If the 'version' passed in is the latest, the callback will return success along with the updated data.
* If the 'version' passed in is not the latest, the callback will return failure(err_code=11108, kBackendKVDataVersionMismatched) along with the current latest data, you may try again with the latest version.
* For other errors, please refer to the error message and the developer manual on the portal, and the callback data is invalid.
*
* @param Data Versioned kvdata items that need to update. Please set the 'version' field to the latest value you got for the player.
*/
void SetMyVersionedKVData(
const FKVDataGroupWithVer& Data,
TFunction<void(const FPgosResult& Ret, const FKVDataGroupWithVer* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction(int32 latest_ver)
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FKVDataGroupWithVer Data;
Data.version = latest_ver;
Data.kvdata.Add(TEXT("num_key"), 100);
Data.kvdata.Add(TEXT("string_key"), TEXT("abc"));
PlayerProfile->SetMyVersionedKVData(Data, [](const FPgosResult& Ret, const FKVDataGroupWithVer* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetMyVersionedKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetMyVersionedKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3 For Game Server
4.3.1 查询 Player KVData
获取玩家数据:
API | Description |
---|---|
GetOneOfPlayerKVData | 查询指定玩家的指定KV Data |
GetPlayerKVData | 查询指定玩家的KV Data |
BatchGetPlayerKVData | 批量查询多个玩家的KV Data。 |
GetPlayerGroupKVData | 查询指定玩家的指定分组的KV Data。 |
BatchGetPlayerGroupKVData | 批量查询多个玩家的指定分组的KV Data。 |
GetPlayerVersionedKVData | 查询指定玩家的特定versioned KV Data |
BatchGetPlayerVersionedKVData | 批量查询多个玩家的versioned KV Data |
API details:
4.3.1.1 GetOneOfPlayerKVData Server API
接口原型:
/**
* Query the specified kvdata of the specified player.
*
* @param PlayerId The player to query.
* @param QueryKey The key to query.
*/
void GetOneOfPlayerKVData(
const FString& PlayerId,
const FString& QueryKey,
TFunction<void(const FPgosResult& Ret, const FOnePlayerKVData* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
FString QueryKey = TEXT("level");
PlayerProfile->GetOneOfPlayerKVData(PlayerId, QueryKey, [](const FPgosResult& Ret, const FOnePlayerKVData* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetOneOfPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetOneOfPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.1.2 GetPlayerKVData Server API
接口原型:
/**
* Query certain kvdata of the specified player.
*
* @param PlayerId The player to query.
* @param QueryKeys Keys to query.
*/
void GetPlayerKVData(
const FString& PlayerId,
const TArray<FString>& QueryKeys,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroupWithFails* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
TArray<FString> QueryKeys = {TEXT("level"), TEXT("experience")};
PlayerProfile->GetPlayerKVData(PlayerId, QueryKeys, [](const FPgosResult& Ret, const FPlayerKVDataGroupWithFails* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.1.3 BatchGetPlayerKVData Server API
接口原型:
/**
* Perform a batch query of KVData for multiple players.
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
*
* @param PlayerIds Players to query.
* @param QueryKeys Keys to query.
*/
void BatchGetPlayerKVData(
const TArray<FString>& PlayerIds,
const TArray<FString>& QueryKeys,
TFunction<void(const FPgosResult& Ret, const FBatchPlayerKVDataGroupWithFails* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {TEXT("197177"), TEXT("197178")};
TArray<FString> QueryKeys = {TEXT("level"), TEXT("experience")};
PlayerProfile->BatchGetPlayerKVData(PlayerIds, QueryKeys, [](const FPgosResult& Ret, const FBatchPlayerKVDataGroupWithFails* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.1.4 GetPlayerGroupKVData Server API
接口原型:
/**
* Query the specified group kvdata of the specified player.
*
* @param PlayerId Player to query.
* @param GroupName Name of the specified group.
*/
void GetPlayerGroupKVData(
const FString& PlayerId,
const FString& GroupName,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
FString GroupName = TEXT("profile_view");
PlayerProfile->GetPlayerGroupKVData(PlayerId, GroupName, [](const FPgosResult& Ret, const FPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerGroupKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerGroupKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.1.5 BatchGetPlayerGroupKVData Server API
接口原型:
/**
* Perform a batch query of the specified group KVData for multiple players.
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
*
* @param PlayerIds Players to query.
* @param GroupName Name of the specified group.
*/
void BatchGetPlayerGroupKVData(
const TArray<FString>& PlayerIds,
const FString& GroupName,
TFunction<void(const FPgosResult& Ret, const FBatchPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {TEXT("197177"), TEXT("197178")};
FString GroupName = TEXT("profile_view");
PlayerProfile->BatchGetPlayerGroupKVData(PlayerIds, GroupName, [](const FPgosResult& Ret, const FBatchPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerGroupKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerGroupKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.1.6 GetPlayerVersionedKVData Server API
接口原型:
/**
* Query certain versioned kvdata of the specified player.
* The keys to be queried must contain at least one versioned key.
* Call 'GetMyKVData' or 'GetPlayerKVData' instead if you don't need to get the 'version' field, which is only needed when updating versioned KVData.
*
* @param PlayerId The player to query.
* @param QueryKeys Keys to query.
*/
void GetPlayerVersionedKVData(
const FString& PlayerId,
const TArray<FString>& QueryKeys,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroupWithVerAndFails* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
TArray<FString> QueryKeys = {TEXT("buff"), TEXT("experience")};
PlayerProfile->GetPlayerVersionedKVData(PlayerId, QueryKeys, [](const FPgosResult& Ret, const FPlayerKVDataGroupWithVerAndFails* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerVersionedKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerVersionedKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.1.7 BatchGetPlayerVersionedKVData Server API
接口原型:
/**
* Perform a batch query of versioned KVData for multiple players.
* The keys to be queried must contain at least one versioned key.
* Call 'BatchGetPlayerKVData' instead if you don't need to get 'version', which is only needed when updating versioned KVData.
*
* @param PlayerIds Players to query.
* @param QueryKeys Keys to query.
*/
void BatchGetPlayerVersionedKVData(
const TArray<FString>& PlayerIds,
const TArray<FString>& QueryKeys,
TFunction<void(const FPgosResult& Ret, const FBatchPlayerKVDataGroupWithVerAndFails* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {TEXT("197177"), TEXT("197178")};
TArray<FString> QueryKeys = {TEXT("level"), TEXT("experience")};
PlayerProfile->BatchGetPlayerVersionedKVData(PlayerIds, QueryKeys, [](const FPgosResult& Ret, const FBatchPlayerKVDataGroupWithVerAndFails* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerVersionedKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerVersionedKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2 更新玩家 KV Data
更新玩家数据:
API | Description |
---|---|
SetOneOfPlayerKVData | 更新指定玩家的指定KV Data |
SetPlayerKVData | 更新指定玩家的KV Data |
BatchSetPlayerKVData | 批量更新多个玩家的 KV Data。 |
IncrOneOfPlayerKVData | 对指定玩家的指定 KV Data 项执行原子递增操作。 |
BatchIncrOneOfPlayerKVData | 对多个玩家的指定 KV Data项执行批量原子递增操作。 |
IncrPlayerKVData | 对指定玩家的多个 KV Data项执行原子递增操作。 |
BatchIncrPlayerKVData | 对多个玩家的多个KV Data项执行批量原子递增操作。 |
SetPlayerVersionedKVData | 更新指定玩家的 versioned KV Data。玩家的KV Data必须至少包含一个带版本号的Key。 |
BatchIncrPlayerKVDataIdempotent | BatchIncrPlayerKVData的幂等版本。每个玩家都可以设置幂等token。 |
BatchSetPlayerVersionedKVData | 批量更新多个玩家的versioned KV Data |
API details:
4.3.2.1 SetOneOfPlayerKVData Server API
接口原型:
/**
* Update the specified kvdata of the specified player.
*
* @param PlayerId Player to query.
* @param Key Key to update
* @param Value The new value can be set to string/int32/int64/float/double.
*/
void SetOneOfPlayerKVData(
const FString& PlayerId,
const FString& Key,
const FKVDataValue& Value,
TFunction<void(const FPgosResult& Ret)> Callback) const;
示例:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
FString Key = TEXT("my_lucky_num");
FKVDataValue Value = 777;
PlayerProfile->SetOneOfPlayerKVData(PlayerId, Key, Value, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetOneOfPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetOneOfPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.2 SetPlayerKVData Server API
接口原型:
/**
* Update kvdata of the specified player.
* The update operation for a player's KVData will either succeed as a whole or fail as a whole.
*
* @param PlayerId Player to update kvdata.
* @param Kvdata KVData to update.
*/
void SetPlayerKVData(
const FString& PlayerId,
const TMap<FString, FKVDataValue>& Kvdata,
TFunction<void(const FPgosResult& Ret)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
TMap<FString, FKVDataValue> Kvdata;
Kvdata.Add(TEXT("num_key"), 100);
Kvdata.Add(TEXT("string_key"), TEXT("abc"));
PlayerProfile->SetPlayerKVData(PlayerId, Kvdata, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.3 BatchSetPlayerKVData Server API
接口原型:
/**
* Perform a batch update of KVData for multiple players.
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
* The update operation for a player's KVData will either succeed as a whole or fail as a whole.
*/
void BatchSetPlayerKVData(
const TArray<FPlayerKVDataGroup>& Kvdatas,
TFunction<void(const FPgosResult& Ret, const FBatchPlayerOperationResult* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FPlayerKVDataGroup op1;
op1.player_id = TEXT("197177");
op1.kvdata.Add(TEXT("level"), 30);
op1.kvdata.Add(TEXT("experience"), 5000);
FPlayerKVDataGroup op2;
op2.player_id = TEXT("197178");
op2.kvdata.Add(TEXT("level"), 40);
op2.kvdata.Add(TEXT("experience"), 7000);
TArray<FPlayerKVDataGroup> Kvdatas = { op1, op2};
PlayerProfile->BatchSetPlayerKVData(Kvdatas, [](const FPgosResult& Ret, const FBatchPlayerOperationResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchSetPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchSetPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.4 IncrOneOfPlayerKVData Server API
接口原型:
/**
* Perform atomic increment operation on a specified kvdata item for a specified player. [Only works on Integer/Float type keys]
* If the operation is successful, the callback will return the updated data.
*
* @param PlayerId Player to operate.
* @param Key Key to operate.
* @param Increment The increment value can be set to int32/int64/float/double.
*/
void IncrOneOfPlayerKVData(
const FString& PlayerId,
const FString& Key,
const FKVDataValue& Increment,
TFunction<void(const FPgosResult& Ret, const FOnePlayerKVData* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
FString Key = TEXT("level");
FKVDataValue Increment = 1;
PlayerProfile->IncrOneOfPlayerKVData(PlayerId, Key, Increment, [](const FPgosResult& Ret, const FOnePlayerKVData* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("IncrOneOfPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("IncrOneOfPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.5 BatchIncrOneOfPlayerKVData Server API
接口原型:
/**
* Perform a batch atomic increment operation on a specified kvdata item for multiple players. [Only works on Integer/Float type keys]
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
* For the players whose operations are successful, the callback data will contain the new value of their updated kvdata item.
* The update operation for a player's KVData will either succeed as a whole or fail as a whole.
*
* @param PlayerIds Players to operate.
* @param Key Key to operate.
* @param Increment The increment value can be set to int32/int64/float/double.
*/
void BatchIncrOneOfPlayerKVData(
const TArray<FString>& PlayerIds,
const FString& Key,
const FKVDataValue& Increment,
TFunction<void(const FPgosResult& Ret, const FServerBatchIncrOneOfPlayerKVDataRsp* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {TEXT("197177"), TEXT("197178"), TEXT("197179")};
FString Key = TEXT("experience");
FKVDataValue Increment = 60;
PlayerProfile->BatchIncrOneOfPlayerKVData(PlayerIds, Key, Increment, [](const FPgosResult& Ret, const FServerBatchIncrOneOfPlayerKVDataRsp* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchIncrOneOfPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchIncrOneOfPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.6 IncrPlayerKVData Server API
接口原型:
/**
* Perform atomic increment operation on multiple kvdata items for a specified player. [Only works on Integer/Float type keys]
* If the operation is successful, the callback will return the updated data.
*
* @param PlayerId Player to operate.
* @param Increments Increments to update, key: kvdata key, value: increment of the value.
*/
void IncrPlayerKVData(
const FString& PlayerId,
const TMap<FString, FKVDataValue>& Increments,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197177");
TMap<FString, FKVDataValue> Increments;
Increments.Add(TEXT("level"), 1);
Increments.Add(TEXT("experience"), 60);
PlayerProfile->IncrPlayerKVData(PlayerId, Increments, [](const FPgosResult& Ret, const FPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("IncrPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("IncrPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.7 BatchIncrPlayerKVData Server API
接口原型:
/**
* Perform a batch atomic increment operation on multiple kvdata items for multiple players. [Only works on Integer/Float type keys]
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
* For the players whose operations are successful, the callback data will contain the new value of their updated kvdata item.
* The update operation for a player's KVData will either succeed as a whole or fail as a whole.
*
* @param Increments Player kvdata increments list.
*/
void BatchIncrPlayerKVData(
const TArray<FPlayerKVDataGroup>& Increments,
TFunction<void(const FPgosResult& Ret, const FBatchPlayerKVDataGroup* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FPlayerKVDataGroup op1;
op1.player_id = TEXT("197177");
op1.kvdata.Add(TEXT("level"), 1);
op1.kvdata.Add(TEXT("experience"), 60);
FPlayerKVDataGroup op2;
op2.player_id = TEXT("197178");
op2.kvdata.Add(TEXT("level"), 2);
op2.kvdata.Add(TEXT("experience"), 120);
TArray<FPlayerKVDataGroup> Increments = {op1, op2};
PlayerProfile->BatchIncrPlayerKVData(Increments, [](const FPgosResult& Ret, const FBatchPlayerKVDataGroup* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchIncrPlayerKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchIncrPlayerKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.8 SetPlayerVersionedKVData Server API
接口原型:
/**
* Update versioned kvdata for the specified player.
* The KVData of the player to be updated must contain at least one versioned key.
* The 'version' needs to pass in can be obtained from the 'GetPlayerVersionedKVData' or 'BatchGetPlayerVersionedKVData' API call.
* If the 'version' passed in is the latest, the callback will return success along with the updated data.
* If the 'version' passed in is not the latest, the callback will return failure(err_code=11108, kBackendKVDataVersionMismatched) along with the current latest data, you may try again with the latest version.
* For other errors, please refer to the error message and the developer manual on the portal, and the callback data is invalid.
*
* @param Data Versioned kvdata items that need to update. Please set version to the latest value you got for the player.
*/
void SetPlayerVersionedKVData(
const FPlayerKVDataGroupWithVer& Data,
TFunction<void(const FPgosResult& Ret, const FPlayerKVDataGroupWithVer* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction(int32 latest_ver)
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FPlayerKVDataGroupWithVer Data;
Data.player_id = TEXT("197177");
Data.version = latest_ver;
Data.kvdata.Add(TEXT("num_key"), 100);
Data.kvdata.Add(TEXT("string_key"), TEXT("abc"));
PlayerProfile->SetPlayerVersionedKVData(Data, [](const FPgosResult& Ret, const FPlayerKVDataGroupWithVer* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetPlayerVersionedKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetPlayerVersionedKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.9 BatchIncrPlayerKVDataIdempotent Server API
接口原型:
/**
* Idempotent version of BatchIncrPlayerKVData. Idempotency token could be set for each player.
*
* @param Params Params of BatchIncrPlayerKVDataIdempotent.
*/
void BatchIncrPlayerKVDataIdempotent(
const FServerBatchIncrPlayerKVDataIdempotentParams& Params,
TFunction<void(const FPgosResult& Ret, const FServerBatchIncrPlayerKVDataIdempotentResult* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FServerBatchIncrPlayerKVDataIdempotentParams Params;
PlayerProfile->BatchIncrPlayerKVDataIdempotent(Params, [](const FPgosResult& Ret, const FServerBatchIncrPlayerKVDataIdempotentResult* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchIncrPlayerKVDataIdempotent Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchIncrPlayerKVDataIdempotent Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
4.3.2.10 BatchSetPlayerVersionedKVData Server API
接口原型:
/**
* Perform a batch update of versioned KVData for multiple players.
* The KVData of the player to be updated must contain at least one versioned key.
* The 'version' needs to pass in can be obtained from the 'GetPlayerVersionedKVData' or 'BatchGetPlayerVersionedKVData' API call.
* If all player operations are successful, the callback result is success.
* If some player operations succeed while others fail, the callback result is success, and the reasons for the failed players can be obtained from the callback data.
* If all player operations fail, the callback result is failure (kBackendAllFailed), and the reasons for the failed players can be obtained from the callback data.
* The update operation for a player's KVData will either succeed as a whole or fail as a whole.
*
* @param Data Versioned kvdata items that need to update. Please set version to the latest value you got for the player.
*/
void BatchSetPlayerVersionedKVData(
const TArray<FPlayerKVDataGroupWithVer>& Data,
TFunction<void(const FPgosResult& Ret, const FServerBatchSetPlayerVersionedKVDataRsp* Data)> Callback) const;
示例代码:
#include "PgosSDKCpp.h"
void SomeUObjectClass::SomeFunction(int32 latest_ver1, int32 latest_ver2)
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FPlayerKVDataGroupWithVer PlayerData1;
PlayerData1.player_id = TEXT("197177");
PlayerData1.version = latest_ver1;
PlayerData1.kvdata.Add(TEXT("num_key"), 100);
PlayerData1.kvdata.Add(TEXT("string_key"), TEXT("abc"));
FPlayerKVDataGroupWithVer PlayerData2;
PlayerData2.player_id = TEXT("197177");
PlayerData2.version = latest_ver2;
PlayerData2.kvdata.Add(TEXT("num_key"), 100);
PlayerData2.kvdata.Add(TEXT("string_key"), TEXT("abc"));
TArray<FPlayerKVDataGroupWithVer> Data = {PlayerData1, PlayerData2};
PlayerProfile->BatchSetPlayerVersionedKVData(Data, [](const FPgosResult& Ret, const FServerBatchSetPlayerVersionedKVDataRsp* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchSetPlayerVersionedKVData Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchSetPlayerVersionedKVData Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}
5. Key Errors Handling
Error Code | Relevant API | Handling Suggestion |
---|---|---|
kBackendKeyNotExist | Query KVData (Client) Update KVData (Client) Query KVData (Server) Update KVData (Server) | Blob 密钥不存在。请检查是否已在门户网站中定义该密钥。 |
kBackendReqPlayerIDIsInvalid | Query KVData (Client) Query KVData (Server) Update KVData (Server) | 请求的玩家ID无效。 |
kBackendClientInaccessibleKey | Query KVData (Client) | 客户端无法访问该密钥。这意味着该密钥的访问权限为仅服务器可用,或者您指定的密钥是属于其他玩家的非客户端公开密钥。请在门户网站上检查密钥的访问权限。 |
kBackendClientUnwritableKey | Update KVData (Client) | 客户端无法写入密钥。请在门户网站上检查密钥的访问权限。 |
kBackendKeyNeedVersionedAPI | Update KVData (Client) Update KVData (Server) | 更新失败,因为该API仅适用于非版本化密钥,但当前密钥已启用版本控制。 |
kBackendNeedVersionedKey | Query KVData (Client) Update KVData (Client) Query KVData (Server) Update KVData (Server) | 更新失败,因为 API 至少需要一个带版本的密钥。 |
kBackendKVDataVersionMismatched | Update KVData (Client) Update KVData (Server) | 由于版本不匹配导致更新失败,您可以从响应中获取最新数据重试。 |
kSdkNetworkError | All Network API | 网络错误,请查看错误信息了解详情。 |