Ejemplo n.º 1
0
        /// <summary>
        /// 生成发送给服务端的包
        /// </summary>
        /// <param name="compress">数据包压缩的阚值</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="IndexOutOfRangeException"></exception>
        public virtual byte[] ToBytes(int compress = -1)
        {
            if (Empty)
            {
                throw new PacketException("Packet is empty");
            }

            byte[] PacketData;
            if (compress > 0)
            {
                /*
                 * 压缩的数据包:
                 *
                 * 名称       类型    备注
                 * 数据包长度 Varint  等于下方两者解压前的总字节数
                 * 解压后长度 Varint  若为0则表示本包未被压缩
                 * 被压缩的数据       经Zlib压缩.开头是一个VarInt字段,代表数据包ID,然后是数据包数据.
                 */
                if (Data.Count >= compress)
                {
                    //拼接PacketID(VarInt)和PacketData(ByteArray)并塞入ZlibUtils.Compress去压缩
                    byte[] uncompressed = new byte[Length];
                    Data.CopyTo(uncompressed, VarInt.WriteTo(ID, uncompressed));
                    byte[] compressed = ZlibUtils.Compress(uncompressed);

                    PacketData = new byte[VarInt.GetLength(VarInt.GetLength(uncompressed.Length) + compressed.Length) + VarInt.GetLength(uncompressed.Length) + compressed.Length];
                    //写入第一个VarInt(解压长度+压缩后的长度)
                    int offset = VarInt.WriteTo(VarInt.GetLength(uncompressed.Length) + compressed.Length, PacketData);
                    //写入第二个VarInt(未压缩长度)
                    offset += VarInt.WriteTo(uncompressed.Length, PacketData.AsSpan().Slice(offset));
                    //写入被压缩的数据
                    compressed.CopyTo(PacketData, offset);
                }
                else
                {
                    PacketData = new byte[VarInt.GetLength(Length + 1) + Length + 1];
                    int offset = VarInt.WriteTo(Length + 1, PacketData);
                    PacketData[offset++] = 0;
                    offset += VarInt.WriteTo(ID, PacketData.AsSpan().Slice(offset));
                    if (Data.Count > 0)
                    {
                        Data.CopyTo(PacketData, offset);
                    }
                }
            }
            else
            {
                PacketData = new byte[VarInt.GetLength(Length) + Length];
                int offset = VarInt.WriteTo(Length, PacketData);
                offset += VarInt.WriteTo(ID, PacketData.AsSpan().Slice(offset));
                if (Data.Count > 0)
                {
                    Data.CopyTo(PacketData, offset);
                }
            }
            return(PacketData);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 生成发送给服务端的包
        /// </summary>
        /// <param name="compress">数据包压缩的阚值</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public virtual List <byte> ToList(int compress = -1)
        {
            if (Empty)
            {
                throw new PacketException("Packet is empty");
            }

            List <byte> PacketData = new List <byte>();

            PacketData.Capacity = Length;
            if (compress > 0)
            {
                if (Data.Count >= compress)
                {
                    PacketData.AddRange(VarInt.GetBytes(Length));
                    int    IdLength = VarInt.GetLength(ID);
                    byte[] buffer   = new byte[IdLength + Data.Count];
                    Array.Copy(VarInt.GetBytes(ID), 0, buffer, 0, IdLength);
                    Data.CopyTo(buffer, IdLength);
                    PacketData.AddRange(ZlibUtils.Compress(buffer));
                    PacketData.InsertRange(0, VarInt.GetBytes(PacketData.Count));
                }
                else
                {
                    PacketData.AddRange(VarInt.GetBytes(Length + 1));
                    PacketData.Add(0);
                    PacketData.AddRange(VarInt.GetBytes(ID));
                    PacketData.AddRange(Data);
                }
            }
            else
            {
                PacketData.AddRange(VarInt.GetBytes(Length));
                PacketData.AddRange(VarInt.GetBytes(ID));
                PacketData.AddRange(Data);
            }
            return(PacketData);
        }