Beispiel #1
0
        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();
                    }
                }
            }
        }
Beispiel #2
0
 public GameMessage(int id, GamePacket packet) : base(id)
 {
     Packets = new[] { packet };
 }