using System; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("GlitnirZDOCompressor")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("GlitnirZDOCompressor")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c7b8edbe-9f5c-406e-8834-cc26205a0e47")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace Glitnir.Network; [BepInPlugin("glitnir.zdocompressor", "Glitnir ZDO Compressor", "0.4.1")] public class GlitnirZDOCompressor : BaseUnityPlugin { [HarmonyPatch] private static class ZPackageCompressionPatch { private static MethodBase TargetMethod() { try { return writeBytesMethod; } catch { return null; } } private static void Prefix(ref byte[] array) { try { if (array != null && array.Length >= 8192) { byte[] array2 = Compress(array); if (array2 != null && array2.Length < array.Length) { totalOriginal += array.Length; totalCompressed += array2.Length; double num = (double)array2.Length / (double)array.Length; Log.LogInfo((object)("[COMPRESSAO_ZDO] Original=" + array.Length + " bytes | Comprimido=" + array2.Length + " bytes | Reducao=" + ((1.0 - num) * 100.0).ToString("F1") + "%")); array = BuildCompressedPayload(array2); } } } catch (Exception ex) { Log.LogWarning((object)("Compressao ignorada automaticamente: " + ex.Message)); } } } [HarmonyPatch] private static class ZPackageDecompressionPatch { private static MethodBase TargetMethod() { try { return readBytesMethod; } catch { return null; } } private static void Postfix(ref byte[] __result) { try { if (__result != null && LooksCompressed(__result)) { byte[] array = Decompress(__result); if (array != null) { Log.LogInfo((object)("[DESCOMPRESSAO_ZDO] Recebido=" + __result.Length + " bytes | Expandido=" + array.Length + " bytes")); __result = array; } } } catch (Exception ex) { Log.LogWarning((object)("Falha ao descomprimir pacote: " + ex.Message)); } } } private static ManualLogSource Log; private Harmony _harmony; private static Type zpackageType; private static MethodInfo writeBytesMethod; private static MethodInfo readBytesMethod; private static long totalCompressed; private static long totalOriginal; private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; PrintGreen("[Glitnir ZDO Compressor] INICIANDO v0.4.1"); try { RuntimeScan(); _harmony = new Harmony("glitnir.zdocompressor"); _harmony.PatchAll(); PrintGreen("[Glitnir ZDO Compressor] CARREGADO COM SUCESSO"); } catch (Exception ex) { Log.LogError((object)("Falha ao iniciar compressor: " + ex)); } } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } private static void RuntimeScan() { try { zpackageType = AccessTools.TypeByName("ZPackage"); if (zpackageType == null) { Log.LogWarning((object)"ZPackage nao encontrado. Compressor desativado."); return; } writeBytesMethod = AccessTools.Method(zpackageType, "Write", new Type[1] { typeof(byte[]) }, (Type[])null); readBytesMethod = AccessTools.Method(zpackageType, "ReadByteArray", (Type[])null, (Type[])null); Log.LogInfo((object)"=== GLITNIR NETWORK SCAN ==="); Log.LogInfo((object)("ZPackage encontrado: " + (zpackageType != null))); Log.LogInfo((object)("Write(byte[]) encontrado: " + (writeBytesMethod != null))); Log.LogInfo((object)("ReadByteArray encontrado: " + (readBytesMethod != null))); Log.LogInfo((object)"================================"); } catch (Exception ex) { Log.LogError((object)("RuntimeScan falhou: " + ex)); } } private static void PrintGreen(string msg) { try { ConsoleColor foregroundColor = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("================================================"); Console.WriteLine(msg); Console.WriteLine("================================================"); Console.ForegroundColor = foregroundColor; } catch { Debug.Log((object)msg); } } private static byte[] BuildCompressedPayload(byte[] compressed) { try { using MemoryStream memoryStream = new MemoryStream(); memoryStream.WriteByte(71); memoryStream.WriteByte(76); memoryStream.WriteByte(90); memoryStream.WriteByte(68); memoryStream.Write(compressed, 0, compressed.Length); return memoryStream.ToArray(); } catch { return compressed; } } private static bool LooksCompressed(byte[] data) { try { if (data.Length < 4) { return false; } return data[0] == 71 && data[1] == 76 && data[2] == 90 && data[3] == 68; } catch { return false; } } private static byte[] Compress(byte[] data) { try { using MemoryStream memoryStream = new MemoryStream(); using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionLevel.Fastest)) { gZipStream.Write(data, 0, data.Length); } return memoryStream.ToArray(); } catch { return null; } } private static byte[] Decompress(byte[] data) { try { using MemoryStream stream = new MemoryStream(data, 4, data.Length - 4); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); gZipStream.CopyTo(memoryStream); return memoryStream.ToArray(); } catch { return null; } } private void Update() { try { if (Time.frameCount % 18000 == 0 && totalOriginal > 0) { double num = (double)totalCompressed / (double)totalOriginal; double num2 = 1.0 - num; Log.LogInfo((object)("[ESTATISTICAS_COMPRESSAO] Original=" + ((double)totalOriginal / 1024.0).ToString("F1") + " KB | Comprimido=" + ((double)totalCompressed / 1024.0).ToString("F1") + " KB | Economia=" + (num2 * 100.0).ToString("F1") + "%")); } } catch { } } }