Skip to main content

Player Info

1. Overview

We believe that Player Info is the core attribute collection used to describe a player. Specifically, it contains two parts:

  • Basic Info are the built-in fields that can not be modified, such as the player_id, display_name, and avatar_uri.
  • Custom Info are the fields customized by game, which is a core set of data from the player data template.

After completing this tutorial, you will learn the following content:

  • How to view and modify player info in the web portal.
  • How to query and update player info in code.

2. Player Info on Portal

2.1 View Player Info

Log in to the web portal, enter the console and go to Players > Query:

image-20210809163842712

Click on the ID of a player to view the player details:

image-20211111172326538

2.2 Player Info Definition

Player info generally appears as a core attribute collection to describe a player in service modules such as Friend, Party, and Lobby. Since its basic info is defined by PGOS with the goal of generality, it cannot meet all the needs of games to describe the core attributes of players. Therefore, PGOS provides a way for games to extend player info: select certain items in the player data template as part of the player info, which is called custom info.

The intention of custom info is to make PlayerInfo richer, Playerinfo may not be enough to describe the "basic information" of the player. For example, when the player receives a friend request from a stranger, the game may display the "level" of the stranger to the player, which could be got from player data, but that would be another API call. If the game adds "level" to custom info and makes it part of the player's basic information, the game does not need an additional API call, which brings convenience to development.

enter the console and go to Players > Player Info Definition:

image-20211117164858714

Click Manage button to choose which items will be in player custom info:

image-20211111192443475

Developers can access the custom info through FPlayerInfo::custom_info, view in Data Structure.

Note:

Player data items in player custom Info will be visible to all players, although you can add any item as custom info regardless of its access permissions, we still recommend that you consider doing this carefully. Another thing to be aware of is that if too many items are added to custom info it may cause unnecessary performance issues.

3. Data Structure

3.1 PlayerInfo and PlayerDetail

Player info has two data structures: FPlayerInfo and FPlayerDetail. FPlayerDetail inherits its data from FPlayerInfo. Only the owner and the game server can access FPlayerDetail.

struct FPlayerInfo
{
FString player_id;
FString display_name;
FString gender;
FString avatar_uri;
int32 account_provider;
FString account_platform;
FString account_open_id;
FString account_id;
EClientOS os;
TMap<FString, FKVDataValue> custom_info;
};

struct FPlayerDetail : public FPlayerInfo
{
FString language;
int64 first_login_time;
int64 last_login_time;
int64 last_logout_time;
int64 total_time;
FString last_login_ip;
FString cur_login_ip;
};

Besides the data members below that are updated by the PGOS backend, other data members are null by default before being set in the game.

  • player_id: an unique player ID in the title region provided by the PGOS.

  • display_name: player's display name.

  • gender: player's gender.

  • avatar_uri: player's avatar uri.

  • account_provider: the account service provider. 0 means FAS, 1 means INTL, 2 means MSDK, 3 means WeGame, 4 means PlayFab, 5 means Steam, 6 means Epic, 7 means XboxLive, 8 means PlayStationNetwork, 9 means Nintendo.

  • account_platform: account platform name, PGOS will get and save it from the parameters passed in when the game calls LoginPGOS. It can be one of the following values:

    [
    "WeChat",
    "QQ",
    "Guest",
    "Facebook",
    "GameCenter",
    "Google",
    "IEGPassport",
    "Twitter",
    "Garena",
    "EGame",
    "Nintendo",
    "LINE",
    "Apple",
    "VK",
    "XboxLive",
    "Steam",
    "EpicGames",
    "Discord",
    "PlayStationNetwork",
    "DMM",
    "SquareEnix",
    "Supercell",
    "Kakao",
    "Instagram",
    "Whatsapp",
    "Sop",
    "LI PASS",
    "Amazon",
    "AndroidDevice",
    "Custom",
    "FacebookInstantGames",
    "GooglePlay",
    "IOSDevice",
    "Kongregate",
    "LoadTest",
    "OpenIdConnect",
    "Organic",
    "Parse",
    "ServerCustom",
    "Twitch",
    "Unknown"
    ]
  • account_open_id: open id of the logged in account service provider.

  • account_id: an account platform user id owned by the player (e.g. Steam SteamID, PSN account id, Xbox XUID).

  • custom_info: custom info from player data, key: item key, value: item value.

  • language: player's display language, if you want your game to be multilingual.

  • first_login_time: player's first login Unix timestamp in the title region.

  • last_login_time: player's last login Unix timestamp in the title region.

  • last_logout_time: player's last logout Unix timestamp in the title region.

  • total_time: player's total online time, in seconds.

tip

Unless otherwise specified, the timestamps in the PGOS interface are all Unix timestamps.

3.2 Player user IDs

The table below uses a few examples to show the various user IDs that a player has:

Account Service Provider usedOpen IDAccount IDPlayer ID
PGOS FASFAS IDFAS IDPGOS Player ID
Steamworks SDKSteam IDSteam IDPGOS Player ID
INTL SDK (e.g. Login on Steam)INTL Open IDSteam IDPGOS Player ID
PlayFab SDK (e.g. Login on Steam)PlayFab IDSteam IDPGOS Player ID

4. Query Player Info

You can fetch the player info of one or more players at once.

4.1 For Game Client

APIDescription
GetMyInfoQuery the current player's detail info. The result is packaged with FPlayerDetail.
GetPlayerInfoQuery a player's info. The result is packaged with FPlayerInfo.
BatchGetPlayerInfoQuery multiple players' info. The result is packaged with FPlayerInfo.

API details:

4.1.1 GetMyInfo Client API

Interface prototype:

/**
* Query the current player's profile.
*/
void GetMyInfo(TFunction<void(const FPgosResult& Ret, const FPlayerDetail* Data)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{

PlayerProfile->GetMyInfo([](const FPgosResult& Ret, const FPlayerDetail* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetMyInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetMyInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

4.1.2 GetPlayerInfo Client API

Interface prototype:

/**
* Query a player's info
*
* @param PlayerId The player id to query.
*/
void GetPlayerInfo(
const FString& PlayerId,
TFunction<void(const FPgosResult& Ret, const FPlayerInfo* Data)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = "197117";
PlayerProfile->GetPlayerInfo(PlayerId, [](const FPgosResult& Ret, const FPlayerInfo* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

4.1.3 BatchGetPlayerInfo Client API

Interface prototype:

/**
* Query multiple players' info
*
* @param PlayerIds The player_ids to query.
*/
void BatchGetPlayerInfo(
const TArray<FString>& PlayerIds,
TFunction<void(const FPgosResult& Ret, const FClientBatchGetPlayerInfoCltRsp* Data)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {"197117", "197118"};
PlayerProfile->BatchGetPlayerInfo(PlayerIds, [](const FPgosResult& Ret, const FClientBatchGetPlayerInfoCltRsp* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

4.2 For Game Server

APIDescription
GetPlayerInfoQuery a player's detail info. The result is packaged with FPlayerDetail.
BatchGetPlayerInfoQuery one or more players' detail info. The result is packaged with FPlayerDetail.

API details:

4.2.1 GetPlayerInfo Server API

Interface prototype:

/**
* Query a player's player detail
*
* @param PlayerId The player to query.
*/
void GetPlayerInfo(
const FString& PlayerId,
TFunction<void(const FPgosResult& Ret, const FPlayerDetail* Data)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
FString PlayerId = TEXT("197117");
PlayerProfile->GetPlayerInfo(PlayerId, [](const FPgosResult& Ret, const FPlayerDetail* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("GetPlayerInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

4.2.2 BatchGetPlayerInfo Server API

Interface prototype:

/**
* Query one or more players' player detail
*
* @param PlayerIds The players to query.
*/
void BatchGetPlayerInfo(
const TArray<FString>& PlayerIds,
TFunction<void(const FPgosResult& Ret, const FServerBatchGetPlayerInfoSvrRsp* Data)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetServerPlayerProfileAPI();
if (PlayerProfile)
{
TArray<FString> PlayerIds = {TEXT("197117"), TEXT("197118")};
PlayerProfile->BatchGetPlayerInfo(PlayerIds, [](const FPgosResult& Ret, const FServerBatchGetPlayerInfoSvrRsp* Data) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerInfo Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("BatchGetPlayerInfo Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

5. Update Player Info

Players can only update their own player info, not that of other players.

5.1 For Game Client

APIDescription
SetMyNameUpdate current player's display name.
SetMyAvatarUpdate the current player's avatar
SetMyLanguageUpdate the current player's language
SetMyGenderUpdate the current player's gender

API details:

5.1.1 SetMyName Client API

Display name length is limited to 2 to 64 characters.

Interface prototype:

/**
* Update current player's display name.
*
* @param display_name Set the current player's display name. The display name length is limited to 2 to 64 characters.
* @param result_callback The result callback after the API execution ends, and it will be called in an ASYNCHRONOUS CHILD THREAD.
*/
void SetMyName(
const FString& DisplayName,
TFunction<void(const FPgosResult& Ret)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString DisplayName = TEXT("ConfusedGirl");
PlayerProfile->SetMyName(DisplayName, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetMyName Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetMyName Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

5.1.2 SetMyAvatar Client API

Interface prototype:

/**
* Update the current player's avatar
*
* @param AvatarUri The new URI of the player avatar.
*/
void SetMyAvatar(
const FString& AvatarUri,
TFunction<void(const FPgosResult& Ret)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString AvatarUri = TEXT("https://images.app.goo.gl/BD9qYfdfYPsMLXW69");
PlayerProfile->SetMyAvatar(AvatarUri, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetMyAvatar Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetMyAvatar Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

5.1.3 SetMyLanguage Client API

Interface prototype:

/**
* Update the current player's language
*
* @param Language The new gender.
*/
void SetMyLanguage(
const FString& Language,
TFunction<void(const FPgosResult& Ret)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString Language = TEXT("en-GB");
PlayerProfile->SetMyLanguage(Language, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetMyLanguage Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetMyLanguage Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

5.1.4 SetMyGender Client API

Interface prototype:

/**
* Update the current player's gender
*
* @param Gender The new language.
*/
void SetMyGender(
const FString& Gender,
TFunction<void(const FPgosResult& Ret)> Callback) const;

Example Code:

#include "PgosSDKCpp.h"
#include "Core/PgosErrorCode.h"

void SomeUObjectClass::SomeFunction()
{
auto PlayerProfile = IPgosSDKCpp::Get().GetClientPlayerProfileAPI();
if (PlayerProfile)
{
FString Gender = TEXT("female");
PlayerProfile->SetMyGender(Gender, [](const FPgosResult& Ret) {
if (Ret.err_code == (int32)Pgos::PgosErrCode::kSuccess)
{
UE_LOG(LogTemp, Log, TEXT("SetMyGender Success"));
}
else
{
UE_LOG(LogTemp, Log, TEXT("SetMyGender Failed: err_code=%d, err_msg=%s"), Ret.err_code, *Ret.msg);
}
});
}
}

6. Key Error Handling

Error CodeRelevant APIHandling Suggestion
kBackendPlayerDisplayNameContainProfanityWordsSetMyNameThe new display name to be submitted contains profanity words. The game can prompt the player to enter a legal display name.
kBackendPlayerDisplayNameVerificationFailedSetMyNameVerification failed by the display name verification settings on the portal.
kBackendDisplayNameAlreadyExistsSetMyNamePlayers' display name is required to be unique within the title region, and the display name to set already exists.
kBackendErrPlayerIsPunishedSetMyNameThe player is punished. msg is the json serialized string of deadline(unix timestamp (in seconds) at the end of the punishment, <= 0 means permanent punishment) and reason.
kSdkNetworkErrorAll Network APInetwork error, check error msg for detail.