DotCloud/Assets/Plugins/LiteNetLib/NetPacket.cs

165 lines
4.8 KiB
C#
Raw Normal View History

2024-12-09 16:51:45 +08:00
using System;
using LiteNetLib.Utils;
namespace LiteNetLib
{
internal enum PacketProperty : byte
{
Unreliable,
Channeled,
Ack,
Ping,
Pong,
ConnectRequest,
ConnectAccept,
Disconnect,
UnconnectedMessage,
MtuCheck,
MtuOk,
Broadcast,
Merged,
ShutdownOk,
PeerNotFound,
InvalidProtocol,
NatMessage,
Empty
}
internal sealed class NetPacket
{
private static readonly int PropertiesCount = Enum.GetValues(typeof(PacketProperty)).Length;
private static readonly int[] HeaderSizes;
static NetPacket()
{
HeaderSizes = NetUtils.AllocatePinnedUninitializedArray<int>(PropertiesCount);
for (int i = 0; i < HeaderSizes.Length; i++)
{
switch ((PacketProperty)i)
{
case PacketProperty.Channeled:
case PacketProperty.Ack:
HeaderSizes[i] = NetConstants.ChanneledHeaderSize;
break;
case PacketProperty.Ping:
HeaderSizes[i] = NetConstants.HeaderSize + 2;
break;
case PacketProperty.ConnectRequest:
HeaderSizes[i] = NetConnectRequestPacket.HeaderSize;
break;
case PacketProperty.ConnectAccept:
HeaderSizes[i] = NetConnectAcceptPacket.Size;
break;
case PacketProperty.Disconnect:
HeaderSizes[i] = NetConstants.HeaderSize + 8;
break;
case PacketProperty.Pong:
HeaderSizes[i] = NetConstants.HeaderSize + 10;
break;
default:
HeaderSizes[i] = NetConstants.HeaderSize;
break;
}
}
}
//Header
public PacketProperty Property
{
get => (PacketProperty)(RawData[0] & 0x1F);
set => RawData[0] = (byte)((RawData[0] & 0xE0) | (byte)value);
}
public byte ConnectionNumber
{
get => (byte)((RawData[0] & 0x60) >> 5);
set => RawData[0] = (byte) ((RawData[0] & 0x9F) | (value << 5));
}
public ushort Sequence
{
get => BitConverter.ToUInt16(RawData, 1);
set => FastBitConverter.GetBytes(RawData, 1, value);
}
public bool IsFragmented => (RawData[0] & 0x80) != 0;
public void MarkFragmented()
{
RawData[0] |= 0x80; //set first bit
}
public byte ChannelId
{
get => RawData[3];
set => RawData[3] = value;
}
public ushort FragmentId
{
get => BitConverter.ToUInt16(RawData, 4);
set => FastBitConverter.GetBytes(RawData, 4, value);
}
public ushort FragmentPart
{
get => BitConverter.ToUInt16(RawData, 6);
set => FastBitConverter.GetBytes(RawData, 6, value);
}
public ushort FragmentsTotal
{
get => BitConverter.ToUInt16(RawData, 8);
set => FastBitConverter.GetBytes(RawData, 8, value);
}
//Data
public byte[] RawData;
public int Size;
//Delivery
public object UserData;
//Pool node
public NetPacket Next;
public NetPacket(int size)
{
RawData = new byte[size];
Size = size;
}
public NetPacket(PacketProperty property, int size)
{
size += GetHeaderSize(property);
RawData = new byte[size];
Property = property;
Size = size;
}
public static int GetHeaderSize(PacketProperty property)
{
return HeaderSizes[(int)property];
}
public int GetHeaderSize()
{
return HeaderSizes[RawData[0] & 0x1F];
}
public bool Verify()
{
byte property = (byte)(RawData[0] & 0x1F);
if (property >= PropertiesCount)
return false;
int headerSize = HeaderSizes[property];
bool fragmented = (RawData[0] & 0x80) != 0;
return Size >= headerSize && (!fragmented || Size >= headerSize + NetConstants.FragmentHeaderSize);
}
#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1
public static implicit operator Span<byte>(NetPacket p) => new Span<byte>(p.RawData, 0, p.Size);
#endif
}
}