/// <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); }
/// <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); }