دسترسی سمت سرور به خدمات بازی های Google Play

توصیه می کنیم از GamesSignInClient برای احراز هویت بازیکنان استفاده کنید و هویت بازیکن را به طور ایمن به سرور پشتیبان منتقل کنید. این به بازی شما امکان می‌دهد تا هویت بازیکن و سایر داده‌ها را بدون قرار گرفتن در معرض دستکاری احتمالی هنگام عبور از دستگاه، به‌طور ایمن بازیابی کند.

هنگامی که بازیکن با موفقیت وارد سیستم شد، می‌توانید یک کد یکبار مصرف خاص (به نام کد تأیید اعتبار سرور ) از Play Games Services v2 SDK درخواست کنید که مشتری به سرور ارسال می‌کند. سپس، در سرور، کد تأیید اعتبار سرور را با یک توکن OAuth 2.0 که سرور می‌تواند برای برقراری تماس با Google Play Games Services API استفاده کند، مبادله کنید.

برای راهنمایی بیشتر در مورد افزودن ورود به سیستم در بازی‌های خود، به ورود به سیستم برای بازی‌های Android مراجعه کنید.

برای دسترسی آفلاین مراحل زیر لازم است:

  1. در کنسول Google Play: یک اعتبار برای سرور بازی خود ایجاد کنید. نوع مشتری OAuth اعتبارنامه "وب" خواهد بود.
  2. در برنامه Android: به عنوان بخشی از ورود به سیستم، یک کد تأیید اعتبار سرور برای اعتبار سرور خود درخواست کنید و آن را به سرور خود ارسال کنید. GamesSigninClient می‌تواند سه محدوده OAuth 2.0 را هنگام درخواست دسترسی سمت سرور به APIهای وب خدمات بازی‌های Play درخواست کند. دامنه های اختیاری عبارتند از EMAIL , PROFILE و OPEN_ID . دو محدوده پیش‌فرض DRIVE_APPFOLDER و GAMES_LITE هستند.
  3. در سرور بازی خود: کد تأیید اعتبار سرور را با یک نشانه دسترسی OAuth با استفاده از سرویس های تأیید اعتبار Google مبادله کنید و سپس از آن برای فراخوانی API های REST Services Games Play استفاده کنید.

قبل از شروع

ابتدا باید بازی خود را در کنسول Google Play اضافه کنید، همانطور که در راه‌اندازی خدمات بازی‌های Google Play توضیح داده شده است، و خدمات بازی‌های Play را با بازی خود ادغام کنید .

یک برنامه وب سمت سرور ایجاد کنید

سرویس‌های بازی Google Play از بازی‌های وب پشتیبانی نمی‌کنند. با این حال، پشتیبانی از سرور باطن را برای سرور بازی اندروید شما فراهم می کند.

اگر می‌خواهید از REST API برای خدمات بازی‌های Google Play در برنامه سمت سرور خود استفاده کنید، این مراحل را دنبال کنید:

  1. در کنسول Google Play ، یک بازی را انتخاب کنید.
  2. به Play Games Services > Setup and management > Configuration بروید.
  3. افزودن اعتبار را انتخاب کنید تا به صفحه افزودن اعتبارنامه آورده شود. سرور بازی را به عنوان نوع اعتبار انتخاب کنید و به بخش مجوز ادامه دهید.
    1. اگر سرور بازی شما قبلاً شناسه مشتری OAuth دارد آن را از منوی کشویی انتخاب کنید. پس از ذخیره تغییرات خود، به بخش بعدی بروید.
    2. اگر شناسه مشتری OAuth موجود برای سرور بازی خود ندارید، می توانید آن را ایجاد کنید.
      1. روی Create OAuth client کلیک کنید و پیوند Create OAuth Client ID را دنبال کنید.
      2. این شما را به صفحه Create OAuth Client ID پلتفرم Google Cloud برای پروژه مرتبط با بازی شما می‌برد.
      3. فرم صفحه را پر کنید و روی ایجاد کلیک کنید. حتماً نوع Application را روی Web application تنظیم کنید.
      4. به بخش مجوز صفحه افزودن اعتبارنامه بازگردید، مشتری OAuth جدید ایجاد شده را انتخاب کنید و تغییرات خود را ذخیره کنید.

کد تایید سرور را دریافت کنید

برای بازیابی کد احراز هویت سرور که بازی شما می تواند از آن برای دسترسی به نشانه های سرور باطن خود استفاده کند:

  1. requestServerSideAccess از مشتری تماس بگیرید.

    1. مطمئن شوید که از OAuth Client ID ثبت شده برای سرور بازی خود استفاده می کنید و نه از OAuth Client ID برنامه اندروید خود.
    2. (اختیاری) اگر سرور بازی شما نیاز به دسترسی آفلاین (دسترسی طولانی مدت با استفاده از نشانه رفرش) به خدمات بازی های Play دارد، می توانید پارامتر forceRefreshToken را روی true تنظیم کنید.
    3. (اختیاری) به عنوان بخشی از ورود به سیستم، کاربران جدید باید با یک صفحه رضایت واحد برای دامنه های اضافی روبرو شوند. پس از پذیرش رضایت، پارامتر scopes با دامنه های EMAIL ، PROFILE و OPEN_ID OAuth تنظیم می کنید. اگر کاربران رضایت خود را رد کنند، فقط دو دامنه پیش‌فرض DRIVE_APPFOLDER و GAMES_LITE به پشتیبان ارسال می‌شوند.

      صفحه رضایت برای دامنه های OAuth اضافی.
      صفحه رضایت برای دامنه های OAuth اضافی. (برای بزرگنمایی کلیک کنید).

      GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(this);
      gamesSignInClient.requestServerSideAccess(OAUTH_2_WEB_CLIENT_ID, /* forceRefreshToken= / false,
       / Additional AuthScope */ scopes)
      .addOnCompleteListener( task -> {
       if (task.isSuccessful()) {
         AuthResponse authresp = task.getResult();
         // Send the authorization code as a string and a
         // list of the granted AuthScopes that were granted by the
         // user. Exchange for an access token.
         // Verify the player with Play Games Services REST APIs.
       } else {
         // Failed to retrieve authentication code.
       }
      });

  2. کد تأیید OAuth را به سرور باطن خود ارسال کنید تا مبادله شود، شناسه پخش کننده در برابر API های خدمات بازی های Play REST تأیید شود و سپس با بازی شما احراز هویت شود.

کد تایید سرور را ارسال کنید

کد احراز هویت سرور را به سرور باطن خود ارسال کنید تا توکن‌های دسترسی و به‌روزرسانی را مبادله کنند. از نماد دسترسی برای فراخوانی API خدمات بازی‌های Play از طرف بازیکن استفاده کنید و به صورت اختیاری، رمز بازخوانی را ذخیره کنید تا زمانی که نشانه دسترسی منقضی شود، یک نشانه دسترسی جدید به دست آورید.

قطعه کد زیر نشان می دهد که چگونه می توانید کد سمت سرور را در زبان برنامه نویسی جاوا پیاده سازی کنید تا کد تأیید اعتبار سرور را برای توکن های دسترسی مبادله کنید.

جاوا

/**
 * Exchanges the authcode for an access token credential. The credential
 * is 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 shouldn't 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();

    TokenVerifier(tokenResponse);

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

می‌توانید دامنه‌های OAuth را با استفاده از کتابخانه‌های Google API Client در جاوا یا پایتون بازیابی کنید تا شی GoogleIdTokenVerifier را دریافت کنید. قطعه کد زیر پیاده سازی در زبان برنامه نویسی جاوا را نشان می دهد.

جاوا

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;

/**
 * Gets the GoogleIdTokenVerifier object and additional OAuth scopes.
 * If additional OAuth scopes are not requested, the idToken will be null.
 *
 * @param tokenResponse - the tokenResponse passed from the exchangeAuthCode
 *                        function.
 *
 **/

void TokenVerifier(GoogleTokenResponse tokenResponse) {

    string idTokenString = tokenResponse.getIdToken();

    GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
        // Specify the WEB_CLIENT_ID of the app that accesses the backend:
        .setAudience(Collections.singletonList(WEB_CLIENT_ID))
        // Or, if multiple clients access the backend:
        //.setAudience(Arrays.asList(WEB_CLIENT_ID_1, WEB_CLIENT_ID_2, WEB_CLIENT_ID_3))
        .build();

    GoogleIdToken idToken = verifier.verify(idTokenString);

    // The idToken can be null if additional OAuth scopes are not requested.
    if (idToken != null) {
        Payload payload = idToken.getPayload();

    // Print user identifier
    String userId = payload.getSubject();
    System.out.println("User ID: " + userId);

    // Get profile information from payload
    String email = payload.getEmail();
    boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
    String name = (String) payload.get("name");
    String pictureUrl = (String) payload.get("picture");
    String locale = (String) payload.get("locale");
    String familyName = (String) payload.get("family_name");
    String givenName = (String) payload.get("given_name");

    // Use or store profile information
    // ...

    } else {
      System.out.println("Invalid ID token.");
    }
}

API های REST را از سرور تماس بگیرید

برای توضیح کامل تماس‌های API موجود، REST APIها را برای خدمات بازی‌های Google Play ببینید.

نمونه‌هایی از تماس‌های REST API که ممکن است برای شما مفید باشد عبارتند از:

بازیکن

آیا می‌خواهید شناسه و اطلاعات نمایه بازیکن واردشده را دریافت کنید؟ با 'me' به عنوان شناسه با Players.get تماس بگیرید.

دوستان

برای جزئیات بیشتر به راهنمای دوستان مراجعه کنید.

  • برای بازیابی لیست دوستان بازیکن، با Players.list با friends_all به عنوان collection تماس بگیرید.

  • برای بررسی اینکه آیا به لیست دوستان دسترسی دارید، با Players.get with me به عنوان playerID تماس بگیرید و قسمت profileSettings.friendsListVisibility را در پاسخ مشاهده کنید.

دستاوردها

برای جزئیات به راهنمای دستاوردها مراجعه کنید.

  • برای دریافت لیستی از دستاوردهای فعلی، با AchievementDefinitions.list تماس بگیرید.

  • آن را با یک تماس به Achievements.list ترکیب کنید تا متوجه شوید بازیکن کدام یک را باز کرده است.

  • برای باز کردن قفل دستاورد بازیکن ، Achievements.unlock را تماس بگیرید.

  • با Achievements.increment تماس بگیرید تا پیشرفت یک دستاورد را گزارش کنید و ببینید آیا بازیکن آن را باز کرده است یا خیر.

  • اگر بازی‌ای را که به مرحله تولید نرسیده است را اشکال زدایی می‌کنید، می‌توانید با Achievements.reset یا Achievements.resetAll از APIهای مدیریت تماس بگیرید تا دستاوردها به حالت اولیه بازنشانی شوند.

تابلوهای امتیازات

برای جزئیات به راهنمای تابلوهای امتیازات مراجعه کنید.

  • آیا می خواهید لیستی از تمام تابلوهای امتیاز بازی را دریافت کنید؟ با Leaderboards.list تماس بگیرید.

  • اگر یک بازیکن با یک بازی تمام شد، می توانید امتیاز خود را به Scores.submit ارسال کنید و ببینید که آیا این یک امتیاز جدید است یا خیر.

  • برای نمایش تابلوی امتیازات، داده ها را از Scores.list دریافت کرده و به کاربر نشان دهید.

  • از Scores.listWindow برای پیدا کردن مجموعه ای از نمرات نزدیک به امتیاز بالای کاربر استفاده کنید.

  • برای دریافت اطلاعات بیشتر در مورد امتیاز بازیکن در یک تابلوی امتیازات خاص (به عنوان مثال، اگر بازیکن در 12٪ برتر همه بازیکنان باشد)، با Scores.get تماس بگیرید.

  • اگر یک بازی را اشکال زدایی می کنید، می توانید با Scores.reset از API های مدیریت تماس بگیرید تا تمام امتیازات آن بازیکن از یک تابلوی امتیازات خاص بازنشانی شود.