public static void UpdateAreaFromPacket(this ITerrain terrain, Packet packet)
        {
            var layerType = (LayerType)packet.ReadByte();

            packet.ReadByte(); // materialType
            packet.ReadByte(); // sizeOfElement;
            var x1   = packet.ReadInt();
            var y1   = packet.ReadInt();
            var x2   = packet.ReadInt();
            var y2   = packet.ReadInt();
            var area = new Area(x1, y1, x2, y2);

            var layer = terrain.GetLayerByType(layerType) as IUpdateableLayer;

            layer?.CopyFromStreamToArea(packet, area);
        }
        public static Packet BuildLayerUpdatePacket(this ITerrain terrain, LayerType layerType, Area area)
        {
            var layer = terrain.GetLayerByType(layerType) as IUpdateableLayer;

            if (layer == null)
            {
                return(null);
            }

            var packet = new Packet(ZoneCommand.LayerUpdate);

            packet.AppendByte((byte)layerType);

            packet.AppendByte(0); // material
            packet.AppendByte((byte)layer.SizeInBytes);
            packet.AppendInt(area.X1);
            packet.AppendInt(area.Y1);
            packet.AppendInt(area.X2);
            packet.AppendInt(area.Y2);

            var compressed = false;
            var data       = layer.CopyAreaToByteArray(area);

            if (data.Length > GZIP_THRESHOLD)
            {
                var compressedData = GZip.Compress(data);
                compressed = ((double)data.Length / compressedData.Length) > 1.0;

                if (compressed)
                {
                    data = compressedData;
                }
            }

            packet.AppendByte((byte)(compressed ? 1 : 0));
            packet.AppendInt(data.Length);
            packet.AppendByteArray(data);

            return(packet);
        }