本页介绍了如何在游戏中实现 Recall API。其中首先介绍如何设置游戏服务器和客户端以支持该 API,然后介绍如何存储和检索令牌。
游戏服务器设置
设置您的游戏服务器,以便对 Google 服务器进行 Recall API 调用。
1. 设置您的 Play 游戏服务项目
如果您尚未这样做,请按照设置 Google Play 游戏服务中的说明进行操作。
2. 为游戏设置服务账号
按照创建服务账号中的说明操作。最后,您应该得到一个包含服务账号凭据的 JSON 文件。
3. 下载适用于 PlayGamesServices 的服务器端 Java 库
下载 google-api-services-games 库,并将其上传到您的 服务器。
4. 准备用于 Recall API 调用的凭据
如需了解更多背景信息,请参阅准备进行已获授权的 API 调用。
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.games.Games;
import com.google.api.services.games.GamesScopes;
// ...
GoogleCredential credential =
GoogleCredential.fromStream(new FileInputStream("<credentials>.json"))
.createScoped(Collections.singleton(GamesScopes.ANDROIDPUBLISHER));
Games gamesApi =
new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
游戏客户端设置
设置游戏客户端,以检索我们的服务器用于与 Google 服务器进行通信的 Recall 会话 ID。
Java SDK
在客户端中设置 Java SDK,并确保在
com.google.android.gms:play-services-games-v2:19.0.0
和 com.google.android.gms:play-services-tasks:18.0.2 或更高版本中包含
Gradle 文件。
若要使用正确的信息与 Google 的服务器进行通信,您需向客户端 SDK 请求 Recall 会话 ID,并将该 ID 发送到游戏服务器。
Kotlin
PlayGames.getRecallClient(getActivity())
.requestRecallAccess()
.addOnSuccessListener { recallAccess -> val recallSessionId: String = recallAccess.getSessionId() }
// Send the recallSessionId to your game server
Java
PlayGames.getRecallClient(getActivity())
.requestRecallAccess()
.addOnSuccessListener(
recallAccess -> {
String recallSessionId = recallAccess.getSessionId();
// Send the recallSessionId to your game server
});
Unity SDK
如果您尚未这样做,请在客户端中设置 Unity SDK。
若要使用正确的信息与 Google 的服务器进行通信,您需向客户端 SDK 请求 Recall 会话 ID,并将该 ID 发送到游戏服务器。
PlayGamesPlatform.Instance.RequestRecallAccess(
recallAccess => {
string recallSessionId = recallAccess.sessionId;
// Send the recallSessionId to your game server
});
v2 原生 SDK(Beta 版)
如果您尚未这样做, 请开始使用面向 C 和 C++ 的 Play 游戏服务。
// Include the following headers
#include "play_games.h"
#include "recall_client.h"
#include "pgs_status_code.h"
// Request Recall Access
// Initializes the Play Games Services v2 Native SDK (beta).
Pgs_initialize(javaVM, activity);
//Creating Recall Client
PgsRecallClient* pgs_recall_client =
PgsRecallClient_create(activity);
// RequestRecallAccess Function
PgsRecallClient_requestRecallAccess(
pgs_recall_client,
// This is your callback function defined as an inline lambda
[](PgsStatusCode status_code, char* session_id, user_data) {
if (status_code == PGS_STATUS_SUCCESS) {
// Recall Session Id Fetched Successfully
} else {
// Fetching Recall Session Id Failed
// Handle error based on status_code.
// Examples:
// PGS_STATUS_NETWORK_ERROR: Check internet connection.
// PGS_STATUS_INTERNAL_ERROR: An unexpected error occurred.
}
// Clean up the client instance passed as user_data
PgsRecallClient* client = static_cast<PgsRecallClient*>(user_data);
if (client != nullptr) {
PgsRecallClient_destroy(client);
}
},
user_data // Data to pass to the callback
);
// Shuts down the Play Games Services v2 Native SDK (beta).
Pgs_destroy()
在游戏服务器中使用 Recall API
配置服务器和客户端后,您可以将 recallSessionID 从游戏客户端发送到游戏服务器,并按照以下指南开始使用 Java API 来存储、检索或删除 Recall 令牌服务器端。
存储令牌
Google Play 游戏 Recall API 中的玩家账号包含以下两部分信息:
- 角色 ,用作游戏内账号的稳定标识符
- 令牌 ,用作安全地将玩家登录到账号的密钥
您可以使用 LinkPersonaRequest 对象存储用户的可靠身份标识和令牌。使用 GoogleCredential 来调用 Google API(如需了解上下文,请参阅 调用 Google
API)。角色具有 1:1 基数限制:一个 PGS
玩家资料只能包含一个角色,而一个角色只能属于一个 PGS
玩家资料。设置 冲突链接解决政策,以定义
如何解决违反 1:1 基数限制的情况。
(可选)设置令牌的失效时间。使用 SetTtl() 和
Durations 对象设置存留时间,或使用 setExpireTime() 提供确切的失效时间。
您必须对角色和游戏令牌进行加密,且它们不能包含个人身份信息。角色和令牌字符串不得超过 256 个字符。
import com.google.api.services.games.Games.Recall.LinkPersona;
import com.google.api.services.games.model.LinkPersonaRequest;
import com.google.api.services.games.model.LinkPersonaResponse;
import com.google.protobuf.util.Durations;
// ...
Games gamesApi =
new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
String recallSessionId = ... // recallSessionID from game client
String persona = ... // encrypted opaque string, stable for in-game account
String token = ... // encrypted opaque string encoding the progress line
LinkPersonaRequest linkPersonaRequest =
LinkPersonaRequest.newBuilder()
.setSessionId(recallSessionId)
.setPersona(persona)
.setToken(token)
.setCardinalityConstraint(ONE_PERSONA_TO_ONE_PLAYER)
.setConflictingLinksResolutionPolicy(CREATE_NEW_LINK)
.setTtl(Durations.fromDays(7)) // Optionally set TTL for token
.build();
LinkPersonaResponse linkPersonaResponse =
gamesApi.recall().linkPersona(linkPersonaRequest).execute();
if (linkPersonaResponse.getState() == LINK_CREATED) {
// success
}
检索令牌
您可以根据游戏的需求,选择以下三种方式来检索令牌。您可以请求以下内容:
- 与当前游戏关联的令牌,包括游戏范围的 Recall 令牌。
- 开发者账号拥有的所有游戏中存储的最后一个令牌。
- 给定开发者账号拥有的游戏列表,与每个游戏关联的所有 Recall 令牌。
游戏范围的 Recall 令牌
如需从当前游戏中检索 Recall 令牌,请从客户端获取 recallSessionId 并将其传递到 retrieveTokens API:
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrievePlayerTokensResponse;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
RetrievePlayerTokensResponse retrievePlayerTokensResponse =
gamesApi.recall().retrieveTokens(recallSessionId).execute();
for (RecallToken recallToken : retrievePlayerTokensResponse.getTokens()) {
String token recallToken.getToken();
// Same string as was written in LinkPersona call
// decrypt and recover in-game account
}
开发者账号拥有的所有游戏中的最新 Recall 令牌
如需检索 Google Play 管理中心内开发者账号拥有的所有游戏中存储的最新令牌,您需要从客户端获取 recallSessionId 并将其传递到 lastTokenFromAllDeveloperGames API,如以下代码段所示。作为响应的一部分,您可以检查与此令牌关联的
应用 ID。
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrieveDeveloperGamesLastPlayerTokenResponse;
import com.google.api.services.games.model.GamePlayerToken;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
RetrieveDeveloperGamesLastPlayerTokenResponse response =
gamesApi.recall().lastTokenFromAllDeveloperGames(recallSessionId)
.execute();
if (response.hasGamePlayerToken()) {
GamePlayerToken gamePlayerToken = response.getGamePlayerToken();
// The ID of the application that the token is associated with.
String applicationId = gamePlayerToken.getApplicationId();
// Same string as was written in LinkPersona call.
RecallToken recallToken = gamePlayerToken.getRecallToken();
// Decrypt and recover in-game account.
}
开发者账号拥有的给定游戏列表中的所有 Recall 令牌
如需检索 Google Play 管理中心内开发者账号拥有的游戏列表中的所有令牌,请从客户端获取 recallSessionId 并将其传递到 gamesPlayerTokens API。提供应用 ID 列表。
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrieveGamesPlayerTokensResponse;
import com.google.api.services.games.model.GamePlayerToken;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
// Application IDs for which you would like to retrieve the recall tokens.
List<String> applicationIds = ...
RetrieveGamesPlayerTokensResponse response =
gamesApiClient
.recall()
.gamesPlayerTokens(recallSessionId)
.setApplicationIds(applicationIds)
.execute();
for (GamePlayerToken gamePlayerToken : response.getGamePlayerTokens()) {
// The ID of the application that the token is associated with.
String applicationId = gamePlayerToken.getApplicationId();
// Same string as was written in LinkPersona call.
RecallToken recallToken = gamePlayerToken.getRecallToken();
// Decrypt and recover in-game account.
}
删除 Recall 令牌
如果需要,您还可以通过以下调用删除 Recall 令牌:
import com.google.api.services.games.Games;
import com.google.api.services.games.model.UnlinkPersonaRequest;
import com.google.api.services.games.model.UnlinkPersonaResponse;
// ...
String recallSessionId = ...
String persona = ...
String token = ...
Games gamesApi =
new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
UnlinkPersonaRequest unlinkPersonaRequest =
UnlinkPersonaRequest.newBuilder()
.setSessionId(recallSessionId)
.setPersona(persona)
// .setToken(token) - alternatively set token, but not both
.build();
UnlinkPersonaResponse unlinkPersonaResponse =
gamesApi.recall().unlinkPersona(unlinkPersonaRequest).execute();
boolean unlinked = unlinkPersonaResponse.isUnlinked();
启用无玩家资料模式
您可以按照以下步骤为没有 PGS 玩家资料的用户启用有限的 Recall API 功能:
<meta-data
android:name="com.google.android.gms.games.PROFILELESS_RECALL_ENABLED"
android:value="true" />
附加条款
您还必须遵守 Play 游戏服务服务条款。如果您为没有 PGS 玩家资料的用户使用 Recall API(这涉及与 Google 分享最终用户数据),则必须在与 Google 分享此数据之前,向最终用户提供适当的通知,其中说明以下内容:
- 您如何与 Google 分享数据以启用 Play 游戏账号关联功能。
- 用于管理此分享的设置的可用性,例如通过 Play 游戏设置。
- 根据 Google 隐私权政策 处理此数据,以及必须为此分享获得符合所有适用法律要求的适当最终用户同意。
