diff --git a/README.md b/README.md index 5aa0908..657265d 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Google Play Games Services Plugin for Godot -This is an Android Play Games Services plugin for Godot Game Engine 3.2.2+. +This is an Android Play Games Services plugin for Godot Game Engine 3.2.3+. [![Android](https://img.shields.io/badge/Platform-Android-brightgreen.svg)](https://developer.android.com) -[![Godot](https://img.shields.io/badge/Godot%20Engine-3.2.2-blue.svg)](https://github.com/godotengine/godot/) +[![Godot](https://img.shields.io/badge/Godot%20Engine-3.2.3-blue.svg)](https://github.com/godotengine/godot/) [![PGS](https://img.shields.io/badge/Play%20Games%20Services-20.0.1-green.svg)](https://developers.google.com/games/services/android/quickstart) [![MIT license](https://img.shields.io/badge/License-MIT-yellowgreen.svg)](https://lbesson.mit-license.org/) @@ -54,10 +54,16 @@ if Engine.has_singleton("GodotPlayGamesServices"): # Initialize plugin by calling init method and passing to it a boolean to enable/disable displaying game pop-ups - var show_popups := true - play_games_services.init(show_popups) + var show_popups := true + var request_email := true + var request_profile := true + #The client id must be created in [the google console](https://console.cloud.google.com/apis/credentials), an OAuth 2.0 Client credentials of a Web application type + var request_token := "Client ID" + + play_games_services.init(show_popups, request_email, request_profile, request_token) + # For enabling saved games functionality use below initialization instead - # play_games_services.initWithSavedGames(show_popups, "SavedGamesName") + # play_games_services.initWithSavedGames(show_popups, "SavedGamesName", request_email, request_profile, request_token) # Connect callbacks (Use only those that you need) play_games_services.connect("_on_sign_in_success", self, "_on_sign_in_success") # account_id: String @@ -92,9 +98,16 @@ After what plugin was initialized you can use supported features play_games_services.signIn() # Callbacks: -func _on_sign_in_success(account_id: String) -> void: - pass - +func _on_sign_in_success(userProfile_json: String) -> void: + var userProfile = parse_json(userProfile_json) + + # The returned JSON contains an object of userProfile info. + # Use the following keys to access the fields + userProfile["displayName"] # The user's display name + userProfile["email"] # The user's email + userProfile["token"] # User token for backend use + userProfile["id"] # The user's id + func _on_sign_in_failed(error_code: int) -> void: pass diff --git a/app/build.gradle b/app/build.gradle index c770030..72811ef 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,7 +4,7 @@ apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 - buildToolsVersion "29.0.3" + buildToolsVersion "30.0.1" defaultConfig { minSdkVersion 16 @@ -34,10 +34,10 @@ android { } dependencies { - compileOnly project(":godot-lib.3.2.2.stable.release") + compileOnly project(":godot-lib.3.2.3.stable.release") implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'com.google.android.gms:play-services-games:20.0.1' - implementation 'com.google.android.gms:play-services-auth:18.1.0' + implementation 'com.google.android.gms:play-services-games:21.0.0' + implementation 'com.google.android.gms:play-services-auth:19.0.0' implementation 'com.google.code.gson:gson:2.8.6' testImplementation 'junit:junit:4.13' diff --git a/app/src/main/java/io/cgisca/godot/gpgs/ConnectionController.kt b/app/src/main/java/io/cgisca/godot/gpgs/ConnectionController.kt index bcf9ee0..95bd5b9 100644 --- a/app/src/main/java/io/cgisca/godot/gpgs/ConnectionController.kt +++ b/app/src/main/java/io/cgisca/godot/gpgs/ConnectionController.kt @@ -1,22 +1,34 @@ package io.cgisca.godot.gpgs import android.app.Activity +import android.util.Log import android.util.Pair import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignInOptions +import io.cgisca.godot.gpgs.signin.UserProfile class ConnectionController( private val activity: Activity, private var signInOptions: GoogleSignInOptions ) { - fun isConnected(): Pair { + fun isConnected(): Pair { + val userProfile = UserProfile(null, null, null, null) val googleSignInAccount = GoogleSignIn.getLastSignedInAccount(activity) - var accId = "" + ?: return Pair(false, userProfile) - googleSignInAccount?.id?.let { - accId = it + if (!googleSignInAccount.isExpired) { + Log.i("godot","Sign in data is valid") + userProfile.let { + it.displayName = googleSignInAccount.displayName + it.email = googleSignInAccount.email + it.token = googleSignInAccount.idToken + it.id = googleSignInAccount.id + } + return Pair(GoogleSignIn.hasPermissions(googleSignInAccount, *signInOptions.scopeArray), userProfile) + }else{ + Log.i("godot","Sign in data has expired") + return Pair(false, userProfile) } - return Pair(GoogleSignIn.hasPermissions(googleSignInAccount, *signInOptions.scopeArray), accId) } } \ No newline at end of file diff --git a/app/src/main/java/io/cgisca/godot/gpgs/PlayGameServicesGodot.kt b/app/src/main/java/io/cgisca/godot/gpgs/PlayGameServicesGodot.kt index d9fb2ff..7a60288 100644 --- a/app/src/main/java/io/cgisca/godot/gpgs/PlayGameServicesGodot.kt +++ b/app/src/main/java/io/cgisca/godot/gpgs/PlayGameServicesGodot.kt @@ -10,6 +10,7 @@ import com.google.android.gms.common.Scopes import com.google.android.gms.common.api.Scope import com.google.android.gms.games.SnapshotsClient import com.google.android.gms.games.snapshot.SnapshotMetadata +import com.google.gson.Gson import io.cgisca.godot.gpgs.accountinfo.PlayerInfoController import io.cgisca.godot.gpgs.accountinfo.PlayerInfoListener import io.cgisca.godot.gpgs.achievements.AchievementsController @@ -22,6 +23,7 @@ import io.cgisca.godot.gpgs.savedgames.SavedGamesController import io.cgisca.godot.gpgs.savedgames.SavedGamesListener import io.cgisca.godot.gpgs.signin.SignInController import io.cgisca.godot.gpgs.signin.SignInListener +import io.cgisca.godot.gpgs.signin.UserProfile import io.cgisca.godot.gpgs.stats.PlayerStatsController import io.cgisca.godot.gpgs.stats.PlayerStatsListener import org.godotengine.godot.Godot @@ -165,22 +167,30 @@ class PlayGameServicesGodot(godot: Godot) : GodotPlugin(godot), AchievementsList } } - fun init(enablePopups: Boolean) { - initialize(false, enablePopups, "DefaultGame") + fun init(enablePopups: Boolean, requestEmail: Boolean, requestProfile: Boolean, requestToken: String) { + initialize(false, enablePopups, "DefaultGame", requestEmail, requestProfile, requestToken) } - fun initWithSavedGames(enablePopups: Boolean, saveGameName: String) { - initialize(true, enablePopups, saveGameName) + fun initWithSavedGames(enablePopups: Boolean, saveGameName: String, requestEmail: Boolean, requestProfile: Boolean, requestToken: String) { + initialize(true, enablePopups, saveGameName, requestEmail, requestProfile, requestToken) } - private fun initialize(enableSaveGamesFunctionality: Boolean, enablePopups: Boolean, saveGameName: String) { + private fun initialize(enableSaveGamesFunctionality: Boolean, enablePopups: Boolean, saveGameName: String, + requestEmail: Boolean, requestProfile: Boolean, requestToken: String) { this.saveGameName = saveGameName - val signInOptions = if (enableSaveGamesFunctionality) { + val signInOptions = run { val signInOptionsBuilder = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) - signInOptionsBuilder.requestScopes(Scope(Scopes.DRIVE_APPFOLDER)) + if (enableSaveGamesFunctionality) + signInOptionsBuilder.requestScopes(Scope(Scopes.DRIVE_APPFOLDER)) + if (requestToken.isNotEmpty()) { + signInOptionsBuilder.requestIdToken(requestToken) + } + if (requestEmail) + signInOptionsBuilder.requestEmail() + if (requestProfile) + signInOptionsBuilder.requestProfile() + signInOptionsBuilder.requestId() signInOptionsBuilder.build() - } else { - GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN } connectionController = ConnectionController(godot as Activity, signInOptions) @@ -405,8 +415,8 @@ class PlayGameServicesGodot(godot: Godot) : GodotPlugin(godot), AchievementsList emitSignal(SIGNAL_SAVED_GAME_CREATE_SNAPSHOT.name, currentSaveName) } - override fun onSignedInSuccessfully(accountId: String) { - emitSignal(SIGNAL_SIGN_IN_SUCCESSFUL.name, accountId) + override fun onSignedInSuccessfully(userProfile: UserProfile) { + emitSignal(SIGNAL_SIGN_IN_SUCCESSFUL.name, Gson().toJson(userProfile)) } override fun onSignInFailed(statusCode: Int) { diff --git a/app/src/main/java/io/cgisca/godot/gpgs/signin/SignInController.kt b/app/src/main/java/io/cgisca/godot/gpgs/signin/SignInController.kt index b3676a7..66abf91 100644 --- a/app/src/main/java/io/cgisca/godot/gpgs/signin/SignInController.kt +++ b/app/src/main/java/io/cgisca/godot/gpgs/signin/SignInController.kt @@ -1,6 +1,7 @@ package io.cgisca.godot.gpgs.signin import android.app.Activity +import android.util.Log import android.util.Pair import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignInClient @@ -25,22 +26,29 @@ class SignInController( } fun signIn(googleSignInClient: GoogleSignInClient) { - val connection: Pair = connectionController.isConnected() + val userProfile = UserProfile(null, null, null, null) + val connection: Pair = connectionController.isConnected() if (connection.first) { + Log.i("godot","Using cached signin data") signInListener.onSignedInSuccessfully(connection.second) enablePopUps() } else { + Log.i("godot","Using new signin data") googleSignInClient .silentSignIn() .addOnCompleteListener(activity) { task -> if (task.isSuccessful) { val googleSignInAccount = task.result - var accId = "" - googleSignInAccount?.id?.let { - accId = it + if (googleSignInAccount != null) { + userProfile.let { + it.displayName = googleSignInAccount.displayName + it.email = googleSignInAccount.email + it.token = googleSignInAccount.idToken + it.id = googleSignInAccount.id + } } - signInListener.onSignedInSuccessfully(accId) + signInListener.onSignedInSuccessfully(userProfile) enablePopUps() } else { val intent = googleSignInClient.signInIntent @@ -51,14 +59,19 @@ class SignInController( } fun onSignInActivityResult(googleSignInResult: GoogleSignInResult?) { + val userProfile = UserProfile(null, null, null, null) if (googleSignInResult != null && googleSignInResult.isSuccess) { val googleSignInAccount = googleSignInResult.signInAccount - var accId = "" - googleSignInAccount?.id?.let { - accId = it + if (googleSignInAccount != null) { + userProfile.let { + it.displayName = googleSignInAccount.displayName + it.email = googleSignInAccount.email + it.token = googleSignInAccount.idToken + it.id = googleSignInAccount.id + } } enablePopUps() - signInListener.onSignedInSuccessfully(accId) + signInListener.onSignedInSuccessfully(userProfile) } else { var statusCode = Int.MIN_VALUE googleSignInResult?.status?.let { diff --git a/app/src/main/java/io/cgisca/godot/gpgs/signin/SignInListener.kt b/app/src/main/java/io/cgisca/godot/gpgs/signin/SignInListener.kt index 50d6998..aa127d2 100644 --- a/app/src/main/java/io/cgisca/godot/gpgs/signin/SignInListener.kt +++ b/app/src/main/java/io/cgisca/godot/gpgs/signin/SignInListener.kt @@ -1,7 +1,7 @@ package io.cgisca.godot.gpgs.signin interface SignInListener { - fun onSignedInSuccessfully(accountId: String) + fun onSignedInSuccessfully(userProfile: UserProfile) fun onSignInFailed(statusCode: Int) fun onSignOutSuccess() fun onSignOutFailed() diff --git a/app/src/main/java/io/cgisca/godot/gpgs/signin/UserProfile.kt b/app/src/main/java/io/cgisca/godot/gpgs/signin/UserProfile.kt new file mode 100644 index 0000000..b52c616 --- /dev/null +++ b/app/src/main/java/io/cgisca/godot/gpgs/signin/UserProfile.kt @@ -0,0 +1,4 @@ +package io.cgisca.godot.gpgs.signin + +data class UserProfile(var displayName: String?, var email: String?, var token: String?, var id: String?) { +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 0cbe343..4c806b9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.4.0" + ext.kotlin_version = "1.4.10" repositories { google() jcenter() } dependencies { - classpath "com.android.tools.build:gradle:4.0.1" + classpath "com.android.tools.build:gradle:4.1.0" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong @@ -23,4 +23,4 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir -} \ No newline at end of file +} diff --git a/demo/Main.gd b/demo/Main.gd index b6197a4..5f99c1f 100644 --- a/demo/Main.gd +++ b/demo/Main.gd @@ -36,8 +36,10 @@ func _ready(): play_games_services.connect("_on_player_info_loaded", self, "_on_player_info_loaded") play_games_services.connect("_on_player_info_loading_failed", self, "_on_player_info_loading_failed") - play_games_services.init(true) -# play_games_services.initWithSavedGames(true, "SAVE_GAME_NAME") # Use this init if you want saved games feature to be enabled + play_games_services.init(true,false,false,"") +# play_games_services.init(true,true,false,"") # Use this init if you want to get email of the player +# play_games_services.init(true,true,true,"") # Use this init if you want to get email and profile data of the player +# play_games_services.initWithSavedGames(true, "SAVE_GAME_NAME",false, false, "") # Use this init if you want saved games feature to be enabled # Sign-in/sign-out methods @@ -127,8 +129,9 @@ func load_player_info() -> void: # CALLBACKS # Sign-in / sign-out callbacks -func _on_sign_in_success(account_id: String) -> void: - print("Sign in success %s"%account_id) +func _on_sign_in_success(userProfile_json: String) -> void: + var userProfile = parse_json(userProfile_json) + print("Sign in success ",userProfile) func _on_sign_in_failed(error_code: int) -> void: print("Sign in failed %s"%error_code) diff --git a/demo/android/.build_version b/demo/android/.build_version index 83cd463..5eebfbc 100644 --- a/demo/android/.build_version +++ b/demo/android/.build_version @@ -1 +1 @@ -3.2.2.stable +3.2.3.stable diff --git a/demo/android/plugins/GodotPlayGamesServices.gdap b/demo/android/plugins/GodotPlayGamesServices.gdap index b4a2265..42dfe8e 100644 --- a/demo/android/plugins/GodotPlayGamesServices.gdap +++ b/demo/android/plugins/GodotPlayGamesServices.gdap @@ -6,6 +6,6 @@ binary="GodotPlayGamesServices.release.aar" [dependencies] -remote=["com.google.android.gms:play-services-games:20.0.1", "com.google.android.gms:play-services-auth:18.1.0", "com.google.code.gson:gson:2.8.6"] +remote=["com.google.android.gms:play-services-games:21.0.0", "com.google.android.gms:play-services-auth:19.0.0", "com.google.code.gson:gson:2.8.6"] diff --git a/demo/android/plugins/GodotPlayGamesServices.release.aar b/demo/android/plugins/GodotPlayGamesServices.release.aar index 5ec8e41..140cbb4 100644 Binary files a/demo/android/plugins/GodotPlayGamesServices.release.aar and b/demo/android/plugins/GodotPlayGamesServices.release.aar differ diff --git a/godot-lib.3.2.2.stable.release/build.gradle b/godot-lib.3.2.2.stable.release/build.gradle deleted file mode 100644 index e8df81e..0000000 --- a/godot-lib.3.2.2.stable.release/build.gradle +++ /dev/null @@ -1,2 +0,0 @@ -configurations.maybeCreate("default") -artifacts.add("default", file('godot-lib.3.2.2.stable.release.aar')) \ No newline at end of file diff --git a/godot-lib.3.2.2.stable.release/godot-lib.3.2.2.stable.release.aar b/godot-lib.3.2.2.stable.release/godot-lib.3.2.2.stable.release.aar deleted file mode 100644 index 62503c1..0000000 Binary files a/godot-lib.3.2.2.stable.release/godot-lib.3.2.2.stable.release.aar and /dev/null differ diff --git a/godot-lib.3.2.3.stable.release/build.gradle b/godot-lib.3.2.3.stable.release/build.gradle new file mode 100644 index 0000000..4f641e5 --- /dev/null +++ b/godot-lib.3.2.3.stable.release/build.gradle @@ -0,0 +1,2 @@ +configurations.maybeCreate("default") +artifacts.add("default", file('godot-lib.3.2.3.stable.release.aar')) \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 422f1c8..23ec0f0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip diff --git a/settings.gradle b/settings.gradle index 4d58af6..d5f8dab 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':godot-lib.3.2.2.stable.release' \ No newline at end of file +include ':app', ':godot-lib.3.2.3.stable.release' \ No newline at end of file