diff --git a/Editor/GuruManager/Helper/AndroidManifestMod.cs b/Editor/GuruManager/Helper/AndroidManifestMod.cs
index 6013807..d4e0c19 100644
--- a/Editor/GuruManager/Helper/AndroidManifestMod.cs
+++ b/Editor/GuruManager/Helper/AndroidManifestMod.cs
@@ -1,5 +1,3 @@
-using System.Collections;
-using Unity.EditorCoroutines.Editor;
namespace Guru.Editor
{
diff --git a/Editor/GuruManager/Manager/GuruSDKManager.cs b/Editor/GuruManager/Manager/GuruSDKManager.cs
index d7eb1b8..3d19fb5 100644
--- a/Editor/GuruManager/Manager/GuruSDKManager.cs
+++ b/Editor/GuruManager/Manager/GuruSDKManager.cs
@@ -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($"[Guru] file not found...");
}
+
+ _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(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
+
+
}
\ No newline at end of file
diff --git a/Editor/GuruManager/Model.meta b/Editor/GuruManager/Model.meta
new file mode 100644
index 0000000..c3e4d38
--- /dev/null
+++ b/Editor/GuruManager/Model.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 7f9d1111a9d94187bf583ae71d9192f0
+timeCreated: 1711858346
\ No newline at end of file
diff --git a/Editor/GuruManager/Model/EditorDataFile.cs b/Editor/GuruManager/Model/EditorDataFile.cs
new file mode 100644
index 0000000..5d17ee7
--- /dev/null
+++ b/Editor/GuruManager/Model/EditorDataFile.cs
@@ -0,0 +1,116 @@
+namespace Guru.Editor
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+
+ public class EaseConfigFile
+ {
+ private Dictionary _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(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(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 lines = new List(_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(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;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Editor/GuruManager/Model/EditorDataFile.cs.meta b/Editor/GuruManager/Model/EditorDataFile.cs.meta
new file mode 100644
index 0000000..d72cf82
--- /dev/null
+++ b/Editor/GuruManager/Model/EditorDataFile.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 58ea378c89d742008a18f019afd54a27
+timeCreated: 1711858357
\ No newline at end of file
diff --git a/Runtime/Code/Config/GuruServicesConfig.cs b/Runtime/Code/Config/GuruServicesConfig.cs
index 0ca4d99..99dd8c9 100644
--- a/Runtime/Code/Config/GuruServicesConfig.cs
+++ b/Runtime/Code/Config/GuruServicesConfig.cs
@@ -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]