Esempio n. 1
0
        private void HandleSplitMessage(PlayerNetworkSession playerSession, SplitPartPacket splitMessage)
        {
            int spId    = splitMessage.SplitId;
            int spIdx   = splitMessage.SplitIdx;
            int spCount = splitMessage.SplitCount;

            Int24       sequenceNumber        = splitMessage.DatagramSequenceNumber;
            Reliability reliability           = splitMessage.Reliability;
            Int24       reliableMessageNumber = splitMessage.ReliableMessageNumber;
            Int24       orderingIndex         = splitMessage.OrderingIndex;
            byte        orderingChannel       = splitMessage.OrderingChannel;

            SplitPartPacket[] spPackets;
            bool haveEmpty = false;

            // Need sync for this part since they come very fast, and very close in time.
            // If no synk, will often detect complete message two times (or more).
            lock (playerSession.Splits)
            {
                if (!playerSession.Splits.ContainsKey(spId))
                {
                    playerSession.Splits.TryAdd(spId, new SplitPartPacket[spCount]);
                }

                spPackets = playerSession.Splits[spId];
                if (spPackets[spIdx] != null)
                {
                    Log.Debug("Already had splitpart (resent). Ignore this part.");
                    return;
                }
                spPackets[spIdx] = splitMessage;

                for (int i = 0; i < spPackets.Length; i++)
                {
                    haveEmpty = haveEmpty || spPackets[i] == null;
                }
            }

            if (!haveEmpty)
            {
                Log.DebugFormat("Got all {0} split packets for split ID: {1}", spCount, spId);

                SplitPartPacket[] waste;
                playerSession.Splits.TryRemove(spId, out waste);

                using (MemoryStream stream = MemoryStreamManager.GetStream())
                {
                    for (int i = 0; i < spPackets.Length; i++)
                    {
                        SplitPartPacket splitPartPacket = spPackets[i];
                        byte[]          buf             = splitPartPacket.Message;
                        if (buf == null)
                        {
                            Log.Error("Expected bytes in splitpart, but got none");
                            continue;
                        }

                        stream.Write(buf, 0, buf.Length);
                        splitPartPacket.PutPool();
                    }

                    byte[] buffer = stream.ToArray();
                    try
                    {
                        ConnectedPacket newPacket = ConnectedPacket.CreateObject();
                        newPacket._datagramSequenceNumber = sequenceNumber;
                        newPacket._reliability            = reliability;
                        newPacket._reliableMessageNumber  = reliableMessageNumber;
                        newPacket._orderingIndex          = orderingIndex;
                        newPacket._orderingChannel        = (byte)orderingChannel;
                        newPacket._hasSplit = false;

                        Packet fullMessage = PacketFactory.Create(buffer[0], buffer, "raknet") ??
                                             new UnknownPacket(buffer[0], buffer);
                        fullMessage.DatagramSequenceNumber = sequenceNumber;
                        fullMessage.Reliability            = reliability;
                        fullMessage.ReliableMessageNumber  = reliableMessageNumber;
                        fullMessage.OrderingIndex          = orderingIndex;
                        fullMessage.OrderingChannel        = orderingChannel;

                        newPacket.Messages = new List <Packet>();
                        newPacket.Messages.Add(fullMessage);

                        Log.Debug(
                            $"Assembled split packet {newPacket._reliability} message #{newPacket._reliableMessageNumber}, Chan: #{newPacket._orderingChannel}, OrdIdx: #{newPacket._orderingIndex}");
                        HandleConnectedPacket(playerSession, newPacket);
                        newPacket.PutPool();
                    }
                    catch (Exception e)
                    {
                        Log.Error("Error during split message parsing", e);
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"0x{buffer[0]:x2}\n{Packet.HexDump(buffer)}");
                        }
                        playerSession.Disconnect("Bad packet received from client.", false);
                    }
                }
            }
        }
Esempio n. 2
0
        protected override void DecodePacket()
        {
            _reader.Position = 0;

            Header = new InternalDatagramHeader(ReadByte());
            Header.DatagramSequenceNumber = ReadLittle();

            // End datagram, online packet starts

            Messages = new List <Packet>();

            while (!_reader.Eof)
            {
                byte flags  = ReadByte();
                var  header = new ReliabilityHeader();

                header.Reliability = (Reliability)((flags & 0b011100000) >> 5);
                header.HasSplit    = (flags & 0b00010000) > 0;

                short dataBitLength = ReadShort(true);

                switch (header.Reliability)
                {
                case Reliability.Reliable:
                case Reliability.ReliableSequenced:
                case Reliability.ReliableOrdered:
                    header.ReliableMessageNumber = ReadLittle();
                    break;
                }

                switch (header.Reliability)
                {
                case Reliability.UnreliableSequenced:
                case Reliability.ReliableSequenced:
                    header.SequencingIndex = ReadLittle();
                    break;
                }

                switch (header.Reliability)
                {
                case Reliability.UnreliableSequenced:
                case Reliability.ReliableSequenced:
                case Reliability.ReliableOrdered:
                case Reliability.ReliableOrderedWithAckReceipt:
                    header.OrderingIndex   = ReadLittle();
                    header.OrderingChannel = ReadByte();                             // flags
                    break;
                }

                if (header.HasSplit)
                {
                    header.PartCount = ReadInt(true);
                    header.PartId    = ReadShort(true);
                    header.PartIndex = ReadInt(true);
                }

                // Slurp the payload
                int messageLength = (int)Math.Ceiling((((double)dataBitLength) / 8));
                ReadOnlyMemory <byte> internalBuffer = Slice(messageLength);
                if (internalBuffer.Length != messageLength)
                {
                    Log.Error($"Didn't get expected length {internalBuffer.Length}");
                }
                if (internalBuffer.Length == 0)
                {
                    continue;                                              //Log.Error($"Read length {internalBuffer.Length}, expected {messageLength}");
                }
                if (messageLength == 0)
                {
                    continue;
                }
                //if(header.Reliability != Reliability.ReliableOrdered) Log.Error($"Parsing message {internalBuffer.Span[0]} with reliability={header.Reliability}");

                if (header.HasSplit)
                {
                    var splitPartPacket = SplitPartPacket.CreateObject();
                    splitPartPacket.ReliabilityHeader = header;
                    splitPartPacket.Id      = internalBuffer.Span[0];
                    splitPartPacket.Message = internalBuffer;
                    Messages.Add(splitPartPacket);

                    if (Log.IsDebugEnabled && _reader.Position < _reader.Length)
                    {
                        Log.Debug($"Got split message, but more to read {_reader.Length - _reader.Position}");
                    }
                }
                else
                {
                    byte   id     = internalBuffer.Span[0];
                    Packet packet = PacketFactory.Create(id, internalBuffer, "raknet") ?? new UnknownPacket(id, internalBuffer.ToArray());
                    packet.ReliabilityHeader = header;

                    Messages.Add(packet);
                }

                if (Log.IsDebugEnabled && messageLength != internalBuffer.Length)
                {
                    Log.Debug("Mismatch of requested length, and actual read length");
                }
            }
        }