הפעלת גישה מצד השרת ל-Google Play Games Services

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

בתרחיש הזה, ברגע של הנגן נכנסים בהצלחה, ניתן לבקש קוד מיוחד לשימוש חד-פעמי (שנקרא קוד ההרשאה של השרת) מה-SDK של Play Games Services v2, שהלקוח מעביר לשרת. לאחר מכן, בשרת, את קוד אימות השרת לאסימון OAuth 2.0 שבו השרת יכול להשתמש כדי לבצע קריאות ממשק ה-API של Google Play Games Services.

לקבלת הנחיות נוספות לגבי הוספת כניסה במשחקים שלך, אפשר לעיין במאמר כניסה לחשבון במשחקי Android.

כדי לקבל גישה במצב אופליין, נדרשים השלבים הבאים:

  1. ב-Google Play Console: יוצרים פרטי כניסה לשרת המשחקים. הסוג של לקוח OAuth של פרטי הכניסה יהיה 'אינטרנט'.
  2. באפליקציה ל-Android: כחלק מהכניסה, מבקשים קוד אימות שרת עבור של השרת שלך, ומעבירים אותם לשרת שלך.
  3. בשרת המשחקים: החלפת קוד ההרשאה של השרת בגישת OAuth באמצעות שירותי האימות של Google, ואז להשתמש בו כדי לקרוא API ל-REST ב-Play Games Services.

לפני שמתחילים

קודם צריך להוסיף את המשחק Google Play Console, כפי שמתואר מגדירים את Google Play Games Services ומשלבים את התכונה כניסה ל-Play Games Services במשחק.

יצירת אפליקציית אינטרנט משויכת בצד השרת עבור המשחק שלך

שירותי המשחקים של Google Play לא מספקים שירותי קצה עורפי תמיכה במשחקי אינטרנט. עם זאת, הוא מספק תמיכה בשרת עורפי לשרת של המשחק ל-Android.

אם רוצים להשתמש ממשקי API בארכיטקטורת REST לשירותי Google Play Games באפליקציה בצד השרת, מבצעים את השלבים הבאים:

  1. מהמשחק ב-Google Play Console, עוברים אל Play Games Services > הגדרה וניהול > הגדרה.
  2. בוחרים באפשרות Add credential (הוספת פרטי כניסה) כדי לעבור אל Add credential (הוספת פרטי כניסה). בוחרים באפשרות שרת משחקים בתור סוג פרטי הכניסה וממשיכים לקטע הרשאה.
    1. אם לשרת המשחקים כבר יש מזהה לקוח OAuth, בוחרים אותו מהתפריט הנפתח. לאחר שמירת השינויים, עוברים לקטע הבא.
    2. אם אין מזהה לקוח OAuth עבור שרת המשחקים שלכם, אפשר ליצור מזהה כזה.
      1. לוחצים על יצירת לקוח OAuth ולוחצים על יצירת מזהה לקוח של OAuth.
      2. הפעולה הזו תעביר אתכם לדף יצירת מזהה לקוח OAuth ב-Google Cloud Platform, לפרויקט שמשויך למשחק ב-Cloud Platform.
      3. ממלאים את הטופס של הדף ולוחצים על 'יצירה'. צריך להגדיר את סוג האפליקציה כ'אפליקציית אינטרנט'.
      4. חוזרים לקטע Add Credential page (הוספת פרטי כניסה), בוחרים את לקוח ה-OAuth החדש שנוצר ושומרים את השינויים.

קבלת קוד ההרשאה של השרת

כדי לאחזר קוד אימות שרת שהמשחק יכול להשתמש בו לאסימוני גישה בשרת העורפי:

  1. התקשרות אל requestServerSideAccess מהלקוח.

    1. ודאו שאתם משתמשים במזהה הלקוח של OAuth שרשום לשרת המשחק שלכם ולא במזהה הלקוח של OAuth של האפליקציה ל-Android.
    2. (אופציונלי) אם שרת המשחקים שלכם מחייב גישה אופליין (גישה לטווח ארוך באמצעות אסימון רענון) ל-Play Games Services, אפשר להגדיר את הפרמטר forceRToken כ-True.
    GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(this);
    gamesSignInClient
      .requestServerSideAccess(OAUTH_2_WEB_CLIENT_ID, /* forceRefreshToken= */ false)
      .addOnCompleteListener( task -> {
        if (task.isSuccessful()) {
          String serverAuthToken = task.getResult();
          // Send authentication code to the backend game server to be
          // exchanged for an access token and used to verify the player
          // via the Play Games Services REST APIs.
        } else {
          // Failed to retrieve authentication code.
        }
    });
    
  2. יש לשלוח את אסימון קוד האימות של OAuth לשרת הקצה העורפי שלך כדי שאפשר יהיה שיוחלף, את מזהה השחקן יאומת מול ממשקי ה-API ל-REST של Play Games Services, ואז אומת באמצעות המשחק.

החלפת קוד אימות השרת באסימון גישה בשרת

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

קטע הקוד הבא מראה איך ליישם את הקוד בצד השרת ב-Java שפת תכנות כדי להחליף את קוד ההרשאה של השרת באסימוני גישה. זה כן באמצעות clientserverskeleton לדוגמה app:

/**
 * Exchanges the authcode for an access token credential.  The credential
 * is the associated with the given player.
 *
 * @param authCode - the non-null authcode passed from the client.
 * @param player   - the player object which the given authcode is
 *                 associated with.
 * @return the HTTP response code indicating the outcome of the exchange.
 */
private int exchangeAuthCode(String authCode, Player player) {
try {

    // The client_secret.json file is downloaded from the Google API
    // console.  This is used to identify your web application.  The
    // contents of this file should not be shared.
    //
    File secretFile = new File("client_secret.json");

    // If we don't have the file, we can't access any APIs, so return
    // an error.
    if (!secretFile.exists()) {
        log("Secret file : " + secretFile
                .getAbsolutePath() + "  does not exist!");
        return HttpServletResponse.SC_FORBIDDEN;
    }

    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(
            JacksonFactory.getDefaultInstance(), new
            FileReader(secretFile));

    // Extract the application id of the game from the client id.
    String applicationId = extractApplicationId(clientSecrets
            .getDetails().getClientId());

    GoogleTokenResponse tokenResponse =
            new GoogleAuthorizationCodeTokenRequest(
            HTTPTransport,
            JacksonFactory.getDefaultInstance(),
            "https://oauth2.googleapis.com/token",
            clientSecrets.getDetails().getClientId(),
            clientSecrets.getDetails().getClientSecret(),
            authCode,
            "")
            .execute();

    log("hasRefresh == " + (tokenResponse.getRefreshToken() != null));
    log("Exchanging authCode: " + authCode + " for token");
    Credential credential = new Credential
            .Builder(BearerToken.authorizationHeaderAccessMethod())
            .setJsonFactory(JacksonFactory.getDefaultInstance())
            .setTransport(HTTPTransport)
            .setTokenServerEncodedUrl("https://www.googleapis.com/oauth2/v4/token")
            .setClientAuthentication(new HttpExecuteInterceptor() {
                @Override
                public void intercept(HttpRequest request)
                        throws IOException {
                        }
            })
            .build()
            .setFromTokenResponse(tokenResponse);

    player.setCredential(credential);

    // Now that we have a credential, we can access the Games API.
    PlayGamesAPI api = new PlayGamesAPI(player, applicationId,
            HTTPTransport, JacksonFactory.getDefaultInstance());

    // Call the verify method, which checks that the access token has
    // access to the Games API, and that the player id used by the
    // client matches the playerId associated with the accessToken.
    boolean ok = api.verifyPlayer();

    // Call a Games API on the server.
    if (ok) {
        ok = api.updatePlayerInfo();
        if (ok) {
            // persist the player.
            savePlayer(api.getPlayer());
        }
    }

    return ok ? HttpServletResponse.SC_OK :
            HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

  } catch (IOException e) {
    e.printStackTrace();
  }
  return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
}

קריאה לממשקי API בארכיטקטורת REST מהשרת

למידע נוסף, אפשר לעיין בממשקי API בארכיטקטורת REST לשירותי Google Play Games תיאור מלא של הקריאות הזמינות ל-API.

ריכזנו כאן דוגמאות לקריאות API ל-REST שיכולות להועיל:

שחקן

  • רוצה לקבל את המזהה ונתוני הפרופיל של השחקן שמחובר לחשבון? התקשרות אל Players.get עם 'me' כמזהה.

חברים

הקפידו לקרוא את המדריך חברים, שכולל הסבר מפורט על 'חברים'.

  • רוצה לאחזר את רשימת החברים של השחקן? התקשרות אל Players.list באמצעות 'friends_all' בתור collection.
  • לבדוק אם יש לכם גישה לרשימת החברים? התקשרות אל Players.get תמורת me, וגם בודקים את השדה profileSettings.friendsListVisibility בתשובה.

הישגים

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

  • רוצה לקבל רשימה של ההישגים הנוכחיים? אפשר לבצע קריאה אל AchievementDefinitions.list.
  • ניתן לשלב את הפעולה הזו עם קריאה אל Achievements.list כדי לברר אילו מהם השחקן ביטל את הנעילה שלו.
  • האם השחקן צבר הישג? אפשר להשתמש בכתובת Achievements.unlock.
  • האם השחקן התקדם להישג חלקי? משתמשים בפרמטר Achievements.increment כדי: לדווח על ההתקדמות (ולבדוק אם השחקן ביטל את הנעילה).
  • אתם מנסים לנפות באגים במשחק שעדיין לא נמצא בסביבת ייצור? רוצה לנסות להתקשר? Achievements.reset או Achievements.resetAll דרך ממשקי ה-API של ניהול. לאפס את ההישגים למצבם המקורי.

Leaderboards

מומלץ לקרוא את המדריך בנושא לוחות לידרבורד, שמסביר בצורה מפורטת יותר את לוחות הלידרבורד.

  • רוצה לקבל רשימה של כל לוחות התוצאות במשחק? מבצעים שיחה אל Leaderboards.list.
  • האם השחקן סיים משחק? אפשר לשלוח את הניקוד שלהם אל Scores.submit ובודקים אם זהו תוצאה גבוהה חדשה.
  • רוצה להציג Leaderboard? ניתן לקבל את הנתונים מ-Scores.list ולהציג אותם למשתמש.
  • משתמשים ב-Scores.listWindow כדי למצוא מגוון של ציונים שקרובים לתוצאה של המשתמש.
  • כדי לקבל מידע נוסף על הניקוד של השחקן בלידרבורד מסוים (לדוגמה, אם שהשחקן נמצא ב-12% המובילים מכל השחקנים, ניתן לקרוא ל-Scores.get.
  • אתם מתקנים באגים במשחק? אפשר לנסות לקרוא אל Scores.reset בניהול הניהול ממשקי API לאיפוס כל הניקוד של אותו שחקן מ-Leaderboard מסוים