بعد إيقاف واجهة برمجة التطبيقات تسجيل الدخول باستخدام Google نهائيًا، سنزيل الإصدار v1 من حزمة تطوير البرامج (SDK) للألعاب في عام 2026. بعد فبراير 2025، لن يكون بإمكانك نشر الألعاب التي تم دمجها حديثًا مع الإصدار v1 من حزمة SDK للألعاب على Google Play. ننصحك باستخدام الإصدار v2 من حزمة SDK للألعاب بدلاً من ذلك.
مع أنّ التطبيقات الحالية التي تتضمّن عمليات الدمج السابقة للإصدار 1 من "خدمات ألعاب Google Play" ستستمر في العمل لعدّة سنوات، ننصحك
بنقل البيانات إلى الإصدار 2
بدءًا من يونيو 2025.
هذا الدليل مخصّص لاستخدام الإصدار 1 من حزمة تطوير البرامج (SDK) الخاصة بـ "خدمات ألعاب Play". للحصول على معلومات حول أحدث إصدار من حزمة SDK، يُرجى الاطّلاع على مستندات الإصدار 2.
إذا كانت لعبتك تستخدم خادمًا خلفيًا، ننصحك باستخدام خدمة تسجيل الدخول باستخدام حساب Google لمصادقة اللاعبين ونقل هوية اللاعب بشكل آمن إلى الخادم الخلفي. يتيح ذلك أيضًا للعبتك استرداد هوية اللاعب وبيانات أخرى بشكل آمن بدون التعرّض لخطر التلاعب المحتمل أثناء مرورها عبر الجهاز.
في هذا السيناريو، تطلب لعبتك من اللاعب تسجيل الدخول إلى "خدمات ألعاب Google Play" كالمعتاد. عندما يسجّل اللاعب الدخول بنجاح، يحتوي العنصر GoogleSignInAccount
على رمز خاص صالح للاستخدام مرة واحدة
(يُسمى رمز مصادقة الخادم) يرسله العميل إلى الخادم. بعد ذلك، يمكنك على الخادم استبدال رمز مصادقة الخادم برمز OAuth 2.0 يمكن للخادم استخدامه لإجراء طلبات إلى واجهة برمجة التطبيقات الخاصة بـ "خدمات ألعاب Google Play".
للحصول على إرشادات إضافية حول إضافة ميزة تسجيل الدخول في ألعابك، اطّلِع على تسجيل الدخول في ألعاب Android.
للاطّلاع على نموذج رمز تفصيلي يوضّح كيفية استخدام خدمة "تسجيل الدخول باستخدام حساب Google" لمصادقة اللاعبين، يمكنك الاطّلاع على نموذج clientserverskeleton
على GitHub.
يجب اتّباع الخطوات التالية لإتاحة الوصول بلا إنترنت:
- في Google Play Console: أنشئ بيانات اعتماد لخادم لعبتك. سيكون نوع عميل OAuth لبيانات الاعتماد هو "الويب".
- في تطبيق Android: كجزء من عملية تسجيل الدخول، اطلب رمز مصادقة الخادم لبيانات اعتماد الخادم، ثم أرسِله إلى الخادم.
- على خادم اللعبة: استبدِل رمز مصادقة الخادم برمز مميّز للوصول عبر بروتوكول OAuth باستخدام خدمات مصادقة Google، ثم استخدِم هذا الرمز للاتصال بواجهات REST API الخاصة بـ "خدمات ألعاب Play".
قبل البدء
قبل أن تتمكّن من دمج خدمة "تسجيل الدخول باستخدام Google" في لعبتك، عليك أولاً إضافة لعبتك في Google Play Console، كما هو موضّح في إعداد "خدمات ألعاب Google Play".
إنشاء تطبيق ويب مرتبط على الخادم للعبتك
لا توفّر "خدمات ألعاب Google Play" دعمًا للأنظمة الخلفية لألعاب الويب. ومع ذلك، يوفّر خدمة دعم لخادم الخلفية في خادم لعبة Android.
إذا كنت تريد استخدام واجهات REST API لخدمات "ألعاب Google Play" في تطبيقك من جهة الخادم، اتّبِع الخطوات التالية:
- أنشئ تطبيق ويب مرتبطًا بلعبتك في قسم التطبيقات المرتبطة ضمن Google Play Console. يُرجى العِلم أنّه لا يتم استخدام
launch_url
في هذا المسار ويمكن تركه فارغًا. - للحصول على معلومات بيانات الاعتماد الخاصة بتطبيقك، اتّبِع الخطوات التالية:
- من لعبتك في Google Play Console، انقر على تفاصيل اللعبة.
- انتقِل للأسفل إلى قسم مشروع وحدة تحكّم واجهة برمجة التطبيقات وانقر على الرابط المؤدي إلى مشروع وحدة تحكّم واجهة برمجة التطبيقات.
- من شاشة واجهات برمجة التطبيقات والخدمات > بيانات الاعتماد في Google API Console، نزِّل ملف
client_secret.json
لتطبيق الويب واحفظه في مكان يمكن لخادمك الوصول إليه. سجِّل معرّف العميل الخاص ببيانات الاعتماد للرجوع إليه لاحقًا.
- أعِد تشغيل تطبيقك على الخادم ليكون جاهزًا لقبول الطلبات من تطبيق العميل الخاص بلعبتك.
تنفيذ عملية تسجيل الدخول على الجهاز
فئة GoogleSignInClient
هي نقطة الدخول الرئيسية لاسترداد حساب اللاعب الذي سجّل الدخول حاليًا، ولتسجيل دخول اللاعب إذا لم يسبق له إجراء ذلك على تطبيقك على الجهاز.
لإنشاء برنامج تسجيل دخول، اتّبِع الخطوات التالية:
- أنشئ عميل تسجيل دخول من خلال العنصر
GoogleSignInOptions
. فيGoogleSignInOptions.Builder
، عليك تحديدGoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
لضبط إعدادات تسجيل الدخول. - عليك أيضًا تحديد أنّ لعبتك تتطلّب رمز مصادقة لخادم الخلفية من خلال استدعاء طريقة
GoogleSignInOptions.Builder.requestServerAuthCode()
مع معرّف عميل الخادم كمعلَمة. ستستردّ رمز المصادقة لاحقًا للحصول على رموز الدخول على خادم الخلفية، كما هو موضّح في الحصول على رمز مصادقة الخادم. - استدعِ طريقة
GoogleSignIn.getClient()
وأدخِل الخيارات التي سبق لك ضبطها. إذا كان الطلب ناجحًا، تعرض Google Sign-In API مثيلاً منGoogleSignInClient
. - بعد الحصول على مثيل
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" عند تسجيل دخول اللاعب بنجاح.
وفي ما يلي مثال لذلك:
// 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(); } } }
استبدال رمز المصادقة الخاص بالخادم برمز دخول على الخادم
أرسِل رمز مصادقة الخادم إلى خادم الخلفية لتبديله برموز مميزة للوصول وإعادة التحميل. استخدِم رمز الدخول لاستدعاء واجهة برمجة التطبيقات "خدمات ألعاب 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;
}
لمزيد من المعلومات حول الوصول إلى واجهات برمجة تطبيقات Google من خادم الخلفية نيابةً عن لاعب مسجّل الدخول، اطّلِع على تفعيل الوصول من جهة الخادم.
التعامل مع تسجيل خروج اللاعب
لتسجيل خروج اللاعبين من لعبتك، استخدِم طريقة signOut()
في GoogleSignInClient
. للاطّلاع على مثال لمقتطف الرمز، يُرجى الرجوع إلى تسجيل خروج اللاعب.
طلب بيانات من واجهات REST API من الخادم
راجِع واجهات REST API لخدمات "ألعاب 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 APIs لإعادة ضبط الإنجازات على حالتها الأصلية.
لوحات الصدارة
يُرجى الاطّلاع على دليل لوحات الصدارة الذي يقدّم شرحًا أكثر تفصيلاً عن لوحات الصدارة.
- هل تريد الحصول على قائمة بجميع لوحات الصدارة في اللعبة؟ أجرِ مكالمة إلى Leaderboards.list.
- هل انتهى اللاعب من إحدى الألعاب؟ يمكنك إرسال النتيجة إلى Scores.submit ومعرفة ما إذا كانت هذه النتيجة هي الأعلى.
- هل تريد عرض قائمة "في الصدارة"؟ احصل على البيانات من Scores.list واعرضها على المستخدم.
- استخدِم Scores.listWindow للعثور على مجموعة من النتائج القريبة من أعلى نتيجة حقّقها المستخدم.
- للحصول على مزيد من المعلومات حول نتيجة اللاعب في قائمة صدارة معيّنة (على سبيل المثال، إذا كان اللاعب ضمن أفضل% 12 من جميع اللاعبين)، استخدِم الدالة Scores.get.
- هل تعمل على تصحيح أخطاء في لعبة؟ جرِّب استدعاء Scores.reset من واجهات برمجة التطبيقات الإدارية لإعادة ضبط جميع النتائج الخاصة بهذا اللاعب من قائمة صدارة معيّنة.