在游戏中集成 PGS Recall API

本页介绍了如何在游戏中实现 Recall API。其中首先介绍如何设置游戏服务器和客户端以支持该 API,然后介绍如何存储和检索令牌。

游戏服务器设置

设置您的游戏服务器,以便对 Google 服务器进行 Recall API 调用。

设置您的 Play 游戏服务项目

(如果尚未完成)请按照设置 Google Play 游戏服务中的说明进行操作。

为游戏设置服务账号

按照创建服务账号中的说明操作。最后,您应该得到一个包含服务账号凭据的 JSON 文件。

下载适用于 Play 游戏服务的服务器端 Java 库

下载最新的 google-api-services-games,并将其上传到您的服务器。

准备用于 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,并确保在 Gradle 文件中添加 com.google.android.gms:play-services-games-v2:19.0.0com.google.android.gms:play-services-tasks:18.0.2 或更高版本。

如需使用正确的信息与 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
  });

在游戏服务器中使用 Recall API

配置服务器和客户端后,您可以将 recallSessionID 从游戏客户端发送到游戏服务器,并按照以下指南开始使用 Java API 来存储、检索或删除 Recall 令牌服务器端。

存储令牌

使用 LinkPersonaRequest 对象存储用户的角色和游戏令牌。使用 GoogleCredential 调用 Google API。为了遵循 1 对 1 基数限制条件,您一次只能将一个角色关联到一个 PGS 玩家资料,反之亦然。设置解决政策,以防此 PGS 玩家资料已与其他角色相关联。

(可选)您可以选择设置令牌的 TTL,使用 Durations 对象声明令牌的有效时长。您可以选择使用 SetTtl()(如下所示)或 setExpireTime() 进行设置,前者会根据方法中指定的时间量设置失效日期,后者允许您设置确切的令牌到期时间。

您必须对角色和游戏令牌进行加密,且它们不能包含个人身份信息。角色和令牌字符串不得超过 256 个字符,并且每个游戏最多可以为每位玩家存储 20 个令牌或角色。

在给定的时间只能为每位玩家的每个角色存储一个令牌。如果您尝试存储具有相同角色的其他令牌,系统会覆盖原始令牌。

import com.google.api.services.games.Games.Recall.LinkPersona;
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 令牌,请从客户端获取 recallSessionId 并将其传递到 retrieveTokens API:

import com.google.api.services.games.Games.Recall.RetrieveTokens;

// ...

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 令牌

如果需要,您还可以通过以下调用删除 Recall 令牌:

import com.google.api.services.games.Games.Recall.UnlinkPersona;

// ...

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();

// Confirm that the unlinking process completed successfully.
boolean unlinked = unlinkPersonaResponse.isUnlinked();