// encrypts a packet and sends it to the endpoint private void sendPacketToClient(NetcodePacketHeader packetHeader, byte[] packetData, int packetDataLen, EndPoint endpoint, byte[] key) { // assign a sequence number to this packet packetHeader.SequenceNumber = this.nextSequenceNumber++; // encrypt packet data byte[] encryptedPacketBuffer = BufferPool.GetBuffer(2048); int encryptedBytes = PacketIO.EncryptPacketData(packetHeader, protocolID, packetData, packetDataLen, key, encryptedPacketBuffer); int packetLen = 0; // write packet to byte array var packetBuffer = BufferPool.GetBuffer(2048); using (var packetWriter = ByteArrayReaderWriter.Get(packetBuffer)) { packetHeader.Write(packetWriter); packetWriter.WriteBuffer(encryptedPacketBuffer, encryptedBytes); packetLen = (int)packetWriter.WritePosition; } // send packet listenSocket.SendTo(packetBuffer, packetLen, SocketFlags.None, endpoint); BufferPool.ReturnBuffer(packetBuffer); BufferPool.ReturnBuffer(encryptedPacketBuffer); }
internal sealed override void Deserialize(byte[] buffer) { using (var packetWriter = ByteArrayReaderWriter.Get(buffer)) { Action = packetWriter.ReadByte(); var haveSendTime = packetWriter.ReadByte(); var havePayload = packetWriter.ReadByte(); if (havePayload == 0x1) { _payloadLen = packetWriter.ReadUInt16(); } SendType = (GProtocolSendType)packetWriter.ReadByte(); Hash = (long)packetWriter.ReadUInt64(); if (havePayload == 0x1) { Payload = packetWriter.ReadBytes(_payloadLen); } if (haveSendTime == 0x1) { ClientSendTime = packetWriter.ReadInt64(); } } }
public bool Read(ByteArrayReaderWriter stream, int length, byte[] key, ulong protocolID) { byte[] packetBuffer = BufferPool.GetBuffer(8 + 300 + Defines.MAC_SIZE); int packetLen = 0; try { packetLen = PacketIO.ReadPacketData(Header, stream, length, protocolID, key, packetBuffer); } catch (System.Exception e) { BufferPool.ReturnBuffer(packetBuffer); return(false); } if (packetLen != 308) { BufferPool.ReturnBuffer(packetBuffer); return(false); } ChallengeTokenBytes = BufferPool.GetBuffer(300); using (var reader = ByteArrayReaderWriter.Get(packetBuffer)) { ChallengeTokenSequence = reader.ReadUInt64(); reader.ReadBytesIntoBuffer(ChallengeTokenBytes, 300); } BufferPool.ReturnBuffer(packetBuffer); return(true); }
public void ReadData(ByteArrayReaderWriter stream) { byte addressVal = stream.ReadByte(); // if address type is not 0 or 1, data is not valid if (addressVal != 0 && addressVal != 1) { throw new FormatException(); } this.AddressType = (NetcodeAddressType)addressVal; IPAddress ip = null; if (this.AddressType == NetcodeAddressType.IPv4) { stream.ReadBytesIntoBuffer(tempIPV4, 4); ip = new IPAddress(tempIPV4); } else { stream.ReadBytesIntoBuffer(tempIPV6, 16); ip = new IPAddress(tempIPV6); } var port = stream.ReadUInt16(); this.Endpoint = new IPEndPoint(ip, port); }
/// <summary> /// Decrypt a challenge token /// </summary> public static int DecryptChallengeToken(ulong sequenceNum, byte[] packetData, byte[] key, byte[] outBuffer) { byte[] additionalData = BufferPool.GetBuffer(0); byte[] nonce = BufferPool.GetBuffer(12); using (var writer = ByteArrayReaderWriter.Get(nonce)) { writer.Write((UInt32)0); writer.Write(sequenceNum); } int ret; try { ret = CryptoUtils.Decrypt(packetData, 0, 300, additionalData, key, nonce, outBuffer); } catch (Exception e) { BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); throw e; } BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); return(ret); }
// Decrypt a private connect token public static int DecryptPrivateConnectToken(byte[] encryptedConnectToken, ulong protocolID, ulong expireTimestamp, ulong sequence, byte[] key, byte[] outBuffer) { int len = encryptedConnectToken.Length; byte[] additionalData = BufferPool.GetBuffer(Defines.NETCODE_VERSION_INFO_BYTES + 8 + 8); using (var writer = ByteArrayReaderWriter.Get(additionalData)) { writer.WriteASCII(Defines.NETCODE_VERSION_INFO_STR); writer.Write(protocolID); writer.Write(expireTimestamp); } byte[] nonce = BufferPool.GetBuffer(12); using (var writer = ByteArrayReaderWriter.Get(nonce)) { writer.Write((UInt32)0); writer.Write(sequence); } var ret = CryptoUtils.Decrypt(encryptedConnectToken, 0, len, additionalData, key, nonce, outBuffer); BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); return(ret); }
/// <summary> /// Decrypt a packet's data /// </summary> public static int DecryptPacketData(NetcodePacketHeader header, ulong protocolID, byte[] packetData, int packetDataLen, byte[] key, byte[] outBuffer) { byte[] additionalData = BufferPool.GetBuffer(Defines.NETCODE_VERSION_INFO_BYTES + 8 + 1); using (var writer = ByteArrayReaderWriter.Get(additionalData)) { writer.WriteASCII(Defines.NETCODE_VERSION_INFO_STR); writer.Write(protocolID); writer.Write(header.ReadSequenceByte); } byte[] nonce = BufferPool.GetBuffer(12); using (var writer = ByteArrayReaderWriter.Get(nonce)) { writer.Write((UInt32)0); writer.Write(header.SequenceNumber); } int ret; try { ret = CryptoUtils.Decrypt(packetData, 0, packetDataLen, additionalData, key, nonce, outBuffer); } catch (Exception e) { BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); throw e; } BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); return(ret); }
protected void processPacket(ushort seq, byte[] packetData, int packetLen) { using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(packetData)) { while (byteArrayReaderWriter.ReadPosition < packetLen) { ushort num = byteArrayReaderWriter.ReadUInt16(); ushort num2 = readVariableLengthUShort(byteArrayReaderWriter); if (num2 != 0) { if (!receiveBuffer.Exists(num)) { BufferedPacket bufferedPacket = receiveBuffer.Insert(num); bufferedPacket.buffer.SetSize(num2); byteArrayReaderWriter.ReadBytesIntoBuffer(bufferedPacket.buffer.InternalBuffer, num2); } else { byteArrayReaderWriter.SeekRead(byteArrayReaderWriter.ReadPosition + (int)num2); } while (receiveBuffer.Exists(nextReceive)) { BufferedPacket bufferedPacket2 = receiveBuffer.Find(nextReceive); ReceiveCallback(ChannelID, bufferedPacket2.buffer.InternalBuffer, bufferedPacket2.buffer.Length); receiveBuffer.Remove(nextReceive); nextReceive++; } } } } }
/// <summary> /// Encrypt a challenge token /// </summary> public static int EncryptChallengeToken(ulong sequenceNum, byte[] packetData, byte[] key, byte[] outBuffer) { byte[] additionalData = BufferPool.GetBuffer(0); byte[] nonce = BufferPool.GetBuffer(12); using (var writer = ByteArrayReaderWriter.Get(nonce)) { writer.Write((UInt32)0); writer.Write(sequenceNum); } int ret; try { ret = AEAD_Chacha20_Poly1305.Encrypt(packetData, 0, 300 - Defines.MAC_SIZE, additionalData, nonce, key, outBuffer); } catch (Exception e) { BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); throw e; } BufferPool.ReturnBuffer(additionalData); BufferPool.ReturnBuffer(nonce); return(ret); }
private void sendPacket(NetcodePacketHeader packetHeader, byte[] packetData, int packetDataLen, byte[] key) { // assign a sequence number to this packet packetHeader.SequenceNumber = this.nextPacketSequence++; // encrypt packet data byte[] encryptedPacketBuffer = BufferPool.GetBuffer(2048); int encryptedBytes = PacketIO.EncryptPacketData(packetHeader, connectToken.ProtocolID, packetData, packetDataLen, key, encryptedPacketBuffer); int packetLen = 0; // write packet to byte array var packetBuffer = BufferPool.GetBuffer(2048); using (var packetWriter = ByteArrayReaderWriter.Get(packetBuffer)) { packetHeader.Write(packetWriter); packetWriter.WriteBuffer(encryptedPacketBuffer, encryptedBytes); packetLen = (int)packetWriter.WritePosition; } // send packet try { socket.SendTo(packetBuffer, packetLen, currentServerEndpoint); } catch { } BufferPool.ReturnBuffer(packetBuffer); BufferPool.ReturnBuffer(encryptedPacketBuffer); }
public bool Read(ByteArrayReaderWriter stream, int length, byte[] key, ulong protocolID) { if (length != 8 + Defines.MAC_SIZE) { return(false); } byte[] tempBuffer = BufferPool.GetBuffer(length); try { PacketIO.ReadPacketData(Header, stream, length, protocolID, key, tempBuffer); } catch { BufferPool.ReturnBuffer(tempBuffer); return(false); } using (var dataReader = ByteArrayReaderWriter.Get(tempBuffer)) { ClientIndex = dataReader.ReadUInt32(); MaxSlots = dataReader.ReadUInt32(); } return(true); }
public bool Read(ByteArrayReaderWriter stream, int length, ulong protocolID) { if (length != 13 + 8 + 8 + 8 + Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES) { return(false); } char[] vInfo = new char[Defines.NETCODE_VERSION_INFO_BYTES]; stream.ReadASCIICharsIntoBuffer(vInfo, Defines.NETCODE_VERSION_INFO_BYTES); if (!MiscUtils.MatchChars(vInfo, Defines.NETCODE_VERSION_INFO_STR)) { return(false); } if (stream.ReadUInt64() != protocolID) { return(false); } this.Expiration = stream.ReadUInt64(); this.TokenSequenceNum = stream.ReadUInt64(); this.ConnectTokenBytes = BufferPool.GetBuffer(Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES); stream.ReadBytesIntoBuffer(this.ConnectTokenBytes, Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES); return(true); }
// process a received datagram private void processDatagram(byte[] payload, int size, EndPoint sender) { using (var reader = ByteArrayReaderWriter.Get(payload)) { NetcodePacketHeader packetHeader = new NetcodePacketHeader(); packetHeader.Read(reader); if (packetHeader.PacketType == NetcodePacketType.ConnectionRequest) { processConnectionRequest(reader, size, sender); } else { switch (packetHeader.PacketType) { case NetcodePacketType.ChallengeResponse: processConnectionResponse(reader, packetHeader, size, sender); break; case NetcodePacketType.ConnectionKeepAlive: processConnectionKeepAlive(reader, packetHeader, size, sender); break; case NetcodePacketType.ConnectionPayload: processConnectionPayload(reader, packetHeader, size, sender); break; case NetcodePacketType.ConnectionDisconnect: processConnectionDisconnect(reader, packetHeader, size, sender); break; } } } }
public void Connect(byte[] connectToken, bool autoTick) { if (state != ClientState.Disconnected) { throw new InvalidOperationException(); } keepAliveTimer = 0.0; connectServers.Clear(); replayProtection.Reset(); if (connectToken.Length != Defines.NETCODE_CONNECT_TOKEN_PUBLIC_BYTES) { changeState(ClientState.InvalidConnectToken); return; } NetcodePublicConnectToken tokenData = new NetcodePublicConnectToken(); using (var reader = ByteArrayReaderWriter.Get(connectToken)) { if (!tokenData.Read(reader)) { changeState(ClientState.InvalidConnectToken); return; } } if (tokenData.CreateTimestamp >= tokenData.ExpireTimestamp) { changeState(ClientState.InvalidConnectToken); return; } clientToServerKey = tokenData.ClientToServerKey; serverToClientKey = tokenData.ServerToClientKey; foreach (var server in tokenData.ConnectServers) { connectServers.Enqueue(server.Endpoint); } this.connectToken = tokenData; this.state = ClientState.SendingConnectionRequest; // bind socket, spin up threads, and start trying to connect isRunning = true; currentServerEndpoint = connectServers.Dequeue(); createSocket(currentServerEndpoint); if (autoTick) { this.time = DateTime.Now.GetTotalSeconds(); ThreadPool.QueueUserWorkItem(clientTick); } }
internal static Tuple <string, byte[]> GetObserver(byte[] buffer) { using (var packetReader = ByteArrayReaderWriter.Get(buffer)) { var len = packetReader.ReadByte(); var ownerId = GetStringFromBuffer(packetReader.ReadBytes(len), true); var payload = packetReader.ReadBytes(buffer.Length - len); return(Tuple.Create(ownerId, payload)); } }
// sends a connection challenge packet to the endpoint private void sendConnectionChallenge(NetcodePrivateConnectToken connectToken, EndPoint endpoint) { log("Sending connection challenge", NetcodeLogLevel.Debug); var challengeToken = new NetcodeChallengeToken(); challengeToken.ClientID = connectToken.ClientID; challengeToken.UserData = connectToken.UserData; ulong challengeSequence = nextChallengeSequenceNumber++; byte[] tokenBytes = BufferPool.GetBuffer(300); using (var tokenWriter = ByteArrayReaderWriter.Get(tokenBytes)) challengeToken.Write(tokenWriter); byte[] encryptedToken = BufferPool.GetBuffer(300); int encryptedTokenBytes; try { encryptedTokenBytes = PacketIO.EncryptChallengeToken(challengeSequence, tokenBytes, challengeKey, encryptedToken); } catch { BufferPool.ReturnBuffer(tokenBytes); BufferPool.ReturnBuffer(encryptedToken); return; } var challengePacket = new NetcodeConnectionChallengeResponsePacket(); challengePacket.ChallengeTokenSequence = challengeSequence; challengePacket.ChallengeTokenBytes = encryptedToken; var cryptIdx = encryptionManager.FindEncryptionMapping(endpoint, time); if (cryptIdx == -1) { return; } var cryptKey = encryptionManager.GetSendKey(cryptIdx); serializePacket(new NetcodePacketHeader() { PacketType = NetcodePacketType.ConnectionChallenge }, (writer) => { challengePacket.Write(writer); }, endpoint, cryptKey); BufferPool.ReturnBuffer(tokenBytes); BufferPool.ReturnBuffer(encryptedToken); }
private static void startClient() { // get token var webRequest = WebRequest.Create("http://127.0.0.1:8080/token"); webRequest.Credentials = CredentialCache.DefaultCredentials; HttpWebResponse response; try { response = (HttpWebResponse)webRequest.GetResponse(); } catch (Exception e) { Console.WriteLine("Failed to get token: " + e.Message); Console.ReadLine(); return; } if (response.StatusCode != HttpStatusCode.OK) { Console.WriteLine("Failed to get token: " + response.StatusDescription); Console.ReadLine(); return; } Stream dataStream = response.GetResponseStream(); StreamReader reader = new StreamReader(dataStream); string responseStr = reader.ReadToEnd(); reader.Close(); dataStream.Close(); response.Close(); byte[] connectToken = System.Convert.FromBase64String(responseStr); testPacket = new byte[256]; using (var testPacketWriter = ByteArrayReaderWriter.Get(testPacket)) { testPacketWriter.Write((uint)0xAABBCCDD); } client = new Client(); client.OnStateChanged += Client_OnStateChanged; client.OnMessageReceived += Client_OnMessageReceived; Console.WriteLine("Connecting..."); client.Connect(connectToken); Console.ReadLine(); client.Disconnect(); }
// process an incoming disconnect message private void processConnectionDisconnect(ByteArrayReaderWriter reader, NetcodePacketHeader header, int size, EndPoint sender) { if (checkReplay(header, sender)) { return; } // encryption mapping was not registered, so don't bother int cryptIdx = encryptionManager.FindEncryptionMapping(sender, time); if (cryptIdx == -1) { log("No crytpo key for sender", NetcodeLogLevel.Debug); return; } var decryptKey = encryptionManager.GetReceiveKey(cryptIdx); var disconnectPacket = new NetcodeDisconnectPacket() { Header = header }; if (!disconnectPacket.Read(reader, size - (int)reader.ReadPosition, decryptKey, protocolID)) { return; } // locate the client by endpoint and free their slot if (!endpointClientIDMap.ContainsKey(sender)) { log("No client found for sender endpoint", NetcodeLogLevel.Debug); return; } var clientIndex = endpointClientIDMap[sender]; var client = clientSlots[clientIndex]; clientSlots[clientIndex] = null; endpointClientIDMap.Remove(sender); // remove encryption mapping encryptionManager.RemoveEncryptionMapping(sender, time); // trigger client disconnect callback if (OnClientDisconnected != null) { OnClientDisconnected(client); } log("Client {0} disconnected", NetcodeLogLevel.Info, client.RemoteEndpoint); }
public bool Read(byte[] token, byte[] key, ulong protocolID, ulong expiration, ulong sequence) { byte[] tokenBuffer = BufferPool.GetBuffer(Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES); int tokenLen = 0; try { tokenLen = PacketIO.DecryptPrivateConnectToken(token, protocolID, expiration, sequence, key, tokenBuffer); } catch { BufferPool.ReturnBuffer(tokenBuffer); return(false); } try { using (var reader = ByteArrayReaderWriter.Get(tokenBuffer)) { this.ClientID = reader.ReadUInt64(); this.TimeoutSeconds = (int)reader.ReadUInt32(); uint numServerAddresses = reader.ReadUInt32(); if (numServerAddresses == 0 || numServerAddresses > Defines.MAX_SERVER_ADDRESSES) { BufferPool.ReturnBuffer(tokenBuffer); return(false); } this.ConnectServers = new ConnectTokenServerEntry[numServerAddresses]; for (int i = 0; i < numServerAddresses; i++) { this.ConnectServers[i] = new ConnectTokenServerEntry(); this.ConnectServers[i].ReadData(reader); } ClientToServerKey = new byte[32]; ServerToClientKey = new byte[32]; UserData = new byte[256]; reader.ReadBytesIntoBuffer(ClientToServerKey, 32); reader.ReadBytesIntoBuffer(ServerToClientKey, 32); reader.ReadBytesIntoBuffer(UserData, 256); } } catch { BufferPool.ReturnBuffer(tokenBuffer); return(false); } return(true); }
private ushort readVariableLengthUShort(ByteArrayReaderWriter reader) { ushort num = 0; byte b = reader.ReadByte(); num = (ushort)(num | (ushort)(b & 0x7F)); if ((b & 0x80) != 0) { num = (ushort)(num | (ushort)(reader.ReadByte() << 7)); } return(num); }
public void Write(ByteArrayReaderWriter stream) { stream.Write(ClientID); stream.Write((uint)ConnectServers.Length); foreach (var server in ConnectServers) { server.WriteData(stream); } stream.Write(ClientToServerKey); stream.Write(ServerToClientKey); stream.Write(UserData); }
private void serializePacket(NetcodePacketHeader packetHeader, Action <ByteArrayReaderWriter> write, byte[] key) { byte[] tempPacket = BufferPool.GetBuffer(2048); int writeLen = 0; using (var writer = ByteArrayReaderWriter.Get(tempPacket)) { write(writer); writeLen = (int)writer.WritePosition; } sendPacket(packetHeader, tempPacket, writeLen, key); BufferPool.ReturnBuffer(tempPacket); }
internal override byte[] Serialize(string key, bool isCommand) { byte havePayload = 0x0, haveSendTime = 0x0; short prefixLen = 4 * sizeof(byte) + sizeof(ulong); if (Payload != null) { havePayload = 0x1; _payloadLen = Payload.Length; prefixLen += sizeof(ushort); } if (ClientSendTime != 0L) { haveSendTime = 0x1; prefixLen += sizeof(long); } var packetBuffer = BufferPool.GetBuffer(BufferSize(prefixLen)); using (var packetWriter = ByteArrayReaderWriter.Get(packetBuffer)) { // header Segment packetWriter.Write((byte)Action); packetWriter.Write(haveSendTime); packetWriter.Write(havePayload); if (havePayload == 0x1) { packetWriter.Write((ushort)_payloadLen); } // data Segment packetWriter.Write((byte)SendType); packetWriter.Write((ulong)Hash); if (havePayload == 0x1) { packetWriter.Write(Payload); } if (haveSendTime == 0x1) { packetWriter.Write(ClientSendTime); } } return(packetBuffer); }
internal static Queue <byte[]> GetQueueData(byte[] buffer) { var data = new Queue <byte[]>(); using (var packetReader = ByteArrayReaderWriter.Get(buffer)) { var count = packetReader.ReadByte(); for (var i = 0; i < count; i++) { data.Enqueue(packetReader.ReadBytes(packetReader.ReadUInt16())); } } return(data); }
private static string[] GetStringsFromBuffer(byte[] bytes) { var data = new List <string>(); using (var packetReader = ByteArrayReaderWriter.Get(bytes)) { var count = packetReader.ReadUInt16(); for (var i = 0; i < count; i++) { data.Add(GetStringFromBuffer(packetReader.ReadBytes(packetReader.ReadUInt16()), true)); } } return(data.ToArray()); }
private ushort readVariableLengthUShort(ByteArrayReaderWriter reader) { ushort val = 0; byte b1 = reader.ReadByte(); val |= (ushort)(b1 & 0x7F); if ((b1 & 0x80) != 0) { val |= (ushort)(reader.ReadByte() << 7); } return(val); }
private void sendConnectionRequest(EndPoint server) { byte[] packetBuffer = BufferPool.GetBuffer(1 + 13 + 8 + 8 + 8 + Defines.NETCODE_CONNECT_TOKEN_PRIVATE_BYTES); using (var stream = ByteArrayReaderWriter.Get(packetBuffer)) { stream.Write((byte)0); stream.WriteASCII(Defines.NETCODE_VERSION_INFO_STR); stream.Write(connectToken.ProtocolID); stream.Write(connectToken.ExpireTimestamp); stream.Write(connectToken.ConnectTokenSequence); stream.Write(connectToken.PrivateConnectTokenBytes); } socket.SendTo(packetBuffer, server); BufferPool.ReturnBuffer(packetBuffer); }
// process an incoming payload private void processConnectionPayload(ByteArrayReaderWriter reader, NetcodePacketHeader header, int size, EndPoint sender) { if (checkReplay(header, sender)) { return; } // encryption mapping was not registered, so don't bother int cryptIdx = encryptionManager.FindEncryptionMapping(sender, time); if (cryptIdx == -1) { log("No crytpo key for sender", NetcodeLogLevel.Debug); return; } // grab the decryption key and decrypt the packet var decryptKey = encryptionManager.GetReceiveKey(cryptIdx); var payloadPacket = new NetcodePayloadPacket() { Header = header }; if (!payloadPacket.Read(reader, size - (int)reader.ReadPosition, decryptKey, protocolID)) { return; } // locate the client by endpoint if (!endpointClientIDMap.ContainsKey(sender)) { payloadPacket.Release(); return; } var clientIndex = endpointClientIDMap[sender]; var client = clientSlots[clientIndex]; // trigger callback if (OnClientMessageReceived != null) { OnClientMessageReceived(client, payloadPacket.Payload, payloadPacket.Length); } payloadPacket.Release(); }
public void Write(ByteArrayReaderWriter writer) { writer.Write(CreateTimestamp); writer.Write(ExpireTimestamp); writer.Write(ConnectTokenSequence); writer.Write(PrivateConnectTokenBytes); writer.Write((uint)ConnectServers.Length); for (int i = 0; i < ConnectServers.Length; i++) { ConnectServers[i].WriteData(writer); } writer.Write(ClientToServerKey); writer.Write(ServerToClientKey); writer.Write(TimeoutSeconds); }
internal void Deserialize(byte[] buff) { using (var packetWriter = ByteArrayReaderWriter.Get(buff)) { var haveSender = packetWriter.ReadByte(); var haveReceiver = packetWriter.ReadByte(); var havePayload = packetWriter.ReadByte(); var haveExtra = packetWriter.ReadByte(); if (haveSender == 0x1) { _senderLen = packetWriter.ReadByte(); } if (haveReceiver == 0x1) { _receiverLen = packetWriter.ReadByte(); } if (havePayload == 0x1) { _payloadLen = packetWriter.ReadUInt16(); } if (haveExtra == 0x1) { _extraLen = packetWriter.ReadUInt16(); } if (haveSender == 0x1) { SenderId = ConvertToString(packetWriter.ReadBytes(_senderLen)); } if (haveReceiver == 0x1) { ReceiverId = ConvertToString(packetWriter.ReadBytes(_receiverLen)); } if (havePayload == 0x1) { Payload = packetWriter.ReadBytes(_payloadLen); } if (haveExtra == 0x1) { ExtraData = packetWriter.ReadBytes(_extraLen); } } }