Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong domain key logging and writing config to disk #254

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions Runtime/Editor/ProjectSettings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#if UNITY_EDITOR
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
Expand All @@ -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)
Expand Down Expand Up @@ -78,6 +81,7 @@ private void DrawGameSettings()
if (EditorGUI.EndChangeCheck())
{
gameSettings.apiKey = m_CustomSettings.FindProperty("apiKey").stringValue;
APIKeyEnteredEvent?.Invoke();
}

var content = new GUIContent();
Expand All @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I understand m_CustomSettings will be recreated from gameSettings next frame right? So why set this?

}
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";
Expand Down
1 change: 1 addition & 0 deletions Runtime/Game/LootLockerSDKManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
107 changes: 105 additions & 2 deletions Runtime/Game/Resources/LootLockerConfig.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,70 @@
using System;
using System.IO;
using System.Linq;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you really using 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;

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
Comment on lines +26 to +38
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I need to be taught how all this works. We have more settings than api key and domain key. Game version for example is a game breaking setting that needs to be persisted.

public static LootLockerConfig Get()
{
if (settingsInstance != null)
{
#if UNITY_EDITOR
if (string.IsNullOrEmpty(settingsInstance.apiKey))
{
string filePath = "Assets/LootLockerSDK/Resources/Config/Editor/PersistedLootLockerConfig.txt";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're writing to disk, then why not use something like .ini that is a standard for configuration?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either that, or simply write LootLockerConfig as a serizialized json and then we can deserialize the object straight into an instance when reading?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, here you hard code the file path but below you use Application.dataPath. These risk not being the same. Please settle for one.


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<LootLockerConfig>("Config/LootLockerConfig");


#if UNITY_EDITOR
// Could not be loaded, create it
if (settingsInstance == null)
Expand All @@ -40,7 +73,7 @@ public static LootLockerConfig Get()
LootLockerConfig newConfig = ScriptableObject.CreateInstance<LootLockerConfig>();

// 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))
Expand All @@ -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
Expand Down Expand Up @@ -100,7 +140,6 @@ private void CheckForSettingOverrides()
[InitializeOnLoadMethod]
static void CreateConfigFile()
{

// Get the path to the project directory
string projectPath = Application.dataPath;

Expand All @@ -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/";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really should create these once statically I feel like and then just reuse the paths instead of typing it out like this every time.

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();

}
Comment on lines +164 to +173
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!Directory.Exists(fileDirectory))
{
Directory.CreateDirectory(fileDirectory);
File.Create(filePath).Close();
}
else if(!File.Exists(filePath))
{
File.Create(filePath).Close();
}
if(!Directory.Exists(fileDirectory))
{
Directory.CreateDirectory(fileDirectory);
}
if(!File.Exists(filePath))
{
File.Create(filePath).Close();
}


var tempConfig = Get();

List<string> config = new List<string>();

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to be explicit about this. They should figure it out when the input changes.

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;

Expand Down Expand Up @@ -267,6 +369,7 @@ static void OnEnterPlaymodeInEditor(EnterPlayModeOptions options)
{
_current = null;
}

#endif
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down