diff --git a/PulsarModLoader/SaveValue.cs b/PulsarModLoader/SaveValue.cs index 853fa64..380499e 100644 --- a/PulsarModLoader/SaveValue.cs +++ b/PulsarModLoader/SaveValue.cs @@ -4,11 +4,35 @@ using System.IO; using System.Reflection; using Valve.Newtonsoft.Json; +using Valve.Newtonsoft.Json.Linq; namespace PulsarModLoader { + [HarmonyPatch] internal class SaveValueManager { + [HarmonyPostfix] + [HarmonyPatch(typeof(PLGlobal), "OnApplicationQuit")] + private static void ForceSaveAllConfigsOnApplicationQuit() + { + PulsarModLoader.Utilities.Logger.Info("OnApplicationQuit"); + foreach(object saveValue in AllSaveValues) + { + var type = saveValue.GetType(); + var id = (string)AccessTools.Field(type, "id").GetValue(saveValue); + var mod = (Assembly)AccessTools.Field(type, "mod").GetValue(saveValue); + var value = AccessTools.Field(type, "_value").GetValue(saveValue); + ModToCacheValues[mod][id] = JToken.FromObject(value); + } + + foreach(KeyValuePair keyValuePair in ModToCacheValues) + { + Assembly mod = keyValuePair.Key; + var cfg = GetConfigFile(mod); + File.WriteAllText(cfg, JsonConvert.SerializeObject(ModToCacheValues[mod], serializerSettings)); + } + } + public static string GetConfigFolder() { string ModConfigDir = Path.Combine(Directory.GetCurrentDirectory(), "ModConfigs"); @@ -26,37 +50,26 @@ static SaveValueManager() serializerSettings.Formatting = Formatting.Indented; } - internal static void SaveValueFor(string id, Assembly mod, string value) + internal static T GetValueFor(SaveValue saveValue, T @default) { - ModToCacheValues[mod][id] = value; - var cfg = GetConfigFile(mod); - File.WriteAllText(cfg, JsonConvert.SerializeObject(ModToCacheValues[mod], serializerSettings)); - } + AllSaveValues.Add(saveValue); - internal static T GetValueFor(string id, Assembly mod, T @default) - { - var cfg = GetConfigFile(mod); - if (ModToCacheValues.TryGetValue(mod, out var values)) + var cfg = GetConfigFile(saveValue.mod); // Trying to open a config (Read | create a new one | take it from the cache) + + if (ModToCacheValues.TryGetValue(saveValue.mod, out JObject values)) // try to access the processed configuration { - if (values.TryGetValue(id, out var ret)) - { - if (@default is Enum) - return (T)Enum.Parse(typeof(T), ret); - - return (T)AccessTools.Method(@default.GetType(), "Parse", new Type[] { typeof(string) }) - .Invoke(null, new[] { ret }); - } + if (values.TryGetValue(saveValue.id, out JToken value)) // If it contains our field + return value.ToObject(); // then parse and return + // otherwise add a default value to values and return it } - else + else // If there is no such thing { - ModToCacheValues.Add(mod, new Dictionary()); - ModToCacheValues[mod].Add(id, @default.ToString()); - File.WriteAllText(cfg, JsonConvert.SerializeObject(ModToCacheValues[mod], serializerSettings)); - return @default; + ModToCacheValues.Add(saveValue.mod, new JObject()); // create an empty config } - ModToCacheValues[mod].Add(id, @default.ToString()); - return @default; + ModToCacheValues[saveValue.mod].Add(saveValue.id, JToken.FromObject(@default)); // add the missing value + File.WriteAllText(cfg, JsonConvert.SerializeObject(ModToCacheValues[saveValue.mod], serializerSettings)); // save file + return @default; // return default } private static string GetConfigFile(Assembly mod) @@ -65,45 +78,41 @@ private static string GetConfigFile(Assembly mod) string newFile = Path.Combine(GetConfigFolder(), mod.GetName().Name + ".json"); ModToConfigFile.Add(mod, newFile); if (!ModToCacheValues.ContainsKey(mod) && File.Exists(newFile)) - ModToCacheValues.Add(mod, JsonConvert.DeserializeObject>(File.ReadAllText(newFile))); + ModToCacheValues.Add(mod, JObject.Parse(File.ReadAllText(newFile))); return newFile; } private static Dictionary ModToConfigFile = new Dictionary(); - private static Dictionary> ModToCacheValues = - new Dictionary>(); + private static Dictionary ModToCacheValues = + new Dictionary(); + + private static List AllSaveValues = new List(); } public class SaveValue : IEquatable { - public SaveValue(string id, T @defualt) + public SaveValue(string id, T @default) { this.id = id; this.mod = Assembly.GetCallingAssembly(); - _value = SaveValueManager.GetValueFor(id, mod, @defualt); + _value = SaveValueManager.GetValueFor(this, @default); } - private string id; - private Assembly mod; + internal string id; + internal Assembly mod; - private T _value; + internal T _value; public T Value { get => _value; set { - if (!_value.Equals(value)) SetValue(value); + _value = value; } } - private void SetValue(T newValue) - { - _value = newValue; - SaveValueManager.SaveValueFor(id, mod, newValue.ToString()); - } - public static implicit operator T(SaveValue v) => v._value; public override bool Equals(object obj) => _value.Equals(obj);