1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-08 20:53:28 +08:00

release CompressSave 1.2.1

This commit is contained in:
2022-11-22 17:52:48 +08:00
parent 768c277d13
commit 173c439b65
9 changed files with 53 additions and 100 deletions

View File

@@ -9,6 +9,13 @@ using CompressSave.Wrapper;
namespace CompressSave;
public enum CompressionType
{
None = 0,
LZ4 = 1,
Zstd = 2,
}
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
public class CompressSave : BaseUnityPlugin
{
@@ -43,8 +50,7 @@ public class CompressSave : BaseUnityPlugin
new AcceptableValueList<string>("lz4", "zstd", "none"), new {}))
.Value);
PatchSave.CompressionLevelForSaves = Config.Bind("Compression", "Level", PatchSave.CompressionLevelForSaves,
new ConfigDescription("Set default compression level. -1 for fastest level, 0 for default level. And positive levels for lz4: 3-12, for zstd: 1-22.",
new AcceptableValueRange<int>(-1, 22), new {}))
"Set default compression level.\n0 for default level.\n3 ~ 12 for lz4, -5 ~ 22 for zstd.\nSmaller level leads to faster speed and less compression ratio.")
.Value;
PatchSave.CreateCompressBuffer();
if (GameConfig.gameVersion != SaveUtil.VerifiedVersion)
@@ -217,10 +223,6 @@ class PatchSave
.MatchBack(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IO.Stream), "Seek")));
if (matcher.IsValid)
matcher.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "ReadSeek"));
matcher.Start()
.MatchForward(false, new CodeMatch(OpCodes.Newobj, AccessTools.Constructor(typeof(GameSaveHeader))));
if (matcher.IsValid)
matcher.Set(OpCodes.Newobj, AccessTools.Constructor(typeof(CompressionGameSaveHeader))); //ReadHeader
EnableDecompress = true;
return matcher.InstructionEnumeration();
@@ -233,15 +235,6 @@ class PatchSave
return instructions;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameSave), "ReadHeader")]
[HarmonyPatch(typeof(GameSave), "ReadHeaderAndDescAndProperty")]
static void ReadHeader_Postfix(ref GameSaveHeader header)
{
if (header != null)
((CompressionGameSaveHeader)header).CompressionType = CompressedType;
}
public static BinaryReader CreateBinaryReader(FileStream fileStream)
{
switch (CompressedType = SaveUtil.SaveGetCompressType(fileStream))

View File

@@ -4,7 +4,7 @@
<AssemblyName>CompressSave</AssemblyName>
<BepInExPluginGuid>org.soardev.compresssave</BepInExPluginGuid>
<Description>DSP MOD - CompressSave</Description>
<Version>1.2.0</Version>
<Version>1.2.1</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<TargetFramework>net472</TargetFramework>
@@ -23,6 +23,6 @@
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip&#xA;zip -9 -j package/$(ProjectName)-$(Version).zip $(TargetPath) $(TargetDir)/System.Runtime.CompilerServices.Unsafe.dll package/lz4wrap.dll package/zstdwrap.dll package/icon.png package/manifest.json README.md" />
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip&#xA;zip -9 -j package/$(ProjectName)-$(Version).zip $(TargetPath) $(TargetDir)/System.Runtime.CompilerServices.Unsafe.dll package/icon.png package/manifest.json README.md&#xA;cd package&#xA;zip -9 -r $(ProjectName)-$(Version).zip x64" />
</Target>
</Project>

View File

@@ -1,13 +0,0 @@
namespace CompressSave;
public enum CompressionType
{
None = 0,
LZ4 = 1,
Zstd = 2,
}
internal class CompressionGameSaveHeader: GameSaveHeader
{
public CompressionType CompressionType = CompressionType.None;
}

View File

@@ -12,56 +12,25 @@ class PatchUILoadGame
{
static UIButton decompressButton;
[HarmonyTranspiler]
[HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange")]
[HarmonyPatch(typeof(UILoadGameWindow), "OnSelectedChange")]
static IEnumerable<CodeInstruction> OnSelectedChange_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var ReadHeader = typeof(GameSave).GetMethod("ReadHeaderAndDescAndProperty", BindingFlags.Static | BindingFlags.Public);
if (ReadHeader == null) return instructions;
var codes = new List<CodeInstruction>(instructions);
for (int i = 0; i < codes.Count; i++)
{
var code = codes[i];
if (code.opcode == OpCodes.Ldstr && code.OperandIs("#,##0"))
{
var iffalse = generator.DefineLabel();
var ifzstd = generator.DefineLabel();
var callLabel = generator.DefineLabel();
code.WithLabels(iffalse)
.operand = "(N)#,##0";
codes[i + 1].WithLabels(callLabel);
var IL = new List<CodeInstruction> {
new CodeInstruction(OpCodes.Ldloc_0),
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(CompressionGameSaveHeader),"CompressionType")),
new CodeInstruction(OpCodes.Ldc_I4_S, 0),
new CodeInstruction(OpCodes.Beq_S, iffalse),
new CodeInstruction(OpCodes.Ldloc_0),
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(CompressionGameSaveHeader),"CompressionType")),
new CodeInstruction(OpCodes.Ldc_I4_S, 2),
new CodeInstruction(OpCodes.Beq_S, ifzstd),
new CodeInstruction(OpCodes.Ldstr,"(LZ4)#,##0"),
new CodeInstruction(OpCodes.Br_S,callLabel),
new CodeInstruction(OpCodes.Ldstr,"(ZSTD)#,##0").WithLabels(ifzstd),
new CodeInstruction(OpCodes.Br_S,callLabel),
};
codes.InsertRange(i, IL);
break;
}
}
return codes.AsEnumerable();
}
[HarmonyPatch(typeof(UILoadGameWindow), "OnSelectedChange"), HarmonyPostfix]
static void OnSelectedChange(UILoadGameWindow __instance, UIButton ___loadButton, Text ___prop3Text)
static void OnSelectedChange(UILoadGameWindow __instance, Text ___prop3Text)
{
bool compressedSave = (___prop3Text != null && (___prop3Text.text.Contains("(LZ4)") || ___prop3Text.text.Contains("(ZSTD)"))) || (___loadButton.button.interactable == false && SaveUtil.SaveGetCompressType(__instance.selected?.saveName) != CompressionType.None);
if (decompressButton)
var compressedType = SaveUtil.SaveGetCompressType(__instance.selected?.saveName);
switch (compressedType)
{
decompressButton.button.interactable = compressedSave;
decompressButton.gameObject.SetActive(compressedSave);
case CompressionType.LZ4:
___prop3Text.text = "(LZ4)" + ___prop3Text.text;
break;
case CompressionType.Zstd:
___prop3Text.text = "(ZSTD)" + ___prop3Text.text;
break;
default:
___prop3Text.text = "(N)" + ___prop3Text.text;
break;
}
if (!decompressButton) return;
decompressButton.button.interactable = compressedType != CompressionType.None;
decompressButton.gameObject.SetActive(compressedType != CompressionType.None);
}
[HarmonyPatch(typeof(UILoadGameWindow), "_OnOpen"), HarmonyPostfix]

View File

@@ -6,35 +6,31 @@ namespace CompressSave;
static class PatchUISaveGame
{
[HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange"), HarmonyPostfix]
static void OnSelectedChange(UISaveGameWindow __instance, Text ___prop3Text)
{
var compressedType = SaveUtil.SaveGetCompressType(__instance.selected?.saveName);
switch (compressedType)
{
case CompressionType.LZ4:
___prop3Text.text = "(LZ4)" + ___prop3Text.text;
break;
case CompressionType.Zstd:
___prop3Text.text = "(ZSTD)" + ___prop3Text.text;
break;
default:
___prop3Text.text = "(N)" + ___prop3Text.text;
break;
}
}
[HarmonyPatch(typeof(UISaveGameWindow), "_OnDestroy"), HarmonyPostfix]
static void _OnDestroy()
{
//Console.WriteLine("OnCreate");
context = new UIContext();
}
//[HarmonyPatch(typeof(UISaveGameWindow), "_OnRegEvent"), HarmonyPostfix]
//static void _OnRegEvent()
//{
// Console.WriteLine("OnRegEvent");
//}
//[HarmonyPatch(typeof(UISaveGameWindow), "_OnUnregEvent"), HarmonyPostfix]
//static void _OnUnregEvent()
//{
// Console.WriteLine("OnUnregEvent");
//}
static void Test()
{
GameSave.ReadHeaderAndDescAndProperty("aa", true, out var header, out var desc, out var property);
if (header != null)
if (header is CompressionGameSaveHeader)
"b".Translate();
else
"a".Translate();
"d.A".Translate();
return;
}
[HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick"), HarmonyReversePatch]
static void OSaveGameAs(this UISaveGameWindow ui, int data) { }

View File

@@ -7,6 +7,14 @@
## Updates
### 1.2.1
* Simplified codes to display compression type and `Decompress` button on save/load UI, making CompressSave compatible with other MODs(like GalacticScale) which override `UILoadGameWindow::OnSelectedChange()`.
* Add compression level -5 to -1 for zstd, which makes it working better than lz4(which is actually lz4hc used by lz4frame) now:
* -5 gets faster compression speed than lz4 with still a little better compression ratio.
* -1 has almost the same speed against lz4 with greater compression ratio.
* Due to bug of r2modman UI which does not support negative integer, the config value of compression level is not limited any more.
* move native wrapper DLLs into `x64` folder to avoid warning logs on loading BepInEx plugins.
### 1.2.0
* Match game version 0.9.27.15033.
* Add new compression type: zstd (a bit slower but get better compression ratio than lz4).

View File

@@ -1,6 +1,6 @@
{
"name": "CompressSave",
"version_number": "1.2.0",
"version_number": "1.2.1",
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CompressSave",
"description": "Compress game saves to reduce space use and boost save speed / 压缩游戏存档以降低空间使用并提升保存速度",
"dependencies": ["xiaoye97-BepInEx-5.4.17"]