1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-08 22:13:30 +08:00

CompressSave v1.3.2

This commit is contained in:
2023-09-26 21:19:46 +08:00
parent 6311e3b9fb
commit 7a0a1b90ab
7 changed files with 301 additions and 58 deletions

View File

@@ -20,7 +20,7 @@ public enum CompressionType
public class CompressSave : BaseUnityPlugin public class CompressSave : BaseUnityPlugin
{ {
private Harmony _patchSave, _patchUISave, _patchUILoad; private Harmony _patchSave, _patchUISave, _patchUILoad;
private static string StringFromCompresstionType(CompressionType type) public static string StringFromCompresstionType(CompressionType type)
{ {
return type switch return type switch
{ {
@@ -46,25 +46,22 @@ public class CompressSave : BaseUnityPlugin
SaveUtil.Logger = Logger; SaveUtil.Logger = Logger;
if (LZ4API.Avaliable && ZstdAPI.Avaliable) if (LZ4API.Avaliable && ZstdAPI.Avaliable)
{ {
PatchSave.CompressionTypeForSaves = CompressionTypeFromString( PatchSave.CompressionTypeForSavesConfig = Config.Bind("Compression", "Type", StringFromCompresstionType(PatchSave.CompressionTypeForSaves),
Config.Bind("Compression", "Type", StringFromCompresstionType(PatchSave.CompressionTypeForSaves),
new ConfigDescription("Set default compression type for manual saves.", new ConfigDescription("Set default compression type for manual saves.",
new AcceptableValueList<string>("lz4", "zstd", "none"), new { })) new AcceptableValueList<string>("lz4", "zstd", "none"), new { }));
.Value); PatchSave.CompressionTypeForSaves = CompressionTypeFromString(PatchSave.CompressionTypeForSavesConfig.Value);
PatchSave.CompressionTypeForAutoSaves = CompressionTypeFromString( PatchSave.CompressionTypeForAutoSavesConfig = Config.Bind("Compression", "TypeForAuto", StringFromCompresstionType(PatchSave.CompressionTypeForAutoSaves),
Config.Bind("Compression", "TypeForAuto", StringFromCompresstionType(PatchSave.CompressionTypeForSaves),
new ConfigDescription("Set default compression type for auto saves and last-exit save.", new ConfigDescription("Set default compression type for auto saves and last-exit save.",
new AcceptableValueList<string>("lz4", "zstd", "none"), new { })) new AcceptableValueList<string>("lz4", "zstd", "none"), new { }));
.Value); PatchSave.CompressionTypeForAutoSaves = CompressionTypeFromString(PatchSave.CompressionTypeForAutoSavesConfig.Value);
PatchSave.CompressionLevelForSaves = Config.Bind("Compression", "Level", PatchSave.CompressionLevelForSaves, PatchSave.CompressionLevelForSaves = Config.Bind("Compression", "Level", PatchSave.CompressionLevelForSaves,
"Set default compression level for manual saves.\n0 for default level.\n3 ~ 12 for lz4, -5 ~ 22 for zstd.\nSmaller level leads to faster speed and less compression ratio.") "Set default compression level for manual saves.\n0 for default level.\n3 ~ 12 for lz4, -5 ~ 22 for zstd.\nSmaller level leads to faster speed and less compression ratio.")
.Value; .Value;
PatchSave.CompressionLevelForAutoSaves = Config.Bind("Compression", "LevelForAuto", PatchSave.CompressionLevelForAutoSaves, PatchSave.CompressionLevelForAutoSaves = Config.Bind("Compression", "LevelForAuto", PatchSave.CompressionLevelForAutoSaves,
"Set default compression level for auto saves and last-exit save.\n0 for default level.\n3 ~ 12 for lz4, -5 ~ 22 for zstd.\nSmaller level leads to faster speed and less compression ratio.") "Set default compression level for auto saves and last-exit save.\n0 for default level.\n3 ~ 12 for lz4, -5 ~ 22 for zstd.\nSmaller level leads to faster speed and less compression ratio.")
.Value; .Value;
PatchSave.EnableForAutoSaves = Config.Bind("Compression", "EnableForAutoSaves", PatchSave.EnableForAutoSaves, PatchSave.EnableForAutoSaves = Config.Bind("Compression", "EnableForAutoSaves", true,
"Enable the feature for auto saves and last-exit save.") "Enable the feature for auto saves and last-exit save.");
.Value;
PatchSave.CreateCompressBuffer(); PatchSave.CreateCompressBuffer();
if (GameConfig.gameVersion != SaveUtil.VerifiedVersion) if (GameConfig.gameVersion != SaveUtil.VerifiedVersion)
{ {
@@ -78,7 +75,14 @@ public class CompressSave : BaseUnityPlugin
_patchUILoad = Harmony.CreateAndPatchAll(typeof(PatchUILoadGame)); _patchUILoad = Harmony.CreateAndPatchAll(typeof(PatchUILoadGame));
} }
else else
SaveUtil.Logger.LogWarning("Either lz4warp.dll or zstdwrap.dll is not avaliable."); SaveUtil.Logger.LogWarning("Either nonewrap.dll, lz4warp.dll or zstdwrap.dll is not avaliable.");
I18N.Init();
I18N.Add("Store", "Store (No Compression)", "存储(不压缩)");
I18N.Add("Decompress", "Decompress", "解压存档");
I18N.Add("Save with Compression", "Save (Compress)", "压缩保存");
I18N.Add("Compression for auto saves", "Compression for auto saves", "  自动存档压缩方式");
I18N.Add("Compression for manual saves", "Compression for manual saves", "  手动存档压缩方式");
I18N.Apply();
} }
public void OnDestroy() public void OnDestroy()
@@ -108,9 +112,11 @@ public class PatchSave
private static int _compressionLevelForSaving; private static int _compressionLevelForSaving;
public static CompressionType CompressionTypeForSaves = CompressionType.Zstd; public static CompressionType CompressionTypeForSaves = CompressionType.Zstd;
public static CompressionType CompressionTypeForAutoSaves = CompressionType.Zstd; public static CompressionType CompressionTypeForAutoSaves = CompressionType.Zstd;
public static ConfigEntry<string> CompressionTypeForSavesConfig;
public static ConfigEntry<string> CompressionTypeForAutoSavesConfig;
public static int CompressionLevelForSaves; public static int CompressionLevelForSaves;
public static int CompressionLevelForAutoSaves; public static int CompressionLevelForAutoSaves;
public static bool EnableForAutoSaves = true; public static ConfigEntry<bool> EnableForAutoSaves;
private static Stream _compressionStream; private static Stream _compressionStream;
public static bool EnableCompress; public static bool EnableCompress;
@@ -151,7 +157,7 @@ public class PatchSave
[HarmonyPatch(typeof(GameSave), "SaveAsLastExit")] [HarmonyPatch(typeof(GameSave), "SaveAsLastExit")]
private static void BeforeAutoSave() private static void BeforeAutoSave()
{ {
UseCompressSave = EnableForAutoSaves && EnableCompress; UseCompressSave = EnableForAutoSaves.Value && EnableCompress;
if (!UseCompressSave) return; if (!UseCompressSave) return;
_compressionTypeForSaving = CompressionTypeForAutoSaves; _compressionTypeForSaving = CompressionTypeForAutoSaves;
_compressionLevelForSaving = CompressionLevelForAutoSaves; _compressionLevelForSaving = CompressionLevelForAutoSaves;

View File

@@ -5,7 +5,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.3.1</Version> <Version>1.3.2</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
<TargetFramework>net472</TargetFramework> <TargetFramework>net472</TargetFramework>

85
CompressSave/I18N.cs Normal file
View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
namespace CompressSave;
public static class I18N
{
private static bool _initialized;
public static Action OnInitialized;
public static void Init()
{
Harmony.CreateAndPatchAll(typeof(I18N));
}
public static bool Initialized() => _initialized;
private static int _nextID = 1;
private static readonly List<StringProto> StringsToAdd = new();
public static void Add(string key, string enus, string zhcn = null, string frfr = null)
{
var strings = LDB._strings;
var strProto = new StringProto
{
Name = key,
SID = "",
ENUS = enus,
ZHCN = string.IsNullOrEmpty(zhcn) ? enus : zhcn,
FRFR = string.IsNullOrEmpty(frfr) ? enus : frfr
};
StringsToAdd.Add(strProto);
}
public static void Apply()
{
if (!_initialized) return;
var strings = LDB._strings;
var index = strings.dataArray.Length;
strings.dataArray = strings.dataArray.Concat(StringsToAdd).ToArray();
StringsToAdd.Clear();
var newIndex = strings.dataArray.Length;
for (; index < newIndex; index++)
{
var strProto = strings.dataArray[index];
strProto.ID = GetNextID();
strings.dataIndices[strProto.ID] = index;
strings.nameIndices[strings.dataArray[index].Name] = index;
}
}
[HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")]
private static void VFPreload_InvokeOnLoadWorkEnded_Postfix()
{
if (_initialized) return;
_initialized = true;
if (StringsToAdd.Count == 0)
{
OnInitialized?.Invoke();
return;
}
Apply();
OnInitialized?.Invoke();
}
private static int GetNextID()
{
var strings = LDB._strings;
while (_nextID <= 12000)
{
if (!strings.dataIndices.ContainsKey(_nextID))
{
break;
}
_nextID++;
}
var result = _nextID;
_nextID++;
return result;
}
}

View File

@@ -32,32 +32,44 @@ class PatchUILoadGame
if (_decompressButton) return; if (_decompressButton) return;
var loadButton = __instance.loadButton; var loadButton = __instance.loadButton;
var created = false;
var gameObj = __instance.transform.Find("button-decompress")?.gameObject; var gameObj = __instance.transform.Find("button-decompress")?.gameObject;
if (gameObj == null) if (gameObj == null)
{
gameObj = Object.Instantiate(loadButton.gameObject, loadButton.transform.parent); gameObj = Object.Instantiate(loadButton.gameObject, loadButton.transform.parent);
created = true;
}
_decompressButton = gameObj.GetComponent<UIButton>(); _decompressButton = gameObj.GetComponent<UIButton>();
__instance.loadSandboxGroup.transform.Translate(new Vector3(-2.5f, 0, 0)); if (created)
_decompressButton.gameObject.name = "button-decompress";
_decompressButton.transform.Translate(new Vector3(-2.0f, 0, 0));
_decompressButton.button.image.color = new Color32(0, 0xf4, 0x92, 0x77);
var localizer = _decompressButton.transform.Find("button-text")?.GetComponent<Localizer>();
var text = _decompressButton.transform.Find("button-text")?.GetComponent<Text>();
if (localizer)
{ {
localizer.stringKey = "Decompress"; var rtrans = (RectTransform)__instance.loadSandboxGroup.transform;
localizer.translation = "Decompress".Translate(); var pos = rtrans.anchoredPosition3D;
} rtrans.anchoredPosition3D = new Vector3(pos.x - 230, pos.y, pos.z);
if (text) _decompressButton.gameObject.name = "button-decompress";
rtrans = (RectTransform)_decompressButton.transform;
pos = rtrans.anchoredPosition3D;
rtrans.anchoredPosition3D = new Vector3(pos.x - 180, pos.y, pos.z);
_decompressButton.button.image.color = new Color32(0, 0xf4, 0x92, 0x77);
var textTrans = _decompressButton.transform.Find("button-text");
var text = textTrans.GetComponent<Text>();
text.text = "Decompress".Translate(); text.text = "Decompress".Translate();
var localizer = textTrans.GetComponent<Localizer>();
if (localizer)
{
localizer.stringKey = "Decompress";
localizer.translation = "Decompress".Translate();
}
_decompressButton.onClick += _ =>
{
if (!SaveUtil.DecompressSave(__instance.selected.saveName, out var newfileName)) return;
__instance.RefreshList();
__instance.selected = __instance.entries.First(e => e.saveName == newfileName);
};
}
_decompressButton.onClick += _ =>
{
if (!SaveUtil.DecompressSave(__instance.selected.saveName, out var newfileName)) return;
__instance.RefreshList();
__instance.selected = __instance.entries.First(e => e.saveName == newfileName);
};
_decompressButton.button.interactable = false; _decompressButton.button.interactable = false;
_decompressButton.gameObject.SetActive(false); _decompressButton.gameObject.SetActive(false);
} }

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using HarmonyLib; using HarmonyLib;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
@@ -19,7 +20,7 @@ static class PatchUISaveGame
} }
[HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange"), HarmonyPostfix] [HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange"), HarmonyPostfix]
static void OnSelectedChange(UISaveGameWindow __instance) private static void OnSelectedChange(UISaveGameWindow __instance)
{ {
var selected = __instance.selected; var selected = __instance.selected;
var compressedType = SaveUtil.SaveGetCompressType(selected == null ? null : selected.saveName); var compressedType = SaveUtil.SaveGetCompressType(selected == null ? null : selected.saveName);
@@ -46,20 +47,16 @@ static class PatchUISaveGame
private static void CheckAndSetSaveButtonEnable(UISaveGameWindow __instance) private static void CheckAndSetSaveButtonEnable(UISaveGameWindow __instance)
{ {
_OnOpen(__instance); _OnOpen(__instance);
if (_context.SaveButtonText && _context.SaveButton) if (_context.SaveButton)
SetButtonState(_context.SaveButtonText.text, _context.SaveButton.button.interactable); _context.ButtonCompress.button.interactable = _context.SaveButton.button.interactable;
}
private static void SetButtonState(string text, bool interactable)
{
_context.ButtonCompress.button.interactable = interactable;
_context.ButtonCompressText.text = text;
} }
private class UIContext private class UIContext
{ {
public UIButton ButtonCompress; public UIButton ButtonCompress;
public UIButton SaveButton; public UIButton SaveButton;
public GameObject ManualSaveTypeComboBox;
public GameObject AutoSaveTypeComboBox;
public Text ButtonCompressText; public Text ButtonCompressText;
public Text SaveButtonText; public Text SaveButtonText;
public UISaveGameWindow Window; public UISaveGameWindow Window;
@@ -77,23 +74,134 @@ static class PatchUISaveGame
private static void _OnOpen(UISaveGameWindow __instance) private static void _OnOpen(UISaveGameWindow __instance)
{ {
if (_context.ButtonCompress) return; if (_context.ButtonCompress) return;
RectTransform rtrans;
Vector3 pos;
_context.SaveButton = __instance.saveButton; _context.SaveButton = __instance.saveButton;
_context.SaveButtonText = __instance.saveButtonText; _context.SaveButtonText = __instance.saveButtonText;
_context.Window = __instance; _context.Window = __instance;
var gameObj = __instance.transform.Find("button-compress")?.gameObject; var gameObj = __instance.transform.Find("button-compress")?.gameObject;
var created = false;
if (gameObj == null) if (gameObj == null)
{
gameObj = Object.Instantiate(__instance.saveButton.gameObject, __instance.saveButton.transform.parent); gameObj = Object.Instantiate(__instance.saveButton.gameObject, __instance.saveButton.transform.parent);
created = true;
}
_context.ButtonCompress = gameObj.GetComponent<UIButton>(); _context.ButtonCompress = gameObj.GetComponent<UIButton>();
if (created)
{
_context.ButtonCompress.gameObject.name = "button-compress";
rtrans = (RectTransform)_context.ButtonCompress.transform;
pos = rtrans.anchoredPosition3D;
rtrans.anchoredPosition3D = new Vector3(pos.x - 180, pos.y, pos.z);
_context.ButtonCompress.button.image.color = new Color32(0xfc, 0x6f, 00, 0x77);
var textTrans = _context.ButtonCompress.transform.Find("button-text");
_context.ButtonCompressText = textTrans.GetComponent<Text>();
_context.ButtonCompress.onClick += __instance.OnSaveClick;
_context.SaveButton.onClick -= __instance.OnSaveClick;
_context.SaveButton.onClick += WrapClick;
_context.ButtonCompressText.text = "Save with Compression".Translate();
var localizer = textTrans.GetComponent<Localizer>();
if (localizer)
{
localizer.stringKey = "Save with Compression";
localizer.translation = "Save with Compression".Translate();
}
}
_context.ButtonCompress.gameObject.name = "button-compress"; created = false;
_context.ButtonCompress.transform.Translate(new Vector3(-2.0f, 0, 0)); gameObj = __instance.transform.Find("manual-save-type-combobox")?.gameObject;
_context.ButtonCompress.button.image.color = new Color32(0xfc, 0x6f, 00, 0x77); if (gameObj == null)
_context.ButtonCompressText = _context.ButtonCompress.transform.Find("button-text")?.GetComponent<Text>(); {
gameObj = Object.Instantiate(UIRoot.instance.optionWindow.resolutionComp.transform.parent.gameObject, __instance.saveButton.transform.parent);
created = true;
}
_context.ManualSaveTypeComboBox = gameObj;
if (created)
{
_context.ManualSaveTypeComboBox.name = "manual-save-type-combobox";
rtrans = (RectTransform)_context.ManualSaveTypeComboBox.transform;
var rtrans2 = (RectTransform)_context.ButtonCompress.transform;
pos = rtrans2.anchoredPosition3D;
rtrans.anchorMin = rtrans2.anchorMin;
rtrans.anchorMax = rtrans2.anchorMax;
rtrans.pivot = rtrans2.pivot;
rtrans.anchoredPosition3D = new Vector3(pos.x + 100, pos.y + 45, pos.z);
var cb = rtrans.transform.Find("ComboBox").GetComponent<UIComboBox>();
cb.onSubmit.RemoveAllListeners();
cb.onItemIndexChange.RemoveAllListeners();
cb.Items = new List<string> { "Store".Translate(), "LZ4", "Zstd" };
cb.itemIndex = (int)PatchSave.CompressionTypeForSaves;
cb.onItemIndexChange.AddListener(()=>
{
PatchSave.CompressionTypeForSaves = (CompressionType)cb.itemIndex;
PatchSave.CompressionTypeForSavesConfig.Value = CompressSave.StringFromCompresstionType(PatchSave.CompressionTypeForSaves);
});
rtrans = (RectTransform)cb.transform;
pos = rtrans.anchoredPosition3D;
rtrans.anchoredPosition3D = new Vector3(pos.x - 50, pos.y, pos.z);
var size = rtrans.sizeDelta;
rtrans.sizeDelta = new Vector2(150f, size.y);
var txt = _context.ManualSaveTypeComboBox.GetComponent<Text>();
txt.text = "Compression for manual saves".Translate();
var localizer = _context.ManualSaveTypeComboBox.GetComponent<Localizer>();
if (localizer != null)
{
localizer.stringKey = "Compression for manual saves";
localizer.translation = "Compression for manual saves".Translate();
}
}
_context.ButtonCompress.onClick += __instance.OnSaveClick; created = false;
_context.SaveButton.onClick -= __instance.OnSaveClick; gameObj = __instance.transform.Find("auto-save-type-combobox")?.gameObject;
_context.SaveButton.onClick += WrapClick; if (gameObj == null)
{
gameObj = Object.Instantiate(UIRoot.instance.optionWindow.resolutionComp.transform.parent.gameObject, __instance.saveButton.transform.parent);
created = true;
}
_context.AutoSaveTypeComboBox = gameObj;
if (created)
{
_context.AutoSaveTypeComboBox.name = "auto-save-type-combobox";
rtrans = (RectTransform)_context.AutoSaveTypeComboBox.transform;
var rtrans2 = (RectTransform)_context.ButtonCompress.transform;
pos = rtrans2.anchoredPosition3D;
rtrans.anchorMin = rtrans2.anchorMin;
rtrans.anchorMax = rtrans2.anchorMax;
rtrans.pivot = rtrans2.pivot;
rtrans.anchoredPosition3D = new Vector3(pos.x + 510, pos.y + 45, pos.z);
var cb = rtrans.transform.Find("ComboBox").GetComponent<UIComboBox>();
cb.onSubmit.RemoveAllListeners();
cb.onItemIndexChange.RemoveAllListeners();
cb.Items = new List<string> { "已停用".Translate(), "Store".Translate(), "LZ4", "Zstd" };
cb.itemIndex = PatchSave.EnableForAutoSaves.Value ? (int)PatchSave.CompressionTypeForAutoSaves + 1 : 0;
cb.onItemIndexChange.AddListener(() =>
{
var idx = cb.itemIndex;
if (idx == 0)
{
PatchSave.EnableForAutoSaves.Value = false;
}
else
{
PatchSave.EnableForAutoSaves.Value = true;
PatchSave.CompressionTypeForAutoSaves = (CompressionType)idx - 1;
PatchSave.CompressionTypeForAutoSavesConfig.Value = CompressSave.StringFromCompresstionType(PatchSave.CompressionTypeForAutoSaves);
}
});
rtrans = (RectTransform)cb.transform;
pos = rtrans.anchoredPosition3D;
rtrans.anchoredPosition3D = new Vector3(pos.x - 50, pos.y, pos.z);
var size = rtrans.sizeDelta;
rtrans.sizeDelta = new Vector2(150f, size.y);
var txt = _context.AutoSaveTypeComboBox.GetComponent<Text>();
txt.text = "Compression for auto saves".Translate();
var localizer = _context.AutoSaveTypeComboBox.GetComponent<Localizer>();
if (localizer != null)
{
localizer.stringKey = "Compression for auto saves";
localizer.translation = "Compression for auto saves".Translate();
}
}
} }
private static void WrapClick(int data) private static void WrapClick(int data)
@@ -101,5 +209,4 @@ static class PatchUISaveGame
PatchSave.UseCompressSave = false; PatchSave.UseCompressSave = false;
_context.Window.OSaveGameAs(data); _context.Window.OSaveGameAs(data);
} }
}
}

View File

@@ -5,7 +5,11 @@
#### 压缩游戏存档以降低空间使用并提升保存速度 #### 压缩游戏存档以降低空间使用并提升保存速度
#### 原作者 [@bluedoom](https://github.com/bluedoom/DSP_Mod)(直到1.1.11) 和 [@starfi5h](https://github.com/starfi5h/DSP_CompressSave)(1.1.12),本人继续更新以支持最新游戏版本。 #### 原作者 [@bluedoom](https://github.com/bluedoom/DSP_Mod)(直到1.1.11) 和 [@starfi5h](https://github.com/starfi5h/DSP_CompressSave)(1.1.12),本人继续更新以支持最新游戏版本。
## Updates ## Changelog
### 1.3.2
* Add config UI on Save Game dialog, to set compression types.
* Change button text to `Save (Compress)` for better understanding.
### 1.3.1 ### 1.3.1
* Add config to disable feature for auto saves. * Add config to disable feature for auto saves.
@@ -14,7 +18,7 @@
### 1.3.0 ### 1.3.0
* Separate config entries for manual save and auto save. * Separate config entries for manual save and auto save.
* Now you can still get speed benefit while setting compression type to `None` for auto saves, and for manual saves if using the new `Save` button. * Now you can still get speed benefit while setting compression type to `None` for auto saves, and for manual saves if using the new `Save` button.
* Adds a `nonewrap.dll` for this function. + Adds a `nonewrap.dll` for this function.
* Update `LZ4` and `Zstd` library to latest version. * Update `LZ4` and `Zstd` library to latest version.
* `lz4wrap.dll` and `zstdwrap.dll` are compiled using `-O3` instead of `-Os`, expect to be slightly faster but larger. * `lz4wrap.dll` and `zstdwrap.dll` are compiled using `-O3` instead of `-Os`, expect to be slightly faster but larger.
@@ -112,7 +116,7 @@
## Introduction ## Introduction
* Reduce archive size by 30% / save time by 75% (On HDD + i7-4790K@4.4G + DDR3 2400MHz) * Reduce archive size by 30% / save time by 75% (Compressed by LZ4, on HDD + i7-4790K@4.4G + DDR3 2400MHz)
| Before | After | | Before | After |
| - | - | | - | - |
@@ -128,9 +132,38 @@
* You can decompress saves on load panel. * You can decompress saves on load panel.
* Remember to backup your save(use original save button) before updating game to avoid loading failure. * Remember to backup your save(use original save button) before updating game to avoid loading failure.
## 更新日志
### 1.3.2
* 在保存面板上增加设置压缩方式的UI。
* 将按钮文本改为`压缩保存`以区分功能。
### 1.3.1
* 增加在自动存档中禁用压缩的设置项。
* 修复一个导致游戏开始后第一次保存总是使用Zstd压缩的bug。
### 1.3.0
* 分离手动存档和自动存档的设置项。
* 现在在自动存档设置压缩类型为`存储`也可以获得速度提升,手动存档也可以在使用新的`保存`按钮后获得速度提升。
+ 为此增加了`nonewrap.dll`
* 更新`LZ4``Zstd`库到最新版本。
* `lz4wrap.dll``zstdwrap.dll`使用`-O3`编译而不是`-Os`,速度略有提升但体积变大。
### 1.2.2
* 修复 #4一个导致非ASCII UTF-8字符导致的bug。
* 移除使用Harmony.UnpatchAll()以避免在BepInEx日志中出现警告。
### 1.2.1
* 简化代码以在存档读取面板上显示压缩类型和`解压`按钮使得CompressSave与其他MOD(如GalacticScale)兼容,因为它们都覆盖了`UILoadGameWindow::OnSelectedChange()`
* 为zstd添加了压缩等级-5到-1现在它比lz4(实际上是lz4frame)表现更好了:
* -5比lz4更快但压缩比略有提升。
* -1和lz4几乎一样快但压缩比更高。
* 由于r2modman UI的bug压缩等级的设置项不再限制范围。
* 将本地的wrapper DLL移动到`x64`
## 介绍 ## 介绍
* 减少存档容量30% / 存档用时75% (测试环境:机械硬盘 + i7-4790K@4.4G + DDR3 2400MHz) * 减少存档容量30% / 存档用时75% (LZ4压缩测试环境:机械硬盘 + i7-4790K@4.4G + DDR3 2400MHz)
| 原存档 | 压缩后 | | 原存档 | 压缩后 |
| - | - | | - | - |

View File

@@ -1,6 +1,6 @@
{ {
"name": "CompressSave", "name": "CompressSave",
"version_number": "1.3.1", "version_number": "1.3.2",
"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"]