From 6311e3b9fbc5ffd6b94df284c0a20c289db6db86 Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Tue, 26 Sep 2023 16:08:52 +0800 Subject: [PATCH] cleanup codes --- CompressSave/CompressSave.cs | 223 +++++++++++++++----------------- CompressSave/PatchUILoadGame.cs | 97 +++++++------- CompressSave/PatchUISaveGame.cs | 118 ++++++++--------- CompressSave/SaveUtil.cs | 60 ++++----- 4 files changed, 239 insertions(+), 259 deletions(-) diff --git a/CompressSave/CompressSave.cs b/CompressSave/CompressSave.cs index 14b0805..6a778e1 100644 --- a/CompressSave/CompressSave.cs +++ b/CompressSave/CompressSave.cs @@ -19,31 +19,31 @@ public enum CompressionType [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class CompressSave : BaseUnityPlugin { - private Harmony patchSave, patchUISave, patchUILoad; - string StringFromCompresstionType(CompressionType type) + private Harmony _patchSave, _patchUISave, _patchUILoad; + private static string StringFromCompresstionType(CompressionType type) { - switch (type) + return type switch { - case CompressionType.LZ4: return "lz4"; - case CompressionType.Zstd: return "zstd"; - case CompressionType.None: return "none"; - default: throw new ArgumentException("Unknown compression type."); - } + CompressionType.LZ4 => "lz4", + CompressionType.Zstd => "zstd", + CompressionType.None => "none", + _ => 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; - case "zstd": return CompressionType.Zstd; - default: return CompressionType.None; - } + "lz4" => CompressionType.LZ4, + "zstd" => CompressionType.Zstd, + _ => CompressionType.None + }; } public void Awake() { - SaveUtil.logger = Logger; + SaveUtil.Logger = Logger; if (LZ4API.Avaliable && ZstdAPI.Avaliable) { PatchSave.CompressionTypeForSaves = CompressionTypeFromString( @@ -68,36 +68,36 @@ public class CompressSave : BaseUnityPlugin PatchSave.CreateCompressBuffer(); 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."); } - patchSave = Harmony.CreateAndPatchAll(typeof(PatchSave)); + _patchSave = Harmony.CreateAndPatchAll(typeof(PatchSave)); if (PatchSave.EnableCompress) - patchUISave = Harmony.CreateAndPatchAll(typeof(PatchUISaveGame)); - patchUILoad = Harmony.CreateAndPatchAll(typeof(PatchUILoadGame)); + _patchUISave = Harmony.CreateAndPatchAll(typeof(PatchUISaveGame)); + _patchUILoad = Harmony.CreateAndPatchAll(typeof(PatchUILoadGame)); } 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() { - if (patchUISave != null) + if (_patchUISave != null) { PatchUISaveGame.OnDestroy(); - patchUISave.UnpatchSelf(); + _patchUISave.UnpatchSelf(); } - if (patchUILoad != null) + if (_patchUILoad != null) { 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(); private static readonly WrapperDefines NoneWrapper = new NoneAPI(); @@ -105,7 +105,7 @@ class PatchSave public static bool UseCompressSave; private static CompressionType _compressionTypeForLoading = CompressionType.None; private static CompressionType _compressionTypeForSaving = CompressionType.Zstd; - private static int _compressionLevelForSaving = 0; + private static int _compressionLevelForSaving; public static CompressionType CompressionTypeForSaves = CompressionType.Zstd; public static CompressionType CompressionTypeForAutoSaves = CompressionType.Zstd; public static int CompressionLevelForSaves; @@ -116,7 +116,7 @@ class PatchSave public static void CreateCompressBuffer() { - var bufSize = CompressionStream.MB; + const int bufSize = CompressionStream.MB; var outBufSize = LZ4Wrapper.CompressBufferBound(bufSize); outBufSize = Math.Max(outBufSize, ZstdWrapper.CompressBufferBound(bufSize)); outBufSize = Math.Max(outBufSize, NoneWrapper.CompressBufferBound(bufSize)); @@ -127,6 +127,7 @@ class PatchSave private static void WriteHeader(FileStream fileStream) { + if (fileStream == null) throw new ArgumentNullException(nameof(fileStream)); switch (_compressionTypeForSaving) { case CompressionType.Zstd: @@ -148,59 +149,57 @@ class PatchSave [HarmonyPrefix] [HarmonyPatch(typeof(GameSave), "AutoSave")] [HarmonyPatch(typeof(GameSave), "SaveAsLastExit")] - static void BeforeAutoSave() + private static void BeforeAutoSave() { UseCompressSave = EnableForAutoSaves && EnableCompress; - if (UseCompressSave) - { - _compressionTypeForSaving = CompressionTypeForAutoSaves; - _compressionLevelForSaving = CompressionLevelForAutoSaves; - } + if (!UseCompressSave) return; + _compressionTypeForSaving = CompressionTypeForAutoSaves; + _compressionLevelForSaving = CompressionLevelForAutoSaves; } [HarmonyTranspiler] [HarmonyPatch(typeof(GameSave), "SaveCurrentGame")] - static IEnumerable SaveCurrentGame_Transpiler(IEnumerable instructions, - ILGenerator generator) + private static IEnumerable SaveCurrentGame_Transpiler(IEnumerable instructions, ILGenerator generator) { /* BinaryWriter binaryWriter = new BinaryWriter(fileStream); => Create compressionStream and replace binaryWriter. * set PerformanceMonitor.BeginStream to compressionStream. * fileStream.Seek(6L, SeekOrigin.Begin); binaryWriter.Write(position); => Disable seek&write function. * binaryWriter.Dispose(); => Dispose compressionStream before fileStream close. */ + var matcher = new CodeMatcher(instructions, generator); try { - var matcher = new CodeMatcher(instructions, generator) - .MatchForward(false, - new CodeMatch(OpCodes.Newobj, - AccessTools.Constructor(typeof(BinaryWriter), new Type[] { typeof(FileStream) }))) - .Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryWriter")) - .MatchForward(false, - new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream"))) - .Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "MonitorStream")) - .MatchForward(false, - new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IO.Stream), "Seek"))) - .Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthWrite0")) - .MatchForward(false, - new CodeMatch(OpCodes.Callvirt, - AccessTools.Method(typeof(BinaryWriter), "Write", new Type[] { typeof(long) }))) - .Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthWrite1")) - .MatchForward(false, - new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IDisposable), "Dispose"))) - .Advance(1) - .Insert(new CodeInstruction(OpCodes.Call, - AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream"))); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Newobj, AccessTools.Constructor(typeof(BinaryWriter), new [] { typeof(FileStream) })) + ).Set( + OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryWriter") + ).MatchForward(false, + new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream")) + ).Set( + OpCodes.Call, AccessTools.Method(typeof(PatchSave), "MonitorStream") + ).MatchForward(false, + new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(Stream), "Seek")) + ).Set( + OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthWrite0") + ).MatchForward(false, + new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BinaryWriter), "Write", new [] { typeof(long) })) + ).Set( + OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthWrite1") + ).MatchForward(false, + new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(IDisposable), "Dispose")) + ).Advance(1).Insert( + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream")) + ); EnableCompress = true; return matcher.InstructionEnumeration(); } catch (Exception ex) { - SaveUtil.logger.LogError( + SaveUtil.Logger.LogError( "SaveCurrentGame_Transpiler failed. Mod version not compatible with game version."); - SaveUtil.logger.LogError(ex); + SaveUtil.Logger.LogError(ex); } - - return instructions; + return matcher.InstructionEnumeration(); } public static void MonitorStream(Stream fileStream) @@ -212,43 +211,32 @@ class PatchSave { if (UseCompressSave) { - SaveUtil.logger.LogDebug("Begin compress save"); + SaveUtil.Logger.LogDebug("Begin compress save"); WriteHeader(fileStream); - switch (_compressionTypeForSaving) + _compressionStream = _compressionTypeForSaving switch { - case CompressionType.LZ4: - _compressionStream = new CompressionStream(LZ4Wrapper, _compressionLevelForSaving, fileStream, _compressBuffer, true); - break; - case CompressionType.Zstd: - _compressionStream = new CompressionStream(ZstdWrapper, _compressionLevelForSaving, fileStream, _compressBuffer, true); - break; - case CompressionType.None: - _compressionStream = new CompressionStream(NoneWrapper, 0, fileStream, _compressBuffer, true); - break; - } + CompressionType.LZ4 => new CompressionStream(LZ4Wrapper, _compressionLevelForSaving, fileStream, _compressBuffer, true), + CompressionType.Zstd => new CompressionStream(ZstdWrapper, _compressionLevelForSaving, fileStream, _compressBuffer, true), + CompressionType.None => new CompressionStream(NoneWrapper, 0, fileStream, _compressBuffer, true), + _ => _compressionStream + }; return ((CompressionStream)_compressionStream).BufferWriter; } - SaveUtil.logger.LogDebug("Begin normal save"); + SaveUtil.Logger.LogDebug("Begin normal save"); return new BinaryWriter(fileStream); } public static long FileLengthWrite0(FileStream fileStream, long offset, SeekOrigin origin) { - if (!UseCompressSave) - { - return fileStream.Seek(offset, origin); - } - return 0L; + return UseCompressSave ? 0L : fileStream.Seek(offset, origin); } public static void FileLengthWrite1(BinaryWriter binaryWriter, long value) { - if (!UseCompressSave) - { - binaryWriter.Write(value); - } + if (UseCompressSave) return; + binaryWriter.Write(value); } public static void DisposeCompressionStream() @@ -265,23 +253,23 @@ class PatchSave { 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; - 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); - stream.Seek(6L, SeekOrigin.Begin); - var writer = new BinaryWriter(stream); - writer.Write(saveLen); - writer.Dispose(); - } - _compressionTypeForSaving = CompressionTypeForSaves; - _compressionLevelForSaving = CompressionLevelForSaves; - UseCompressSave = false; + // Ugly implementation, but it works. May find a better solution someday. + var saveLen = stream.Seek(0L, SeekOrigin.End); + stream.Seek(6L, SeekOrigin.Begin); + var writer = new BinaryWriter(stream); + writer.Write(saveLen); + writer.Dispose(); } + _compressionTypeForSaving = CompressionTypeForSaves; + _compressionLevelForSaving = CompressionLevelForSaves; + UseCompressSave = false; } [HarmonyTranspiler] @@ -290,8 +278,7 @@ class PatchSave [HarmonyPatch(typeof(GameSave), "ReadHeader")] [HarmonyPatch(typeof(GameSave), "ReadHeaderAndDescAndProperty")] [HarmonyPatch(typeof(GameSave), "ReadModes")] - static IEnumerable LoadCurrentGame_Transpiler(IEnumerable instructions, - ILGenerator iLGenerator) + private static IEnumerable LoadCurrentGame_Transpiler(IEnumerable instructions, ILGenerator generator) { /* using (BinaryReader binaryReader = new BinaryReader(fileStream)) => Create decompressionStream and replace binaryReader. * set PerformanceMonitor.BeginStream to decompressionStream. @@ -299,29 +286,31 @@ class PatchSave * fileStream.Seek((long)num2, SeekOrigin.Current); => Use decompressionStream.Read to seek forward * binaryReader.Dispose(); => Dispose decompressionStream before fileStream close. */ + var matcher = new CodeMatcher(instructions, generator); try { - var matcher = new CodeMatcher(instructions, iLGenerator) - .MatchForward(false, - new CodeMatch(OpCodes.Newobj, - AccessTools.Constructor(typeof(BinaryReader), new Type[] { typeof(FileStream) }))) - .Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryReader")) - .MatchForward(false, - new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream"))); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Newobj, AccessTools.Constructor(typeof(BinaryReader), new [] { typeof(FileStream) })) + ).Set( + OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryReader") + ).MatchForward(false, + new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream")) + ); if (matcher.IsValid) matcher.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "MonitorStream")); matcher.Start().MatchForward(false, - new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BinaryReader), "ReadInt64"))) - .Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthRead")) - .MatchForward(false, - new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IDisposable), "Dispose"))) - .Advance(1) - .Insert(new CodeInstruction(OpCodes.Call, - AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream"))) - .MatchBack(false, - new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IO.Stream), "Seek"))); + new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BinaryReader), "ReadInt64")) + ).Set( + OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthRead") + ).MatchForward(false, + new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(IDisposable), "Dispose")) + ).Advance(1).Insert( + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "DisposeCompressionStream")) + ).MatchBack(false, + new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(Stream), "Seek")) + ); if (matcher.IsValid) matcher.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "ReadSeek")); @@ -329,12 +318,12 @@ class PatchSave } catch (Exception ex) { - SaveUtil.logger.LogError( + SaveUtil.Logger.LogError( "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) diff --git a/CompressSave/PatchUILoadGame.cs b/CompressSave/PatchUILoadGame.cs index 5b60c45..aa6874e 100644 --- a/CompressSave/PatchUILoadGame.cs +++ b/CompressSave/PatchUILoadGame.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Linq; using HarmonyLib; using UnityEngine; @@ -8,69 +7,65 @@ namespace CompressSave; class PatchUILoadGame { - static UIButton decompressButton; + static UIButton _decompressButton; [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); - switch (compressedType) + var selected = __instance.selected; + var compressedType = SaveUtil.SaveGetCompressType(selected == null ? null : selected.saveName); + var prop3Text = __instance.prop3Text; + prop3Text.text = compressedType switch { - case CompressionType.LZ4: - ___prop3Text.text = "(LZ4)" + ___prop3Text.text; - break; - case CompressionType.Zstd: - ___prop3Text.text = "(ZSTD)" + ___prop3Text.text; - break; - default: - ___prop3Text.text = "(N)" + ___prop3Text.text; - break; - } - if (!decompressButton) return; - decompressButton.button.interactable = compressedType != CompressionType.None; - decompressButton.gameObject.SetActive(compressedType != CompressionType.None); + CompressionType.LZ4 => "(LZ4)" + prop3Text.text, + CompressionType.Zstd => "(ZSTD)" + prop3Text.text, + _ => "(N)" + prop3Text.text + }; + if (!_decompressButton) return; + _decompressButton.button.interactable = compressedType != CompressionType.None; + _decompressButton.gameObject.SetActive(compressedType != CompressionType.None); } [HarmonyPatch(typeof(UILoadGameWindow), "_OnOpen"), HarmonyPostfix] - static void _OnOpen(UILoadGameWindow __instance, UIButton ___loadButton, GameObject ___loadSandboxGroup, List ___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(); + + __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(); + var text = _decompressButton.transform.Find("button-text")?.GetComponent(); + + if (localizer) { - decompressButton = ___loadButton; - - decompressButton = (__instance.transform.Find("button-decompress")?.gameObject ?? GameObject.Instantiate(___loadButton.gameObject, ___loadButton.transform.parent)).GetComponent(); - - ___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(); - var text = decompressButton.transform.Find("button-text")?.GetComponent(); - - 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); + localizer.stringKey = "Decompress"; + localizer.translation = "Decompress".Translate(); } + 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() { - if (decompressButton) - GameObject.Destroy(decompressButton.gameObject); - decompressButton = null; + if (_decompressButton) + Object.Destroy(_decompressButton.gameObject); + _decompressButton = null; } } \ No newline at end of file diff --git a/CompressSave/PatchUISaveGame.cs b/CompressSave/PatchUISaveGame.cs index 4cdc4f4..db66471 100644 --- a/CompressSave/PatchUISaveGame.cs +++ b/CompressSave/PatchUISaveGame.cs @@ -6,104 +6,100 @@ namespace CompressSave; static class PatchUISaveGame { - [HarmonyPatch(typeof(UISaveGameWindow), "OnSelectedChange"), HarmonyPostfix] - static void OnSelectedChange(UISaveGameWindow __instance, Text ___prop3Text) + public static void OnDestroy() { - var compressedType = SaveUtil.SaveGetCompressType(__instance.selected?.saveName); - switch (compressedType) + if (_context.ButtonCompress) + Object.Destroy(_context.ButtonCompress.gameObject); + if (_context.Window) { - 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; + _context.SaveButton.onClick -= WrapClick; + _context.SaveButton.onClick += _context.Window.OnSaveClick; } + _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] - static void _OnDestroy() + private static void _OnDestroy() { //Console.WriteLine("OnCreate"); - context = new UIContext(); + _context = new UIContext(); } [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] - static void CheckAndSetSaveButtonEnable(UISaveGameWindow __instance, UIButton ___saveButton, Text ___saveButtonText) + private static void CheckAndSetSaveButtonEnable(UISaveGameWindow __instance) { - _OnOpen(__instance, ___saveButton, ___saveButtonText); - if (context.saveButtonText && context.saveButton) - SetButtonState(context.saveButtonText.text, context.saveButton.button.interactable); + _OnOpen(__instance); + if (_context.SaveButtonText && _context.SaveButton) + 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.buttonCompressText.text = text; + _context.ButtonCompress.button.interactable = interactable; + _context.ButtonCompressText.text = text; } - class UIContext + private class UIContext { - public UIButton buttonCompress; - public UIButton saveButton; - public Text buttonCompressText; - public Text saveButtonText; - public UISaveGameWindow ui; + public UIButton ButtonCompress; + public UIButton SaveButton; + public Text ButtonCompressText; + public Text SaveButtonText; + public UISaveGameWindow Window; } [HarmonyPatch(typeof(UISaveGameWindow), "OnSaveClick"), HarmonyPrefix] - static void OnSaveClick() + private static void OnSaveClick() { PatchSave.UseCompressSave = true; } - static UIContext context = new UIContext(); + private static UIContext _context = new UIContext(); [HarmonyPatch(typeof(UISaveGameWindow), "_OnOpen"), HarmonyPostfix] - static void _OnOpen(UISaveGameWindow __instance, UIButton ___saveButton, Text ___saveButtonText) + private static void _OnOpen(UISaveGameWindow __instance) { - if (context.buttonCompress) return; - context.saveButton = ___saveButton; - context.saveButtonText = ___saveButtonText; + if (_context.ButtonCompress) return; + _context.SaveButton = __instance.saveButton; + _context.SaveButtonText = __instance.saveButtonText; - context.ui = __instance; - context.buttonCompress = - (__instance.transform.Find("button-compress")?.gameObject ?? - GameObject.Instantiate(___saveButton.gameObject, ___saveButton.transform.parent)) - .GetComponent(); + _context.Window = __instance; + var gameObj = __instance.transform.Find("button-compress")?.gameObject; + if (gameObj == null) + gameObj = Object.Instantiate(__instance.saveButton.gameObject, __instance.saveButton.transform.parent); + _context.ButtonCompress = gameObj.GetComponent(); - 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(); + _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(); - context.buttonCompress.onClick += __instance.OnSaveClick; - context.saveButton.onClick -= __instance.OnSaveClick; - context.saveButton.onClick += WrapClick; + _context.ButtonCompress.onClick += __instance.OnSaveClick; + _context.SaveButton.onClick -= __instance.OnSaveClick; + _context.SaveButton.onClick += WrapClick; } - static void WrapClick(int data) + private static void WrapClick(int data) { 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(); - } } \ No newline at end of file diff --git a/CompressSave/SaveUtil.cs b/CompressSave/SaveUtil.cs index 2e4da61..034eff1 100644 --- a/CompressSave/SaveUtil.cs +++ b/CompressSave/SaveUtil.cs @@ -7,9 +7,9 @@ namespace CompressSave; 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, Minor = 9, @@ -19,19 +19,21 @@ public static class SaveUtil private static string UnzipToFile(DecompressionStream lzStream, string fullPath) { lzStream.ResetStream(); - string dir = Path.GetDirectoryName(fullPath); - string filename = "[Recovery]-" + Path.GetFileNameWithoutExtension(fullPath); - fullPath = Path.Combine(dir, filename + GameSave.saveExt); - int i = 0; + var dir = Path.GetDirectoryName(fullPath); + var filename = "[Recovery]-" + Path.GetFileNameWithoutExtension(fullPath); + fullPath = filename + GameSave.saveExt; + if (dir != null) fullPath = Path.Combine(dir, fullPath); + var i = 0; 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]; using (var fs = new FileStream(fullPath, FileMode.Create)) 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); } @@ -45,37 +47,35 @@ public static class SaveUtil public static bool DecompressSave(string saveName, out string newSaveName) { newSaveName = string.Empty; - string path = GameConfig.gameSaveFolder + saveName + GameSave.saveExt; + var path = GameConfig.gameSaveFolder + saveName + GameSave.saveExt; 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); - switch (compressType) - { - case CompressionType.LZ4: - case CompressionType.Zstd: - using (var lzstream = new DecompressionStream(compressType == CompressionType.LZ4 ? PatchSave.LZ4Wrapper : PatchSave.ZstdWrapper, fileStream)) - { - newSaveName = UnzipToFile(lzstream, path); - } - return true; - case CompressionType.None: - return false; - default: - throw new ArgumentOutOfRangeException(); - } + case CompressionType.LZ4: + case CompressionType.Zstd: + using (var lzstream = new DecompressionStream(compressType == CompressionType.LZ4 ? PatchSave.LZ4Wrapper : PatchSave.ZstdWrapper, fileStream)) + { + newSaveName = UnzipToFile(lzstream, path); + } + return true; + case CompressionType.None: + return false; + default: + throw new ArgumentOutOfRangeException(); } } catch (Exception e) { - logger.LogError(e); + Logger.LogError(e); return false; } } public static CompressionType SaveGetCompressType(FileStream fs) { - for (int i = 0; i < 3; i++) + for (var i = 0; i < 3; i++) { if (0xCC != fs.ReadByte()) return CompressionType.None; @@ -94,12 +94,12 @@ public static class SaveUtil if (string.IsNullOrEmpty(saveName)) return CompressionType.None; try { - using (FileStream fileStream = new FileStream(GetFullSavePath(saveName), FileMode.Open)) - return SaveGetCompressType(fileStream); + using var fileStream = new FileStream(GetFullSavePath(saveName), FileMode.Open); + return SaveGetCompressType(fileStream); } catch (Exception e) { - logger.LogWarning(e); + Logger.LogWarning(e); return CompressionType.None; } }