משלבים את PGS Recall API במשחק

בדף הזה מוסבר איך להטמיע את Recall API במשחק. המדריך מתחיל בהסבר על הגדרת שרת המשחק והלקוח לתמיכה ב-API, ואז מוסבר בו איך לאחסן ולאחזר טוקנים.

הגדרת שרת גיימינג

מגדירים את שרת המשחק כך שיבצע קריאות ל-Recall API לשרתי Google.

1. הגדרת פרויקט Play Games Services

אם עדיין לא עשיתם זאת, פועלים לפי ההוראות שבמאמר הגדרת שירותי Google Play Games.

2. הגדרת חשבון שירות למשחק

פועלים לפי ההוראות ליצירת חשבון שירות. בסיום התהליך אמור להיות לכם קובץ JSON עם פרטי הכניסה של חשבון השירות.

3. הורדת ספריית Java בצד השרת ל-PlayGamesServices

מורידים את ספריית 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();

הגדרת לקוח משחק

מגדירים את לקוח המשחק כך שיאחזר את מזהי סשן Recall שבהם השרת שלנו משתמש כדי לתקשר עם השרתים של Google.

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 ולשלוח אותו לשרת של המשחק.

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 ולשלוח אותו לשרת של המשחק.

PlayGamesPlatform.Instance.RequestRecallAccess(
    recallAccess => {
        string recallSessionId = recallAccess.sessionId;
        // Send the recallSessionId to your game server
    });

גרסה 2 של Native SDK (בטא)

אם עדיין לא עשיתם את זה, כדאי להתחיל להשתמש ב-Play Games Services ל-C ול-C++‎.

// 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 Games Recall API מורכב משני חלקי מידע:

  • פרסונה שמשמשת כמזהה יציב לחשבון במשחק
  • אסימון שמשמש כמפתח לחתימה מאובטחת של שחקן בחשבון

אפשר לשמור את הפרסונה והאסימון של המשתמש באמצעות האובייקט LinkPersonaRequest. משתמשים ב-GoogleCredential כדי לשלוח קריאה ל-Google APIs (פרטים נוספים זמינים במאמר שליחת קריאה ל-Google APIs). לפרסונה יש אילוץ קרדינליות של 1:1: פרופיל PGS יכול להכיל רק פרסונה אחת, ופרסונה יכולה להשתייך רק לפרופיל PGS אחד. מגדירים את מדיניות הפתרון של קישורים סותרים כדי להגדיר איך לפתור הפרות של אילוץ הקרדינליות 1:1.

אפשר להגדיר את תאריך התפוגה של הטוקן. משתמשים ב-SetTtl() עם אובייקט Durations כדי להגדיר זמן חיים (TTL) או לציין זמן תפוגה מדויק באמצעות 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
}

אחזור טוקנים

יש 3 אפשרויות לאחזור טוקן, בהתאם לצרכים של המשחקים שלכם. אפשר לבקש את הפעולות הבאות:

  • האסימונים שמשויכים למשחק הנוכחי, כולל אסימוני שליפה בהיקף המשחק.
  • האסימון האחרון שאוחסן בכל המשחקים שבבעלות חשבון המפתח.
  • בהינתן רשימה של משחקים שנמצאים בבעלות חשבון המפתח, כל אסימוני הביטול שמשויכים לכל משחק.

טוקנים של ריקול בהיקף המשחק

כדי לאחזר את טוקני הזיכרון מהמשחק הנוכחי, צריך לקבל את 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
}

הטוקן האחרון לביטול ההסכמה בכל המשחקים שבבעלות חשבון המפתח

כדי לאחזר את הטוקן האחרון שמאוחסן בכל המשחקים שבבעלות חשבון המפתח ב-Google Play Console, צריך לקבל את recallSessionId מהלקוח ולהעביר אותו אל API‏ lastTokenFromAllDeveloperGames, כמו שמוצג בקטע הקוד הבא. כחלק מהתשובה, אפשר לבדוק את מזהה האפליקציה שמשויך לאסימון הזה.

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.
}

כל אסימוני הביטול ברשימה נתונה של משחקים שבבעלות חשבון המפתח

כדי לאחזר את כל האסימונים שמשויכים לרשימת משחקים שנמצאים בבעלות חשבון הפיתוח שלכם ב-Google Play Console, צריך לקבל את recallSessionId מהלקוח ולהעביר אותו אל API‏ gamesPlayerTokens. צריך לציין רשימה של מזהי אפליקציות.

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.
}

מחיקת טוקן הגישה

במקרה הצורך, אפשר גם למחוק את אסימון הביטול באמצעות הקריאה הבאה:

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

הפעלת מצב ללא פרופיל

כדי להפעיל פונקציונליות מוגבלת של Recall API למשתמשים שאין להם פרופילים ב-PGS:

  1. מפעילים את התכונה 'ריקול ללא פרופיל' בפרויקט המשחק של PGS ב-Play Console. בוחרים באפשרות &#39;הפעלת האחסון&#39;.
  2. כדאי לעיין בתנאים הנוספים שמתוארים בהמשך הקטע הזה.
  3. מוסיפים את תג המטא-נתונים הבא אל המניפסט של האפליקציה:
<meta-data
  android:name="com.google.android.gms.games.PROFILELESS_RECALL_ENABLED"
  android:value="true" />

תנאים נוספים

אתם צריכים גם לפעול בהתאם לתנאים ולהגבלות של שירותי Play Games. אם אתם משתמשים ב-Recall API עבור משתמשים ללא פרופיל PGS, שכולל שיתוף נתונים של משתמשי קצה עם Google, אתם צריכים, לפני שאתם משתפים את הנתונים האלה עם Google, לספק למשתמשי הקצה הודעה מתאימה שמתארת את הפרטים הבאים:

  • איך משתפים נתונים עם Google כדי להפעיל את התכונה של קישור חשבון Play Games.
  • הזמינות של הגדרות לניהול השיתוף הזה, למשל, דרך ההגדרות של Play Games.
  • העיבוד של הנתונים האלה מתבצע בהתאם למדיניות הפרטיות של Google, ונדרש לקבל הסכמה מתאימה ממשתמשי הקצה לשיתוף הזה, בהתאם לכל הדרישות המשפטיות הרלוונטיות.