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

[KKS][MainGameOptimizations] Avoid error when saving more than 2 GB in the main game #63

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions src/KKS_Fix_MainGameOptimizations/FixWorldData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using HarmonyLib;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using System.IO;
using MessagePack;
using SaveData;


namespace IllusionFixes
{
/// <summary>
/// Fix to allow saving when the number of characters and their costumes is large and the total saved data exceeds 2 GB.
/// </summary>
public partial class MainGameOptimizations
{
static bool _inWorldSaveHooks = false;

[HarmonyPatch(typeof(SaveData.WorldData), nameof(SaveData.WorldData.Save), typeof(string), typeof(string))]
[HarmonyPrefix]
[HarmonyPriority(Priority.Last)]
static bool WorldDataSavePrefix( SaveData.WorldData __instance, string path, string fileName)
{
_inWorldSaveHooks = true;

try
{
Illusion.Utils.File.OpenWrite(path + fileName, false, (Action<FileStream>)(f =>
{
using (BinaryWriter binaryWriter = new BinaryWriter((Stream)f))
{
var saveData = __instance;

// Data to be written by WorldData.GetBytes
byte[] buffer = MessagePackSerializer.Serialize<WorldData>(saveData);
binaryWriter.Write(buffer.Length);
binaryWriter.Write(buffer);
byte[] bytes1 = SaveData.Player.GetBytes(saveData.player);
binaryWriter.Write(bytes1.Length);
binaryWriter.Write(bytes1);
int count = saveData.heroineList.Count;
binaryWriter.Write(count);
for (int index = 0; index < count; ++index)
{
byte[] bytes2 = Heroine.GetBytes(saveData.heroineList[index]);
binaryWriter.Write(bytes2.Length);
binaryWriter.Write(bytes2);
}

// Data added by hooks behind normal save data.
// Normal data is erased by WorldDataGetBytesPrefix and only the data to be added is stored.
var extensionData = SaveData.WorldData.GetBytes(saveData);
binaryWriter.Write(extensionData);
}

}));

return false;
}
catch( System.Exception e )
{
UnityEngine.Debug.LogException(e);
return true;
}
finally
{
_inWorldSaveHooks = false;
}
}

/// <summary>
/// Function assuming the following hooks to WorldData.GetBytes() in BepisPlugins
/// https://github.com/IllusionMods/BepisPlugins/blob/abee07b2392e9d7db88a7f80e68230cf9a7268a8/src/KKS_ExtensibleSaveFormat/KKS.ExtendedSave.SaveData.Hooks.cs#L61
/// </summary>
[HarmonyPatch(typeof(SaveData.WorldData), nameof(SaveData.WorldData.GetBytes), typeof(SaveData.WorldData))]
[HarmonyPrefix]
[HarmonyPriority(Priority.VeryHigh)]
private static bool WorldDataGetBytesPrefix(SaveData.WorldData saveData, ref byte[] __result)
{
if ( _inWorldSaveHooks )
{
__result = new byte[0];
return false;
}
else
{
return true;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="FixWorldData.cs" />
<Compile Include="MainGameOptimizations.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/KKS_Fix_MainGameOptimizations/MainGameOptimizations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace IllusionFixes
//[BepInProcess(Constants.GameProcessNameSteam)]
[BepInPlugin(GUID, PluginName, Constants.PluginsVersion)]
[DefaultExecutionOrder(-1000)]
public class MainGameOptimizations : BaseUnityPlugin
public partial class MainGameOptimizations : BaseUnityPlugin
{
public const string GUID = "KKS_Fix_MainGameOptimizations";
public const string PluginName = "Main Game Optimizations";
Expand All @@ -44,7 +44,7 @@ internal void Start()
ThrottleDynamicBoneUpdatesRange.SettingChanged += (sender, args) => UpdateThrottleDynamicBoneUpdatesRange();
ThrottleDynamicBoneUpdatesViewport = Config.Bind(Utilities.ConfigSectionTweaks, "Pause dynamic bones outside camera view", false, new ConfigDescription("Stops dynamic bone physics in roaming mode for characters that are outside of the camera view (e.g. behind or to the side). Improves performance, but can cause the bones to visibly jerk into place as camera rotates to show the character.\nNeeds 'Throttle dynamic bone updates' to be enabled."));

Harmony.CreateAndPatchAll(typeof(MainGameOptimizations));
Harmony.CreateAndPatchAll(typeof(MainGameOptimizations), GUID);

SceneManager.sceneLoaded += (arg0, mode) =>
{
Expand Down