diff --git a/Runtime/Editor/ProjectSettings.cs b/Runtime/Editor/ProjectSettings.cs index 7985d623..beba73ba 100644 --- a/Runtime/Editor/ProjectSettings.cs +++ b/Runtime/Editor/ProjectSettings.cs @@ -1,5 +1,6 @@ #if UNITY_EDITOR using System.Collections.Generic; +using System.IO; using System.Text.RegularExpressions; using UnityEditor; using UnityEngine; @@ -9,11 +10,13 @@ namespace LootLocker.Admin { public class ProjectSettings : SettingsProvider { + private static LootLockerConfig gameSettings; private SerializedObject m_CustomSettings; public delegate void SendAttributionDelegate(); public static event SendAttributionDelegate APIKeyEnteredEvent; + public static event SendAttributionDelegate DomainKeyEnteredEvent; internal static SerializedObject GetSerializedSettings() { if (gameSettings == null) @@ -78,6 +81,7 @@ private void DrawGameSettings() if (EditorGUI.EndChangeCheck()) { gameSettings.apiKey = m_CustomSettings.FindProperty("apiKey").stringValue; + APIKeyEnteredEvent?.Invoke(); } var content = new GUIContent(); @@ -91,6 +95,8 @@ private void DrawGameSettings() if (EditorGUI.EndChangeCheck()) { gameSettings.domainKey = m_CustomSettings.FindProperty("domainKey").stringValue; + DomainKeyEnteredEvent?.Invoke(); + m_CustomSettings.FindProperty("domainKey").stringValue = gameSettings.domainKey; } var domainContent = new GUIContent(); domainContent.text = "Domain key can be found in `Settings > API Keys` in the Web Console: https://console.lootlocker.com/settings/api-keys"; diff --git a/Runtime/Game/LootLockerSDKManager.cs b/Runtime/Game/LootLockerSDKManager.cs index 80107ba9..d20c87fe 100644 --- a/Runtime/Game/LootLockerSDKManager.cs +++ b/Runtime/Game/LootLockerSDKManager.cs @@ -68,6 +68,7 @@ static bool LoadConfig() } if (string.IsNullOrEmpty(LootLockerConfig.current.apiKey)) { + LootLockerConfig.Get(); LootLockerLogger.GetForLogLevel(LootLockerLogger.LogLevel.Error)("API Key has not been set, set it in project settings or manually calling Init(string apiKey, string gameVersion, bool onDevelopmentMode, string domainKey)"); return false; } diff --git a/Runtime/Game/Resources/LootLockerConfig.cs b/Runtime/Game/Resources/LootLockerConfig.cs index aee6fb00..a3a7e27d 100644 --- a/Runtime/Game/Resources/LootLockerConfig.cs +++ b/Runtime/Game/Resources/LootLockerConfig.cs @@ -1,10 +1,14 @@ using System; using System.IO; +using System.Linq; #if UNITY_EDITOR +using System.Collections.Generic; using UnityEditor; using UnityEditor.PackageManager; using UnityEditor.PackageManager.Requests; using UnityEditor.PackageManager.UI; +using LootLocker.Admin; +using System.Text.RegularExpressions; #endif using UnityEngine; @@ -12,26 +16,55 @@ namespace LootLocker { public class LootLockerConfig : ScriptableObject + { private static LootLockerConfig settingsInstance; public virtual string SettingName { get { return "LootLockerConfig"; } } +#if UNITY_EDITOR + private void OnEnable() + { + ProjectSettings.APIKeyEnteredEvent += WriteConfigToDisk; + ProjectSettings.DomainKeyEnteredEvent += WriteConfigToDisk; + } + + private void OnDisable() + { + ProjectSettings.APIKeyEnteredEvent -= WriteConfigToDisk; + ProjectSettings.DomainKeyEnteredEvent -= WriteConfigToDisk; + } +#endif public static LootLockerConfig Get() { if (settingsInstance != null) { +#if UNITY_EDITOR + if (string.IsNullOrEmpty(settingsInstance.apiKey)) + { + string filePath = "Assets/LootLockerSDK/Resources/Config/Editor/PersistedLootLockerConfig.txt"; + + if (File.Exists(filePath) && EditorPrefs.GetBool("LootLocker.HasWrittenConfigFirstTime", false)) + { + settingsInstance.apiKey = File.ReadLines(filePath).ElementAt(0); + settingsInstance.domainKey = File.ReadLines(filePath).ElementAt(1); //Gets domainkey + settingsInstance.deviceID = File.ReadLines(filePath).ElementAt(2); + } + } +#endif settingsInstance.ConstructUrls(); #if LOOTLOCKER_COMMANDLINE_SETTINGS settingsInstance.CheckForSettingOverrides(); #endif + return settingsInstance; } //Try to load it settingsInstance = Resources.Load("Config/LootLockerConfig"); + #if UNITY_EDITOR // Could not be loaded, create it if (settingsInstance == null) @@ -40,7 +73,7 @@ public static LootLockerConfig Get() LootLockerConfig newConfig = ScriptableObject.CreateInstance(); // Folder needs to exist for Unity to be able to create an asset in it - string dir = Application.dataPath+ "/LootLockerSDK/Resources/Config"; + string dir = Application.dataPath + "/LootLockerSDK/Resources/Config"; // If directory does not exist, create it if (!Directory.Exists(dir)) @@ -54,6 +87,13 @@ public static LootLockerConfig Get() EditorApplication.delayCall += AssetDatabase.SaveAssets; AssetDatabase.Refresh(); settingsInstance = newConfig; + + string diskConfigPath = "Asset/LootLockerSDK/Resources/Config/Editor/"; + if (!Directory.Exists(diskConfigPath)) + { + Directory.CreateDirectory(diskConfigPath); + File.Create(diskConfigPath + "PersistedLootLockerConfig.txt").Close(); + } } #else @@ -100,7 +140,6 @@ private void CheckForSettingOverrides() [InitializeOnLoadMethod] static void CreateConfigFile() { - // Get the path to the project directory string projectPath = Application.dataPath; @@ -115,6 +154,69 @@ static void CreateConfigFile() EditorPrefs.SetBool(configFileEditorPref, true); } } +#if UNITY_EDITOR + static void WriteConfigToDisk() + { + //Check for an already existing persistent config file + string fileDirectory = "Assets/LootLockerSDK/Resources/Config/Editor/"; + string filePath = fileDirectory + "PersistedLootLockerConfig.txt"; + + if(!Directory.Exists(fileDirectory)) + { + Directory.CreateDirectory(fileDirectory); + File.Create(filePath).Close(); + } + else if(!File.Exists(filePath)) + { + File.Create(filePath).Close(); + + } + + var tempConfig = Get(); + + List config = new List(); + + if (!string.IsNullOrEmpty(tempConfig.apiKey)) + { + config.Add(tempConfig.apiKey); + } + + if (!string.IsNullOrEmpty(tempConfig.domainKey)) + { + string pattern = @"(?<=https://)\w+(?=\.api\.lootlocker\.io/)"; + Regex regex = new Regex(pattern); + Match match = regex.Match(tempConfig.domainKey); + + if (match.Success) + { + string domainkey = match.Value; + Debug.LogWarning("You accidentally used the domain url instead of the domain key,\nWe took the domain key from the url.: " + domainkey); + tempConfig.domainKey = domainkey; + config.Add(domainkey); + } + else + { + config.Add(tempConfig.domainKey); + } + } + if(!string.IsNullOrEmpty(tempConfig.deviceID)) + { + config.Add(tempConfig.deviceID); + } + + if (config.Count > 1) + { + using(StreamWriter sw = new StreamWriter(filePath)) + { + foreach (var s in config) + { + sw.WriteLine(s); + } + } + EditorPrefs.SetBool("LootLocker.HasWrittenDiskFirstTime", true); + } + } +#endif protected static ListRequest ListInstalledPackagesRequest; @@ -267,6 +369,7 @@ static void OnEnterPlaymodeInEditor(EnterPlayModeOptions options) { _current = null; } + #endif } } \ No newline at end of file diff --git a/package.json b/package.json index 40c0a45b..0501a3dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "com.lootlocker.lootlockersdk", - "version": "2.1.5", + "version": "2.1.6", "displayName": "LootLocker", "description": "LootLocker is a game backend-as-a-service with plug and play tools to upgrade your game and give your players the best experience possible. Designed for teams of all shapes and sizes, on mobile, PC and console. From solo developers, indie teams, AAA studios, and publishers. Built with cross-platform in mind.\n\n\u25AA Manage your game\nSave time and upgrade your game with leaderboards, progression, and more. Completely off-the-shelf features, built to work with any game and platform.\n\n\u25AA Manage your content\nTake charge of your game's content on all platforms, in one place. Sort, edit and manage everything, from cosmetics to currencies, UGC to DLC. Without breaking a sweat.\n\n\u25AA Manage your players\nStore your players' data together in one place. Access their profile and friends list cross-platform. Manage reports, messages, refunds and gifts to keep them hooked.\n", "unity": "2019.2",