public static void WritePacked(this Span <byte> dest, ref int pos, ReadOnlySpan <byte> source) { var length = source.Length; if (length == 0) { #if NO_LOCAL_INIT dest.Write(ref pos, 0); #else pos += 4; #endif return; } var packLength = (ulong)dest.Length - 8; ZlibError ce = Zlib.Pack(dest.Slice(pos + 8), ref packLength, source, ZlibQuality.Default); if (ce != ZlibError.Okay) { Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce); } dest.Write(ref pos, (int)(4 + packLength)); dest.Write(ref pos, length); pos += (int)packLength; }
private static void WritePacked(ref SpanWriter writer, ReadOnlySpan <byte> span) { var length = span.Length; if (length == 0) { writer.Write(0); return; } var wantLength = 1 + span.Length * 1024 / 1000; wantLength += 4095; wantLength &= ~4095; var packBuffer = ArrayPool <byte> .Shared.Rent(wantLength); var packLength = wantLength; Zlib.Pack(packBuffer, ref packLength, span, length, ZlibQuality.Default); writer.Write(4 + packLength); writer.Write(length); writer.Write(packBuffer.AsSpan(0, packLength)); ArrayPool <byte> .Shared.Return(packBuffer); }
private static void WritePacked(ReadOnlySpan <byte> span, ref SpanWriter writer) { var length = span.Length; if (length == 0) { writer.Write(0); return; } var wantLength = Zlib.MaxPackSize(length); var packBuffer = _packBuffer; byte[] rentedBuffer = null; if (wantLength > packBuffer.Length) { packBuffer = rentedBuffer = ArrayPool <byte> .Shared.Rent(wantLength); } var packLength = wantLength; var error = Zlib.Pack(packBuffer, ref packLength, span, length, ZlibQuality.Default); if (error != ZlibError.Okay) { Utility.PushColor(ConsoleColor.Red); Core.WriteConsoleLine($"Gump compression failed {error}"); Utility.PopColor(); writer.Write(4); writer.Write(0); return; } writer.Write(4 + packLength); writer.Write(length); writer.Write(packBuffer.AsSpan(0, packLength)); if (rentedBuffer != null) { ArrayPool <byte> .Shared.Return(rentedBuffer); } }
private static void WritePacked(ReadOnlySpan <byte> source, ref SpanWriter writer, out int length) { var size = source.Length; var dest = writer.RawBuffer.Slice(writer.Position + 3); length = dest.Length; var ce = Zlib.Pack(dest, ref length, source, ZlibQuality.Default); if (ce != ZlibError.Okay) { Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce); length = 0; size = 0; } writer.Write((byte)size); writer.Write((byte)length); writer.Write((byte)(((size >> 4) & 0xF0) | ((length >> 8) & 0xF))); writer.Seek(length, SeekOrigin.Current); }
public DesignStateDetailed(Serial serial, int revision, int xMin, int yMin, int xMax, int yMax, MultiTileEntry[] tiles) : base(0xD8) { EnsureCapacity(17 + tiles.Length * 5); Write((byte)0x03); // Compression Type Write((byte)0x00); // Unknown Write(serial.Value); Write(revision); Write((short)tiles.Length); Write((short)0); // Buffer length : reserved Write((byte)0); // Plane count : reserved var totalLength = 1; // includes plane count var width = xMax - xMin + 1; var height = yMax - yMin + 1; var planeBuffers = new byte[9][]; for (var i = 0; i < planeBuffers.Length; ++i) { planeBuffers[i] = ArrayPool <byte> .Shared.Rent(0x400); } var stairBuffers = new byte[6][]; for (var i = 0; i < stairBuffers.Length; ++i) { stairBuffers[i] = ArrayPool <byte> .Shared.Rent(MaxItemsPerStairBuffer * 5); } Clear(planeBuffers[0], width * height * 2); for (var i = 0; i < 4; ++i) { Clear(planeBuffers[1 + i], (width - 1) * (height - 2) * 2); Clear(planeBuffers[5 + i], width * (height - 1) * 2); } var totalStairsUsed = 0; for (var i = 0; i < tiles.Length; ++i) { var mte = tiles[i]; var x = mte.OffsetX - xMin; var y = mte.OffsetY - yMin; int z = mte.OffsetZ; var floor = TileData.ItemTable[mte.ItemId & TileData.MaxItemValue].Height <= 0; int plane, size; switch (z) { case 0: plane = 0; break; case 7: plane = 1; break; case 27: plane = 2; break; case 47: plane = 3; break; case 67: plane = 4; break; default: { var stairBufferIndex = totalStairsUsed / MaxItemsPerStairBuffer; var stairBuffer = stairBuffers[stairBufferIndex]; var byteIndex = totalStairsUsed % MaxItemsPerStairBuffer * 5; stairBuffer[byteIndex++] = (byte)(mte.ItemId >> 8); stairBuffer[byteIndex++] = (byte)mte.ItemId; stairBuffer[byteIndex++] = (byte)mte.OffsetX; stairBuffer[byteIndex++] = (byte)mte.OffsetY; stairBuffer[byteIndex] = (byte)mte.OffsetZ; ++totalStairsUsed; continue; } } if (plane == 0) { size = height; } else if (floor) { size = height - 2; x -= 1; y -= 1; } else { size = height - 1; plane += 4; } var index = (x * size + y) * 2; if (x < 0 || y < 0 || y >= size || index + 1 >= 0x400) { var stairBufferIndex = totalStairsUsed / MaxItemsPerStairBuffer; var stairBuffer = stairBuffers[stairBufferIndex]; var byteIndex = totalStairsUsed % MaxItemsPerStairBuffer * 5; stairBuffer[byteIndex++] = (byte)(mte.ItemId >> 8); stairBuffer[byteIndex++] = (byte)mte.ItemId; stairBuffer[byteIndex++] = (byte)mte.OffsetX; stairBuffer[byteIndex++] = (byte)mte.OffsetY; stairBuffer[byteIndex] = (byte)mte.OffsetZ; ++totalStairsUsed; } else { m_PlaneUsed[plane] = true; planeBuffers[plane][index] = (byte)(mte.ItemId >> 8); planeBuffers[plane][index + 1] = (byte)mte.ItemId; } } var planeCount = 0; var deflatedBuffer = ArrayPool <byte> .Shared.Rent(0x2000); for (var i = 0; i < planeBuffers.Length; ++i) { if (!m_PlaneUsed[i]) { ArrayPool <byte> .Shared.Return(planeBuffers[i]); continue; } ++planeCount; int size = i switch { 0 => width * height * 2, < 5 => (width - 1) * (height - 2) * 2, _ => width * (height - 1) * 2 }; var inflatedBuffer = planeBuffers[i]; var deflatedLength = deflatedBuffer.Length; var ce = Zlib.Pack( deflatedBuffer, ref deflatedLength, inflatedBuffer, size, ZlibQuality.Default ); if (ce != ZlibError.Okay) { Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce); deflatedLength = 0; size = 0; } Write((byte)(0x20 | i)); Write((byte)size); Write((byte)deflatedLength); Write((byte)(((size >> 4) & 0xF0) | ((deflatedLength >> 8) & 0xF))); Write(deflatedBuffer, 0, deflatedLength); totalLength += 4 + deflatedLength; ArrayPool <byte> .Shared.Return(inflatedBuffer); } var totalStairBuffersUsed = (totalStairsUsed + (MaxItemsPerStairBuffer - 1)) / MaxItemsPerStairBuffer; for (var i = 0; i < totalStairBuffersUsed; ++i) { ++planeCount; var count = Math.Min(MaxItemsPerStairBuffer, totalStairsUsed - i * MaxItemsPerStairBuffer); var size = count * 5; var inflatedBuffer = stairBuffers[i]; var deflatedLength = deflatedBuffer.Length; var ce = Zlib.Pack( deflatedBuffer, ref deflatedLength, inflatedBuffer, size, ZlibQuality.Default ); if (ce != ZlibError.Okay) { Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce); deflatedLength = 0; size = 0; } Write((byte)(9 + i)); Write((byte)size); Write((byte)deflatedLength); Write((byte)(((size >> 4) & 0xF0) | ((deflatedLength >> 8) & 0xF))); Write(deflatedBuffer, 0, deflatedLength); totalLength += 4 + deflatedLength; } for (var i = 0; i < stairBuffers.Length; ++i) { ArrayPool <byte> .Shared.Return(stairBuffers[i]); } ArrayPool <byte> .Shared.Return(deflatedBuffer); Stream.Seek(15, SeekOrigin.Begin); Write((short)totalLength); // Buffer length Write((byte)planeCount); // Plane count }