#if DEBUG && !UNITY_WP_8_1 && !UNITY_WSA using System; using FlyingWormConsole3.LiteNetLib.Utils; namespace FlyingWormConsole3.LiteNetLib { internal enum PacketProperty : byte { Unreliable, //0 Reliable, //1 Sequenced, //2 ReliableOrdered, //3 AckReliable, //4 AckReliableOrdered, //5 Ping, //6 Pong, //7 ConnectRequest, //8 ConnectAccept, //9 Disconnect, //10 UnconnectedMessage, //11 NatIntroductionRequest, //12 NatIntroduction, //13 NatPunchMessage, //14 MtuCheck, //15 MtuOk, //16 DiscoveryRequest, //17 DiscoveryResponse, //18 Merged //19 } internal sealed class NetPacket { private const int LastProperty = 19; //Header public PacketProperty Property { get { return (PacketProperty)(RawData[0] & 0x7F); } set { RawData[0] = (byte)((RawData[0] & 0x80) | ((byte)value & 0x7F)); } } public ushort Sequence { get { return BitConverter.ToUInt16(RawData, 1); } set { FastBitConverter.GetBytes(RawData, 1, value); } } public bool IsFragmented { get { return (RawData[0] & 0x80) != 0; } set { if (value) RawData[0] |= 0x80; //set first bit else RawData[0] &= 0x7F; //unset first bit } } public ushort FragmentId { get { return BitConverter.ToUInt16(RawData, 3); } set { FastBitConverter.GetBytes(RawData, 3, value); } } public ushort FragmentPart { get { return BitConverter.ToUInt16(RawData, 5); } set { FastBitConverter.GetBytes(RawData, 5, value); } } public ushort FragmentsTotal { get { return BitConverter.ToUInt16(RawData, 7); } set { FastBitConverter.GetBytes(RawData, 7, value); } } //Data public readonly byte[] RawData; public int Size; public NetPacket(int size) { RawData = new byte[size]; Size = 0; } public static bool GetPacketProperty(byte[] data, out PacketProperty property) { byte properyByte = (byte)(data[0] & 0x7F); if (properyByte > LastProperty) { property = PacketProperty.Unreliable; return false; } property = (PacketProperty)properyByte; return true; } public static int GetHeaderSize(PacketProperty property) { return IsSequenced(property) ? NetConstants.SequencedHeaderSize : NetConstants.HeaderSize; } public int GetHeaderSize() { return GetHeaderSize(Property); } public byte[] GetPacketData() { int headerSize = GetHeaderSize(Property); int dataSize = Size - headerSize; byte[] data = new byte[dataSize]; Buffer.BlockCopy(RawData, headerSize, data, 0, dataSize); return data; } public bool IsClientData() { var property = Property; return property == PacketProperty.Reliable || property == PacketProperty.ReliableOrdered || property == PacketProperty.Unreliable || property == PacketProperty.Sequenced; } public static bool IsSequenced(PacketProperty property) { return property == PacketProperty.ReliableOrdered || property == PacketProperty.Reliable || property == PacketProperty.Sequenced || property == PacketProperty.Ping || property == PacketProperty.Pong || property == PacketProperty.AckReliable || property == PacketProperty.AckReliableOrdered; } //Packet contstructor from byte array public bool FromBytes(byte[] data, int start, int packetSize) { //Reading property byte property = (byte)(data[start] & 0x7F); bool fragmented = (data[start] & 0x80) != 0; int headerSize = GetHeaderSize((PacketProperty) property); if (property > LastProperty || packetSize > NetConstants.PacketSizeLimit || packetSize < headerSize || (fragmented && packetSize < headerSize + NetConstants.FragmentHeaderSize)) { return false; } Buffer.BlockCopy(data, start, RawData, 0, packetSize); Size = packetSize; return true; } } } #endif