public static BasePacket ReceivePacket(this Socket socket, Direction direction) { Span <byte> intBuffer = stackalloc byte[sizeof(int)]; socket.Receive(intBuffer); int packetId = BitConverter.ToInt32(intBuffer); BasePacket packet = PacketRegistry.FromId(packetId, direction); if (packet == null) { throw new Exception($"Packet with id 0x{packetId:x2} not registered!"); } socket.Receive(intBuffer); int dataLength = BitConverter.ToInt32(intBuffer); byte[] packetDataBuffer = new byte[dataLength]; socket.Receive(packetDataBuffer); MemoryStream memoryStream = new MemoryStream(packetDataBuffer, false); packet.Read(new PacketDataReader(new BinaryReader(memoryStream))); return(packet); }
//-------------------------------- deseriialize -------------------------------- public static List <BasePacket> Deserialize(byte[] bytes, int maxBufferSize, ref int amountRead) { List <BasePacket> storage = new List <BasePacket>(); using (MemoryStream stream = new MemoryStream(bytes)) { using (BinaryReader reader = new BinaryReader(stream)) { long len = maxBufferSize; // We've got no way of telling if the buffer ends with an incomplete packet, // but we want to deserialize all of the packets that are in the buffer, so // rather than leaving a bit at the end (which is what the commented out code does), // we're just going to handle the error. // TODO: Update the packet format to include information about length where appropriate. /*if(len > 512)// never read until the absolute end. * { * len = maxBufferSize - 256; * }*/ Debug.Assert(len > 0); // Catch us falling off the end of the stream - this should only happen // if we've received an incomplete packet try { bool hadParseError = false; while (reader.BaseStream.Position < len) { // Record the position before we attempt to read // a packet. If the read fails, this ensures the next time // we start the read again from the start of the packet. // critically, this must be the first thing that we do for each packet read. amountRead = (int)reader.BaseStream.Position; #if DEBUG_NETWORK_PACKETS int numBytesToRead = #endif Network.Utils.SetupRead(reader); ushort packetTypeId = reader.ReadUInt16(); var packetType = (PacketType)packetTypeId; BasePacket packet = null; // TODO: Replace this with something that looks up everything that descends from // BasePacket, and creates new instances if (listOfConstructors.ContainsKey(packetType) == true) { //packet = listOfConstructors[packetType].Invoke(); packet = TakeFromPool(packetType); } else { Console.WriteLine("Unhandled packet type received: {0}", packetTypeId); hadParseError = true; } if (packet != null) { packet.Read(reader); storage.Add(packet); #if DEBUG_NETWORK_PACKETS if (DebugLogPacket(packet)) { Console.WriteLine("Received {0}", packet.GetType()); } #endif } else { break; } } if (!hadParseError) { // We've read the whole buffer, so record the final amount read amountRead = (int)reader.BaseStream.Position; } } catch (EndOfStreamException) { // We've got an incomplete packet at the end of our buffer. // The amountRead points to the start of that incomplete packet, // so we can just continue. #if DEBUG_NETWORK_PACKETS Console.WriteLine("Incomplete packet received"); #endif } } } return(storage); }