mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-09 08:13:35 +08:00
cleanup codes
This commit is contained in:
@@ -19,31 +19,31 @@ public enum CompressionType
|
|||||||
[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
|
||||||
{
|
{
|
||||||
private Harmony patchSave, patchUISave, patchUILoad;
|
private Harmony _patchSave, _patchUISave, _patchUILoad;
|
||||||
string StringFromCompresstionType(CompressionType type)
|
private static string StringFromCompresstionType(CompressionType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
return type switch
|
||||||
{
|
{
|
||||||
case CompressionType.LZ4: return "lz4";
|
CompressionType.LZ4 => "lz4",
|
||||||
case CompressionType.Zstd: return "zstd";
|
CompressionType.Zstd => "zstd",
|
||||||
case CompressionType.None: return "none";
|
CompressionType.None => "none",
|
||||||
default: throw new ArgumentException("Unknown compression type.");
|
_ => throw new ArgumentException("Unknown compression type.")
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
CompressionType CompressionTypeFromString(string str)
|
private static CompressionType CompressionTypeFromString(string str)
|
||||||
{
|
{
|
||||||
switch (str)
|
return str switch
|
||||||
{
|
{
|
||||||
case "lz4": return CompressionType.LZ4;
|
"lz4" => CompressionType.LZ4,
|
||||||
case "zstd": return CompressionType.Zstd;
|
"zstd" => CompressionType.Zstd,
|
||||||
default: return CompressionType.None;
|
_ => CompressionType.None
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Awake()
|
public void Awake()
|
||||||
{
|
{
|
||||||
SaveUtil.logger = Logger;
|
SaveUtil.Logger = Logger;
|
||||||
if (LZ4API.Avaliable && ZstdAPI.Avaliable)
|
if (LZ4API.Avaliable && ZstdAPI.Avaliable)
|
||||||
{
|
{
|
||||||
PatchSave.CompressionTypeForSaves = CompressionTypeFromString(
|
PatchSave.CompressionTypeForSaves = CompressionTypeFromString(
|
||||||
@@ -68,36 +68,36 @@ public class CompressSave : BaseUnityPlugin
|
|||||||
PatchSave.CreateCompressBuffer();
|
PatchSave.CreateCompressBuffer();
|
||||||
if (GameConfig.gameVersion != SaveUtil.VerifiedVersion)
|
if (GameConfig.gameVersion != SaveUtil.VerifiedVersion)
|
||||||
{
|
{
|
||||||
SaveUtil.logger.LogWarning(
|
SaveUtil.Logger.LogWarning(
|
||||||
$"Save version mismatch. Expect:{SaveUtil.VerifiedVersion}, Current:{GameConfig.gameVersion}. MOD may not work as expected.");
|
$"Save version mismatch. Expect:{SaveUtil.VerifiedVersion}, Current:{GameConfig.gameVersion}. MOD may not work as expected.");
|
||||||
}
|
}
|
||||||
|
|
||||||
patchSave = Harmony.CreateAndPatchAll(typeof(PatchSave));
|
_patchSave = Harmony.CreateAndPatchAll(typeof(PatchSave));
|
||||||
if (PatchSave.EnableCompress)
|
if (PatchSave.EnableCompress)
|
||||||
patchUISave = Harmony.CreateAndPatchAll(typeof(PatchUISaveGame));
|
_patchUISave = Harmony.CreateAndPatchAll(typeof(PatchUISaveGame));
|
||||||
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 lz4warp.dll or zstdwrap.dll is not avaliable.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDestroy()
|
public void OnDestroy()
|
||||||
{
|
{
|
||||||
if (patchUISave != null)
|
if (_patchUISave != null)
|
||||||
{
|
{
|
||||||
PatchUISaveGame.OnDestroy();
|
PatchUISaveGame.OnDestroy();
|
||||||
patchUISave.UnpatchSelf();
|
_patchUISave.UnpatchSelf();
|
||||||
}
|
}
|
||||||
if (patchUILoad != null)
|
if (_patchUILoad != null)
|
||||||
{
|
{
|
||||||
PatchUILoadGame.OnDestroy();
|
PatchUILoadGame.OnDestroy();
|
||||||
patchUILoad.UnpatchSelf();
|
_patchUILoad.UnpatchSelf();
|
||||||
}
|
}
|
||||||
patchSave?.UnpatchSelf();
|
_patchSave?.UnpatchSelf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PatchSave
|
public class PatchSave
|
||||||
{
|
{
|
||||||
public static readonly WrapperDefines LZ4Wrapper = new LZ4API(), ZstdWrapper = new ZstdAPI();
|
public static readonly WrapperDefines LZ4Wrapper = new LZ4API(), ZstdWrapper = new ZstdAPI();
|
||||||
private static readonly WrapperDefines NoneWrapper = new NoneAPI();
|
private static readonly WrapperDefines NoneWrapper = new NoneAPI();
|
||||||
@@ -105,7 +105,7 @@ class PatchSave
|
|||||||
public static bool UseCompressSave;
|
public static bool UseCompressSave;
|
||||||
private static CompressionType _compressionTypeForLoading = CompressionType.None;
|
private static CompressionType _compressionTypeForLoading = CompressionType.None;
|
||||||
private static CompressionType _compressionTypeForSaving = CompressionType.Zstd;
|
private static CompressionType _compressionTypeForSaving = CompressionType.Zstd;
|
||||||
private static int _compressionLevelForSaving = 0;
|
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 int CompressionLevelForSaves;
|
public static int CompressionLevelForSaves;
|
||||||
@@ -116,7 +116,7 @@ class PatchSave
|
|||||||
|
|
||||||
public static void CreateCompressBuffer()
|
public static void CreateCompressBuffer()
|
||||||
{
|
{
|
||||||
var bufSize = CompressionStream.MB;
|
const int bufSize = CompressionStream.MB;
|
||||||
var outBufSize = LZ4Wrapper.CompressBufferBound(bufSize);
|
var outBufSize = LZ4Wrapper.CompressBufferBound(bufSize);
|
||||||
outBufSize = Math.Max(outBufSize, ZstdWrapper.CompressBufferBound(bufSize));
|
outBufSize = Math.Max(outBufSize, ZstdWrapper.CompressBufferBound(bufSize));
|
||||||
outBufSize = Math.Max(outBufSize, NoneWrapper.CompressBufferBound(bufSize));
|
outBufSize = Math.Max(outBufSize, NoneWrapper.CompressBufferBound(bufSize));
|
||||||
@@ -127,6 +127,7 @@ class PatchSave
|
|||||||
|
|
||||||
private static void WriteHeader(FileStream fileStream)
|
private static void WriteHeader(FileStream fileStream)
|
||||||
{
|
{
|
||||||
|
if (fileStream == null) throw new ArgumentNullException(nameof(fileStream));
|
||||||
switch (_compressionTypeForSaving)
|
switch (_compressionTypeForSaving)
|
||||||
{
|
{
|
||||||
case CompressionType.Zstd:
|
case CompressionType.Zstd:
|
||||||
@@ -148,59 +149,57 @@ class PatchSave
|
|||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(GameSave), "AutoSave")]
|
[HarmonyPatch(typeof(GameSave), "AutoSave")]
|
||||||
[HarmonyPatch(typeof(GameSave), "SaveAsLastExit")]
|
[HarmonyPatch(typeof(GameSave), "SaveAsLastExit")]
|
||||||
static void BeforeAutoSave()
|
private static void BeforeAutoSave()
|
||||||
{
|
{
|
||||||
UseCompressSave = EnableForAutoSaves && EnableCompress;
|
UseCompressSave = EnableForAutoSaves && EnableCompress;
|
||||||
if (UseCompressSave)
|
if (!UseCompressSave) return;
|
||||||
{
|
_compressionTypeForSaving = CompressionTypeForAutoSaves;
|
||||||
_compressionTypeForSaving = CompressionTypeForAutoSaves;
|
_compressionLevelForSaving = CompressionLevelForAutoSaves;
|
||||||
_compressionLevelForSaving = CompressionLevelForAutoSaves;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyTranspiler]
|
[HarmonyTranspiler]
|
||||||
[HarmonyPatch(typeof(GameSave), "SaveCurrentGame")]
|
[HarmonyPatch(typeof(GameSave), "SaveCurrentGame")]
|
||||||
static IEnumerable<CodeInstruction> SaveCurrentGame_Transpiler(IEnumerable<CodeInstruction> instructions,
|
private static IEnumerable<CodeInstruction> SaveCurrentGame_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
ILGenerator generator)
|
|
||||||
{
|
{
|
||||||
/* BinaryWriter binaryWriter = new BinaryWriter(fileStream); => Create compressionStream and replace binaryWriter.
|
/* BinaryWriter binaryWriter = new BinaryWriter(fileStream); => Create compressionStream and replace binaryWriter.
|
||||||
* set PerformanceMonitor.BeginStream to compressionStream.
|
* set PerformanceMonitor.BeginStream to compressionStream.
|
||||||
* fileStream.Seek(6L, SeekOrigin.Begin); binaryWriter.Write(position); => Disable seek&write function.
|
* fileStream.Seek(6L, SeekOrigin.Begin); binaryWriter.Write(position); => Disable seek&write function.
|
||||||
* binaryWriter.Dispose(); => Dispose compressionStream before fileStream close.
|
* binaryWriter.Dispose(); => Dispose compressionStream before fileStream close.
|
||||||
*/
|
*/
|
||||||
|
var matcher = new CodeMatcher(instructions, generator);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var matcher = new CodeMatcher(instructions, generator)
|
matcher.MatchForward(false,
|
||||||
.MatchForward(false,
|
new CodeMatch(OpCodes.Newobj, AccessTools.Constructor(typeof(BinaryWriter), new [] { typeof(FileStream) }))
|
||||||
new CodeMatch(OpCodes.Newobj,
|
).Set(
|
||||||
AccessTools.Constructor(typeof(BinaryWriter), new Type[] { typeof(FileStream) })))
|
OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryWriter")
|
||||||
.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryWriter"))
|
).MatchForward(false,
|
||||||
.MatchForward(false,
|
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream"))
|
||||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream")))
|
).Set(
|
||||||
.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "MonitorStream"))
|
OpCodes.Call, AccessTools.Method(typeof(PatchSave), "MonitorStream")
|
||||||
.MatchForward(false,
|
).MatchForward(false,
|
||||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IO.Stream), "Seek")))
|
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(Stream), "Seek"))
|
||||||
.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthWrite0"))
|
).Set(
|
||||||
.MatchForward(false,
|
OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthWrite0")
|
||||||
new CodeMatch(OpCodes.Callvirt,
|
).MatchForward(false,
|
||||||
AccessTools.Method(typeof(BinaryWriter), "Write", new Type[] { typeof(long) })))
|
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BinaryWriter), "Write", new [] { typeof(long) }))
|
||||||
.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthWrite1"))
|
).Set(
|
||||||
.MatchForward(false,
|
OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthWrite1")
|
||||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IDisposable), "Dispose")))
|
).MatchForward(false,
|
||||||
.Advance(1)
|
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(IDisposable), "Dispose"))
|
||||||
.Insert(new CodeInstruction(OpCodes.Call,
|
).Advance(1).Insert(
|
||||||
AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream")));
|
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream"))
|
||||||
|
);
|
||||||
EnableCompress = true;
|
EnableCompress = true;
|
||||||
return matcher.InstructionEnumeration();
|
return matcher.InstructionEnumeration();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
SaveUtil.logger.LogError(
|
SaveUtil.Logger.LogError(
|
||||||
"SaveCurrentGame_Transpiler failed. Mod version not compatible with game version.");
|
"SaveCurrentGame_Transpiler failed. Mod version not compatible with game version.");
|
||||||
SaveUtil.logger.LogError(ex);
|
SaveUtil.Logger.LogError(ex);
|
||||||
}
|
}
|
||||||
|
return matcher.InstructionEnumeration();
|
||||||
return instructions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MonitorStream(Stream fileStream)
|
public static void MonitorStream(Stream fileStream)
|
||||||
@@ -212,43 +211,32 @@ class PatchSave
|
|||||||
{
|
{
|
||||||
if (UseCompressSave)
|
if (UseCompressSave)
|
||||||
{
|
{
|
||||||
SaveUtil.logger.LogDebug("Begin compress save");
|
SaveUtil.Logger.LogDebug("Begin compress save");
|
||||||
WriteHeader(fileStream);
|
WriteHeader(fileStream);
|
||||||
switch (_compressionTypeForSaving)
|
_compressionStream = _compressionTypeForSaving switch
|
||||||
{
|
{
|
||||||
case CompressionType.LZ4:
|
CompressionType.LZ4 => new CompressionStream(LZ4Wrapper, _compressionLevelForSaving, fileStream, _compressBuffer, true),
|
||||||
_compressionStream = new CompressionStream(LZ4Wrapper, _compressionLevelForSaving, fileStream, _compressBuffer, true);
|
CompressionType.Zstd => new CompressionStream(ZstdWrapper, _compressionLevelForSaving, fileStream, _compressBuffer, true),
|
||||||
break;
|
CompressionType.None => new CompressionStream(NoneWrapper, 0, fileStream, _compressBuffer, true),
|
||||||
case CompressionType.Zstd:
|
_ => _compressionStream
|
||||||
_compressionStream = new CompressionStream(ZstdWrapper, _compressionLevelForSaving, fileStream, _compressBuffer, true);
|
};
|
||||||
break;
|
|
||||||
case CompressionType.None:
|
|
||||||
_compressionStream = new CompressionStream(NoneWrapper, 0, fileStream, _compressBuffer, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((CompressionStream)_compressionStream).BufferWriter;
|
return ((CompressionStream)_compressionStream).BufferWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveUtil.logger.LogDebug("Begin normal save");
|
SaveUtil.Logger.LogDebug("Begin normal save");
|
||||||
return new BinaryWriter(fileStream);
|
return new BinaryWriter(fileStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long FileLengthWrite0(FileStream fileStream, long offset, SeekOrigin origin)
|
public static long FileLengthWrite0(FileStream fileStream, long offset, SeekOrigin origin)
|
||||||
{
|
{
|
||||||
if (!UseCompressSave)
|
return UseCompressSave ? 0L : fileStream.Seek(offset, origin);
|
||||||
{
|
|
||||||
return fileStream.Seek(offset, origin);
|
|
||||||
}
|
|
||||||
return 0L;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FileLengthWrite1(BinaryWriter binaryWriter, long value)
|
public static void FileLengthWrite1(BinaryWriter binaryWriter, long value)
|
||||||
{
|
{
|
||||||
if (!UseCompressSave)
|
if (UseCompressSave) return;
|
||||||
{
|
binaryWriter.Write(value);
|
||||||
binaryWriter.Write(value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DisposeCompressionStream()
|
public static void DisposeCompressionStream()
|
||||||
@@ -265,23 +253,23 @@ class PatchSave
|
|||||||
{
|
{
|
||||||
stream = ((CompressionStream)_compressionStream).outStream;
|
stream = ((CompressionStream)_compressionStream).outStream;
|
||||||
}
|
}
|
||||||
_compressionStream.Dispose(); //Dispose need to be done before fstream closed.
|
// Dispose need to be done before fstream closed.
|
||||||
|
_compressionStream.Dispose();
|
||||||
_compressionStream = null;
|
_compressionStream = null;
|
||||||
if (writeflag) //Reset UseCompressSave after writing to file
|
if (!writeflag) return;
|
||||||
|
// Reset UseCompressSave after writing to file
|
||||||
|
if (stream != null)
|
||||||
{
|
{
|
||||||
if (stream != null)
|
// Ugly implementation, but it works. May find a better solution someday.
|
||||||
{
|
var saveLen = stream.Seek(0L, SeekOrigin.End);
|
||||||
// Ugly implementation, but it works. May find a better solution someday.
|
stream.Seek(6L, SeekOrigin.Begin);
|
||||||
var saveLen = stream.Seek(0L, SeekOrigin.End);
|
var writer = new BinaryWriter(stream);
|
||||||
stream.Seek(6L, SeekOrigin.Begin);
|
writer.Write(saveLen);
|
||||||
var writer = new BinaryWriter(stream);
|
writer.Dispose();
|
||||||
writer.Write(saveLen);
|
|
||||||
writer.Dispose();
|
|
||||||
}
|
|
||||||
_compressionTypeForSaving = CompressionTypeForSaves;
|
|
||||||
_compressionLevelForSaving = CompressionLevelForSaves;
|
|
||||||
UseCompressSave = false;
|
|
||||||
}
|
}
|
||||||
|
_compressionTypeForSaving = CompressionTypeForSaves;
|
||||||
|
_compressionLevelForSaving = CompressionLevelForSaves;
|
||||||
|
UseCompressSave = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyTranspiler]
|
[HarmonyTranspiler]
|
||||||
@@ -290,8 +278,7 @@ class PatchSave
|
|||||||
[HarmonyPatch(typeof(GameSave), "ReadHeader")]
|
[HarmonyPatch(typeof(GameSave), "ReadHeader")]
|
||||||
[HarmonyPatch(typeof(GameSave), "ReadHeaderAndDescAndProperty")]
|
[HarmonyPatch(typeof(GameSave), "ReadHeaderAndDescAndProperty")]
|
||||||
[HarmonyPatch(typeof(GameSave), "ReadModes")]
|
[HarmonyPatch(typeof(GameSave), "ReadModes")]
|
||||||
static IEnumerable<CodeInstruction> LoadCurrentGame_Transpiler(IEnumerable<CodeInstruction> instructions,
|
private static IEnumerable<CodeInstruction> LoadCurrentGame_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
ILGenerator iLGenerator)
|
|
||||||
{
|
{
|
||||||
/* using (BinaryReader binaryReader = new BinaryReader(fileStream)) => Create decompressionStream and replace binaryReader.
|
/* using (BinaryReader binaryReader = new BinaryReader(fileStream)) => Create decompressionStream and replace binaryReader.
|
||||||
* set PerformanceMonitor.BeginStream to decompressionStream.
|
* set PerformanceMonitor.BeginStream to decompressionStream.
|
||||||
@@ -299,29 +286,31 @@ class PatchSave
|
|||||||
* fileStream.Seek((long)num2, SeekOrigin.Current); => Use decompressionStream.Read to seek forward
|
* fileStream.Seek((long)num2, SeekOrigin.Current); => Use decompressionStream.Read to seek forward
|
||||||
* binaryReader.Dispose(); => Dispose decompressionStream before fileStream close.
|
* binaryReader.Dispose(); => Dispose decompressionStream before fileStream close.
|
||||||
*/
|
*/
|
||||||
|
var matcher = new CodeMatcher(instructions, generator);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var matcher = new CodeMatcher(instructions, iLGenerator)
|
matcher.MatchForward(false,
|
||||||
.MatchForward(false,
|
new CodeMatch(OpCodes.Newobj, AccessTools.Constructor(typeof(BinaryReader), new [] { typeof(FileStream) }))
|
||||||
new CodeMatch(OpCodes.Newobj,
|
).Set(
|
||||||
AccessTools.Constructor(typeof(BinaryReader), new Type[] { typeof(FileStream) })))
|
OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryReader")
|
||||||
.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryReader"))
|
).MatchForward(false,
|
||||||
.MatchForward(false,
|
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream"))
|
||||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream")));
|
);
|
||||||
|
|
||||||
if (matcher.IsValid)
|
if (matcher.IsValid)
|
||||||
matcher.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "MonitorStream"));
|
matcher.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "MonitorStream"));
|
||||||
|
|
||||||
matcher.Start().MatchForward(false,
|
matcher.Start().MatchForward(false,
|
||||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BinaryReader), "ReadInt64")))
|
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BinaryReader), "ReadInt64"))
|
||||||
.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthRead"))
|
).Set(
|
||||||
.MatchForward(false,
|
OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthRead")
|
||||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IDisposable), "Dispose")))
|
).MatchForward(false,
|
||||||
.Advance(1)
|
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(IDisposable), "Dispose"))
|
||||||
.Insert(new CodeInstruction(OpCodes.Call,
|
).Advance(1).Insert(
|
||||||
AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream")))
|
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream"))
|
||||||
.MatchBack(false,
|
).MatchBack(false,
|
||||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IO.Stream), "Seek")));
|
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(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"));
|
||||||
|
|
||||||
@@ -329,12 +318,12 @@ class PatchSave
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
SaveUtil.logger.LogError(
|
SaveUtil.Logger.LogError(
|
||||||
"LoadCurrentGame_Transpiler failed. Mod version not compatible with game version.");
|
"LoadCurrentGame_Transpiler failed. Mod version not compatible with game version.");
|
||||||
SaveUtil.logger.LogError(ex);
|
SaveUtil.Logger.LogError(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return instructions;
|
return matcher.InstructionEnumeration();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BinaryReader CreateBinaryReader(FileStream fileStream)
|
public static BinaryReader CreateBinaryReader(FileStream fileStream)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@@ -8,69 +7,65 @@ namespace CompressSave;
|
|||||||
|
|
||||||
class PatchUILoadGame
|
class PatchUILoadGame
|
||||||
{
|
{
|
||||||
static UIButton decompressButton;
|
static UIButton _decompressButton;
|
||||||
|
|
||||||
[HarmonyPatch(typeof(UILoadGameWindow), "OnSelectedChange"), HarmonyPostfix]
|
[HarmonyPatch(typeof(UILoadGameWindow), "OnSelectedChange"), HarmonyPostfix]
|
||||||
static void OnSelectedChange(UILoadGameWindow __instance, Text ___prop3Text)
|
private static void OnSelectedChange(UILoadGameWindow __instance)
|
||||||
{
|
{
|
||||||
var compressedType = SaveUtil.SaveGetCompressType(__instance.selected?.saveName);
|
var selected = __instance.selected;
|
||||||
switch (compressedType)
|
var compressedType = SaveUtil.SaveGetCompressType(selected == null ? null : selected.saveName);
|
||||||
|
var prop3Text = __instance.prop3Text;
|
||||||
|
prop3Text.text = compressedType switch
|
||||||
{
|
{
|
||||||
case CompressionType.LZ4:
|
CompressionType.LZ4 => "(LZ4)" + prop3Text.text,
|
||||||
___prop3Text.text = "(LZ4)" + ___prop3Text.text;
|
CompressionType.Zstd => "(ZSTD)" + prop3Text.text,
|
||||||
break;
|
_ => "(N)" + prop3Text.text
|
||||||
case CompressionType.Zstd:
|
};
|
||||||
___prop3Text.text = "(ZSTD)" + ___prop3Text.text;
|
if (!_decompressButton) return;
|
||||||
break;
|
_decompressButton.button.interactable = compressedType != CompressionType.None;
|
||||||
default:
|
_decompressButton.gameObject.SetActive(compressedType != CompressionType.None);
|
||||||
___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]
|
[HarmonyPatch(typeof(UILoadGameWindow), "_OnOpen"), HarmonyPostfix]
|
||||||
static void _OnOpen(UILoadGameWindow __instance, UIButton ___loadButton, GameObject ___loadSandboxGroup, List<UIGameSaveEntry> ___entries)
|
static void _OnOpen(UILoadGameWindow __instance)
|
||||||
{
|
{
|
||||||
if (!decompressButton)
|
if (_decompressButton) return;
|
||||||
|
var loadButton = __instance.loadButton;
|
||||||
|
|
||||||
|
var gameObj = __instance.transform.Find("button-decompress")?.gameObject;
|
||||||
|
if (gameObj == null)
|
||||||
|
gameObj = Object.Instantiate(loadButton.gameObject, loadButton.transform.parent);
|
||||||
|
_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)
|
||||||
{
|
{
|
||||||
decompressButton = ___loadButton;
|
localizer.stringKey = "Decompress";
|
||||||
|
localizer.translation = "Decompress".Translate();
|
||||||
decompressButton = (__instance.transform.Find("button-decompress")?.gameObject ?? GameObject.Instantiate(___loadButton.gameObject, ___loadButton.transform.parent)).GetComponent<UIButton>();
|
|
||||||
|
|
||||||
___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)
|
|
||||||
{
|
|
||||||
localizer.stringKey = "Decompress";
|
|
||||||
localizer.translation = "Decompress".Translate();
|
|
||||||
}
|
|
||||||
if (text)
|
|
||||||
text.text = "Decompress".Translate();
|
|
||||||
|
|
||||||
decompressButton.onClick += _ =>{
|
|
||||||
if(SaveUtil.DecompressSave(__instance.selected.saveName, out var newfileName))
|
|
||||||
{
|
|
||||||
__instance.RefreshList();
|
|
||||||
__instance.selected = ___entries.First(e => e.saveName == newfileName);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
decompressButton.button.interactable = false;
|
|
||||||
decompressButton.gameObject.SetActive(false);
|
|
||||||
}
|
}
|
||||||
|
if (text)
|
||||||
|
text.text = "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.button.interactable = false;
|
||||||
|
_decompressButton.gameObject.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnDestroy()
|
public static void OnDestroy()
|
||||||
{
|
{
|
||||||
if (decompressButton)
|
if (_decompressButton)
|
||||||
GameObject.Destroy(decompressButton.gameObject);
|
Object.Destroy(_decompressButton.gameObject);
|
||||||
decompressButton = null;
|
_decompressButton = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,104 +6,100 @@ namespace CompressSave;
|
|||||||
|
|
||||||
static class PatchUISaveGame
|
static class PatchUISaveGame
|
||||||
{
|
{
|
||||||
[HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange"), HarmonyPostfix]
|
public static void OnDestroy()
|
||||||
static void OnSelectedChange(UISaveGameWindow __instance, Text ___prop3Text)
|
|
||||||
{
|
{
|
||||||
var compressedType = SaveUtil.SaveGetCompressType(__instance.selected?.saveName);
|
if (_context.ButtonCompress)
|
||||||
switch (compressedType)
|
Object.Destroy(_context.ButtonCompress.gameObject);
|
||||||
|
if (_context.Window)
|
||||||
{
|
{
|
||||||
case CompressionType.LZ4:
|
_context.SaveButton.onClick -= WrapClick;
|
||||||
___prop3Text.text = "(LZ4)" + ___prop3Text.text;
|
_context.SaveButton.onClick += _context.Window.OnSaveClick;
|
||||||
break;
|
|
||||||
case CompressionType.Zstd:
|
|
||||||
___prop3Text.text = "(ZSTD)" + ___prop3Text.text;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
___prop3Text.text = "(N)" + ___prop3Text.text;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
_OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange"), HarmonyPostfix]
|
||||||
|
static void OnSelectedChange(UISaveGameWindow __instance)
|
||||||
|
{
|
||||||
|
var selected = __instance.selected;
|
||||||
|
var compressedType = SaveUtil.SaveGetCompressType(selected == null ? null : selected.saveName);
|
||||||
|
var prop3Text = __instance.prop3Text;
|
||||||
|
prop3Text.text = compressedType switch
|
||||||
|
{
|
||||||
|
CompressionType.LZ4 => "(LZ4)" + prop3Text.text,
|
||||||
|
CompressionType.Zstd => "(ZSTD)" + prop3Text.text,
|
||||||
|
_ => "(N)" + prop3Text.text
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch(typeof(UISaveGameWindow), "_OnDestroy"), HarmonyPostfix]
|
[HarmonyPatch(typeof(UISaveGameWindow), "_OnDestroy"), HarmonyPostfix]
|
||||||
static void _OnDestroy()
|
private static void _OnDestroy()
|
||||||
{
|
{
|
||||||
//Console.WriteLine("OnCreate");
|
//Console.WriteLine("OnCreate");
|
||||||
context = new UIContext();
|
_context = new UIContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick"), HarmonyReversePatch]
|
[HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick"), HarmonyReversePatch]
|
||||||
static void OSaveGameAs(this UISaveGameWindow ui, int data) { }
|
private static void OSaveGameAs(this UISaveGameWindow ui, int data) { }
|
||||||
|
|
||||||
[HarmonyPatch(typeof(UISaveGameWindow), "CheckAndSetSaveButtonEnable"), HarmonyPostfix]
|
[HarmonyPatch(typeof(UISaveGameWindow), "CheckAndSetSaveButtonEnable"), HarmonyPostfix]
|
||||||
static void CheckAndSetSaveButtonEnable(UISaveGameWindow __instance, UIButton ___saveButton, Text ___saveButtonText)
|
private static void CheckAndSetSaveButtonEnable(UISaveGameWindow __instance)
|
||||||
{
|
{
|
||||||
_OnOpen(__instance, ___saveButton, ___saveButtonText);
|
_OnOpen(__instance);
|
||||||
if (context.saveButtonText && context.saveButton)
|
if (_context.SaveButtonText && _context.SaveButton)
|
||||||
SetButtonState(context.saveButtonText.text, context.saveButton.button.interactable);
|
SetButtonState(_context.SaveButtonText.text, _context.SaveButton.button.interactable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetButtonState(string text, bool interactable)
|
private static void SetButtonState(string text, bool interactable)
|
||||||
{
|
{
|
||||||
context.buttonCompress.button.interactable = interactable;
|
_context.ButtonCompress.button.interactable = interactable;
|
||||||
context.buttonCompressText.text = text;
|
_context.ButtonCompressText.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
class UIContext
|
private class UIContext
|
||||||
{
|
{
|
||||||
public UIButton buttonCompress;
|
public UIButton ButtonCompress;
|
||||||
public UIButton saveButton;
|
public UIButton SaveButton;
|
||||||
public Text buttonCompressText;
|
public Text ButtonCompressText;
|
||||||
public Text saveButtonText;
|
public Text SaveButtonText;
|
||||||
public UISaveGameWindow ui;
|
public UISaveGameWindow Window;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick"), HarmonyPrefix]
|
[HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick"), HarmonyPrefix]
|
||||||
static void OnSaveClick()
|
private static void OnSaveClick()
|
||||||
{
|
{
|
||||||
PatchSave.UseCompressSave = true;
|
PatchSave.UseCompressSave = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UIContext context = new UIContext();
|
private static UIContext _context = new UIContext();
|
||||||
|
|
||||||
[HarmonyPatch(typeof(UISaveGameWindow), "_OnOpen"), HarmonyPostfix]
|
[HarmonyPatch(typeof(UISaveGameWindow), "_OnOpen"), HarmonyPostfix]
|
||||||
static void _OnOpen(UISaveGameWindow __instance, UIButton ___saveButton, Text ___saveButtonText)
|
private static void _OnOpen(UISaveGameWindow __instance)
|
||||||
{
|
{
|
||||||
if (context.buttonCompress) return;
|
if (_context.ButtonCompress) return;
|
||||||
context.saveButton = ___saveButton;
|
_context.SaveButton = __instance.saveButton;
|
||||||
context.saveButtonText = ___saveButtonText;
|
_context.SaveButtonText = __instance.saveButtonText;
|
||||||
|
|
||||||
context.ui = __instance;
|
_context.Window = __instance;
|
||||||
context.buttonCompress =
|
var gameObj = __instance.transform.Find("button-compress")?.gameObject;
|
||||||
(__instance.transform.Find("button-compress")?.gameObject ??
|
if (gameObj == null)
|
||||||
GameObject.Instantiate(___saveButton.gameObject, ___saveButton.transform.parent))
|
gameObj = Object.Instantiate(__instance.saveButton.gameObject, __instance.saveButton.transform.parent);
|
||||||
.GetComponent<UIButton>();
|
_context.ButtonCompress = gameObj.GetComponent<UIButton>();
|
||||||
|
|
||||||
context.buttonCompress.gameObject.name = "button-compress";
|
_context.ButtonCompress.gameObject.name = "button-compress";
|
||||||
context.buttonCompress.transform.Translate(new Vector3(-2.0f, 0, 0));
|
_context.ButtonCompress.transform.Translate(new Vector3(-2.0f, 0, 0));
|
||||||
context.buttonCompress.button.image.color = new Color32(0xfc, 0x6f, 00, 0x77);
|
_context.ButtonCompress.button.image.color = new Color32(0xfc, 0x6f, 00, 0x77);
|
||||||
context.buttonCompressText = context.buttonCompress.transform.Find("button-text")?.GetComponent<Text>();
|
_context.ButtonCompressText = _context.ButtonCompress.transform.Find("button-text")?.GetComponent<Text>();
|
||||||
|
|
||||||
context.buttonCompress.onClick += __instance.OnSaveClick;
|
_context.ButtonCompress.onClick += __instance.OnSaveClick;
|
||||||
context.saveButton.onClick -= __instance.OnSaveClick;
|
_context.SaveButton.onClick -= __instance.OnSaveClick;
|
||||||
context.saveButton.onClick += WrapClick;
|
_context.SaveButton.onClick += WrapClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WrapClick(int data)
|
private static void WrapClick(int data)
|
||||||
{
|
{
|
||||||
PatchSave.UseCompressSave = false;
|
PatchSave.UseCompressSave = false;
|
||||||
context.ui.OSaveGameAs(data);
|
_context.Window.OSaveGameAs(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void OnDestroy()
|
|
||||||
{
|
|
||||||
if (context.buttonCompress)
|
|
||||||
GameObject.Destroy(context.buttonCompress.gameObject);
|
|
||||||
if (context.ui)
|
|
||||||
{
|
|
||||||
context.saveButton.onClick -= WrapClick;
|
|
||||||
context.saveButton.onClick += context.ui.OnSaveClick;
|
|
||||||
}
|
|
||||||
_OnDestroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -7,9 +7,9 @@ namespace CompressSave;
|
|||||||
|
|
||||||
public static class SaveUtil
|
public static class SaveUtil
|
||||||
{
|
{
|
||||||
public static ManualLogSource logger;
|
public static ManualLogSource Logger;
|
||||||
|
|
||||||
public static readonly Version VerifiedVersion = new Version
|
public static readonly Version VerifiedVersion = new()
|
||||||
{
|
{
|
||||||
Major = 0,
|
Major = 0,
|
||||||
Minor = 9,
|
Minor = 9,
|
||||||
@@ -19,19 +19,21 @@ public static class SaveUtil
|
|||||||
private static string UnzipToFile(DecompressionStream lzStream, string fullPath)
|
private static string UnzipToFile(DecompressionStream lzStream, string fullPath)
|
||||||
{
|
{
|
||||||
lzStream.ResetStream();
|
lzStream.ResetStream();
|
||||||
string dir = Path.GetDirectoryName(fullPath);
|
var dir = Path.GetDirectoryName(fullPath);
|
||||||
string filename = "[Recovery]-" + Path.GetFileNameWithoutExtension(fullPath);
|
var filename = "[Recovery]-" + Path.GetFileNameWithoutExtension(fullPath);
|
||||||
fullPath = Path.Combine(dir, filename + GameSave.saveExt);
|
fullPath = filename + GameSave.saveExt;
|
||||||
int i = 0;
|
if (dir != null) fullPath = Path.Combine(dir, fullPath);
|
||||||
|
var i = 0;
|
||||||
while(File.Exists(fullPath))
|
while(File.Exists(fullPath))
|
||||||
{
|
{
|
||||||
fullPath = Path.Combine(dir, $"{filename}[{i++}]{GameSave.saveExt}");
|
fullPath = $"{filename}[{i++}]{GameSave.saveExt}";
|
||||||
|
if (dir != null) fullPath = Path.Combine(dir, fullPath);
|
||||||
}
|
}
|
||||||
var buffer = new byte[1024 * 1024];
|
var buffer = new byte[1024 * 1024];
|
||||||
using (var fs = new FileStream(fullPath, FileMode.Create))
|
using (var fs = new FileStream(fullPath, FileMode.Create))
|
||||||
using (var br = new BinaryWriter(fs))
|
using (var br = new BinaryWriter(fs))
|
||||||
{
|
{
|
||||||
for (int read = lzStream.Read(buffer, 0, buffer.Length); read > 0; read = lzStream.Read(buffer, 0, buffer.Length))
|
for (var read = lzStream.Read(buffer, 0, buffer.Length); read > 0; read = lzStream.Read(buffer, 0, buffer.Length))
|
||||||
{
|
{
|
||||||
fs.Write(buffer, 0, read);
|
fs.Write(buffer, 0, read);
|
||||||
}
|
}
|
||||||
@@ -45,37 +47,35 @@ public static class SaveUtil
|
|||||||
public static bool DecompressSave(string saveName, out string newSaveName)
|
public static bool DecompressSave(string saveName, out string newSaveName)
|
||||||
{
|
{
|
||||||
newSaveName = string.Empty;
|
newSaveName = string.Empty;
|
||||||
string path = GameConfig.gameSaveFolder + saveName + GameSave.saveExt;
|
var path = GameConfig.gameSaveFolder + saveName + GameSave.saveExt;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
|
using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||||
|
var compressType = SaveGetCompressType(fileStream);
|
||||||
|
switch (compressType)
|
||||||
{
|
{
|
||||||
var compressType = SaveGetCompressType(fileStream);
|
case CompressionType.LZ4:
|
||||||
switch (compressType)
|
case CompressionType.Zstd:
|
||||||
{
|
using (var lzstream = new DecompressionStream(compressType == CompressionType.LZ4 ? PatchSave.LZ4Wrapper : PatchSave.ZstdWrapper, fileStream))
|
||||||
case CompressionType.LZ4:
|
{
|
||||||
case CompressionType.Zstd:
|
newSaveName = UnzipToFile(lzstream, path);
|
||||||
using (var lzstream = new DecompressionStream(compressType == CompressionType.LZ4 ? PatchSave.LZ4Wrapper : PatchSave.ZstdWrapper, fileStream))
|
}
|
||||||
{
|
return true;
|
||||||
newSaveName = UnzipToFile(lzstream, path);
|
case CompressionType.None:
|
||||||
}
|
return false;
|
||||||
return true;
|
default:
|
||||||
case CompressionType.None:
|
throw new ArgumentOutOfRangeException();
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.LogError(e);
|
Logger.LogError(e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static CompressionType SaveGetCompressType(FileStream fs)
|
public static CompressionType SaveGetCompressType(FileStream fs)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
for (var i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
if (0xCC != fs.ReadByte())
|
if (0xCC != fs.ReadByte())
|
||||||
return CompressionType.None;
|
return CompressionType.None;
|
||||||
@@ -94,12 +94,12 @@ public static class SaveUtil
|
|||||||
if (string.IsNullOrEmpty(saveName)) return CompressionType.None;
|
if (string.IsNullOrEmpty(saveName)) return CompressionType.None;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (FileStream fileStream = new FileStream(GetFullSavePath(saveName), FileMode.Open))
|
using var fileStream = new FileStream(GetFullSavePath(saveName), FileMode.Open);
|
||||||
return SaveGetCompressType(fileStream);
|
return SaveGetCompressType(fileStream);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.LogWarning(e);
|
Logger.LogWarning(e);
|
||||||
return CompressionType.None;
|
return CompressionType.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user