@@ -0,0 +1,53 @@ | |||
using System.IO; | |||
using System.IO.Compression; | |||
using HarmonyLib; | |||
namespace Kompressor | |||
{ | |||
[HarmonyPatch(typeof(File), "ReadAllBytes")] | |||
public class FileReadAllBytesPatch | |||
{ | |||
public static void Postfix(string path, ref byte[] __result) | |||
{ | |||
if (!path.EndsWith("GameSave.GC")) return; // not a save file; do nothing | |||
for (byte i = 0; i < MyPlugin.COMPRESSION_FRAME_START.Length; i++) | |||
{ | |||
if (__result[i] != MyPlugin.COMPRESSION_FRAME_START[i]) | |||
{ | |||
// Don't do anything; not compressed | |||
return; | |||
} | |||
} | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"Reading compressed save from {path}"); | |||
// remove frame at start of file | |||
byte[] compressedResult = new byte[__result.Length - MyPlugin.COMPRESSION_FRAME_START.Length]; | |||
for (long i = MyPlugin.COMPRESSION_FRAME_START.Length; i < __result.Length; i++) | |||
{ | |||
compressedResult[i - MyPlugin.COMPRESSION_FRAME_START.Length] = __result[i]; | |||
} | |||
MemoryStream compressedData = new MemoryStream(compressedResult); | |||
// decompress | |||
GZipStream gzip = new GZipStream(compressedData, CompressionMode.Decompress, true); | |||
// update result | |||
MemoryStream decompressedData = new MemoryStream(); | |||
byte[] buffer = new byte[1]; | |||
int readCount = gzip.Read(buffer, 0, 1); | |||
while (readCount != 0) | |||
{ | |||
decompressedData.Write(buffer, 0, 1); | |||
readCount = gzip.Read(buffer, 0, 1); | |||
} | |||
gzip.Close(); | |||
byte[] newResult = new byte[decompressedData.Length]; | |||
decompressedData.Seek(0, 0); | |||
decompressedData.Read(newResult, 0, (int)decompressedData.Length); | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"compressedData.Length: {compressedData.Length}"); | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"decompressedData.Length: {decompressedData.Length}"); | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"newResult: \"{System.Text.Encoding.UTF8.GetString(newResult)}\""); | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"Completed decompression of save"); | |||
__result = newResult; | |||
compressedData.Close(); | |||
decompressedData.Close(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,35 @@ | |||
using System.IO; | |||
using System.IO.Compression; | |||
using HarmonyLib; | |||
namespace Kompressor | |||
{ | |||
[HarmonyPatch(typeof(File), "WriteAllBytes")] | |||
public class FileWriteAllBytesPatch | |||
{ | |||
public static void Prefix(string path, ref byte[] bytes) | |||
{ | |||
if (!path.EndsWith("GameSave.GC")) return; // not a save file; do nothing | |||
GamecraftModdingAPI.Utility.Logging.MetaLog($"Writing compressed save to {path}"); | |||
MemoryStream data = new MemoryStream(); | |||
// compress files | |||
GZipStream gzip = new GZipStream(data, CompressionLevel.Optimal, true); | |||
gzip.Write(bytes, 0, bytes.Length); | |||
//GamecraftModdingAPI.Utility.Logging.MetaLog($"bytes.Length: {bytes.Length}"); | |||
gzip.Flush(); | |||
gzip.Close(); | |||
gzip.Dispose(); | |||
byte[] compressedData = new byte[data.Length + MyPlugin.COMPRESSION_FRAME_START.Length]; | |||
// copy frame into start of compressedData | |||
for (byte i = 0; i < MyPlugin.COMPRESSION_FRAME_START.Length; i++) | |||
{ | |||
compressedData[i] = MyPlugin.COMPRESSION_FRAME_START[i]; | |||
} | |||
//GamecraftModdingAPI.Utility.Logging.MetaLog($"compressedData.Length: {data.Length}"); | |||
data.Seek(0, 0); | |||
data.Read(compressedData, MyPlugin.COMPRESSION_FRAME_START.Length, (int) data.Length); | |||
// update stuff to write | |||
bytes = compressedData; | |||
} | |||
} | |||
} |
@@ -1,5 +1,8 @@ | |||
using System; | |||
using System.Reflection; | |||
using System.Text; | |||
using HarmonyLib; | |||
//using UnityEngine; | |||
@@ -9,18 +12,22 @@ using GamecraftModdingAPI.Commands; | |||
namespace Kompressor | |||
{ | |||
public class MyPlugin : IPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin' | |||
public class MyPlugin : IEnhancedPlugin // the Illusion Plugin Architecture (IPA) will ignore classes that don't implement IPlugin' | |||
{ | |||
public string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name; // Kompressor by default | |||
public override string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name; // Kompressor by default | |||
// To change the name, change the project's name | |||
public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); // 0.0.1.0 by default | |||
public override string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString(); // 0.0.1.0 by default | |||
// To change the version, change <Version>0.0.1</Version> in Kompressor.csproj | |||
private const string SETTINGS_PATH = "kompressor.json"; | |||
internal static byte[] COMPRESSION_FRAME_START = Encoding.UTF8.GetBytes("KOMPRESSED"); | |||
private static Harmony harmony = null; | |||
// called when Gamecraft shuts down | |||
public void OnApplicationQuit() | |||
public override void OnApplicationQuit() | |||
{ | |||
// Shutdown this mod | |||
GamecraftModdingAPI.Utility.Logging.LogDebug($"{Name} has shutdown"); | |||
@@ -30,11 +37,13 @@ namespace Kompressor | |||
} | |||
// called when Gamecraft starts up | |||
public void OnApplicationStart() | |||
public override void OnApplicationStart() | |||
{ | |||
// Initialize the Gamecraft modding API first | |||
GamecraftModdingAPI.Main.Init(); | |||
// check out the modding API docs here: https://mod.exmods.org/ | |||
harmony = new Harmony(Name); | |||
harmony.PatchAll(); | |||
// reload command | |||
CommandBuilder.Builder() | |||
@@ -120,15 +129,5 @@ namespace Kompressor | |||
UnityEngine.Camera.main.fieldOfView = qs.FieldOfView; | |||
} | |||
// unused methods | |||
public void OnFixedUpdate() { } // called once per physics update | |||
public void OnLevelWasInitialized(int level) { } // called after a level is initialized | |||
public void OnLevelWasLoaded(int level) { } // called after a level is loaded | |||
public void OnUpdate() { } // called once per rendered frame (frame update) | |||
} | |||
} |
@@ -89,7 +89,7 @@ namespace Kompressor | |||
internal static void Save(QualitySettings qs, string filepath) | |||
{ | |||
string contents = JsonConvert.SerializeObject(qs); | |||
string contents = JsonConvert.SerializeObject(qs, Formatting.Indented); | |||
File.WriteAllText(filepath, contents); | |||
} | |||