From 87d853e7bb86cdd229b7069b65c8f54bf2c527fe Mon Sep 17 00:00:00 2001 From: Ali Sharoz Date: Fri, 11 Apr 2025 20:39:58 +0500 Subject: [PATCH] Added notification permission request --- Assets/GoogleSigninSDK/GoogleSignInManager.cs | 81 +++++++++- Assets/GoogleSigninSDK/Profile.cs | 105 ++++++++++++- Assets/NotificationPermissionRequester.cs | 37 +++++ .../NotificationPermissionRequester.cs.meta | 11 ++ Assets/PipeOut/Scenes/Loading.unity | 141 ++++++++++++------ Assets/Plugins/Android/AndroidManifest.xml | 26 ++++ .../Plugins/Android/AndroidManifest.xml.meta | 7 + Assets/Scripts/HomeScene.cs | 33 +++- ProjectSettings/ProjectSettings.asset | 2 +- 9 files changed, 380 insertions(+), 63 deletions(-) create mode 100644 Assets/NotificationPermissionRequester.cs create mode 100644 Assets/NotificationPermissionRequester.cs.meta create mode 100644 Assets/Plugins/Android/AndroidManifest.xml create mode 100644 Assets/Plugins/Android/AndroidManifest.xml.meta diff --git a/Assets/GoogleSigninSDK/GoogleSignInManager.cs b/Assets/GoogleSigninSDK/GoogleSignInManager.cs index 4ed4c80f..775beeac 100644 --- a/Assets/GoogleSigninSDK/GoogleSignInManager.cs +++ b/Assets/GoogleSigninSDK/GoogleSignInManager.cs @@ -6,6 +6,8 @@ using PlayFab.ClientModels; using System; using System.Collections.Generic; using System.Threading.Tasks; +using OneSignalSDK; +using System.Collections; public class GoogleSignInManager : MonoBehaviour { @@ -24,7 +26,8 @@ public class GoogleSignInManager : MonoBehaviour }; GoogleSignIn.Configuration = configuration; - Application.quitting += SyncPlayerPrefsToPlayFabOnQuit; + Application.quitting += SyncPlayerPrefsToPlayFabOnQuit; + OneSignal.Default.Initialize("3ee530aa-8613-485b-9cbd-0263727badc5"); } void Start() @@ -65,7 +68,37 @@ public class GoogleSignInManager : MonoBehaviour googleSignInButton.gameObject.SetActive(false); guestLoginButton.gameObject.SetActive(false); - bootstrapper.StartGame(); + PlayFabSettings.staticSettings.TitleId = GameConstants.PlayfabTitleId; + + string customId = SystemInfo.deviceUniqueIdentifier; + SafePlayerPrefs.SetString("GuestCustomID", customId); // Save customId + + var request = new LoginWithCustomIDRequest + { + CustomId = customId, + CreateAccount = true + }; + + PlayFabClientAPI.LoginWithCustomID(request, result => + { + Debug.Log("✅ Guest Login Success! PlayFab ID: " + result.PlayFabId); + SafePlayerPrefs.SetString("PlayFabID", result.PlayFabId); + PlayerPrefs.Save(); + + if (result.NewlyCreated) + { + SafePlayerPrefs.SetInt("NeedsDisplayNameUpload", 1); + PlayerPrefs.Save(); + } + + bootstrapper.StartGame(); + }, + error => + { + Debug.LogError("❌ Guest PlayFab login failed: " + error.GenerateErrorReport()); + googleSignInButton.gameObject.SetActive(true); + guestLoginButton.gameObject.SetActive(true); + }); } public void SignInWithGoogle() @@ -144,9 +177,13 @@ public class GoogleSignInManager : MonoBehaviour private void OnPlayFabLoginSuccess(LoginResult result) { Debug.Log("✅ PlayFab Login Success! PlayFab ID: " + result.PlayFabId); + SafePlayerPrefs.SetString("PlayFabID", result.PlayFabId); PlayerPrefs.Save(); + OneSignal.Login(result.PlayFabId); + StartCoroutine(SaveOneSignalPlayerIdToPlayFab()); + LoadPlayerPrefsFromPlayFab(() => { googleSignInButton.gameObject.SetActive(false); @@ -155,6 +192,34 @@ public class GoogleSignInManager : MonoBehaviour }); } + private IEnumerator SaveOneSignalPlayerIdToPlayFab() + { + yield return new WaitForSeconds(1f); + + string playerId = OneSignal.User.PushSubscription.Id; + + if (!string.IsNullOrEmpty(playerId)) + { + Debug.Log("✅ Got OneSignal Player ID: " + playerId); + + var request = new UpdateUserDataRequest + { + Data = new Dictionary + { + { "OneSignalPlayerId", playerId } + } + }; + + PlayFabClientAPI.UpdateUserData(request, + result => Debug.Log("✅ Saved OneSignal Player ID to PlayFab"), + error => Debug.LogError("❌ Failed to save OneSignal Player ID: " + error.GenerateErrorReport())); + } + else + { + Debug.LogWarning("⚠️ OneSignal Player ID not available yet."); + } + } + private void OnPlayFabLoginFailure(PlayFabError error) { Debug.LogError("❌ PlayFab Login Failed: " + error.GenerateErrorReport()); @@ -202,7 +267,7 @@ public class GoogleSignInManager : MonoBehaviour private void SyncPlayerPrefsToPlayFabOnQuit() { - if (PlayerPrefs.HasKey("GuestMode")) return; + if (PlayerPrefs.GetInt("GuestMode", 0) == 1) return; Dictionary allPrefs = new Dictionary(); foreach (var key in PlayerPrefsKeys.GetAllKeys()) @@ -214,12 +279,12 @@ public class GoogleSignInManager : MonoBehaviour { Data = allPrefs }; - if(PlayFabClientAPI.IsClientLoggedIn()) - { - PlayFabClientAPI.UpdateUserData(request, - result => Debug.Log("✅ Synced SafePlayerPrefs to PlayFab on quit."), - error => Debug.LogError("❌ Failed to sync SafePlayerPrefs: " + error.GenerateErrorReport())); + if (PlayFabClientAPI.IsClientLoggedIn()) + { + PlayFabClientAPI.UpdateUserData(request, + result => Debug.Log("✅ Synced SafePlayerPrefs to PlayFab on quit."), + error => Debug.LogError("❌ Failed to sync SafePlayerPrefs: " + error.GenerateErrorReport())); } } diff --git a/Assets/GoogleSigninSDK/Profile.cs b/Assets/GoogleSigninSDK/Profile.cs index 996d7fb4..eef434c1 100644 --- a/Assets/GoogleSigninSDK/Profile.cs +++ b/Assets/GoogleSigninSDK/Profile.cs @@ -1,4 +1,4 @@ -using PlayFab.ClientModels; +using PlayFab.ClientModels; using PlayFab; using System.Collections; using System.Collections.Generic; @@ -26,6 +26,8 @@ public class Profile : MonoBehaviour CheckForAvatar(); if (EnteredNameButton != null) EnteredNameButton.interactable = false; + + //TryForceFixGuestDisplayName(); } private void CheckForAvatar() { @@ -74,19 +76,112 @@ public class Profile : MonoBehaviour //LevelFillerText.text = bestScore + "/" + maxScore; } - public void OnDisplayNameEntered() + private void TryForceFixGuestDisplayName() { + bool isGuest = PlayerPrefs.GetInt("GuestMode", 0) == 1; + string currentDisplayName = PlayerPrefs.GetString(GameConstants.DisplayNameKey, ""); + + if (!isGuest || string.IsNullOrEmpty(currentDisplayName)) + return; + + // Already suffixed? Then skip + if (currentDisplayName.Length >= 4 && char.IsDigit(currentDisplayName[^1]) && char.IsLetterOrDigit(currentDisplayName[^2])) + { + Debug.Log("✅ Guest display name already has suffix: " + currentDisplayName); + return; + } + + string suffix = GetCleanSuffixFromDeviceId(); + string updatedName = currentDisplayName + suffix; + + SafePlayerPrefs.SetString(GameConstants.DisplayNameKey, updatedName); + PlayerPrefs.Save(); + if (PlayFabClientAPI.IsClientLoggedIn()) { - PlayFabManager.Instance.playFabLeaderboards.SetDisplayName(nameInputField.text); + var request = new UpdateUserTitleDisplayNameRequest + { + DisplayName = updatedName + }; + + PlayFabClientAPI.UpdateUserTitleDisplayName(request, + result => Debug.Log("✅ Fixed guest display name to: " + result.DisplayName), + error => Debug.LogError("❌ Failed to update guest display name: " + error.GenerateErrorReport())); } + } + + public void OnDisplayNameEntered() + { + string inputName = nameInputField.text; + string finalName = inputName; + + if (PlayerPrefs.GetInt("GuestMode", 0) == 1) + { + Debug.Log("1Inside collecting 3 chars from playerpref"); + string customId = PlayerPrefs.GetString("GuestCustomID", ""); + string suffix = ""; + + if (customId.Length >= 3) + { + char[] last3 = customId.Substring(customId.Length - 3).ToCharArray(); + System.Text.StringBuilder cleanSuffix = new System.Text.StringBuilder(); + System.Random rand = new System.Random(); + + foreach (char c in last3) + { + cleanSuffix.Append(char.IsLetterOrDigit(c) ? c : rand.Next(0, 10).ToString()[0]); + } + + suffix = cleanSuffix.ToString(); + } + + finalName = inputName + suffix; + Debug.Log("2Inside collecting 3 chars from playerpref"); + } + + SafePlayerPrefs.SetString(GameConstants.DisplayNameKey, finalName); SafePlayerPrefs.SetInt(GameConstants.NameEnteredCheckKey, 1); - SafePlayerPrefs.SetString(GameConstants.DisplayNameKey, nameInputField.text); - HeaderProfileName.text = nameInputField.text; + PlayerPrefs.Save(); + + if (PlayFabClientAPI.IsClientLoggedIn()) + { + PlayFabClientAPI.UpdateUserTitleDisplayName(new UpdateUserTitleDisplayNameRequest + { + DisplayName = finalName + }, + result => Debug.Log("✅ Display name updated in PlayFab: " + result.DisplayName), + error => Debug.LogError("❌ Failed to update display name: " + error.GenerateErrorReport())); + } + HeaderProfileName.text = inputName; // Show clean name in UI EnterNamePanel.Close(); LevelFillerSetter(); } + + private string GetCleanSuffixFromDeviceId() + { + string id = SystemInfo.deviceUniqueIdentifier; + string last3 = id.Length >= 3 ? id.Substring(id.Length - 3) : id; + + char[] safeChars = new char[3]; + System.Random rand = new System.Random(); + + for (int i = 0; i < last3.Length; i++) + { + char c = last3[i]; + if (char.IsLetterOrDigit(c)) + { + safeChars[i] = c; + } + else + { + safeChars[i] = rand.Next(0, 10).ToString()[0]; // Replace with random digit + } + } + + return new string(safeChars); + } + public void OnAvatarSelected(int AvatarID) { //PlayFabManager.Instance.playFabLeaderboards.SetDisplayName(nameInputField.text); diff --git a/Assets/NotificationPermissionRequester.cs b/Assets/NotificationPermissionRequester.cs new file mode 100644 index 00000000..b7c27e26 --- /dev/null +++ b/Assets/NotificationPermissionRequester.cs @@ -0,0 +1,37 @@ +using UnityEngine; + +public class NotificationPermissionRequester : MonoBehaviour +{ + void Start() + { +#if UNITY_ANDROID && !UNITY_EDITOR + using (AndroidJavaClass version = new AndroidJavaClass("android.os.Build$VERSION")) + { + int sdkInt = version.GetStatic("SDK_INT"); + + if (sdkInt >= 33) + { + using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) + using (AndroidJavaObject activity = unityPlayer.GetStatic("currentActivity")) + { + string permission = "android.permission.POST_NOTIFICATIONS"; + + using (AndroidJavaClass permissionChecker = new AndroidJavaClass("androidx.core.content.ContextCompat")) + { + int permissionStatus = permissionChecker.CallStatic("checkSelfPermission", activity, permission); + + if (permissionStatus != 0) // not granted + { + string[] permissions = new string[] { permission }; + using (AndroidJavaClass activityCompat = new AndroidJavaClass("androidx.core.app.ActivityCompat")) + { + activityCompat.CallStatic("requestPermissions", activity, permissions, 0); + } + } + } + } + } + } +#endif + } +} diff --git a/Assets/NotificationPermissionRequester.cs.meta b/Assets/NotificationPermissionRequester.cs.meta new file mode 100644 index 00000000..f3da9fa2 --- /dev/null +++ b/Assets/NotificationPermissionRequester.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee36348b412d6b340b8433894803846a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PipeOut/Scenes/Loading.unity b/Assets/PipeOut/Scenes/Loading.unity index 1f051794..3709de06 100644 --- a/Assets/PipeOut/Scenes/Loading.unity +++ b/Assets/PipeOut/Scenes/Loading.unity @@ -169,53 +169,6 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!21 &79986214 -Material: - serializedVersion: 8 - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: 2DxFX/Standard/Shiny_Reflect - m_Shader: {fileID: 4800000, guid: 6fc94ae14d17d3642b09718b5b932fd2, type: 3} - m_Parent: {fileID: 0} - m_ModifiedSerializedProperties: 0 - m_ValidKeywords: [] - m_InvalidKeywords: [] - m_LightmapFlags: 4 - m_EnableInstancingVariants: 0 - m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 - stringTagMap: {} - disabledShaderPasses: [] - m_LockedProperties: - m_SavedProperties: - serializedVersion: 3 - m_TexEnvs: - - _MainTex: - m_Texture: {fileID: 0} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - - _MainTex2: - m_Texture: {fileID: 2800000, guid: 6ed1aafd335608e48aa3198044a161df, type: 3} - m_Scale: {x: 1, y: 1} - m_Offset: {x: 0, y: 0} - m_Ints: [] - m_Floats: - - _Alpha: 0 - - _ColorMask: 15 - - _Distortion: 0.15873456 - - _Stencil: 0 - - _StencilComp: 8 - - _StencilOp: 0 - - _StencilReadMask: 255 - - _StencilWriteMask: 255 - - _Value2: 0.5 - - _Value3: 1 - - _Value4: 0 - m_Colors: - - _Color: {r: 1, g: 1, b: 1, a: 1} - m_BuildTextureStacks: [] --- !u!1 &83133762 GameObject: m_ObjectHideFlags: 0 @@ -2046,7 +1999,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: - m_Material: {fileID: 79986214} + m_Material: {fileID: 1728434433} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} @@ -2164,6 +2117,50 @@ Transform: m_Children: [] m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1466205355 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1466205357} + - component: {fileID: 1466205356} + m_Layer: 0 + m_Name: NotificationRequestor + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1466205356 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1466205355} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: ee36348b412d6b340b8433894803846a, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &1466205357 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1466205355} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 90} + 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!1001 &1467084552 PrefabInstance: m_ObjectHideFlags: 0 @@ -2361,6 +2358,53 @@ RectTransform: type: 3} m_PrefabInstance: {fileID: 1467084552} m_PrefabAsset: {fileID: 0} +--- !u!21 &1728434433 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: 2DxFX/Standard/Shiny_Reflect + m_Shader: {fileID: 4800000, guid: 6fc94ae14d17d3642b09718b5b932fd2, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex2: + m_Texture: {fileID: 2800000, guid: 6ed1aafd335608e48aa3198044a161df, type: 3} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - _Alpha: 0 + - _ColorMask: 15 + - _Distortion: -0.55730546 + - _Stencil: 0 + - _StencilComp: 8 + - _StencilOp: 0 + - _StencilReadMask: 255 + - _StencilWriteMask: 255 + - _Value2: 0.5 + - _Value3: 1 + - _Value4: 0 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + m_BuildTextureStacks: [] --- !u!1 &1797903891 GameObject: m_ObjectHideFlags: 0 @@ -2546,3 +2590,4 @@ SceneRoots: - {fileID: 1407567917} - {fileID: 1797903893} - {fileID: 11358293} + - {fileID: 1466205357} diff --git a/Assets/Plugins/Android/AndroidManifest.xml b/Assets/Plugins/Android/AndroidManifest.xml new file mode 100644 index 00000000..00610040 --- /dev/null +++ b/Assets/Plugins/Android/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + diff --git a/Assets/Plugins/Android/AndroidManifest.xml.meta b/Assets/Plugins/Android/AndroidManifest.xml.meta new file mode 100644 index 00000000..ac61b15c --- /dev/null +++ b/Assets/Plugins/Android/AndroidManifest.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 26f38cbdd19c5fa419a4157f06e71de7 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/HomeScene.cs b/Assets/Scripts/HomeScene.cs index c37ada7f..7b3516b3 100644 --- a/Assets/Scripts/HomeScene.cs +++ b/Assets/Scripts/HomeScene.cs @@ -135,10 +135,41 @@ public class HomeScene : MonoBehaviour } public void OnDisplayNameEntered() { - PlayFabManager.Instance.playFabLeaderboards.SetDisplayName(nameInputField.text); + string inputName = nameInputField.text; + string finalName = inputName; + + if (PlayerPrefs.GetInt("GuestMode", 0) == 1) + { + string customId = PlayerPrefs.GetString("GuestCustomID", ""); + string suffix = ""; + + if (customId.Length >= 3) + { + char[] last3 = customId.Substring(customId.Length - 3).ToCharArray(); + System.Text.StringBuilder cleanSuffix = new System.Text.StringBuilder(); + System.Random rand = new System.Random(); + + foreach (char c in last3) + { + cleanSuffix.Append(char.IsLetterOrDigit(c) ? c : rand.Next(0, 10).ToString()[0]); + } + + suffix = cleanSuffix.ToString(); + } + + finalName = inputName + suffix; + } + + // Set full name with suffix to leaderboard + PlayFabManager.Instance.playFabLeaderboards.SetDisplayName(finalName); + + // Store only clean name for UI use + SafePlayerPrefs.SetString(GameConstants.DisplayNameKey, finalName); SafePlayerPrefs.SetInt(GameConstants.NameEnteredCheckKey, 1); + NameEnterPanel.Close(); } + public void OnAvatarSelected(int AvatarID) { //PlayFabManager.Instance.playFabLeaderboards.SetDisplayName(nameInputField.text); diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 0decfe05..8dc47291 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -253,7 +253,7 @@ PlayerSettings: clonedFromGUID: 00000000000000000000000000000000 templatePackageId: templateDefaultScene: - useCustomMainManifest: 0 + useCustomMainManifest: 1 useCustomLauncherManifest: 0 useCustomMainGradleTemplate: 1 useCustomLauncherGradleManifest: 0