public void Reassemble(bool verboseLog) { Packets = new List <Packet>(); Messages = new List <Message>(); foreach (Datagram datagram in Datagrams) { if (datagram.Server == Server.Matrix) { Packets.Add(new MatrixPacket(Packets.Count, datagram)); } else { int consumed = 0; Span <byte> data = datagram.Data; while (consumed < data.Length) { GamePacket packet = new GamePacket(Packets.Count, datagram, consumed); Packets.Add(packet); consumed += packet.Length; } } } //SequenceStart = SwapBytes(SequenceStart); // was the wrong endianness in the old fileformat, fixed now ReliableGamePacketInputQueue sMatrix = new ReliableGamePacketInputQueue(SequenceStart); ReliableGamePacketInputQueue sGSS = new ReliableGamePacketInputQueue(SequenceStart); ReliableGamePacketInputQueue cMatrix = new ReliableGamePacketInputQueue(SequenceStart); ReliableGamePacketInputQueue cGSS = new ReliableGamePacketInputQueue(SequenceStart); List <GamePacket> sMBuffer = new List <GamePacket>(); List <GamePacket> sGBuffer = new List <GamePacket>(); List <GamePacket> cMBuffer = new List <GamePacket>(); List <GamePacket> cGBuffer = new List <GamePacket>(); Dictionary <ushort, GamePacket> sMAck = new Dictionary <ushort, GamePacket>(); Dictionary <ushort, GamePacket> cMAck = new Dictionary <ushort, GamePacket>(); Dictionary <ushort, GamePacket> sGAck = new Dictionary <ushort, GamePacket>(); Dictionary <ushort, GamePacket> cGAck = new Dictionary <ushort, GamePacket>(); foreach (Packet packet in Packets) { if (packet.Server == Server.Matrix) { Messages.Add(new MatrixMessage(Messages.Count, packet as MatrixPacket)); continue; } GamePacket gPacket = packet as GamePacket; Dictionary <ushort, GamePacket> needsAck = null; ReliableGamePacketInputQueue queue = null; List <GamePacket> buffer = null; switch (gPacket.Channel) { case Channel.Control: ControlMessage.MessageType type = ControlMessage.GetMessageType(packet.Data); if (type == ControlMessage.MessageType.MatrixAck) { needsAck = packet.FromServer ? cMAck : sMAck; } else if (type == ControlMessage.MessageType.GSSAck) { needsAck = packet.FromServer ? cGAck : sGAck; } if (needsAck == null) { Messages.Add(new GameMessage(Messages.Count, gPacket)); break; } ushort ackFor = ControlMessage.GetAckFor(gPacket.Data); if (needsAck.ContainsKey(ackFor)) { needsAck[ackFor].AckPacket = gPacket; gPacket.AckPacket = needsAck[ackFor]; needsAck.Remove(ackFor); Messages.Add(new GameMessage(Messages.Count, gPacket)); } else { if (verboseLog) { Console.WriteLine("Duplicate " + type + ", seq: " + ackFor + " - " + (gPacket.FromServer ? "Server -> Client" : "Client -> Server")); } } break; case Channel.UnreliableGss: var message = new GameMessage(Messages.Count, gPacket); Messages.Add(message); SplitOutRoutedMessages(message); break; case Channel.Matrix: queue = (gPacket.FromServer ? sMatrix : cMatrix); buffer = (gPacket.FromServer ? sMBuffer : cMBuffer); needsAck = packet.FromServer ? sMAck : cMAck; break; case Channel.ReliableGss: queue = (gPacket.FromServer ? sGSS : cGSS); buffer = (gPacket.FromServer ? sGBuffer : cGBuffer); needsAck = packet.FromServer ? sGAck : cGAck; break; } if (queue == null) { continue; } ReliableGamePacketInputQueue.EnqueueResult result = queue.Enqueue(gPacket); if (result == ReliableGamePacketInputQueue.EnqueueResult.Ok) { needsAck.Add(gPacket.SequenceNumber, gPacket); } else { if (verboseLog) { Console.WriteLine(result + " packet, seq: " + gPacket.SequenceNumber + ", channel: " + gPacket.Channel + " - " + (gPacket.FromServer ? "Server -> Client" : "Client -> Server")); } } GamePacket qPacket; while (queue.TryDequeue(out qPacket)) { buffer.Add(qPacket); if (!qPacket.IsSplit) { if (buffer.Count > 1) { if (verboseLog) { StringBuilder sb = new StringBuilder(); sb.Append("Reassembled split packet, seq: "); sb.Append(buffer[0].SequenceNumber); sb.Append("->"); sb.Append(buffer[buffer.Count - 1].SequenceNumber); sb.Append(", channel "); sb.Append(qPacket.Channel); sb.Append(" - "); sb.Append((qPacket.FromServer ? "Server -> Client" : "Client -> Server")); Console.WriteLine(sb.ToString()); } } Messages.Add(new GameMessage(Messages.Count, buffer.ToArray())); buffer.Clear(); } } } }
public GameMessage(int id, GamePacket packet) : base(id) { Packets = new[] { packet }; }