Skip to content

Commit

Permalink
Refund licenses in case mod is unninstalled.
Browse files Browse the repository at this point in the history
  • Loading branch information
WhistleWiz committed Apr 28, 2024
1 parent 368f108 commit 3142b13
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 56 deletions.
2 changes: 2 additions & 0 deletions CL.Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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_";
}
}
17 changes: 9 additions & 8 deletions CL.Game/CL.Game.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>$(MSBuildProjectName)</AssemblyName>
<TargetFramework>netframework4.8</TargetFramework>
Expand All @@ -19,18 +19,19 @@
<Publicize Include="Assembly-CSharp" />
</ItemGroup>
<ItemGroup>
<Reference Include="Assembly-CSharp" />
<Reference Include="UnityModManager" />
<Reference Include="0Harmony" />
<Reference Include="Assembly-CSharp" />
<Reference Include="DV.Inventory" />
<Reference Include="DV.Localization" />
<Reference Include="DV.ThingTypes" />
<Reference Include="DV.Utils" />
<Reference Include="DVLangHelper.Data" />
<Reference Include="DVLangHelper.Runtime" />
<Reference Include="UnityEngine" />
<Reference Include="UnityEngine.AssetBundleModule" />
<Reference Include="UnityEngine.CoreModule" />
<Reference Include="UnityEngine.ImageConversionModule" />
<Reference Include="UnityEngine.UI" />
<Reference Include="DVLangHelper.Data" />
<Reference Include="DVLangHelper.Runtime" />
<Reference Include="DV.Localization" />
<Reference Include="DV.ThingTypes" />
<Reference Include="DV.Utils" />
<Reference Include="UnityModManager" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion CL.Game/LicenseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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!;
Expand Down
27 changes: 27 additions & 0 deletions CL.Game/Patches/SaveGameManagerPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down
14 changes: 14 additions & 0 deletions CL.Game/Patches/StartingItemsControllerPatches.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
151 changes: 104 additions & 47 deletions CL.Game/SaveInjector.cs
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -20,72 +17,132 @@ internal static void ExtractDataFromSaveGame(SaveGameData data)

if (LoadedData != null)
{
ProcessGeneralMapping();
ProcessJobMapping();
var mappingData = LoadedData.GetObjectViaJSON<LicenseMappingDataHolder>(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<string, int>();

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<string[]>();
var values = LoadedData[s_gValues]!.ToObject<int[]>();
var keys = data.JobKeys;
var values = data.JobValues;

if (keys != null && values != null)
var dictionary = new Dictionary<string, int>();

for (int i = 0; i < keys.Length; i++)
{
var dictionary = new Dictionary<string, int>();
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<string[]>();
var values = LoadedData[s_jValues]!.ToObject<int[]>();

if (keys != null && values != null)
if (LoadedData != null && Inventory.Instance)
{
var dictionary = new Dictionary<string, int>();
CLMod.Log("Acquiring licenses...");
List<string> general = new List<string>();
List<string> job = new List<string>();
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];
}
}
}
}

0 comments on commit 3142b13

Please sign in to comment.