namespace Supercell.Laser.Titan.DataStream { using System; using System.IO; using System.IO.Compression; using System.Text; public class LogicCompressedString { private string m_string; public LogicCompressedString(string str) => m_string = str ?? string.Empty; public string GetString() => m_string; public static LogicCompressedString Decode(ByteStream stream) { if (stream == null || stream.IsAtEnd()) return null; int length = stream.ReadBytesLength(); if (length <= 0) return new LogicCompressedString(string.Empty); byte[] bytes = stream.ReadBytes(length, 900000); if (bytes == null || bytes.Length == 0) return new LogicCompressedString(string.Empty); try { if (bytes.Length > 4 && (bytes[4] == 0x78 || bytes[4] == 0x58)) { using var ms = new MemoryStream(bytes, 4, bytes.Length - 4); using var zlib = new ZLibStream(ms, CompressionMode.Decompress); using var outMs = new MemoryStream(); zlib.CopyTo(outMs); return new LogicCompressedString(Encoding.UTF8.GetString(outMs.ToArray())); } return new LogicCompressedString(Encoding.UTF8.GetString(bytes)); } catch { return new LogicCompressedString(Encoding.UTF8.GetString(bytes)); } } public static void Encode(LogicCompressedString compStr, ByteStream stream) { if (stream == null) return; string str = compStr?.GetString(); if (string.IsNullOrEmpty(str)) { stream.WriteInt(-1); return; } byte[] rawBytes = Encoding.UTF8.GetBytes(str); try { using var outMs = new MemoryStream(); outMs.WriteByte((byte)(rawBytes.Length >> 24)); outMs.WriteByte((byte)(rawBytes.Length >> 16)); outMs.WriteByte((byte)(rawBytes.Length >> 8)); outMs.WriteByte((byte)rawBytes.Length); using (var zlib = new ZLibStream(outMs, CompressionLevel.Optimal, true)) { zlib.Write(rawBytes, 0, rawBytes.Length); } byte[] compressed = outMs.ToArray(); stream.WriteBytes(compressed, compressed.Length); } catch { stream.WriteString(str); } } } }