From 5b756716ea074c25bbc2986b7d1fc4544a3e6722 Mon Sep 17 00:00:00 2001
From: Ali Sharoz <sharoz_dev@rizzestudios.com>
Date: Sat, 22 Mar 2025 00:19:00 +0500
Subject: [PATCH] Almost progress fixed

---
 Assets/GoogleSignInManager.cs         | 152 +++++++++++++++++---------
 Assets/PlayerPrefsKeys.cs             |  23 ++++
 Assets/PlayerPrefsKeys.cs.meta        |  11 ++
 Assets/PlayerPrefsSyncManager.cs      |  60 ++++++++++
 Assets/PlayerPrefsSyncManager.cs.meta |  11 ++
 Assets/Profile.cs                     |   3 +
 Assets/SafePlayerPrefs.cs             |  24 ++++
 Assets/SafePlayerPrefs.cs.meta        |  11 ++
 Assets/Scenes/Loading.unity           |  46 +++++++-
 Assets/Scripts/Dev/Bootstrapper.cs    |   7 +-
 10 files changed, 292 insertions(+), 56 deletions(-)
 create mode 100644 Assets/PlayerPrefsKeys.cs
 create mode 100644 Assets/PlayerPrefsKeys.cs.meta
 create mode 100644 Assets/PlayerPrefsSyncManager.cs
 create mode 100644 Assets/PlayerPrefsSyncManager.cs.meta
 create mode 100644 Assets/SafePlayerPrefs.cs
 create mode 100644 Assets/SafePlayerPrefs.cs.meta

diff --git a/Assets/GoogleSignInManager.cs b/Assets/GoogleSignInManager.cs
index 087a2353..9b5f548a 100644
--- a/Assets/GoogleSignInManager.cs
+++ b/Assets/GoogleSignInManager.cs
@@ -3,36 +3,31 @@ using UnityEngine.UI;
 using Google;
 using PlayFab;
 using PlayFab.ClientModels;
+using System;
+using System.Collections.Generic;
 using System.Threading.Tasks;
 
 public class GoogleSignInManager : MonoBehaviour
 {
-    //#if UNITY_IOS
-    //    private string webClientId = "723833850517-2j378fbm2a8u644p4qqod4qbi93dsgom.apps.googleusercontent.com"; // Replace with your actual Google Web Client ID
-    //#elif UNITY_ANDROID
-    //    private string webClientId = "723833850517-tfaer77vetml1bhv9qbj3o84ec52u45d.apps.googleusercontent.com"; // Replace with your actual Google Web Client ID
-    //#endif
-    //private string webClientId = "723833850517-865419enf8t0j1itln3cgmd1b67shsue.apps.googleusercontent.com";
-
     private GoogleSignInConfiguration configuration;
-    public Bootstrapper bootstrapper; // Assign Bootstrapper in Inspector
+    public Bootstrapper bootstrapper; // Assign in Inspector
     public Button googleSignInButton;
+
     void Awake()
     {
-        // Set up the Google Sign-In configuration
         configuration = new GoogleSignInConfiguration
         {
             WebClientId = "723833850517-865419enf8t0j1itln3cgmd1b67shsue.apps.googleusercontent.com",
             RequestEmail = true,
-            RequestIdToken = false,  // ❌ We no longer request IdToken, since we use ServerAuthCode instead
-            RequestAuthCode = true   // βœ… Enable ServerAuthCode for secure backend authentication
+            RequestAuthCode = true
         };
 
         GoogleSignIn.Configuration = configuration;
+        Application.quitting += SyncPlayerPrefsToPlayFabOnQuit;
     }
+
     void Start()
     {
-
         if (PlayerPrefs.HasKey("PlayFabID"))
         {
             Debug.Log("User already signed in, attempting silent login...");
@@ -42,51 +37,62 @@ public class GoogleSignInManager : MonoBehaviour
         {
             Debug.Log("No saved PlayFab ID, waiting for user sign-in.");
             googleSignInButton.gameObject.SetActive(true);
+            googleSignInButton.onClick.RemoveAllListeners();
             googleSignInButton.onClick.AddListener(SignInWithGoogle);
-            SignInWithGoogle();
         }
     }
 
     public void SignInWithGoogle()
     {
+        googleSignInButton.interactable = false;
         GoogleSignIn.DefaultInstance.SignIn().ContinueWith(OnGoogleSignIn);
     }
 
     private void OnGoogleSignIn(Task<GoogleSignInUser> task)
     {
-        if (task.IsFaulted)
+        if (task.IsFaulted || task.IsCanceled)
         {
-            Debug.LogError("Google Sign-In encountered an error: " + task.Exception);
+            Debug.LogError("Google Sign-In failed: " + task.Exception);
+
+            // βœ… Show the sign-in button again
+            googleSignInButton.gameObject.SetActive(true);
+            googleSignInButton.interactable = true;
+            googleSignInButton.onClick.RemoveAllListeners();
+            googleSignInButton.onClick.AddListener(SignInWithGoogle);
+            return;
         }
-        else if (task.IsCanceled)
+
+        GoogleSignInUser user = task.Result;
+        string authCode = user.AuthCode;
+        PlayerPrefs.SetString("GoogleAuthCode", authCode);
+        PlayerPrefsKeys.RegisterKey("GoogleAuthCode");
+        PlayerPrefs.Save();
+
+        LoginToPlayFab(authCode);
+    }
+
+    private void SignInSilently()
+    {
+        if (PlayerPrefs.HasKey("GoogleAuthCode"))
         {
-            Debug.Log("Google Sign-In was canceled.");
+            string authCode = PlayerPrefs.GetString("GoogleAuthCode");
+            LoginToPlayFab(authCode);
         }
         else
         {
-            GoogleSignInUser user = task.Result;
-            Debug.Log("βœ… Google Sign-In succeeded!");
-            Debug.Log("πŸ‘€ Display Name: " + user.DisplayName);
-            Debug.Log("πŸ“§ Email: " + user.Email);
-            Debug.Log("πŸ”‘ Server Auth Code: " + user.AuthCode);
-            string idToken = user.AuthCode;
-            PlayerPrefs.SetString("GoogleIdToken", idToken); // Save Google Token for auto-login
-            PlayerPrefs.Save();
-
-            Debug.Log("Google Sign-In Successful! Fetching PlayFab login...");
-            LoginToPlayFab(idToken);
-            // πŸ”Ή Send this AuthCode to your backend (PlayFab, Firebase, or custom server)
-            // The backend will exchange this for an access token.
+            Debug.LogWarning("No Google AuthCode found for silent sign-in.");
+            googleSignInButton.gameObject.SetActive(true);
+            googleSignInButton.onClick.RemoveAllListeners();
+            googleSignInButton.onClick.AddListener(SignInWithGoogle);
         }
+    }
 
-           }
-
-    private void LoginToPlayFab(string idToken)
+    private void LoginToPlayFab(string authCode)
     {
         var request = new LoginWithGoogleAccountRequest
         {
             TitleId = PlayFabSettings.TitleId,
-            ServerAuthCode = idToken,
+            ServerAuthCode = authCode,
             CreateAccount = true
         };
 
@@ -95,47 +101,85 @@ public class GoogleSignInManager : MonoBehaviour
 
     private void OnPlayFabLoginSuccess(LoginResult result)
     {
-        Debug.Log("PlayFab Login Success! PlayFab ID: " + result.PlayFabId);
+        Debug.Log("βœ… PlayFab Login Success! PlayFab ID: " + result.PlayFabId);
 
-        // Save PlayFab ID to keep the user signed in automatically
         PlayerPrefs.SetString("PlayFabID", result.PlayFabId);
+        PlayerPrefsKeys.RegisterKey("PlayFabID");
         PlayerPrefs.Save();
 
-        // Start the game after login
-        bootstrapper.StartGame();
+        LoadPlayerPrefsFromPlayFab(() =>
+        {
+            googleSignInButton.gameObject.SetActive(false);
+            bootstrapper.StartGame(); // Start the game after loading
+        });
     }
 
     private void OnPlayFabLoginFailure(PlayFabError error)
     {
-        Debug.LogError("PlayFab Login Failed: " + error.GenerateErrorReport());
+        Debug.LogError("❌ PlayFab Login Failed: " + error.GenerateErrorReport());
+
+        // βœ… Re-enable button so player can retry
+        googleSignInButton.gameObject.SetActive(true);
+        googleSignInButton.interactable = true;
+        googleSignInButton.onClick.RemoveAllListeners();
+        googleSignInButton.onClick.AddListener(SignInWithGoogle);
     }
 
-    private void SignInSilently()
+    private void LoadPlayerPrefsFromPlayFab(Action onComplete)
     {
-        if (PlayerPrefs.HasKey("GoogleIdToken"))
+        PlayFabClientAPI.GetUserData(new GetUserDataRequest(), result =>
         {
-            Debug.Log("Attempting silent Google Sign-In...");
-            string savedIdToken = PlayerPrefs.GetString("GoogleIdToken");
-            LoginToPlayFab(savedIdToken); // Skip Google UI, go directly to PlayFab login
-        }
-        else
+            if (result.Data != null)
+            {
+                foreach (var entry in result.Data)
+                {
+                    PlayerPrefs.SetString(entry.Key, entry.Value.Value);
+                    PlayerPrefsKeys.RegisterKey(entry.Key);
+                }
+
+                PlayerPrefs.Save();
+                Debug.Log("βœ… Loaded PlayerPrefs from PlayFab.");
+            }
+            else
+            {
+                Debug.Log("ℹ️ No saved PlayerPrefs found in PlayFab.");
+            }
+
+            onComplete?.Invoke();
+        },
+        error =>
         {
-            Debug.LogWarning("No Google ID Token saved, user must sign in manually.");
+            Debug.LogError("❌ Failed to load PlayerPrefs from PlayFab: " + error.GenerateErrorReport());
+            onComplete?.Invoke();
+        });
+    }
+
+    private void SyncPlayerPrefsToPlayFabOnQuit()
+    {
+        Dictionary<string, string> allPrefs = new Dictionary<string, string>();
+
+        foreach (var key in PlayerPrefsKeys.GetAllKeys())
+        {
+            allPrefs[key] = PlayerPrefs.GetString(key);
         }
+
+        var request = new UpdateUserDataRequest
+        {
+            Data = allPrefs
+        };
+
+        PlayFabClientAPI.UpdateUserData(request,
+            result => Debug.Log("βœ… Synced PlayerPrefs to PlayFab on quit."),
+            error => Debug.LogError("❌ Failed to sync PlayerPrefs on quit: " + error.GenerateErrorReport()));
     }
 
     public void SignOut()
     {
-        Debug.Log("Signing out user...");
-
-        // Clear stored login data
         PlayerPrefs.DeleteKey("PlayFabID");
-        PlayerPrefs.DeleteKey("GoogleIdToken");
+        PlayerPrefs.DeleteKey("GoogleAuthCode");
         PlayerPrefs.Save();
 
-        // Sign out from Google
         GoogleSignIn.DefaultInstance.SignOut();
-
-        Debug.Log("User signed out. They will need to log in again.");
+        Debug.Log("User signed out.");
     }
 }
diff --git a/Assets/PlayerPrefsKeys.cs b/Assets/PlayerPrefsKeys.cs
new file mode 100644
index 00000000..5a8c7a1b
--- /dev/null
+++ b/Assets/PlayerPrefsKeys.cs
@@ -0,0 +1,23 @@
+using System.Collections.Generic;
+using UnityEngine;
+public static class PlayerPrefsKeys
+{
+    private const string KeyRegistry = "_AllPlayerPrefsKeys";
+
+    public static void RegisterKey(string key)
+    {
+        var keys = PlayerPrefs.GetString(KeyRegistry, "");
+        if (!keys.Contains(key))
+        {
+            keys += key + ";";
+            PlayerPrefs.SetString(KeyRegistry, keys);
+            PlayerPrefs.Save();
+        }
+    }
+
+    public static List<string> GetAllKeys()
+    {
+        var keysString = PlayerPrefs.GetString(KeyRegistry, "");
+        return new List<string>(keysString.Split(';', System.StringSplitOptions.RemoveEmptyEntries));
+    }
+}
diff --git a/Assets/PlayerPrefsKeys.cs.meta b/Assets/PlayerPrefsKeys.cs.meta
new file mode 100644
index 00000000..59a532b4
--- /dev/null
+++ b/Assets/PlayerPrefsKeys.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ffa4debad77245b4d9620a5fc2b07c9d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/PlayerPrefsSyncManager.cs b/Assets/PlayerPrefsSyncManager.cs
new file mode 100644
index 00000000..deadfdde
--- /dev/null
+++ b/Assets/PlayerPrefsSyncManager.cs
@@ -0,0 +1,60 @@
+ο»Ώusing UnityEngine;
+using PlayFab;
+using PlayFab.ClientModels;
+using System.Collections.Generic;
+using Google.Impl;
+
+public class PlayerPrefsSyncManager : MonoBehaviour
+{
+    private static PlayerPrefsSyncManager instance;
+    private void OnApplicationQuit()
+    {
+        SyncPlayerPrefsToPlayFabOnQuit();
+    }
+    private void OnApplicationPause()
+    {
+        SyncPlayerPrefsToPlayFabOnQuit();
+    }
+
+    void Awake()
+    {
+        // Make this object persistent across scenes
+        if (instance == null)
+        {
+            instance = this;
+            DontDestroyOnLoad(this.gameObject);
+            Application.quitting += SyncPlayerPrefsToPlayFabOnQuit;
+        }
+        else
+        {
+            Destroy(gameObject);
+        }
+    }
+
+    private void SyncPlayerPrefsToPlayFabOnQuit()
+    {
+        var keys = PlayerPrefsKeys.GetAllKeys();
+        if (keys.Count == 0)
+        {
+            Debug.Log("No PlayerPrefs keys registered, skipping sync.");
+            return;
+        }
+
+        Dictionary<string, string> allPrefs = new Dictionary<string, string>();
+
+        foreach (var key in keys)
+        {
+            string value = PlayerPrefs.GetString(key);
+            allPrefs[key] = value;
+        }
+
+        var request = new UpdateUserDataRequest
+        {
+            Data = allPrefs
+        };
+
+        PlayFabClientAPI.UpdateUserData(request,
+            result => Debug.Log("βœ… Synced PlayerPrefs to PlayFab on quit."),
+            error => Debug.LogError("❌ Failed to sync PlayerPrefs on quit: " + error.GenerateErrorReport()));
+    }
+}
diff --git a/Assets/PlayerPrefsSyncManager.cs.meta b/Assets/PlayerPrefsSyncManager.cs.meta
new file mode 100644
index 00000000..73653bba
--- /dev/null
+++ b/Assets/PlayerPrefsSyncManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 505af05eda8a6824684d079a3bd27291
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Profile.cs b/Assets/Profile.cs
index 14897d74..00650d90 100644
--- a/Assets/Profile.cs
+++ b/Assets/Profile.cs
@@ -7,6 +7,7 @@ using UnityEngine.UI;
 using MS;
 using TMPro;
 using static D2D.Utilities.CommonGameplayFacade;
+using ES3Internal;
 
 public class Profile : MonoBehaviour
 {
@@ -48,6 +49,7 @@ public class Profile : MonoBehaviour
         int hasEnteredName = PlayerPrefs.GetInt(GameConstants.NameEnteredCheckKey, 0);
         if (hasEnteredName > 0)
         {
+            
             string name = PlayerPrefs.GetString(GameConstants.DisplayNameKey);
             PlayFabLeaderboards.DisplayName = name;
             HeaderProfileName.text = name;
@@ -55,6 +57,7 @@ public class Profile : MonoBehaviour
         }
         else
         {
+            Debug.Log("Name not found in plaerprefs");
             if (!EnterNamePanel.isOpen)
                 EnterNamePanel.Open();
         }
diff --git a/Assets/SafePlayerPrefs.cs b/Assets/SafePlayerPrefs.cs
new file mode 100644
index 00000000..64ac397c
--- /dev/null
+++ b/Assets/SafePlayerPrefs.cs
@@ -0,0 +1,24 @@
+using UnityEngine;
+public static class SafePlayerPrefs
+{
+    public static void SetInt(string key, int value)
+    {
+        PlayerPrefs.SetInt(key, value);
+        PlayerPrefsKeys.RegisterKey(key);
+        PlayerPrefs.Save();
+    }
+
+    public static void SetFloat(string key, float value)
+    {
+        PlayerPrefs.SetFloat(key, value);
+        PlayerPrefsKeys.RegisterKey(key);
+        PlayerPrefs.Save();
+    }
+
+    public static void SetString(string key, string value)
+    {
+        PlayerPrefs.SetString(key, value);
+        PlayerPrefsKeys.RegisterKey(key);
+        PlayerPrefs.Save();
+    }
+}
diff --git a/Assets/SafePlayerPrefs.cs.meta b/Assets/SafePlayerPrefs.cs.meta
new file mode 100644
index 00000000..10756386
--- /dev/null
+++ b/Assets/SafePlayerPrefs.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3f16590318a73204e98d26d21f94e188
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scenes/Loading.unity b/Assets/Scenes/Loading.unity
index dffdbf5a..32318531 100644
--- a/Assets/Scenes/Loading.unity
+++ b/Assets/Scenes/Loading.unity
@@ -2193,6 +2193,50 @@ Transform:
   m_Children: []
   m_Father: {fileID: 0}
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1440779027
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1440779029}
+  - component: {fileID: 1440779028}
+  m_Layer: 0
+  m_Name: PlayerPrefSyncManager
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!114 &1440779028
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1440779027}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 505af05eda8a6824684d079a3bd27291, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+--- !u!4 &1440779029
+Transform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 1440779027}
+  serializedVersion: 2
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_ConstrainProportionsScale: 0
+  m_Children: []
+  m_Father: {fileID: 0}
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
 --- !u!1 &1601498681
 GameObject:
   m_ObjectHideFlags: 0
@@ -2456,7 +2500,6 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   loadingSlider: {fileID: 448233536}
   loadingBarObj: {fileID: 1845972577}
-  signInButton: {fileID: 561952461}
 --- !u!4 &1696995257
 Transform:
   m_ObjectHideFlags: 0
@@ -2564,3 +2607,4 @@ SceneRoots:
   - {fileID: 834550948}
   - {fileID: 812377085}
   - {fileID: 168582916}
+  - {fileID: 1440779029}
diff --git a/Assets/Scripts/Dev/Bootstrapper.cs b/Assets/Scripts/Dev/Bootstrapper.cs
index bd02c543..8a6e01b2 100644
--- a/Assets/Scripts/Dev/Bootstrapper.cs
+++ b/Assets/Scripts/Dev/Bootstrapper.cs
@@ -7,7 +7,12 @@ public class Bootstrapper : MonoBehaviour
 {
     [SerializeField] private Image loadingSlider;
     [SerializeField] private GameObject loadingBarObj;
-
+    private void Start()
+    {
+#if UNITY_EDITOR
+        StartGame();
+#endif
+    }
     // Called from GoogleSignInManager when login is successful
     public void StartGame()
     {