From 3142b139141e72d32b34c4bdd3f240e0e6783f8c Mon Sep 17 00:00:00 2001 From: Wiz Date: Mon, 29 Apr 2024 00:20:09 +0100 Subject: [PATCH] Refund licenses in case mod is unninstalled. --- CL.Common/Constants.cs | 2 + CL.Game/CL.Game.csproj | 17 +- CL.Game/LicenseManager.cs | 2 +- CL.Game/Patches/SaveGameManagerPatches.cs | 27 ++++ .../Patches/StartingItemsControllerPatches.cs | 14 ++ CL.Game/SaveInjector.cs | 151 ++++++++++++------ 6 files changed, 157 insertions(+), 56 deletions(-) create mode 100644 CL.Game/Patches/StartingItemsControllerPatches.cs diff --git a/CL.Common/Constants.cs b/CL.Common/Constants.cs index 8b128c1..66297ac 100644 --- a/CL.Common/Constants.cs +++ b/CL.Common/Constants.cs @@ -19,5 +19,7 @@ public static class Constants // Misc. public const int DefaultLicenseValue = 10000; public const string SaveKey = "dv_custom_license"; + public const string SaveKeyMapping = "mapping_data"; + public const string SaveKeyAcquiredLicense = "license_acquired_"; } } diff --git a/CL.Game/CL.Game.csproj b/CL.Game/CL.Game.csproj index 651e538..0f5e993 100644 --- a/CL.Game/CL.Game.csproj +++ b/CL.Game/CL.Game.csproj @@ -1,4 +1,4 @@ - + $(MSBuildProjectName) netframework4.8 @@ -19,18 +19,19 @@ - - + + + + + + + - - - - - + diff --git a/CL.Game/LicenseManager.cs b/CL.Game/LicenseManager.cs index 5cf3cb0..5e5e6d2 100644 --- a/CL.Game/LicenseManager.cs +++ b/CL.Game/LicenseManager.cs @@ -267,7 +267,7 @@ private static Sprite TryLoadIcon(string directory) tex.LoadImage(data); // Create a sprite that covers the whole texture. - return Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100, 1, SpriteMeshType.Tight); + return Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f)); } return null!; diff --git a/CL.Game/Patches/SaveGameManagerPatches.cs b/CL.Game/Patches/SaveGameManagerPatches.cs index d689c61..4840b43 100644 --- a/CL.Game/Patches/SaveGameManagerPatches.cs +++ b/CL.Game/Patches/SaveGameManagerPatches.cs @@ -9,6 +9,33 @@ internal class SaveGameManagerPatches public static void InjectSaveData(SaveGameData data) { SaveInjector.InjectDataIntoSaveGame(data); + + // Refund all licenses so the mod can be removed without + // throwing money into the void. + float totalRefund = 0; + + foreach (var (_, V2) in LicenseManager.AddedGeneralLicenses) + { + if (global::LicenseManager.Instance.IsGeneralLicenseAcquired(V2)) + { + totalRefund += V2.price; + } + } + + foreach (var (_, V2) in LicenseManager.AddedJobLicenses) + { + if (global::LicenseManager.Instance.IsJobLicenseAcquired(V2)) + { + totalRefund += V2.price; + } + } + + float? money = data.GetFloat(SaveGameKeys.Player_money); + + if (money.HasValue) + { + data.SetFloat(SaveGameKeys.Player_money, money.Value + totalRefund); + } } [HarmonyPostfix, HarmonyPatch(nameof(SaveGameManager.FindStartGameData))] diff --git a/CL.Game/Patches/StartingItemsControllerPatches.cs b/CL.Game/Patches/StartingItemsControllerPatches.cs new file mode 100644 index 0000000..ab7bff0 --- /dev/null +++ b/CL.Game/Patches/StartingItemsControllerPatches.cs @@ -0,0 +1,14 @@ +using HarmonyLib; + +namespace CL.Game.Patches +{ + [HarmonyPatch(typeof(StartingItemsController))] + internal class StartingItemsControllerPatches + { + [HarmonyPostfix, HarmonyPatch(nameof(StartingItemsController.AddStartingItems))] + public static void AddStartingItemsPostfix() + { + SaveInjector.AcquireLicenses(); + } + } +} diff --git a/CL.Game/SaveInjector.cs b/CL.Game/SaveInjector.cs index 62424ed..f50c485 100644 --- a/CL.Game/SaveInjector.cs +++ b/CL.Game/SaveInjector.cs @@ -1,17 +1,14 @@ -using Newtonsoft.Json.Linq; +using CL.Common; +using DV.InventorySystem; +using DV.JObjectExtstensions; +using Newtonsoft.Json.Linq; using System.Collections.Generic; -using CL.Common; using System.Linq; namespace CL.Game { internal class SaveInjector { - private const string s_gKeys = "GeneralKeys"; - private const string s_gValues = "GeneralValues"; - private const string s_jKeys = "JobKeys"; - private const string s_jValues = "JobValues"; - internal static JObject? LoadedData; internal static void ExtractDataFromSaveGame(SaveGameData data) @@ -20,72 +17,132 @@ internal static void ExtractDataFromSaveGame(SaveGameData data) if (LoadedData != null) { - ProcessGeneralMapping(); - ProcessJobMapping(); + var mappingData = LoadedData.GetObjectViaJSON(Constants.SaveKeyMapping); + + if (mappingData != null) + { + ProcessGeneralMapping(mappingData); + ProcessJobMapping(mappingData); + return; + } } - else + + CLMod.Warning("No data found in save file, using new cache."); + } + + private static void ProcessGeneralMapping(LicenseMappingDataHolder data) + { + var keys = data.GeneralKeys; + var values = data.GeneralValues; + var dictionary = new Dictionary(); + + for (int i = 0; i < keys.Length; i++) { - CLMod.Warning("No data found in save file, using new cache."); + dictionary.Add(keys[i], values[i]); } + + LicenseManager.GeneralMapping = dictionary; + CLMod.Log("General mapping cache sucessfully loaded."); } - private static void ProcessGeneralMapping() + private static void ProcessJobMapping(LicenseMappingDataHolder data) { - var keys = LoadedData![s_gKeys]!.ToObject(); - var values = LoadedData[s_gValues]!.ToObject(); + var keys = data.JobKeys; + var values = data.JobValues; - if (keys != null && values != null) + var dictionary = new Dictionary(); + + for (int i = 0; i < keys.Length; i++) { - var dictionary = new Dictionary(); + dictionary.Add(keys[i], values[i]); + } - for (int i = 0; i < keys.Length; i++) - { - dictionary.Add(keys[i], values[i]); - } + LicenseManager.JobMapping = dictionary; + CLMod.Log("Job mapping cache sucessfully loaded."); + } + + internal static void InjectDataIntoSaveGame(SaveGameData data) + { + LoadedData = data.GetJObject(Constants.SaveKey); + LoadedData ??= new JObject(); + + LoadedData.SetObjectViaJSON(Constants.SaveKeyMapping, new LicenseMappingDataHolder + { + GeneralKeys = LicenseManager.GeneralMapping.Keys.ToArray(), + GeneralValues = LicenseManager.GeneralMapping.Values.ToArray(), + JobKeys = LicenseManager.JobMapping.Keys.ToArray(), + JobValues = LicenseManager.JobMapping.Values.ToArray() + }); - LicenseManager.GeneralMapping = dictionary; - CLMod.Log("General mapping cache sucessfully loaded."); + foreach (var (_, V2) in LicenseManager.AddedGeneralLicenses) + { + LoadedData.SetBool($"{Constants.SaveKeyAcquiredLicense}{V2.id}", global::LicenseManager.Instance.IsGeneralLicenseAcquired(V2)); } - else + + foreach (var (_, V2) in LicenseManager.AddedJobLicenses) { - CLMod.Error("Error loading data: general mapping is null!"); + LoadedData.SetBool($"{Constants.SaveKeyAcquiredLicense}{V2.id}", global::LicenseManager.Instance.IsJobLicenseAcquired(V2)); } + + data.SetJObject(Constants.SaveKey, LoadedData); } - private static void ProcessJobMapping() + internal static void AcquireLicenses() { - var keys = LoadedData![s_jKeys]!.ToObject(); - var values = LoadedData[s_jValues]!.ToObject(); - - if (keys != null && values != null) + if (LoadedData != null && Inventory.Instance) { - var dictionary = new Dictionary(); + CLMod.Log("Acquiring licenses..."); + List general = new List(); + List job = new List(); + float totalCost = 0; - for (int i = 0; i < keys.Length; i++) + foreach (var (_, V2) in LicenseManager.AddedGeneralLicenses) { - dictionary.Add(keys[i], values[i]); + var result = LoadedData.GetBool($"{Constants.SaveKeyAcquiredLicense}{V2.id}"); + + if (result != null && result.Value) + { + global::LicenseManager.Instance.AcquireGeneralLicense(V2); + general.Add(V2.id); + totalCost += V2.price; + } } - LicenseManager.JobMapping = dictionary; - CLMod.Log("Job mapping cache sucessfully loaded."); - } - else - { - CLMod.Error("Error loading data: job mapping is null!"); + CLMod.Log($"GL: {string.Join(", ", general)}"); + + foreach (var (_, V2) in LicenseManager.AddedJobLicenses) + { + var result = LoadedData.GetBool($"{Constants.SaveKeyAcquiredLicense}{V2.id}"); + + if (result != null && result.Value) + { + global::LicenseManager.Instance.AcquireJobLicense(V2); + job.Add(V2.id); + totalCost += V2.price; + } + } + + CLMod.Log($"JL: {string.Join(", ", job)}"); + + // Remove total license cost. + Inventory.Instance.RemoveMoney(totalCost); } } - internal static void InjectDataIntoSaveGame(SaveGameData data) + private class LicenseMappingDataHolder { - LoadedData = new JObject - { - { s_gKeys, JToken.FromObject(LicenseManager.GeneralMapping.Keys.ToArray()) }, - { s_gValues, JToken.FromObject(LicenseManager.GeneralMapping.Values.ToArray()) }, - { s_jKeys, JToken.FromObject(LicenseManager.JobMapping.Keys.ToArray()) }, - { s_jValues, JToken.FromObject(LicenseManager.JobMapping.Values.ToArray()) } - }; + public string[] GeneralKeys; + public int[] GeneralValues; + public string[] JobKeys; + public int[] JobValues; - data.SetJObject(Constants.SaveKey, LoadedData); + public LicenseMappingDataHolder() + { + GeneralKeys = new string[0]; + GeneralValues = new int[0]; + JobKeys = new string[0]; + JobValues = new int[0]; + } } } }