mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-08 20:53:28 +08:00
CompressSave v1.3.2
This commit is contained in:
@@ -20,7 +20,7 @@ public enum CompressionType
|
||||
public class CompressSave : BaseUnityPlugin
|
||||
{
|
||||
private Harmony _patchSave, _patchUISave, _patchUILoad;
|
||||
private static string StringFromCompresstionType(CompressionType type)
|
||||
public static string StringFromCompresstionType(CompressionType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
@@ -46,25 +46,22 @@ public class CompressSave : BaseUnityPlugin
|
||||
SaveUtil.Logger = Logger;
|
||||
if (LZ4API.Avaliable && ZstdAPI.Avaliable)
|
||||
{
|
||||
PatchSave.CompressionTypeForSaves = CompressionTypeFromString(
|
||||
Config.Bind("Compression", "Type", StringFromCompresstionType(PatchSave.CompressionTypeForSaves),
|
||||
PatchSave.CompressionTypeForSavesConfig = Config.Bind("Compression", "Type", StringFromCompresstionType(PatchSave.CompressionTypeForSaves),
|
||||
new ConfigDescription("Set default compression type for manual saves.",
|
||||
new AcceptableValueList<string>("lz4", "zstd", "none"), new { }))
|
||||
.Value);
|
||||
PatchSave.CompressionTypeForAutoSaves = CompressionTypeFromString(
|
||||
Config.Bind("Compression", "TypeForAuto", StringFromCompresstionType(PatchSave.CompressionTypeForSaves),
|
||||
new AcceptableValueList<string>("lz4", "zstd", "none"), new { }));
|
||||
PatchSave.CompressionTypeForSaves = CompressionTypeFromString(PatchSave.CompressionTypeForSavesConfig.Value);
|
||||
PatchSave.CompressionTypeForAutoSavesConfig = Config.Bind("Compression", "TypeForAuto", StringFromCompresstionType(PatchSave.CompressionTypeForAutoSaves),
|
||||
new ConfigDescription("Set default compression type for auto saves and last-exit save.",
|
||||
new AcceptableValueList<string>("lz4", "zstd", "none"), new { }))
|
||||
.Value);
|
||||
new AcceptableValueList<string>("lz4", "zstd", "none"), new { }));
|
||||
PatchSave.CompressionTypeForAutoSaves = CompressionTypeFromString(PatchSave.CompressionTypeForAutoSavesConfig.Value);
|
||||
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.")
|
||||
.Value;
|
||||
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.")
|
||||
.Value;
|
||||
PatchSave.EnableForAutoSaves = Config.Bind("Compression", "EnableForAutoSaves", PatchSave.EnableForAutoSaves,
|
||||
"Enable the feature for auto saves and last-exit save.")
|
||||
.Value;
|
||||
PatchSave.EnableForAutoSaves = Config.Bind("Compression", "EnableForAutoSaves", true,
|
||||
"Enable the feature for auto saves and last-exit save.");
|
||||
PatchSave.CreateCompressBuffer();
|
||||
if (GameConfig.gameVersion != SaveUtil.VerifiedVersion)
|
||||
{
|
||||
@@ -78,7 +75,14 @@ public class CompressSave : BaseUnityPlugin
|
||||
_patchUILoad = Harmony.CreateAndPatchAll(typeof(PatchUILoadGame));
|
||||
}
|
||||
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()
|
||||
@@ -108,9 +112,11 @@ public class PatchSave
|
||||
private static int _compressionLevelForSaving;
|
||||
public static CompressionType CompressionTypeForSaves = 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 CompressionLevelForAutoSaves;
|
||||
public static bool EnableForAutoSaves = true;
|
||||
public static ConfigEntry<bool> EnableForAutoSaves;
|
||||
private static Stream _compressionStream;
|
||||
public static bool EnableCompress;
|
||||
|
||||
@@ -151,7 +157,7 @@ public class PatchSave
|
||||
[HarmonyPatch(typeof(GameSave), "SaveAsLastExit")]
|
||||
private static void BeforeAutoSave()
|
||||
{
|
||||
UseCompressSave = EnableForAutoSaves && EnableCompress;
|
||||
UseCompressSave = EnableForAutoSaves.Value && EnableCompress;
|
||||
if (!UseCompressSave) return;
|
||||
_compressionTypeForSaving = CompressionTypeForAutoSaves;
|
||||
_compressionLevelForSaving = CompressionLevelForAutoSaves;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<AssemblyName>CompressSave</AssemblyName>
|
||||
<BepInExPluginGuid>org.soardev.compresssave</BepInExPluginGuid>
|
||||
<Description>DSP MOD - CompressSave</Description>
|
||||
<Version>1.3.1</Version>
|
||||
<Version>1.3.2</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
|
||||
85
CompressSave/I18N.cs
Normal file
85
CompressSave/I18N.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -32,32 +32,44 @@ class PatchUILoadGame
|
||||
if (_decompressButton) return;
|
||||
var loadButton = __instance.loadButton;
|
||||
|
||||
var created = false;
|
||||
var gameObj = __instance.transform.Find("button-decompress")?.gameObject;
|
||||
if (gameObj == null)
|
||||
{
|
||||
gameObj = Object.Instantiate(loadButton.gameObject, loadButton.transform.parent);
|
||||
created = true;
|
||||
}
|
||||
|
||||
_decompressButton = gameObj.GetComponent<UIButton>();
|
||||
|
||||
__instance.loadSandboxGroup.transform.Translate(new Vector3(-2.5f, 0, 0));
|
||||
_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)
|
||||
if (created)
|
||||
{
|
||||
localizer.stringKey = "Decompress";
|
||||
localizer.translation = "Decompress".Translate();
|
||||
}
|
||||
if (text)
|
||||
var rtrans = (RectTransform)__instance.loadSandboxGroup.transform;
|
||||
var pos = rtrans.anchoredPosition3D;
|
||||
rtrans.anchoredPosition3D = new Vector3(pos.x - 230, pos.y, pos.z);
|
||||
_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();
|
||||
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.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@@ -19,7 +20,7 @@ static class PatchUISaveGame
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange"), HarmonyPostfix]
|
||||
static void OnSelectedChange(UISaveGameWindow __instance)
|
||||
private static void OnSelectedChange(UISaveGameWindow __instance)
|
||||
{
|
||||
var selected = __instance.selected;
|
||||
var compressedType = SaveUtil.SaveGetCompressType(selected == null ? null : selected.saveName);
|
||||
@@ -46,20 +47,16 @@ static class PatchUISaveGame
|
||||
private static void CheckAndSetSaveButtonEnable(UISaveGameWindow __instance)
|
||||
{
|
||||
_OnOpen(__instance);
|
||||
if (_context.SaveButtonText && _context.SaveButton)
|
||||
SetButtonState(_context.SaveButtonText.text, _context.SaveButton.button.interactable);
|
||||
}
|
||||
|
||||
private static void SetButtonState(string text, bool interactable)
|
||||
{
|
||||
_context.ButtonCompress.button.interactable = interactable;
|
||||
_context.ButtonCompressText.text = text;
|
||||
if (_context.SaveButton)
|
||||
_context.ButtonCompress.button.interactable = _context.SaveButton.button.interactable;
|
||||
}
|
||||
|
||||
private class UIContext
|
||||
{
|
||||
public UIButton ButtonCompress;
|
||||
public UIButton SaveButton;
|
||||
public GameObject ManualSaveTypeComboBox;
|
||||
public GameObject AutoSaveTypeComboBox;
|
||||
public Text ButtonCompressText;
|
||||
public Text SaveButtonText;
|
||||
public UISaveGameWindow Window;
|
||||
@@ -77,23 +74,134 @@ static class PatchUISaveGame
|
||||
private static void _OnOpen(UISaveGameWindow __instance)
|
||||
{
|
||||
if (_context.ButtonCompress) return;
|
||||
RectTransform rtrans;
|
||||
Vector3 pos;
|
||||
_context.SaveButton = __instance.saveButton;
|
||||
_context.SaveButtonText = __instance.saveButtonText;
|
||||
|
||||
_context.Window = __instance;
|
||||
var gameObj = __instance.transform.Find("button-compress")?.gameObject;
|
||||
var created = false;
|
||||
if (gameObj == null)
|
||||
{
|
||||
gameObj = Object.Instantiate(__instance.saveButton.gameObject, __instance.saveButton.transform.parent);
|
||||
created = true;
|
||||
}
|
||||
_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";
|
||||
_context.ButtonCompress.transform.Translate(new Vector3(-2.0f, 0, 0));
|
||||
_context.ButtonCompress.button.image.color = new Color32(0xfc, 0x6f, 00, 0x77);
|
||||
_context.ButtonCompressText = _context.ButtonCompress.transform.Find("button-text")?.GetComponent<Text>();
|
||||
created = false;
|
||||
gameObj = __instance.transform.Find("manual-save-type-combobox")?.gameObject;
|
||||
if (gameObj == null)
|
||||
{
|
||||
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;
|
||||
_context.SaveButton.onClick -= __instance.OnSaveClick;
|
||||
_context.SaveButton.onClick += WrapClick;
|
||||
created = false;
|
||||
gameObj = __instance.transform.Find("auto-save-type-combobox")?.gameObject;
|
||||
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)
|
||||
@@ -101,5 +209,4 @@ static class PatchUISaveGame
|
||||
PatchSave.UseCompressSave = false;
|
||||
_context.Window.OSaveGameAs(data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
#### 压缩游戏存档以降低空间使用并提升保存速度
|
||||
#### 原作者 [@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
|
||||
* Add config to disable feature for auto saves.
|
||||
@@ -14,7 +18,7 @@
|
||||
### 1.3.0
|
||||
* 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.
|
||||
* Adds a `nonewrap.dll` for this function.
|
||||
+ Adds a `nonewrap.dll` for this function.
|
||||
* 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.
|
||||
|
||||
@@ -112,7 +116,7 @@
|
||||
|
||||
## 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 |
|
||||
| - | - |
|
||||
@@ -128,9 +132,38 @@
|
||||
* You can decompress saves on load panel.
|
||||
* 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)
|
||||
|
||||
| 原存档 | 压缩后 |
|
||||
| - | - |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "CompressSave",
|
||||
"version_number": "1.3.1",
|
||||
"version_number": "1.3.2",
|
||||
"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"]
|
||||
|
||||
Reference in New Issue
Block a user