mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-09 02:13:29 +08:00
release CompressSave 1.2.1
This commit is contained in:
@@ -9,6 +9,13 @@ using CompressSave.Wrapper;
|
|||||||
|
|
||||||
namespace CompressSave;
|
namespace CompressSave;
|
||||||
|
|
||||||
|
public enum CompressionType
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
LZ4 = 1,
|
||||||
|
Zstd = 2,
|
||||||
|
}
|
||||||
|
|
||||||
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)]
|
||||||
public class CompressSave : BaseUnityPlugin
|
public class CompressSave : BaseUnityPlugin
|
||||||
{
|
{
|
||||||
@@ -43,8 +50,7 @@ public class CompressSave : BaseUnityPlugin
|
|||||||
new AcceptableValueList<string>("lz4", "zstd", "none"), new {}))
|
new AcceptableValueList<string>("lz4", "zstd", "none"), new {}))
|
||||||
.Value);
|
.Value);
|
||||||
PatchSave.CompressionLevelForSaves = Config.Bind("Compression", "Level", PatchSave.CompressionLevelForSaves,
|
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.",
|
"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.")
|
||||||
new AcceptableValueRange<int>(-1, 22), new {}))
|
|
||||||
.Value;
|
.Value;
|
||||||
PatchSave.CreateCompressBuffer();
|
PatchSave.CreateCompressBuffer();
|
||||||
if (GameConfig.gameVersion != SaveUtil.VerifiedVersion)
|
if (GameConfig.gameVersion != SaveUtil.VerifiedVersion)
|
||||||
@@ -217,10 +223,6 @@ class PatchSave
|
|||||||
.MatchBack(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IO.Stream), "Seek")));
|
.MatchBack(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IO.Stream), "Seek")));
|
||||||
if (matcher.IsValid)
|
if (matcher.IsValid)
|
||||||
matcher.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "ReadSeek"));
|
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;
|
EnableDecompress = true;
|
||||||
return matcher.InstructionEnumeration();
|
return matcher.InstructionEnumeration();
|
||||||
@@ -233,15 +235,6 @@ class PatchSave
|
|||||||
return instructions;
|
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)
|
public static BinaryReader CreateBinaryReader(FileStream fileStream)
|
||||||
{
|
{
|
||||||
switch (CompressedType = SaveUtil.SaveGetCompressType(fileStream))
|
switch (CompressedType = SaveUtil.SaveGetCompressType(fileStream))
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<AssemblyName>CompressSave</AssemblyName>
|
<AssemblyName>CompressSave</AssemblyName>
|
||||||
<BepInExPluginGuid>org.soardev.compresssave</BepInExPluginGuid>
|
<BepInExPluginGuid>org.soardev.compresssave</BepInExPluginGuid>
|
||||||
<Description>DSP MOD - CompressSave</Description>
|
<Description>DSP MOD - CompressSave</Description>
|
||||||
<Version>1.2.0</Version>
|
<Version>1.2.1</Version>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net472</TargetFramework>
|
||||||
@@ -23,6 +23,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
<Exec Command="del /F /Q package\$(ProjectName)-$(Version).zip
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
zip -9 -j package/$(ProjectName)-$(Version).zip $(TargetPath) $(TargetDir)/System.Runtime.CompilerServices.Unsafe.dll package/icon.png package/manifest.json README.md
cd package
zip -9 -r $(ProjectName)-$(Version).zip x64" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
namespace CompressSave;
|
|
||||||
|
|
||||||
public enum CompressionType
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
LZ4 = 1,
|
|
||||||
Zstd = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class CompressionGameSaveHeader: GameSaveHeader
|
|
||||||
{
|
|
||||||
public CompressionType CompressionType = CompressionType.None;
|
|
||||||
}
|
|
||||||
@@ -12,56 +12,25 @@ class PatchUILoadGame
|
|||||||
{
|
{
|
||||||
static UIButton decompressButton;
|
static UIButton decompressButton;
|
||||||
|
|
||||||
[HarmonyTranspiler]
|
[HarmonyPatch(typeof(UILoadGameWindow), "OnSelectedChange"), HarmonyPostfix]
|
||||||
[HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange")]
|
static void OnSelectedChange(UILoadGameWindow __instance, Text ___prop3Text)
|
||||||
[HarmonyPatch(typeof(UILoadGameWindow), "OnSelectedChange")]
|
|
||||||
static IEnumerable<CodeInstruction> OnSelectedChange_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
|
||||||
{
|
{
|
||||||
var ReadHeader = typeof(GameSave).GetMethod("ReadHeaderAndDescAndProperty", BindingFlags.Static | BindingFlags.Public);
|
var compressedType = SaveUtil.SaveGetCompressType(__instance.selected?.saveName);
|
||||||
if (ReadHeader == null) return instructions;
|
switch (compressedType)
|
||||||
var codes = new List<CodeInstruction>(instructions);
|
|
||||||
for (int i = 0; i < codes.Count; i++)
|
|
||||||
{
|
{
|
||||||
var code = codes[i];
|
case CompressionType.LZ4:
|
||||||
if (code.opcode == OpCodes.Ldstr && code.OperandIs("#,##0"))
|
___prop3Text.text = "(LZ4)" + ___prop3Text.text;
|
||||||
{
|
break;
|
||||||
var iffalse = generator.DefineLabel();
|
case CompressionType.Zstd:
|
||||||
var ifzstd = generator.DefineLabel();
|
___prop3Text.text = "(ZSTD)" + ___prop3Text.text;
|
||||||
var callLabel = generator.DefineLabel();
|
break;
|
||||||
code.WithLabels(iffalse)
|
default:
|
||||||
.operand = "(N)#,##0";
|
___prop3Text.text = "(N)" + ___prop3Text.text;
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
if (!decompressButton) return;
|
||||||
|
decompressButton.button.interactable = compressedType != CompressionType.None;
|
||||||
return codes.AsEnumerable();
|
decompressButton.gameObject.SetActive(compressedType != CompressionType.None);
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyPatch(typeof(UILoadGameWindow), "OnSelectedChange"), HarmonyPostfix]
|
|
||||||
static void OnSelectedChange(UILoadGameWindow __instance, UIButton ___loadButton, 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)
|
|
||||||
{
|
|
||||||
decompressButton.button.interactable = compressedSave;
|
|
||||||
decompressButton.gameObject.SetActive(compressedSave);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch(typeof(UILoadGameWindow), "_OnOpen"), HarmonyPostfix]
|
[HarmonyPatch(typeof(UILoadGameWindow), "_OnOpen"), HarmonyPostfix]
|
||||||
|
|||||||
@@ -6,34 +6,30 @@ namespace CompressSave;
|
|||||||
|
|
||||||
static class PatchUISaveGame
|
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]
|
[HarmonyPatch(typeof(UISaveGameWindow), "_OnDestroy"), HarmonyPostfix]
|
||||||
static void _OnDestroy()
|
static void _OnDestroy()
|
||||||
{
|
{
|
||||||
//Console.WriteLine("OnCreate");
|
//Console.WriteLine("OnCreate");
|
||||||
context = new UIContext();
|
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]
|
[HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick"), HarmonyReversePatch]
|
||||||
static void OSaveGameAs(this UISaveGameWindow ui, int data) { }
|
static void OSaveGameAs(this UISaveGameWindow ui, int data) { }
|
||||||
|
|||||||
@@ -7,6 +7,14 @@
|
|||||||
|
|
||||||
## Updates
|
## 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
|
### 1.2.0
|
||||||
* Match game version 0.9.27.15033.
|
* Match game version 0.9.27.15033.
|
||||||
* Add new compression type: zstd (a bit slower but get better compression ratio than lz4).
|
* Add new compression type: zstd (a bit slower but get better compression ratio than lz4).
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "CompressSave",
|
"name": "CompressSave",
|
||||||
"version_number": "1.2.0",
|
"version_number": "1.2.1",
|
||||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CompressSave",
|
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CompressSave",
|
||||||
"description": "Compress game saves to reduce space use and boost save speed / 压缩游戏存档以降低空间使用并提升保存速度",
|
"description": "Compress game saves to reduce space use and boost save speed / 压缩游戏存档以降低空间使用并提升保存速度",
|
||||||
"dependencies": ["xiaoye97-BepInEx-5.4.17"]
|
"dependencies": ["xiaoye97-BepInEx-5.4.17"]
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user