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

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

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

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

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

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

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

Прежде чем вы начнете

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

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

Игровые сервисы Google Play не обеспечивают серверную поддержку веб-игр. Тем не менее, он обеспечивает поддержку внутреннего сервера для сервера вашей игры для Android.

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

  1. Создайте связанное веб-приложение для своей игры в разделе «Связанные приложения» консоли Google Play . Обратите внимание, что launch_url не используется для этого потока и может быть оставлен пустым.
  2. Чтобы получить учетные данные для вашего приложения, выполните следующие действия.
    1. В своей игре в Google Play Console нажмите «Сведения об игре» .
    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() и передайте ранее настроенные параметры. Если вызов выполнен успешно, Google Sign-In API возвращает экземпляр 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 см. в разделе REST API для сервисов Google Play Games .

Примеры вызовов 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 управления, чтобы сбросить все баллы для этого игрока из определенной таблицы лидеров.