From 0c614dc69303f5426bf938193349304ba321b534 Mon Sep 17 00:00:00 2001 From: Henadz Date: Fri, 20 Sep 2019 16:07:28 +0300 Subject: [PATCH] Add possibility to get id_token or server_auth_code after login (#10) * Add possibility to get id_token or server_auth_code after login --- docs/_data/api.yml | 41 +++++ game.project | 5 + gpgs/api/gpg.script_api | 41 +++++ gpgs/src/gpgs_extension.cpp | 201 ++++++++++++--------- gpgs/src/java/com/defold/gpgs/GpgsJNI.java | 51 ++++-- main/main.gui_script | 102 ++++++----- 6 files changed, 290 insertions(+), 151 deletions(-) diff --git a/docs/_data/api.yml b/docs/_data/api.yml index 4734c1c..461b10b 100644 --- a/docs/_data/api.yml +++ b/docs/_data/api.yml @@ -29,6 +29,7 @@ [icon:attention] By default login methods request `GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN`. But if you use Disk, we have to request extra scope `Drive.SCOPE_APPFOLDER`. + Or if you use ID token, we have to request ID token with provided client_id. If so it causes the first time silent sign-in to fail, except for users who have already signed in successfully on a different device. Turn off GPGS features you don't want to use in `game.project`. @@ -95,6 +96,46 @@ end ``` +#***************************************************************************************************** + + - name: get_id_token + type: function + desc: Get the current GPGS player id token. Available only if "gpgs.client_id" is configured in game.project + and "gpgs.request_id_token = 1". + + returns: + - name: id_token + type: string + desc: The player ID token. + + examples: + - desc: |- + ```lua + if gpgs then + local id_token = gpgs.get_id_token() + end + ``` + +#***************************************************************************************************** + + - name: get_server_auth_code + type: function + desc: Get the current GPGS player id token. Available only if "gpgs.client_id" is configured in game.project + and "gpgs.request_server_auth_code = 1". + + returns: + - name: server_auth_code + type: string + desc: The server auth code for logged in account. + + examples: + - desc: |- + ```lua + if gpgs then + local server_auth_code = gpgs.get_server_auth_code() + end + ``` + #***************************************************************************************************** - name: is_logged_in diff --git a/game.project b/game.project index 5c66ac6..072a467 100644 --- a/game.project +++ b/game.project @@ -21,13 +21,18 @@ shared_state = 1 [android] package = com.potatojam.onet_paradise.match_two_tiles +minimum_sdk_version = 16 +target_sdk_version = 28 [ios] bundle_identifier = com.defoldtest.gpgs [gpgs] app_id = 567627510591 +#client_id = client id from google console use_saved_games = 1 +request_server_auth_code = 0 +request_id_token = 0 [library] include_dirs = gpgs diff --git a/gpgs/api/gpg.script_api b/gpgs/api/gpg.script_api index 4734c1c..461b10b 100644 --- a/gpgs/api/gpg.script_api +++ b/gpgs/api/gpg.script_api @@ -29,6 +29,7 @@ [icon:attention] By default login methods request `GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN`. But if you use Disk, we have to request extra scope `Drive.SCOPE_APPFOLDER`. + Or if you use ID token, we have to request ID token with provided client_id. If so it causes the first time silent sign-in to fail, except for users who have already signed in successfully on a different device. Turn off GPGS features you don't want to use in `game.project`. @@ -95,6 +96,46 @@ end ``` +#***************************************************************************************************** + + - name: get_id_token + type: function + desc: Get the current GPGS player id token. Available only if "gpgs.client_id" is configured in game.project + and "gpgs.request_id_token = 1". + + returns: + - name: id_token + type: string + desc: The player ID token. + + examples: + - desc: |- + ```lua + if gpgs then + local id_token = gpgs.get_id_token() + end + ``` + +#***************************************************************************************************** + + - name: get_server_auth_code + type: function + desc: Get the current GPGS player id token. Available only if "gpgs.client_id" is configured in game.project + and "gpgs.request_server_auth_code = 1". + + returns: + - name: server_auth_code + type: string + desc: The server auth code for logged in account. + + examples: + - desc: |- + ```lua + if gpgs then + local server_auth_code = gpgs.get_server_auth_code() + end + ``` + #***************************************************************************************************** - name: is_logged_in diff --git a/gpgs/src/gpgs_extension.cpp b/gpgs/src/gpgs_extension.cpp index 9c2976f..7403b97 100644 --- a/gpgs/src/gpgs_extension.cpp +++ b/gpgs/src/gpgs_extension.cpp @@ -7,6 +7,8 @@ #if defined(DM_PLATFORM_ANDROID) +#include + #include "gpgs_jni.h" #include "private_gpgs_callback.h" #include "com_defold_gpgs_GpgsJNI.h" @@ -23,6 +25,8 @@ struct GPGS jmethodID m_activityResult; jmethodID m_getDisplayName; jmethodID m_getId; + jmethodID m_getIdToken; + jmethodID m_getServerAuthCode; jmethodID m_isLoggedIn; jmethodID m_setGravityForPopups; }; @@ -46,51 +50,28 @@ struct GPGS_Disk static GPGS g_gpgs; static GPGS_Disk g_gpgs_disk; -// GPGPS autorization - -static int GpgAuth_Login(lua_State* L) -{ - DM_LUA_STACK_CHECK(L, 0); - - ThreadAttacher attacher; - JNIEnv *env = attacher.env; - - env->CallVoidMethod(g_gpgs.m_GpgsJNI, g_gpgs.m_login); - - return 0; -} - -static int GpgAuth_Logout(lua_State* L) -{ - DM_LUA_STACK_CHECK(L, 0); - - ThreadAttacher attacher; - JNIEnv *env = attacher.env; +// generic JNI calls - env->CallVoidMethod(g_gpgs.m_GpgsJNI, g_gpgs.m_logout); - - return 0; -} - -static int GpgAuth_SilentLogin(lua_State* L) +static int GenericJNIVoidCall(lua_State* L, jobject instance, jmethodID method) { DM_LUA_STACK_CHECK(L, 0); ThreadAttacher attacher; JNIEnv *env = attacher.env; - env->CallVoidMethod(g_gpgs.m_GpgsJNI, g_gpgs.m_silentLogin); + env->CallVoidMethod(instance, method); return 0; } -static int GpgAuth_getDisplayName(lua_State* L) +static int GenericJNIStringCall(lua_State* L, jobject instance, jmethodID method) { DM_LUA_STACK_CHECK(L, 1); ThreadAttacher attacher; JNIEnv *env = attacher.env; - jstring return_value = (jstring)env->CallObjectMethod(g_gpgs.m_GpgsJNI, g_gpgs.m_getDisplayName); + + jstring return_value = (jstring)env->CallObjectMethod(instance, method); if (return_value) { const char* new_char = env->GetStringUTFChars(return_value, 0); @@ -105,42 +86,77 @@ static int GpgAuth_getDisplayName(lua_State* L) return 1; } -static int GpgAuth_getId(lua_State* L) +static int GenericJNIBooleanCall(lua_State* L, jobject instance, jmethodID method) { DM_LUA_STACK_CHECK(L, 1); ThreadAttacher attacher; JNIEnv *env = attacher.env; - jstring return_value = (jstring)env->CallObjectMethod(g_gpgs.m_GpgsJNI, g_gpgs.m_getId); - if (return_value) - { - const char* new_char = env->GetStringUTFChars(return_value, 0); - env->DeleteLocalRef(return_value); - lua_pushstring(L, new_char); - } - else - { - lua_pushnil(L); - } + jboolean return_value = (jboolean)env->CallBooleanMethod(instance, method); + + lua_pushboolean(L, JNI_TRUE == return_value); return 1; } -static int GpgAuth_isLoggedIn(lua_State* L) +static int GenericJNIIntCall(lua_State* L, jobject instance, jmethodID method) { DM_LUA_STACK_CHECK(L, 1); ThreadAttacher attacher; JNIEnv *env = attacher.env; - jboolean return_value = (jboolean)env->CallBooleanMethod(g_gpgs.m_GpgsJNI, g_gpgs.m_isLoggedIn); + int return_value = (int)env->CallIntMethod(instance, method); - lua_pushboolean(L, JNI_TRUE == return_value); + lua_pushnumber(L, return_value); return 1; } + +// GPGPS autorization + +static int GpgAuth_Login(lua_State* L) +{ + return GenericJNIVoidCall(L, g_gpgs.m_GpgsJNI, g_gpgs.m_login); +} + +static int GpgAuth_Logout(lua_State* L) +{ + return GenericJNIVoidCall(L, g_gpgs.m_GpgsJNI, g_gpgs.m_logout); +} + +static int GpgAuth_SilentLogin(lua_State* L) +{ + return GenericJNIVoidCall(L, g_gpgs.m_GpgsJNI, g_gpgs.m_silentLogin); +} + +static int GpgAuth_getDisplayName(lua_State* L) +{ + return GenericJNIStringCall(L, g_gpgs.m_GpgsJNI, g_gpgs.m_getDisplayName); +} + +static int GpgAuth_getId(lua_State* L) +{ + return GenericJNIStringCall(L, g_gpgs.m_GpgsJNI, g_gpgs.m_getId); +} + +static int GpgAuth_getIdToken(lua_State* L) +{ + return GenericJNIStringCall(L, g_gpgs.m_GpgsJNI, g_gpgs.m_getIdToken); +} + +static int GpgAuth_getServerAuthCode(lua_State* L) +{ + return GenericJNIStringCall(L, g_gpgs.m_GpgsJNI, g_gpgs.m_getServerAuthCode); +} + +static int GpgAuth_isLoggedIn(lua_State* L) +{ + return GenericJNIBooleanCall(L, g_gpgs.m_GpgsJNI, g_gpgs.m_isLoggedIn); +} + static int GpgAuth_setGravityForPopups(lua_State* L) { DM_LUA_STACK_CHECK(L, 0); @@ -399,16 +415,7 @@ static int GpgDisk_SnapshotIsOpened(lua_State* L) return 0; } - DM_LUA_STACK_CHECK(L, 1); - - ThreadAttacher attacher; - JNIEnv *env = attacher.env; - - jboolean return_value = (jboolean)env->CallBooleanMethod(g_gpgs.m_GpgsJNI, g_gpgs_disk.m_isSnapshotOpened); - - lua_pushboolean(L, JNI_TRUE == return_value); - - return 1; + return GenericJNIBooleanCall(L, g_gpgs.m_GpgsJNI, g_gpgs_disk.m_isSnapshotOpened); } static int GpgDisk_GetMaxCoverImageSize(lua_State* L) @@ -418,16 +425,7 @@ static int GpgDisk_GetMaxCoverImageSize(lua_State* L) return 0; } - DM_LUA_STACK_CHECK(L, 1); - - ThreadAttacher attacher; - JNIEnv *env = attacher.env; - - int return_value = (int)env->CallIntMethod(g_gpgs.m_GpgsJNI, g_gpgs_disk.m_getMaxCoverImageSize); - - lua_pushnumber(L, return_value); - - return 1; + return GenericJNIIntCall(L, g_gpgs.m_GpgsJNI, g_gpgs_disk.m_getMaxCoverImageSize); } static int GpgDisk_GetMaxDataSize(lua_State* L) @@ -437,16 +435,7 @@ static int GpgDisk_GetMaxDataSize(lua_State* L) return 0; } - DM_LUA_STACK_CHECK(L, 1); - - ThreadAttacher attacher; - JNIEnv *env = attacher.env; - - int return_value = (int)env->CallIntMethod(g_gpgs.m_GpgsJNI, g_gpgs_disk.m_getMaxDataSize); - - lua_pushnumber(L, return_value); - - return 1; + return GenericJNIIntCall(L, g_gpgs.m_GpgsJNI, g_gpgs_disk.m_getMaxDataSize); } static int GpgDisk_SnapshotGetConflictingData(lua_State* L) @@ -528,6 +517,8 @@ static const luaL_reg Gpg_methods[] = {"silent_login", GpgAuth_SilentLogin}, {"get_display_name", GpgAuth_getDisplayName}, {"get_id", GpgAuth_getId}, + {"get_id_token", GpgAuth_getIdToken}, + {"get_server_auth_code", GpgAuth_getServerAuthCode}, {"is_logged_in", GpgAuth_isLoggedIn}, {"set_popup_position", GpgAuth_setGravityForPopups}, {"set_callback", Gpg_set_callback}, @@ -602,13 +593,9 @@ static void LuaInit(lua_State* L) lua_pop(L, 1); } -static void InitializeJNI() -{ - ThreadAttacher attacher; - JNIEnv *env = attacher.env; - ClassLoader class_loader = ClassLoader(env); - jclass cls = class_loader.load("com.defold.gpgs.GpgsJNI"); +static void InitJNIMethods(JNIEnv* env, jclass cls) +{ //authorization g_gpgs.m_silentLogin = env->GetMethodID(cls, "silentLogin", "()V"); g_gpgs.m_login = env->GetMethodID(cls, "login", "()V"); @@ -616,6 +603,8 @@ static void InitializeJNI() g_gpgs.m_isLoggedIn = env->GetMethodID(cls, "isLoggedIn", "()Z"); g_gpgs.m_getDisplayName = env->GetMethodID(cls, "getDisplayName", "()Ljava/lang/String;"); g_gpgs.m_getId = env->GetMethodID(cls, "getId", "()Ljava/lang/String;"); + g_gpgs.m_getIdToken = env->GetMethodID(cls, "getIdToken", "()Ljava/lang/String;"); + g_gpgs.m_getServerAuthCode = env->GetMethodID(cls, "getServerAuthCode", "()Ljava/lang/String;"); g_gpgs.m_setGravityForPopups = env->GetMethodID(cls, "setGravityForPopups", "(I)V"); //disk @@ -635,9 +624,43 @@ static void InitializeJNI() //private methods g_gpgs.m_activityResult = env->GetMethodID(cls, "activityResult", "(IILandroid/content/Intent;)V"); +} + - jmethodID jni_constructor = env->GetMethodID(cls, "", "(Landroid/app/Activity;Z)V"); - g_gpgs.m_GpgsJNI = env->NewGlobalRef(env->NewObject(cls, jni_constructor, dmGraphics::GetNativeAndroidActivity(), g_gpgs_disk.is_using)); +static void CheckInitializationParams(const char* client_id, bool request_server_auth_code, bool request_id_token) +{ + bool is_empty_client_id = client_id == 0 || strlen(client_id) == 0; + + if (is_empty_client_id && request_server_auth_code) + { + dmLogError("'gpgs.client_id' must be defined to request server auth code"); + } + + if (is_empty_client_id && request_id_token) + { + dmLogError("'gpgs.client_id' must be defined to request id token"); + } +} + + +static void InitializeJNI(const char* client_id, bool request_server_auth_code, bool request_id_token) +{ + CheckInitializationParams(client_id, request_server_auth_code > 0, request_id_token > 0); + + ThreadAttacher attacher; + JNIEnv *env = attacher.env; + ClassLoader class_loader = ClassLoader(env); + jclass cls = class_loader.load("com.defold.gpgs.GpgsJNI"); + + InitJNIMethods(env, cls); + + jmethodID jni_constructor = env->GetMethodID(cls, "", "(Landroid/app/Activity;ZZZLjava/lang/String;)V"); + jstring java_client_id = env->NewStringUTF(client_id); + + g_gpgs.m_GpgsJNI = env->NewGlobalRef(env->NewObject(cls, jni_constructor, dmGraphics::GetNativeAndroidActivity(), + g_gpgs_disk.is_using, request_server_auth_code, request_id_token, java_client_id)); + + env->DeleteLocalRef(java_client_id); } static dmExtension::Result InitializeGpg(dmExtension::Params* params) @@ -645,12 +668,14 @@ static dmExtension::Result InitializeGpg(dmExtension::Params* params) LuaInit(params->m_L); int is_using = dmConfigFile::GetInt(params->m_ConfigFile, "gpgs.use_saved_games", 0); - if (is_using > 0) - { - g_gpgs_disk.is_using = true; - } + g_gpgs_disk.is_using = is_using > 0; + + int request_server_auth_code = dmConfigFile::GetInt(params->m_ConfigFile, "gpgs.request_server_auth_code", 0); + int request_id_token = dmConfigFile::GetInt(params->m_ConfigFile, "gpgs.request_id_token", 0); + + const char* client_id = dmConfigFile::GetString(params->m_ConfigFile, "gpgs.client_id", 0); - InitializeJNI(); + InitializeJNI(client_id, request_server_auth_code > 0, request_id_token > 0); dmExtension::RegisterAndroidOnActivityResultListener(OnActivityResult); gpgs_callback_initialize(); return dmExtension::RESULT_OK; @@ -680,7 +705,7 @@ DM_DECLARE_EXTENSION(EXTENSION_NAME, LIB_NAME, AppInitializeGpg, AppFinalizeGpg, dmExtension::Result InitializeGpg(dmExtension::Params* params) { - dmLogInfo("Registered extension Gpg (null)"); + dmLogInfo("Registered extension Gpgs (null)"); return dmExtension::RESULT_OK; } diff --git a/gpgs/src/java/com/defold/gpgs/GpgsJNI.java b/gpgs/src/java/com/defold/gpgs/GpgsJNI.java index 617a2ef..84b543c 100644 --- a/gpgs/src/java/com/defold/gpgs/GpgsJNI.java +++ b/gpgs/src/java/com/defold/gpgs/GpgsJNI.java @@ -71,6 +71,9 @@ public class GpgsJNI { //-------------------------------------------------- private Activity activity; private boolean is_disk_active; + private String client_id; + private boolean is_request_id_token; + private boolean is_request_auth_code; //-------------------------------------------------- // Autorization @@ -121,9 +124,12 @@ private void sendSimpleMessage(int msg, String key_1, int value_1, String key_2, } - public GpgsJNI(Activity activity, boolean is_disk_active) { + public GpgsJNI(Activity activity, boolean is_disk_active, boolean is_request_auth_code, boolean is_request_id_token, String client_id) { this.activity = activity; this.is_disk_active = is_disk_active; + this.client_id = client_id; + this.is_request_auth_code = is_request_auth_code; + this.is_request_id_token = is_request_id_token; mGoogleSignInClient = GoogleSignIn.getClient(activity, getSignInOptions()); } @@ -165,14 +171,23 @@ public void onFailure(@NonNull Exception e) { private GoogleSignInOptions getSignInOptions() { if (mSignInOptions == null) { + GoogleSignInOptions.Builder builder = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN); + if (is_disk_active) { - mSignInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) - .requestScopes(Drive.SCOPE_APPFOLDER) - .build(); - } else { - mSignInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN; + builder.requestScopes(Drive.SCOPE_APPFOLDER); + } + + if (is_request_id_token && client_id != null) { + builder.requestIdToken(client_id); + } + + if (is_request_auth_code && client_id != null) { + builder.requestServerAuthCode(client_id); } + + mSignInOptions = builder.build(); } + return mSignInOptions; } @@ -181,6 +196,7 @@ public void activityResult(int requestCode, int resultCode, Intent intent) { if (intent != null) { Task task = GoogleSignIn.getSignedInAccountFromIntent(intent); + if (task.isSuccessful()) { onConnected(task.getResult(), MSG_SIGN_IN); } else { @@ -251,24 +267,23 @@ public void onComplete(@NonNull Task task) { } public String getDisplayName() { - if (mPlayer == null) { - return null; - } - return mPlayer.getDisplayName(); + return isLoggedIn() ? mPlayer.getDisplayName() : null; } public String getId() { - if (mPlayer == null) { - return null; - } - return mPlayer.getPlayerId(); + return isLoggedIn() ? mPlayer.getPlayerId() : null; + } + + public String getIdToken() { + return isLoggedIn() ? mSignedInAccount.getIdToken() : null; + } + + public String getServerAuthCode() { + return isLoggedIn() ? mSignedInAccount.getServerAuthCode() : null; } public boolean isLoggedIn() { - if (mPlayer == null) { - return false; - } - return true; + return mPlayer != null && mSignedInAccount != null; } public void setGravityForPopups(int gravity) { diff --git a/main/main.gui_script b/main/main.gui_script index efadbc6..e84081c 100644 --- a/main/main.gui_script +++ b/main/main.gui_script @@ -12,23 +12,33 @@ local positions = { "POPUP_POS_BOTTOM_RIGHT" } +local use_saved_games = sys.get_config("gpgs.use_saved_games") == "1" + function gpg_callback(self, message_id, message) print("---------") print(message_id) pprint(message) print("---------") - if message_id == gpg.MSG_SIGN_IN or message_id == gpg.MSG_SILENT_SIGN_IN then - if message.status == gpg.STATUS_SUCCESS then - gui.set_text(gui.get_node("id"), gpg.get_id()) - gui.set_text(gui.get_node("name"), gpg.get_display_name()) - print("max_snapshot_image_size: "..gpg.snapshot_get_max_image_size().." bytes", - "max_snapshot_size: "..gpg.snapshot_get_max_save_size().." bytes") + if message_id == gpgs.MSG_SIGN_IN or message_id == gpgs.MSG_SILENT_SIGN_IN then + if message.status == gpgs.STATUS_SUCCESS then + gui.set_text(gui.get_node("id"), gpgs.get_id()) + gui.set_text(gui.get_node("name"), gpgs.get_display_name()) + + if sys.get_config("gpgs.client_id") then + print("id_token: ", gpgs.get_id_token()) + print("auth_code: ", gpgs.get_server_auth_code()) + end + + if use_saved_games then + print("max_snapshot_image_size: "..gpgs.snapshot_get_max_image_size().." bytes", + "max_snapshot_size: "..gpgs.snapshot_get_max_save_size().." bytes") + end end - elseif message_id == gpg.MSG_SIGN_OUT then + elseif message_id == gpgs.MSG_SIGN_OUT then gui.set_text(gui.get_node("id"), "---") gui.set_text(gui.get_node("name"), "---") - elseif message_id == gpg.MSG_LOAD_SNAPSHOT then - if message.status == gpg.STATUS_CONFLICT then + elseif message_id == gpgs.MSG_LOAD_SNAPSHOT then + if message.status == gpgs.STATUS_CONFLICT then self.conflictId = message.conflictId end end @@ -36,23 +46,25 @@ end function init(self) msg.post(".", "acquire_input_focus") - pprint(_G.gpg) - if gpg then - gpg.set_callback(gpg_callback) - gpg.silent_login() + pprint(_G.gpgs) + if gpgs then + gpgs.set_callback(gpg_callback) + gpgs.silent_login() end end function update(self, dt) - if gpg then - if self.is_logged_in ~= gpg.is_logged_in() then - self.is_logged_in = gpg.is_logged_in() - gui.set_text(gui.get_node("autorized"), "is_logged_in: "..tostring(gpg.is_logged_in())) + if gpgs then + if self.is_logged_in ~= gpgs.is_logged_in() then + self.is_logged_in = gpgs.is_logged_in() + gui.set_text(gui.get_node("autorized"), "is_logged_in: "..tostring(gpgs.is_logged_in())) end - - if self.snapshot_is_opened ~= gpg.snapshot_is_opened() then - self.snapshot_is_opened = gpg.snapshot_is_opened() - gui.set_text(gui.get_node("snapshotOpened"), "snapshot_is_opened: "..tostring(gpg.snapshot_is_opened())) + + if use_saved_games then + if self.snapshot_is_opened ~= gpgs.snapshot_is_opened() then + self.snapshot_is_opened = gpgs.snapshot_is_opened() + gui.set_text(gui.get_node("snapshotOpened"), "snapshot_is_opened: "..tostring(gpgs.snapshot_is_opened())) + end end end end @@ -62,8 +74,8 @@ local function change_popup_pos(self) self.pos = 3 end gui.set_text(gui.get_node("popup_pos_value"), positions[self.pos]) - if gpg then - gpg.set_popup_position(gpg[positions[self.pos]]) + if gpgs then + gpgs.set_popup_position(gpgs[positions[self.pos]]) end self.pos = self.pos + 1 if self.pos > #positions then @@ -74,15 +86,15 @@ end function on_input(self, action_id, action) dirtylarry:button("login", action_id, action, function () print("LOGIN was pressed") - if gpg then - gpg.login() + if gpgs then + gpgs.login() end end) - + dirtylarry:button("logout", action_id, action, function () print("LOGOUT was pressed") - if gpg then - gpg.logout() + if gpgs then + gpgs.logout() end end) @@ -91,20 +103,20 @@ function on_input(self, action_id, action) end) dirtylarry:button("show_snapshots", action_id, action, function () - if gpg then - gpg.snapshot_display_saves("My cool saves", true, true, 3) + if gpgs then + gpgs.snapshot_display_saves("My cool saves", true, true, 3) end end) dirtylarry:button("snapshot_open", action_id, action, function () - if gpg then - gpg.snapshot_open("my_save", true, gpg.RESOLUTION_POLICY_MANUAL) + if gpgs then + gpgs.snapshot_open("my_save", true, gpgs.RESOLUTION_POLICY_MANUAL) end end) dirtylarry:button("snapshot_get_data", action_id, action, function () - if gpg then - local bytes, error_message = gpg.snapshot_get_data() + if gpgs then + local bytes, error_message = gpgs.snapshot_get_data() if not bytes then print("snapshot_get_data ERROR:", error_message) else @@ -114,9 +126,9 @@ function on_input(self, action_id, action) end) dirtylarry:button("save_snapshot", action_id, action, function () - if gpg then + if gpgs then local png, w, h = screenshot.png() - gpg.snapshot_commit_and_close({ + gpgs.snapshot_commit_and_close({ coverImage = png, description = "LEVEL 31, CAVE", playedTime = math.random(1000, 2000), @@ -126,8 +138,8 @@ function on_input(self, action_id, action) end) dirtylarry:button("snapshot_get_conflicting_data", action_id, action, function () - if gpg then - local bytes, error_message = gpg.snapshot_get_conflicting_data() + if gpgs then + local bytes, error_message = gpgs.snapshot_get_conflicting_data() if not bytes then print("snapshot_get_conflicting_data ERROR: ", error_message) else @@ -137,8 +149,8 @@ function on_input(self, action_id, action) end) dirtylarry:button("snapshot_set_data", action_id, action, function () - if gpg then - local success, error_message = gpg.snapshot_set_data("MyCustomBytesForSnapshot") + if gpgs then + local success, error_message = gpgs.snapshot_set_data("MyCustomBytesForSnapshot") if not success then print("snapshot_set_data ERROR:", error_message) end @@ -146,8 +158,8 @@ function on_input(self, action_id, action) end) dirtylarry:button("snapshot_resolve_conflict", action_id, action, function () - if gpg then - local success, error_message = gpg.snapshot_resolve_conflict(self.conflictId, gpg.SNAPSHOT_CURRENT) + if gpgs then + local success, error_message = gpgs.snapshot_resolve_conflict(self.conflictId, gpgs.SNAPSHOT_CURRENT) if not success then print("snapshot_resolve_conflict ERROR:", error_message) end @@ -155,9 +167,9 @@ function on_input(self, action_id, action) end) dirtylarry:button("snapshot_resolve_conflict_conflicting", action_id, action, function () - if gpg then - gpg.snapshot_resolve_conflict(self.conflictId, gpg.SNAPSHOT_CONFLICTING) + if gpgs then + gpgs.snapshot_resolve_conflict(self.conflictId, gpgs.SNAPSHOT_CONFLICTING) end end) - + end \ No newline at end of file