Включите серверный доступ к игровым сервисам Google Play.

В связи с прекращением поддержки API входа Google мы удалим SDK для игр v1 в 2026 году. После февраля 2025 года вы не сможете публиковать в Google Play игры, недавно интегрированные с SDK для игр v1. Вместо этого мы рекомендуем использовать SDK для игр v2.
Хотя существующие игры с интеграцией предыдущих игр v1 продолжат функционировать еще пару лет, вам рекомендуется перейти на v2, начиная с июня 2025 года.
Это руководство посвящено использованию SDK Play Games Services v1. Информацию о последней версии SDK см. в документации v2 .

Если ваша игра использует внутренний сервер, мы рекомендуем использовать вход через Google для аутентификации игроков и безопасной передачи их идентификационных данных на внутренний сервер. Это также позволит вашей игре безопасно извлекать идентификационные данные игрока и другие данные, не подвергаясь потенциальному вмешательству при использовании устройства.

В этом сценарии ваша игра предлагает игроку войти в Google Play Games Services как обычно. После успешного входа в систему объект GoogleSignInAccount содержит специальный одноразовый код (называемый кодом авторизации сервера ), который клиент передаёт серверу. Затем на сервере обменяйте код авторизации сервера на токен OAuth 2.0, который сервер сможет использовать для вызовов API Google Play Games Services.

Дополнительные рекомендации по добавлению входа в игры см. в разделе Вход в игры для Android .

Подробный пример кода, демонстрирующий использование входа Google для аутентификации игроков, можно найти в примере clientserverskeleton на GitHub.

Для автономного доступа необходимо выполнить следующие шаги:

  1. В Google Play Console: создайте учётные данные для вашего игрового сервера. Тип клиента OAuth для учётных данных — «web».
  2. В приложении для Android: в процессе входа запросите код авторизации сервера для учетных данных вашего сервера и передайте его на свой сервер.
  3. На игровом сервере: обменяйте код авторизации сервера на токен доступа OAuth с помощью служб авторизации Google, а затем используйте его для вызова API REST игровых сервисов Play.

Прежде чем начать

Прежде чем интегрировать функцию входа через Google в свою игру, вам сначала нужно добавить игру в Google Play Console , как описано в разделе Настройка игровых сервисов Google Play .

Создайте соответствующее серверное веб-приложение для вашей игры.

Сервисы Google Play Game не предоставляют серверную поддержку для веб-игр. Однако они предоставляют серверную поддержку для сервера вашей игры на Android.

Если вы хотите использовать REST API для сервисов Google Play Игр в своем серверном приложении, выполните следующие действия:

  1. Создайте связанное веб-приложение для своей игры в разделе «Связанные приложения» консоли Google Play . Обратите внимание, что launch_url не используется в этом процессе и может быть оставлен пустым.
  2. Чтобы получить учетные данные для вашего приложения, выполните следующие действия:
    1. В консоли Google Play выберите игру, нажав «Сведения об игре» .
    2. Прокрутите страницу вниз до раздела «Проект консоли API» и нажмите ссылку на проект консоли API.
    3. На экране «API и сервисы» > «Учётные данные» в консоли API Google загрузите файл client_secret.json для вашего веб-приложения и сохраните его в месте, к которому ваш сервер имеет доступ. Запишите идентификатор клиента учётных данных для дальнейшего использования.
  3. Перезапустите серверное приложение, чтобы оно было готово принимать запросы от клиентского приложения вашей игры.

Выполните вход в систему на клиенте.

Класс GoogleSignInClient является основной точкой входа для получения учетной записи текущего вошедшего в систему игрока, а также для входа игрока в систему, если он ранее не сделал этого в вашем приложении на устройстве.

Чтобы создать клиент входа, выполните следующие действия:

  1. Создайте клиент входа через объект GoogleSignInOptions . В GoogleSignInOptions.Builder для настройки входа необходимо указать GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN .
  2. Вам также необходимо указать, что вашей игре требуется код авторизации для вашего внутреннего сервера, вызвав метод GoogleSignInOptions.Builder.requestServerAuthCode() с идентификатором клиента сервера в качестве параметра. Код авторизации будет получен позже для токенов доступа на внутреннем сервере, как описано в разделе Получение кода авторизации сервера .
  3. Вызовите метод GoogleSignIn.getClient() и передайте ему ранее настроенные параметры. Если вызов успешен, API входа Google возвращает экземпляр GoogleSignInClient .
  4. Получив экземпляр GoogleSignInClient , необходимо выполнить скрытую регистрацию игрока с помощью onResume() активности, как описано в разделе Выполнение скрытой регистрации .

Вот пример:

private static final int RC_SIGN_IN = 9001;
private GoogleSignInClient mGoogleSignInClient;

private void startSignInForAuthCode() {

  // Client ID for your backend server.
  String webClientId = getString(R.string.webclient_id);

  GoogleSignInOptions signInOption = new
      GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
      .requestServerAuthCode(webClientId)
      .build();

  GoogleSignInClient signInClient = GoogleSignIn.getClient(this, signInOption);
  Intent intent = signInClient.getSignInIntent();
  startActivityForResult(intent, RC_SIGN_IN);
}

Получить код авторизации сервера

Чтобы получить код авторизации сервера, который ваша игра может использовать для токенов доступа на вашем внутреннем сервере, вызовите метод getServerAuthCode() объекта GoogleSignInAccount , который Google Sign-In возвращает при успешном входе игрока в систему.

Вот пример:

// Auth code to send to backend server.
private String mServerAuthCode;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (requestCode == RC_SIGN_IN) {
    GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
    if (result.isSuccess()) {
      mServerAuthCode = result.getSignInAccount().getServerAuthCode();
    } else {
      String message = result.getStatus().getStatusMessage();
      if (message == null || message.isEmpty()) {
        message = getString(R.string.signin_other_error);
      }
      new AlertDialog.Builder(this).setMessage(message)
          .setNeutralButton(android.R.string.ok, null).show();
    }
  }
}

Обменять код авторизации сервера на токен доступа на сервере

Отправьте код авторизации сервера на ваш внутренний сервер для обмена на токены доступа и обновления. Используйте токен доступа для вызова API игровых сервисов Google Play от имени игрока и, при необходимости, сохраните токен обновления для получения нового токена доступа по истечении срока действия текущего токена доступа.

В следующем фрагменте кода показано, как можно реализовать серверный код на языке программирования 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;
}

Дополнительную информацию о доступе к API Google с внутреннего сервера от имени вошедшего в систему игрока см. в разделе Включение доступа на стороне сервера .

Обработка выхода игрока

Чтобы вывести игроков из игры, вызовите метод signOut() в GoogleSignInClient . Пример кода см. в разделе Вывод игрока из игры .

Вызов REST API с сервера

Полное описание доступных вызовов API см. в разделе API REST для сервисов Google Play Игр .

Примеры вызовов REST API, которые могут оказаться вам полезными, включают следующее:

Игрок

  • Хотите получить идентификатор и данные профиля вошедшего в систему игрока? Вызовите Players.get , указав 'me' в качестве идентификатора.

Друзья

Обязательно ознакомьтесь с руководством по сериалу «Друзья» , в котором о сериале «Друзья» рассказывается более подробно.

  • Хотите получить список друзей игрока? Вызовите Players.list , указав 'friends_all' в качестве collection .
  • Проверьте, есть ли у вас доступ к списку друзей? me Players.get и посмотрите поле 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 управления, чтобы сбросить все результаты игрока в таблице лидеров.