আমরা আপনাকে খেলোয়াড়দের প্রমাণীকরণ করতে এবং খেলোয়াড়ের পরিচয় নিরাপদে ব্যাকএন্ড সার্ভারে পাঠাতে GamesSignInClient ব্যবহার করার পরামর্শ দিই। এর ফলে, ডিভাইস দিয়ে যাওয়ার সময় সম্ভাব্য বিকৃতির ঝুঁকি ছাড়াই আপনার গেমটি খেলোয়াড়ের পরিচয় এবং অন্যান্য ডেটা নিরাপদে পুনরুদ্ধার করতে পারে।
প্লেয়ার সফলভাবে প্রমাণীকরণ সম্পন্ন করলে, আপনি প্লে গেমস সার্ভিসেস v2 SDK থেকে একটি বিশেষ এককালীন ব্যবহারযোগ্য কোড (যাকে সার্ভার অথ কোড বলা হয়) অনুরোধ করতে পারেন, যা ক্লায়েন্ট সার্ভারে পাঠায়। এরপর, সার্ভারে সার্ভার অথ কোডটির বিনিময়ে একটি OAuth 2.0 টোকেন দেওয়া হয়, যা ব্যবহার করে সার্ভার গুগল প্লে গেমস সার্ভিসেস API-তে কল করতে পারে।
আপনার গেমগুলিতে প্রমাণীকরণ যোগ করার বিষয়ে অতিরিক্ত নির্দেশনার জন্য, অ্যান্ড্রয়েড গেমের জন্য প্ল্যাটফর্ম প্রমাণীকরণ দেখুন।
অফলাইনে প্রবেশের জন্য নিম্নলিখিত পদক্ষেপগুলি প্রয়োজন:
- গুগল প্লে কনসোলে: আপনার গেম সার্ভারের জন্য একটি ক্রেডেনশিয়াল তৈরি করুন। ক্রেডেনশিয়ালটির OAuth ক্লায়েন্ট টাইপ হবে "web"।
- অ্যান্ড্রয়েড অ্যাপে: প্ল্যাটফর্ম অথেনটিকেশনের অংশ হিসেবে, আপনার সার্ভারের ক্রেডেনশিয়ালের জন্য একটি সার্ভার অথ কোড অনুরোধ করুন এবং সেটি আপনার সার্ভারে পাঠান। প্লে গেমস সার্ভিসেস ওয়েব এপিআই-এর সার্ভার-সাইড অ্যাক্সেসের অনুরোধ করার সময়
GamesSigninClientতিনটি OAuth 2.0 স্কোপের জন্য অনুরোধ করতে পারে। ঐচ্ছিক স্কোপগুলো হলোEMAIL,PROFILEএবংOPEN_ID। দুটি ডিফল্ট স্কোপ হলোDRIVE_APPFOLDERএবংGAMES_LITE। - আপনার গেম সার্ভারে: গুগল অথ সার্ভিস ব্যবহার করে সার্ভার অথ কোডটির বিনিময়ে একটি OAuth অ্যাক্সেস টোকেন নিন, এবং তারপর এটি ব্যবহার করে প্লে গেমস সার্ভিসেস REST API-গুলো কল করুন।
শুরু করার আগে
প্রথমে আপনাকে ‘গুগল প্লে গেমস সার্ভিসেস সেট আপ করুন’ অংশে বর্ণিত পদ্ধতি অনুযায়ী গুগল প্লে কনসোলে আপনার গেমটি যুক্ত করতে হবে এবং আপনার গেমের সাথে প্লে গেমস সার্ভিসেস প্ল্যাটফর্ম অথেনটিকেশন সংযুক্ত করতে হবে।
একটি সার্ভার-সাইড ওয়েব অ্যাপ তৈরি করুন
গুগল প্লে গেম সার্ভিসেস ওয়েব গেমের জন্য ব্যাকএন্ড সাপোর্ট প্রদান করে না। তবে, এটি আপনার অ্যান্ড্রয়েড গেমের সার্ভারের জন্য ব্যাকএন্ড সার্ভার সাপোর্ট প্রদান করে।
আপনার সার্ভার-সাইড অ্যাপে গুগল প্লে গেমস পরিষেবার জন্য REST API ব্যবহার করতে চাইলে, এই ধাপগুলো অনুসরণ করুন:
- গুগল প্লে কনসোলে একটি গেম নির্বাচন করুন।
- প্লে গেমস সার্ভিসেস > সেটআপ ও ব্যবস্থাপনা > কনফিগারেশন- এ যান।
- ক্রেডেনশিয়াল যোগ করুন (Add credential) নির্বাচন করলে আপনাকে ক্রেডেনশিয়াল যোগ করুন (Add credential) পৃষ্ঠায় নিয়ে যাওয়া হবে। ক্রেডেনশিয়ালের ধরন হিসেবে গেম সার্ভার (Game server) নির্বাচন করুন এবং অনুমোদন (Authorization) বিভাগে এগিয়ে যান।
- আপনার গেম সার্ভারে যদি আগে থেকেই একটি OAuth ক্লায়েন্ট আইডি থাকে, তবে ড্রপ-ডাউন মেনু থেকে সেটি নির্বাচন করুন। আপনার পরিবর্তনগুলি সংরক্ষণ করার পর, পরবর্তী বিভাগে যান।
- আপনার গেম সার্ভারের জন্য যদি আগে থেকে কোনো OAuth ক্লায়েন্ট আইডি না থাকে, তাহলে আপনি একটি তৈরি করে নিতে পারেন।
- Create OAuth client-এ ক্লিক করুন এবং Create OAuth Client ID লিঙ্কটি অনুসরণ করুন।
- এটি আপনাকে আপনার গেমের সাথে যুক্ত প্রজেক্টের জন্য গুগল ক্লাউড প্ল্যাটফর্মের 'ক্রিয়েট ওঅথ ক্লায়েন্ট আইডি' পেজে নিয়ে যাবে।
- পৃষ্ঠার ফর্মটি পূরণ করুন এবং তৈরি করুন-এ ক্লিক করুন। অ্যাপ্লিকেশন টাইপটি অবশ্যই ওয়েব অ্যাপ্লিকেশন হিসেবে সেট করতে ভুলবেন না।
- 'Add credential' পেজের 'Authorization' সেকশনে ফিরে যান, নতুন তৈরি করা OAuth ক্লায়েন্টটি সিলেক্ট করুন এবং আপনার পরিবর্তনগুলো সেভ করুন।
সার্ভার প্রমাণীকরণ কোডটি নিন
আপনার গেমের ব্যাকএন্ড সার্ভারে অ্যাক্সেস টোকেন হিসেবে ব্যবহার করার জন্য একটি সার্ভার অথোরাইজেশন কোড পেতে:
- ক্লায়েন্ট থেকে
requestServerSideAccessকল করুন।- নিশ্চিত করুন যে আপনি আপনার গেম সার্ভারের জন্য নিবন্ধিত OAuth ক্লায়েন্ট আইডি ব্যবহার করছেন, আপনার অ্যান্ড্রয়েড অ্যাপ্লিকেশনের OAuth ক্লায়েন্ট আইডি নয়।
- (ঐচ্ছিক) যদি আপনার গেম সার্ভারের প্লে গেমস সার্ভিসেস-এ অফলাইন অ্যাক্সেসের (রিফ্রেশ টোকেন ব্যবহার করে দীর্ঘস্থায়ী অ্যাক্সেস) প্রয়োজন হয়, তাহলে আপনি
forceRefreshTokenপ্যারামিটারটি true-তে সেট করতে পারেন।
(ঐচ্ছিক) প্রমাণীকরণের অংশ হিসেবে, নতুন ব্যবহারকারীদের অতিরিক্ত স্কোপের জন্য একটিমাত্র সম্মতি স্ক্রিন দেখানো উচিত। সম্মতি দিলে, আপনি
EMAIL,PROFILEএবংOPEN_IDOAuth স্কোপগুলো দিয়েscopesপ্যারামিটারটি সেট করবেন। যদি ব্যবহারকারীরা সম্মতি না দেন, তবে শুধুমাত্র দুটি ডিফল্ট স্কোপDRIVE_APPFOLDERএবংGAMES_LITEব্যাকএন্ডে পাঠানো হবে।
অতিরিক্ত 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. } });
OAuth অথ কোড টোকেনটি আপনার ব্যাকএন্ড সার্ভারে পাঠান, যাতে এটি বিনিময় করা যায়, প্লে গেমস সার্ভিসেস REST API-এর মাধ্যমে প্লেয়ার আইডি যাচাই করা যায় এবং তারপরে আপনার গেমে প্রমাণীকরণ করা যায়।
সার্ভার প্রমাণীকরণ কোড পাঠান
অ্যাক্সেস এবং রিফ্রেশ টোকেনের বিনিময়ে সার্ভার অথোরাইজেশন কোডটি আপনার ব্যাকএন্ড সার্ভারে পাঠান। প্লেয়ারের পক্ষ থেকে প্লে গেমস সার্ভিসেস এপিআই (Play Games Services API) কল করতে অ্যাক্সেস টোকেনটি ব্যবহার করুন এবং, ঐচ্ছিকভাবে, অ্যাক্সেস টোকেনের মেয়াদ শেষ হয়ে গেলে একটি নতুন অ্যাক্সেস টোকেন পাওয়ার জন্য রিফ্রেশ টোকেনটি সংরক্ষণ করুন।
প্লেয়ার আইডি কীভাবে কাজ করে সে সম্পর্কে আরও তথ্যের জন্য, পরবর্তী প্রজন্মের প্লেয়ার আইডি দেখুন।
নিম্নলিখিত কোড স্নিপেটটি দেখায় যে, কীভাবে আপনি জাভা প্রোগ্রামিং ভাষায় সার্ভার অথোরাইজেশন কোডের বিনিময়ে অ্যাক্সেস টোকেন আদান-প্রদানের জন্য সার্ভার-সাইড কোড প্রয়োগ করতে পারেন।
জাভা
/** * 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 স্কোপগুলো পুনরুদ্ধার করতে পারেন এবং 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"); // This ID is unique to each Google Account, making it suitable for use as // a primary key during account lookup. Email is not a good choice because // it can be changed by the user. String sub = payload.getSubject(); // Use or store profile information // ... } else { System.out.println("Invalid ID token."); } }
সার্ভার থেকে REST API কল করুন
উপলব্ধ এপিআই কলগুলোর সম্পূর্ণ বিবরণের জন্য গুগল প্লে গেমস পরিষেবাগুলোর REST API দেখুন।
REST API কলের কিছু উদাহরণ যা আপনার কাজে লাগতে পারে, সেগুলো নিচে দেওয়া হলো:
খেলোয়াড়
খেলোয়াড়ের আইডি এবং প্রোফাইল ডেটা দিয়ে প্রমাণীকরণ করতে চান? আইডি হিসেবে 'me' ব্যবহার করে Players.get কল করুন।
বন্ধুরা
বিস্তারিত জানতে ফ্রেন্ডস গাইডটি দেখুন।
খেলোয়াড়ের বন্ধুদের তালিকা পেতে,
collectionহিসেবেfriends_allব্যবহার করে Players.list ফাংশনটি কল করুন।আপনার ফ্রেন্ডস লিস্টে অ্যাক্সেস আছে কিনা তা যাচাই করতে,
playerIDহিসেবেmeব্যবহার করে Players.get কল করুন এবং রেসপন্সেরprofileSettings.friendsListVisibilityফিল্ডটি দেখুন।
অর্জন
বিস্তারিত জানতে অ্যাচিভমেন্ট গাইড দেখুন।
বর্তমান অ্যাচিভমেন্টগুলোর তালিকা পেতে AchievementDefinitions.list ফাইলটি খুলুন।
এর সাথে Achievements.list- এ কল করে জেনে নিন প্লেয়ার কোনগুলো আনলক করেছে।
খেলোয়াড়ের কোনো অ্যাচিভমেন্ট আনলক করতে Achievements.unlock- এ কল করুন।
কোনো অ্যাচিভমেন্টের অগ্রগতি জানতে এবং প্লেয়ারটি সেটি আনলক করেছে কিনা তা জানতে Achievements.increment কল করুন।
আপনি যদি এমন কোনো গেম ডিবাগ করেন যা এখনো প্রোডাকশনে পৌঁছায়নি, তাহলে অ্যাচিভমেন্টগুলোকে তাদের মূল অবস্থায় রিসেট করার জন্য ম্যানেজমেন্ট এপিআই (Management APIs) থেকে Achievements.reset অথবা Achievements.resetAll কল করতে পারেন।
লিডারবোর্ড
বিস্তারিত জানতে লিডারবোর্ড নির্দেশিকা দেখুন।
গেমের সমস্ত স্কোরবোর্ডের তালিকা পেতে Leaderboards.list ফাইলটি কল করুন।
কোনো খেলোয়াড়ের খেলা শেষ হয়ে গেলে, আপনি তার স্কোর Scores.submit- এ জমা দিয়ে জানতে পারবেন সেটি নতুন সর্বোচ্চ স্কোর কি না।
লিডারবোর্ড প্রদর্শন করতে, Scores.list থেকে ডেটা নিয়ে ব্যবহারকারীকে দেখান।
ব্যবহারকারীর সর্বোচ্চ স্কোরের কাছাকাছি বিভিন্ন স্কোর খুঁজে পেতে Scores.listWindow ব্যবহার করুন।
কোনো নির্দিষ্ট লিডারবোর্ডে খেলোয়াড়ের স্কোর সম্পর্কে আরও তথ্য পেতে (উদাহরণস্বরূপ, খেলোয়াড়টি যদি সকল খেলোয়াড়ের মধ্যে শীর্ষ ১২%-এর মধ্যে থাকে), Scores.get কল করুন।
আপনি যদি কোনো গেম ডিবাগ করেন, তাহলে কোনো নির্দিষ্ট লিডারবোর্ড থেকে সেই খেলোয়াড়ের সমস্ত স্কোর রিসেট করার জন্য ম্যানেজমেন্ট এপিআই (Management APIs) থেকে Scores.reset কল করতে পারেন।