update: 新增设置 KeyStore 功能
							parent
							
								
									17ea49120a
								
							
						
					
					
						commit
						ac3f88422a
					
				|  | @ -1,5 +1,3 @@ | |||
| using System.Collections; | ||||
| using Unity.EditorCoroutines.Editor; | ||||
| 
 | ||||
| namespace Guru.Editor | ||||
| { | ||||
|  |  | |||
|  | @ -14,9 +14,12 @@ namespace Guru.Editor | |||
|         private const string GURU_SETTINGS_PATH = "Assets/Guru/Resources/GuruSettings.asset"; | ||||
|         private const string APPLOVIN_SETTINGS_PATH = "Assets/Guru/Resources/AppLovinSettings.asset"; | ||||
|         private const string FACEBOOK_SETTINGS_PATH = "Assets/FacebookSDK/SDK/Resources/FacebookSettings.asset"; | ||||
|         private const string ANDROID_KEYSTORE_PATH = "Assets/Plugins/Android/guru_key.jks"; | ||||
|         private const string ANDROID_PLUGINS_DIR = "Assets/Plugins/Android"; | ||||
|         private const string KeyMaxAutoUpdateEnabled = "com.applovin.auto_update_enabled"; | ||||
|          | ||||
|         private static string ANDROID_KEYSTORE_NAME = "guru_key.jks"; | ||||
|         private static string GuruKeyStore => $"{ANDROID_PLUGINS_DIR}/{ANDROID_KEYSTORE_NAME}"; | ||||
| 
 | ||||
|          | ||||
|         private static GuruSDKManager _instance; | ||||
|         public static GuruSDKManager Instance { | ||||
|  | @ -53,10 +56,12 @@ namespace Guru.Editor | |||
| 
 | ||||
|         private bool _hasCheckingCompleted = false; | ||||
| 
 | ||||
|         private SDKMgrModel _model; | ||||
| 
 | ||||
| 
 | ||||
|         public GuruSDKManager() | ||||
|         { | ||||
|             this.minSize = new Vector2(480, 640); | ||||
|             this.minSize = new Vector2(480, 680); | ||||
|         } | ||||
|          | ||||
| 
 | ||||
|  | @ -79,6 +84,16 @@ namespace Guru.Editor | |||
|             { | ||||
|                 Debug.Log($"<color=red>[Guru] <guru-services> file not found...</color>"); | ||||
|             } | ||||
|              | ||||
|             _model ??= SDKMgrModel.Load(); | ||||
| 
 | ||||
|             InitPushIcon(); | ||||
| 
 | ||||
|             if (_servicesConfig?.UseCustomKeystore() ?? false) | ||||
|             { | ||||
|                 InitCustomKeystore(); | ||||
|             } | ||||
|              | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -165,6 +180,10 @@ namespace Guru.Editor | |||
|                         AddResultLine($"{MARK_INDENT}{mk_no} Support Email is missing!", CheckStatus.Failed); | ||||
|                         _serviceNormalFail++; | ||||
|                     } | ||||
|                     if (_servicesConfig.app_settings.custom_keystore) | ||||
|                     { | ||||
|                         AddResultLine($"{MARK_INDENT}{mk_warn} Using Custom Keystore.", CheckStatus.Warning); | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|                 if (passed) AddResultLine(check_passed); | ||||
|  | @ -395,10 +414,17 @@ namespace Guru.Editor | |||
|                 GUI_OnConfigEnabled(); | ||||
|             } | ||||
|              | ||||
|             GUILayout.Space(10); | ||||
|             // Push | ||||
|             GUI_PushIconMaker();  | ||||
|              | ||||
|             GUILayout.Space(10); | ||||
|             GUI_PushIconMaker(); | ||||
| 
 | ||||
|             // Keystore | ||||
|             if (_servicesConfig != null && _servicesConfig.UseCustomKeystore()) | ||||
|             { | ||||
|                 GUILayout.Space(10); | ||||
|                 GUI_CustomKeystore(); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         private void GUI_WindowTitle() | ||||
|  | @ -493,9 +519,10 @@ namespace Guru.Editor | |||
|             ImportFacebookSettings(); | ||||
|             progress += 0.2f; | ||||
|             EditorUtility.DisplayCancelableProgressBar(barTitle, "FacebookSettings is done", progress); | ||||
|              | ||||
|              | ||||
|             CheckAndroidKeyStore(); | ||||
|             EditorGuruServiceIO.DeployLocalServiceFile(); // 部署文件 | ||||
|             progress += 0.1f; | ||||
|             EditorUtility.DisplayCancelableProgressBar(barTitle, "Deploy service file...", progress); | ||||
|              | ||||
|             AssetDatabase.SaveAssets(); | ||||
|              | ||||
|  | @ -869,10 +896,18 @@ namespace Guru.Editor | |||
|                 n.InsertArrayElementAtIndex(0); | ||||
|                 n.GetArrayElementAtIndex(0).stringValue = _servicesConfig.fb_settings.fb_client_token; | ||||
|             } | ||||
|              | ||||
| 
 | ||||
| 
 | ||||
|             string ks_path = GuruKeyStore; | ||||
|             if (_servicesConfig?.UseCustomKeystore() ?? false) | ||||
|             { | ||||
|                 ks_path = _model?.KeyStorePath ?? ""; | ||||
|             } | ||||
|             n = so.FindProperty("androidKeystorePath"); | ||||
|             n.stringValue = ANDROID_KEYSTORE_PATH; | ||||
|             DeployKeystore(); | ||||
|             if (n != null && File.Exists(ks_path)) | ||||
|             { | ||||
|                 n.stringValue = ks_path; | ||||
|             } | ||||
|              | ||||
|             Facebook.Unity.Editor.ManifestMod.GenerateManifest(); // 重新生成 Manifest | ||||
|              | ||||
|  | @ -881,11 +916,20 @@ namespace Guru.Editor | |||
|             AssetDatabase.SaveAssetIfDirty(settings); | ||||
|         } | ||||
| 
 | ||||
|         //------------------------- Androi Keystore ---------------------------------- | ||||
| 
 | ||||
|         private void DeployKeystore() | ||||
|         private void CheckAndroidKeyStore() | ||||
|         { | ||||
|             if (!_servicesConfig.UseCustomKeystore()) | ||||
|             { | ||||
|                 DeployGuruKeystore(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void DeployGuruKeystore() | ||||
|         { | ||||
|             var from = "Packages/com.guru.unity.sdk.core/Editor/BuildTool/guru_key.jks"; | ||||
|             var to = ANDROID_KEYSTORE_PATH.Replace("Assets", Application.dataPath); | ||||
|             var to = GuruKeyStore.Replace("Assets", Application.dataPath); | ||||
|             if (File.Exists(from) && !File.Exists(to)) | ||||
|             { | ||||
|                 File.Copy(from, to); | ||||
|  | @ -896,14 +940,12 @@ namespace Guru.Editor | |||
|         private void ApplyMods() | ||||
|         { | ||||
|             PlayerSettings.applicationIdentifier = _servicesConfig.app_settings.bundle_id; // 设置包名 | ||||
| 
 | ||||
| // #if UNITY_ANDROID | ||||
|              | ||||
|             //-------- 部署 Android 相关的文件和资源 ---------- | ||||
|             AndroidManifestMod.Apply(); | ||||
|             AndroidProjectMod.Apply(); | ||||
|             AndroidResMod.Apply(); // 部署 GuruSDKRes 资源文件, 目前部署在 guru.sdk.core 的 Plugins/Android/SDKRes.androidlib 中 | ||||
| // #endif | ||||
| 
 | ||||
|              | ||||
|             AssetDatabase.Refresh(); | ||||
|         } | ||||
| 
 | ||||
|  | @ -1009,23 +1051,37 @@ namespace Guru.Editor | |||
|         #region Push Icon Maker | ||||
| 
 | ||||
|         private bool _showSegmentPush = false; | ||||
|         private Texture2D _pushIconTexture; | ||||
|         private Texture2D _pushIconSource; | ||||
|         private Color _pushIconColor = Color.white; | ||||
|          | ||||
|         private void InitPushIcon() | ||||
|         { | ||||
|             if (_pushIconSource == null) | ||||
|             { | ||||
|                 var path = _model?.PushIconPath ?? ""; | ||||
|                 if(!string.IsNullOrEmpty(path)) | ||||
|                 { | ||||
|                     _pushIconSource = AssetDatabase.LoadAssetAtPath<Texture2D>(path); | ||||
|                 } | ||||
|                  | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         private void GUI_PushIconMaker() | ||||
|         { | ||||
|             float btnH = 24; | ||||
|              | ||||
|             _showSegmentPush = EditorGUILayout.Foldout(_showSegmentPush, "[ Android Push Icon ]"); | ||||
|              | ||||
|              | ||||
|             // EditorGUILayout.LabelField("[ Push Icon ]", StyleItemTitle); | ||||
| 
 | ||||
|             _showSegmentPush = EditorGUILayout.Foldout(_showSegmentPush, "[ Android Push Icon ]"); | ||||
|             if (_showSegmentPush) | ||||
|             { | ||||
|                 EditorGUI.indentLevel++; | ||||
|                  | ||||
|                 EditorGUILayout.BeginHorizontal("box"); | ||||
|                 EditorGUILayout.LabelField("Icon ( 96x96 PNG )"); | ||||
|                 _pushIconTexture = EditorGUILayout.ObjectField( _pushIconTexture, typeof(Texture2D), false) as Texture2D; | ||||
|                 _pushIconSource = EditorGUILayout.ObjectField( _pushIconSource, typeof(Texture2D), false) as Texture2D; | ||||
|                 EditorGUILayout.EndHorizontal(); | ||||
|                  | ||||
|                 EditorGUILayout.BeginHorizontal("box"); | ||||
|  | @ -1033,13 +1089,15 @@ namespace Guru.Editor | |||
|                 _pushIconColor = EditorGUILayout.ColorField(_pushIconColor); | ||||
|                 EditorGUILayout.EndHorizontal(); | ||||
|              | ||||
|                 if (null != _pushIconTexture) | ||||
|                 if (null != _pushIconSource) | ||||
|                 { | ||||
|                     GUI_Button("CREATE PUSH ASSETS", () => | ||||
|                     { | ||||
|                         if (AndroidPushIconHelper.SetPushIconAssets(_pushIconTexture, _pushIconColor)) | ||||
|                         if (AndroidPushIconHelper.SetPushIconAssets(_pushIconSource, _pushIconColor)) | ||||
|                         { | ||||
|                             EditorUtility.DisplayDialog("Set Push Icon", "Push Icon assets created success!", "OK"); | ||||
|                             var path = AssetDatabase.GetAssetPath(_pushIconSource); | ||||
|                             if(_model != null) _model.PushIconPath = path; | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|  | @ -1049,16 +1107,161 @@ namespace Guru.Editor | |||
|                         _showSegmentPush = false; | ||||
|                     }, null, GUILayout.Height(btnH)); | ||||
|                 } | ||||
|                  | ||||
|                 EditorGUI.indentLevel--; | ||||
|             } | ||||
| 
 | ||||
|              | ||||
|         } | ||||
|          | ||||
|         #endregion | ||||
| 
 | ||||
|         #region Custom Keystore | ||||
| 
 | ||||
|         private bool _showSegmentCustomKeystore = false; | ||||
|         private string _androidKeystorePath = ""; | ||||
|          | ||||
|          | ||||
|         private void InitCustomKeystore() | ||||
|         { | ||||
|             if (_model != null) | ||||
|             { | ||||
|                 if (!string.IsNullOrEmpty(_model.KeyStorePath)) | ||||
|                 { | ||||
|                     _androidKeystorePath = _model.KeyStorePath; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void GUI_CustomKeystore() | ||||
|         { | ||||
|             float btnH = 24; | ||||
|             _showSegmentCustomKeystore = EditorGUILayout.Foldout(_showSegmentCustomKeystore, "[ Android Keystore ]"); | ||||
|             if (_showSegmentCustomKeystore) | ||||
|             { | ||||
|                 EditorGUI.indentLevel++; | ||||
|                  | ||||
|                 EditorGUILayout.BeginHorizontal("box"); | ||||
|                 EditorGUILayout.LabelField("Keystore Path"); | ||||
|                 _androidKeystorePath = EditorGUILayout.TextField(_androidKeystorePath); | ||||
|                 if (GUILayout.Button("...", GUILayout.Width(24))) | ||||
|                 { | ||||
|                     var path = EditorUtility.OpenFilePanel("Select Keystore File", Path.GetFullPath($"{Application.dataPath}/Plugins/Android"), "jks"); | ||||
|                     if(File.Exists(path) && path != _androidKeystorePath) | ||||
|                     { | ||||
|                         _androidKeystorePath = path; | ||||
|                     } | ||||
|                 } | ||||
|                 EditorGUILayout.EndHorizontal(); | ||||
|                  | ||||
|                 if (!string.IsNullOrEmpty(_androidKeystorePath)) | ||||
|                 { | ||||
|                     GUI_Button("SET KEYSTORE", () => | ||||
|                     { | ||||
|                         if (ApplyCustomKeystore(_androidKeystorePath)) | ||||
|                         { | ||||
|                             EditorUtility.DisplayDialog("Set Keystore", "Keystore path set success!", "OK"); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             EditorUtility.DisplayDialog("Set Keystore", "Keystore file not found!", "Well..."); | ||||
|                         } | ||||
|                     }, null, GUILayout.Height(btnH)); | ||||
|                 } | ||||
|                  | ||||
|                 EditorGUI.indentLevel--; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private bool ApplyCustomKeystore(string storePath) | ||||
|         { | ||||
|             if (!string.IsNullOrEmpty(storePath)) | ||||
|             { | ||||
|                 var file = new FileInfo(storePath); | ||||
|                 if (file.Exists) | ||||
|                 { | ||||
|                     var from = storePath; | ||||
|                     var setPath = $"{ANDROID_PLUGINS_DIR}/{file.Name}"; | ||||
|                     var to = setPath.Replace("Assets", Application.dataPath); | ||||
|                     Debug.Log($"---- fileName: {file.Name}"  ); | ||||
|                     if (!File.Exists(to)) | ||||
|                     { | ||||
|                         File.Copy(from, to); | ||||
|                     } | ||||
| 
 | ||||
|                     if (File.Exists(to)) | ||||
|                     { | ||||
|                         _model.KeyStorePath = setPath; | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         #endregion | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     #region EditorModel | ||||
|      | ||||
|     [Serializable] | ||||
|     internal class SDKMgrModel: EaseConfigFile | ||||
|     { | ||||
|         private const string ModelFileName = "guru_sdkmgr.settings"; | ||||
|         private const string ModelDirName = "guru/editor"; | ||||
|         private static string ModelDirPath => Path.GetFullPath($"{Application.dataPath.Replace("Assets", "ProjectSettings")}/{ModelDirName}"); | ||||
|         private static string ModelFilePath => Path.GetFullPath($"{ModelDirPath}/{ModelFileName}"); | ||||
| 
 | ||||
| 
 | ||||
|         private string _pushIconPath = "push_icon_path"; | ||||
|         private string _pushIconPathValue; | ||||
|         public string PushIconPath | ||||
|         { | ||||
|             get => _pushIconPathValue; | ||||
|             set | ||||
|             { | ||||
|                 _pushIconPathValue = value; | ||||
|                 Set(_pushIconPath, _pushIconPathValue); | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         private string _keyStorePath = "keystore_path"; | ||||
|         private string _keyStorePathValue; | ||||
|         public string KeyStorePath | ||||
|         { | ||||
|             get => _keyStorePathValue; | ||||
|             set | ||||
|             { | ||||
|                 _keyStorePathValue = value; | ||||
|                 Set(_keyStorePath, _keyStorePathValue); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public SDKMgrModel() | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         public SDKMgrModel(string filePath) | ||||
|         { | ||||
|             ReadFile(ModelFilePath); | ||||
| 
 | ||||
|             _pushIconPathValue = Get(_pushIconPath); | ||||
|             _keyStorePathValue = Get(_keyStorePath); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         public static SDKMgrModel Load() | ||||
|         { | ||||
|             return new SDKMgrModel(ModelFilePath); | ||||
|         } | ||||
|          | ||||
|     } | ||||
| 
 | ||||
|     #endregion | ||||
|      | ||||
|      | ||||
| } | ||||
|  | @ -0,0 +1,3 @@ | |||
| fileFormatVersion: 2 | ||||
| guid: 7f9d1111a9d94187bf583ae71d9192f0 | ||||
| timeCreated: 1711858346 | ||||
|  | @ -0,0 +1,116 @@ | |||
| namespace Guru.Editor | ||||
| { | ||||
|     using System; | ||||
|     using System.Collections.Generic; | ||||
|     using System.IO; | ||||
|      | ||||
|     public class EaseConfigFile | ||||
|     { | ||||
|         private Dictionary<string, string> _dataDict; | ||||
|         private string _filePath; | ||||
| 
 | ||||
|         protected bool ReadFile(string path) | ||||
|         { | ||||
|             _filePath = path; | ||||
|              | ||||
|             if (File.Exists(path)) | ||||
|             { | ||||
|                 var lines = File.ReadAllLines(path); | ||||
|                 int len = lines.Length; | ||||
|                 _dataDict = new Dictionary<string, string>(len); | ||||
| 
 | ||||
|                 string key = ""; | ||||
|                 string value = ""; | ||||
|                  | ||||
|                 for (int i=0; i< len; i++) | ||||
|                 { | ||||
|                     var line = lines[i]; | ||||
|                     if (line.Contains("=")) | ||||
|                     { | ||||
|                         key = ""; | ||||
|                         value = ""; | ||||
|                         var kv = line.Split('='); | ||||
|                         if(kv.Length > 0) key = kv[0]; | ||||
|                         if(kv.Length > 1) value = kv[1]; | ||||
|                         if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value)) | ||||
|                         { | ||||
|                             _dataDict[key] = value; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 return true; | ||||
|             } | ||||
|              | ||||
|             _dataDict = new Dictionary<string, string>(10); | ||||
|             var dir = Directory.GetParent(path); | ||||
|             if(dir is { Exists: false }) dir.Create(); | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         public void Save() | ||||
|         { | ||||
|             if (_dataDict == null || _dataDict.Count < 1) return; | ||||
| 
 | ||||
|             List<string> lines = new List<string>(_dataDict.Count); | ||||
|             foreach (var key in _dataDict.Keys) | ||||
|             { | ||||
|                 lines.Add($"{key}={_dataDict[key].ToString()}"); | ||||
|             } | ||||
|              | ||||
|             if(!string.IsNullOrEmpty(_filePath)) | ||||
|                 File.WriteAllLines(_filePath, lines); | ||||
|         } | ||||
|          | ||||
|         public void Set(string key, object value) | ||||
|         { | ||||
|             if (_dataDict == null) _dataDict = new Dictionary<string, string>(10); | ||||
|             _dataDict[key] = value.ToString(); | ||||
|             Save(); | ||||
|         } | ||||
| 
 | ||||
|         public string Get(string key) => _dataDict.ContainsKey(key) ? _dataDict[key] : ""; | ||||
| 
 | ||||
|         public bool TryGet(string key, out string value) | ||||
|         { | ||||
|             value = ""; | ||||
|             return _dataDict?.TryGetValue(key, out value) ?? false; | ||||
|         } | ||||
| 
 | ||||
|         public bool GetBool(string key, bool defaultVal = false) | ||||
|         { | ||||
|             if (TryGet(key, out var str)) | ||||
|             { | ||||
|                 return (str.ToLower() == "true" || str == "1"); | ||||
|             } | ||||
|             return defaultVal; | ||||
|         } | ||||
|          | ||||
|          | ||||
|         public int GetInt(string key, int defaultVal = 0) | ||||
|         { | ||||
|             if (TryGet(key, out var str)) | ||||
|             { | ||||
|                 var inVal = 0; | ||||
|                 if (int.TryParse(str, out inVal)) | ||||
|                 { | ||||
|                     return inVal; | ||||
|                 } | ||||
|             } | ||||
|             return defaultVal; | ||||
|         } | ||||
|          | ||||
|         public float GetFloat(string key, float defaultVal = 0) | ||||
|         { | ||||
|             if (TryGet(key, out var str)) | ||||
|             { | ||||
|                 float val = 0; | ||||
|                 if (float.TryParse(str, out val)) | ||||
|                 { | ||||
|                     return val; | ||||
|                 } | ||||
|             } | ||||
|             return defaultVal; | ||||
|         } | ||||
|          | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,3 @@ | |||
| fileFormatVersion: 2 | ||||
| guid: 58ea378c89d742008a18f019afd54a27 | ||||
| timeCreated: 1711858357 | ||||
|  | @ -42,6 +42,7 @@ namespace Guru | |||
|                                               ad_settings.tradplus_ids_ios.Length > 0; | ||||
|         public bool IsIAPEnabled() => app_settings != null && app_settings.enable_iap  | ||||
|                                                            && products != null && products.Length > 0; | ||||
|         public bool UseCustomKeystore() => app_settings?.custom_keystore ?? false; | ||||
|          | ||||
|         public bool IsFirebaseEnabled() => app_settings?.enable_firebase ?? true; | ||||
|         public bool IsFacebookEnabled() => app_settings?.enable_facebook ?? true; | ||||
|  | @ -82,6 +83,7 @@ namespace Guru | |||
|         public bool enable_facebook = true; | ||||
|         public bool enable_adjust = true; | ||||
|         public bool enable_iap = false; | ||||
|         public bool custom_keystore = false; | ||||
|     } | ||||
| 
 | ||||
|     [Serializable] | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue