using System.IO.Compression; namespace RHLauncher { internal class MIPDecoder { private static readonly byte[] codeMip = new byte[] { 0x30, 0x22, 0x41, 0xa8, 0x5b, 0xa6, 0x6a, 0x49, 0xbf, 0x53, 0x35, 0xe5, 0x9e, 14, 0xec, 0xb8, 0x5e, 0x15, 0x1f, 0xc1, 0x4f, 0xec, 0x77, 0xe8, 0xb7, 0x4e, 0x87, 230, 0xf5, 60, 0xb3, 0x43, 0xcc, 0x53, 0x36, 0xac, 90, 0x77, 0xb8, 0xdd, 0x30, 0x74, 140, 0x4a, 0x9a, 0x9b, 0xbc, 10, 0xa4, 0xad, 0xbb, 0x13, 0x4b, 140, 0xd4, 0x80, 0xce, 0x65, 0x1d, 8, 90, 0x6a, 0x6f, 0x25, 0xf9, 0x3f, 0xef, 0x1b, 0xa4, 0x72, 20, 0xed, 0x97, 0x22, 0x4a, 0x2e, 0xb8, 150, 0x4b, 0x8e, 150, 0x93, 0xf1, 40, 0xb2, 11, 60, 0xf8, 0x5d, 170, 0xa9, 130, 0x13, 110, 0xc1, 0xa9, 0x20, 0x57, 0xb2, 0x5b, 0x16, 0xcf, 0x9e, 0x5f, 0xd4, 0xcc, 0x2e, 0xf5, 0xc9, 0x4c, 0x1c, 0xee, 0xe3, 0x3f, 0x29, 0xb3, 6, 0x70, 0x43, 0x3d, 0xf5, 0x90, 0xa2, 0x42, 2, 0x98, 80, 0xfd, 0x5d, 0x4e, 0x92, 0xad, 0xad, 0x7f, 0xab, 0x60, 0x2c, 0xb8, 0x43, 0x76, 0x8f, 0x5f, 230, 0xa7, 0x19, 0xe0, 0xb9, 0xb5, 0x62, 0x6b, 0xd4, 0x47, 0x69, 0x34, 14, 0x6d, 0xa4, 0x52, 0xe3, 100, 0x4a, 0x65, 0x47, 0xf5, 0x3f, 0x53, 0x5e, 0x8b, 0x1b, 0xfd, 0x21, 0xf7, 0xba, 0x68, 0xf9, 0xdf, 0x68, 0xa8, 150, 15, 0x8b, 1, 0x97, 0x58, 140, 30, 0xef, 0xb3, 0x41, 0x44, 0x21, 0xda, 0xe0, 0xf4, 0xe0, 0x2d, 0xcd, 11, 240, 0x5c, 0x59, 0xd6, 0x99, 0xe7, 1, 0x15, 0x67, 50, 0xe0, 0x12, 0x2f, 0xcd, 0xa2, 0xde, 0x52, 0xce, 0xec, 0xef, 0x77, 14, 0xbc, 0x38, 100, 0x8d, 180, 0xdb, 0x67, 0xff, 200, 0x66, 12, 0x8a, 0x60, 0xe1, 0x2e, 0, 0x43, 0xa9, 0x37, 0x9c, 0x11, 170, 0xb9, 0x98, 0xed, 0x21, 0x35, 0xd4, 0xc3, 0xde, 0x65, 0x54, 0x9d, 0x1c, 0xb0, 0xa9 }; private static void BytesWithCodeMip(byte[] toBytes) { for (int i = 0; i < toBytes.Length; i++) { toBytes[i] = (byte)(toBytes[i] ^ codeMip[i & 0xff]); } } public static async Task DecompressFileAsync(string filePath, string outputPath, CancellationToken cancellationToken) { byte[] buffer; using (FileStream fileStream = new(filePath, FileMode.Open, FileAccess.Read)) { buffer = new byte[fileStream.Length]; await fileStream.ReadAsync(buffer, 0, (int)fileStream.Length, cancellationToken); } BytesWithCodeMip(buffer); buffer = DecompressBytes(buffer); using FileStream outputFileStream = new(outputPath, FileMode.Create, FileAccess.Write); await outputFileStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken); } private static byte[] DecompressBytes(byte[] toBytes) { using MemoryStream inputStream = new(toBytes); using DeflateStream deflateStream = new(inputStream, CompressionMode.Decompress); using MemoryStream outputStream = new(); deflateStream.CopyTo(outputStream); return outputStream.ToArray(); } //Zlib have issues with some files private static byte[] DecompressBytes1(byte[] toBytes) { int num = (toBytes.Length << 4) - toBytes.Length; byte[] buffer = new byte[num]; int err = ZLibDll.Decompress(toBytes, toBytes.Length, buffer, ref num); if (err != 0) throw new Exception(string.Format("Decompress returned error code {0}.", err)); toBytes = new byte[num]; Buffer.BlockCopy(buffer, 0, toBytes, 0, num); return toBytes; } } }