تفعيل ميزة "الوصول من جهة الخادم" إلى "خدمات ألعاب Google Play"

ننصحك بمصادقة اللاعبين ونقْل هوية اللاعب بأمان إلى خادم الخلفية. يتيح ذلك لتطبيقك استرجاع هوية اللاعب وبيانات أخرى بأمان بدون أن يتعرض للاختراق أثناء مروره عبر الجهاز.

في هذا السيناريو، بمجرد أن سجّل اللاعب الدخول بنجاح، يمكنك طلب رمز خاص يُستخدم لمرة واحدة (يُسمّى رمز مصادقة الخادم) من حزمة تطوير البرامج (SDK) للإصدار 2 من "خدمات ألعاب Play"، والذي يمرّره العميل إلى الخادم. بعد ذلك، استبدِل على الخادم رمز مصادقة الخادم برمز مميز لبروتوكول OAuth 2.0 يمكن للخادم استخدامه لإجراء طلبات إلى واجهة برمجة التطبيقات Google Play Games Services API.

للحصول على إرشادات إضافية حول إضافة ميزة تسجيل الدخول في ألعابك، يُرجى الاطّلاع على مقالة تسجيل الدخول في ألعاب Android.

يجب اتّباع الخطوات التالية للوصول إلى المحتوى بلا إنترنت:

  1. في Google Play Console: أنشِئ بيانات اعتماد لخادم لعبتك. سيكون نوع عميل OAuth لبيانات الاعتماد هو "الويب".
  2. في تطبيق Android: كجزء من عملية تسجيل الدخول، اطلب رمز مصادقة الخادم لبيانات اعتماد الخادم، ثم أعِد توجيهه إلى الخادم.
  3. على خادم اللعبة: استبدِل رمز مصادقة الخادم برمز مميّز للوصول عبر بروتوكول OAuth باستخدام خدمات مصادقة Google، ثم استخدِم هذا الرمز للاتّصال بواجهات برمجة تطبيقات REST في "خدمات ألعاب Play".

قبل البدء

عليك أولاً إضافة لعبتك إلى Google Play Console كما هو موضّح في يمكنك إعداد "خدمات ألعاب Google Play" ودمج ميزة تسجيل الدخول إلى "خدمات ألعاب Play" مع لعبتك.

إنشاء تطبيق ويب مرتبط من جهة الخادم للعبة

لا توفّر "خدمات ألعاب Google Play" خلفية لألعاب الويب. ومع ذلك، فهي تتيح دعم خادم الخلفية لخادم ألعاب Android.

إذا كنت تريد استخدام صفحة واجهات برمجة تطبيقات REST الخاصة بـ "خدمات ألعاب Google Play" في التطبيق من جهة الخادم، اتّبِع الخطوات التالية:

  1. من لعبتك في Google Play Console، انتقِل إلى خدمات ألعاب Google Play > الإعداد والإدارة > الضبط.
  2. اختَر إضافة بيانات اعتماد ليتم نقلك إلى صفحة إضافة بيانات اعتماد. اختَر خادم الألعاب كنوع بيانات الاعتماد وانتقِل إلى قسم التفويض.
    1. إذا كان خادم اللعبة يتضمّن معرّف عميل OAuth، اختَره من القائمة المنسدلة. بعد حفظ التغييرات، انتقِل إلى القسم التالي.
    2. إذا لم يكن لديك معرِّف عميل OAuth حالي لخادم الألعاب، يمكنك إنشاء معرِّف.
      1. انقر على إنشاء عميل OAuth واتّبِع الرابط إنشاء معرِّف عميل OAuth.
      2. سيؤدي ذلك إلى نقلك إلى صفحة إنشاء معرّف عميل OAuth في Google Cloud Platform لمشروع Cloud Platform المرتبط بلعبتك.
      3. املأ نموذج الصفحة وانقر على "إنشاء". تأكَّد من ضبط نوع التطبيق على "تطبيق الويب".
      4. ارجع إلى قسم تفويض صفحة "إضافة بيانات اعتماد"، واختَر عميل OAuth الذي تم إنشاؤه حديثًا واحفظ التغييرات.

الحصول على رمز التفويض الخاص بالخادم

لاسترداد رمز مصادقة الخادم الذي يمكن لعبتك استخدامه لإنشاء الرموز المميّزة للوصول على خادم الخلفية:

  1. اتصل برقم requestServerSideAccess من العميل.

    1. تأكَّد من استخدام معرّف عميل OAuth المسجَّل لخادم الألعاب وليس معرّف عميل OAuth لتطبيق Android.
    2. (اختياري) إذا كان خادم اللعبة يتطلّب الوصول إلى "خدمات ألعاب Play" بلا إنترنت (وصول طويل الأمد باستخدام رمز تنشيط جديد)، يمكنك ضبط المَعلمة forceRefreshToken على 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 إلى خادم الخلفية حتى يتم تبادله، والتحقق من معرّف اللاعب مقابل واجهات برمجة تطبيقات REST في "خدمات ألعاب Play"، ثم المصادقة على اللعبة.

استبدل رمز مصادقة الخادم برمز الدخول على الخادم

أرسِل رمز التفويض الخاص بالخادم إلى خادم الخلفية لتبديله برموز الوصول وإعادة التحميل. استخدِم رمز الدخول لطلب واجهة برمجة التطبيقات Google Play Games Services API نيابةً عن اللاعب، ويمكنك اختيار تخزين الرمز المميز للتحديث للحصول على رمز دخول جديد عند انتهاء صلاحية رمز الدخول.

يوضح مقتطف الرمز التالي كيفية تنفيذ الرمز من جانب الخادم في Java لتبادل رمز مصادقة الخادم برموز الدخول. من المهم باستخدام نموذج تطبيق clientserverskeleton:

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

طلب واجهات برمجة تطبيقات REST من الخادم

يُرجى الرجوع إلى واجهات برمجة تطبيقات REST لخدمات "ألعاب Google Play" وصف كامل لطلبات البيانات من واجهة برمجة التطبيقات المتاحة.

تشمل أمثلة طلبات البيانات من واجهة برمجة التطبيقات REST API التي قد تجدها مفيدة ما يلي:

اللاعب

  • هل تريد الحصول على رقم تعريف اللاعب الذي سجّل الدخول وبيانات الملف الشخصي؟ الاتصال بـ 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 من واجهات برمجة التطبيقات Management API لإعادة ضبط الإنجازات إلى حالتها الأصلية.

أشكال ليدربورد

احرص على مراجعة دليل لوحات الصدارة الذي يشرح قوائم الصدارة بمزيد من التفصيل.

  • هل تريد الحصول على قائمة بجميع لوحات النتائج في اللعبة؟ أجرِ مكالمة إلى Leaderboards.list.
  • هل انتهى اللاعب من لعبة؟ ويمكنك إرسال نتيجته إلى Scores.submit ومعرفة ما إذا كان هذه نتيجة عالية جديدة.
  • هل تريد عرض قائمة صدارة؟ احصل على البيانات من Scores.list واعرضها على المستخدم.
  • استخدِم Scores.listWindow للعثور على مجموعة من النتائج القريبة من أعلى نتيجة للمستخدِم.
  • للحصول على مزيد من المعلومات حول نتيجة اللاعب في لوحة صدارة معينة (على سبيل المثال، إذا كان أحد اللاعبين ضمن أعلى 12% من بين جميع اللاعبين)، واستدعِ Scores.get.
  • هل تصحّح أخطاء لعبة؟ حاوِل الاتصال بـ Scores.reset من "الإدارة". واجهات برمجة التطبيقات لإعادة ضبط جميع النتائج لهذا اللاعب من لوحة صدارة معيَّنة