Пример #1
0
        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;
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        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
        }