Пример #1
0
        private static List <MessagePart> CreateMessageParts(Packet message, int mtuSize, RaknetSession session)
        {
            Memory <byte> encodedMessage = message.Encode();

            if (encodedMessage.IsEmpty)
            {
                return(new List <MessagePart>(0));
            }

            if (message.IsMcpe)
            {
                Log.Error($"Got bedrock message in unexpected place {message.GetType().Name}");
            }

            int  maxPayloadSizeNoSplit = mtuSize - RaknetHandler.UdpHeaderSize - 4 - GetHeaderSize(message.ReliabilityHeader, false);
            bool split = encodedMessage.Length >= maxPayloadSizeNoSplit;

            List <(int @from, int length)> splits = ArraySplit(encodedMessage.Length, mtuSize - RaknetHandler.UdpHeaderSize - 4 /*datagram header*/ - GetHeaderSize(message.ReliabilityHeader, split));
            int count = splits.Count;

            if (count == 0)
            {
                Log.Warn("Got zero parts back from split");
            }
            if (count <= 1)
            {
                var messagePart = MessagePart.CreateObject();
                messagePart.ReliabilityHeader.Reliability           = message.ReliabilityHeader.Reliability;
                messagePart.ReliabilityHeader.ReliableMessageNumber = Interlocked.Increment(ref session.ReliableMessageNumber);
                messagePart.ReliabilityHeader.OrderingChannel       = 0;
                messagePart.ReliabilityHeader.OrderingIndex         = message.ReliabilityHeader.OrderingIndex;
                messagePart.ReliabilityHeader.HasSplit = false;
                messagePart.Buffer = encodedMessage;

                return(new List <MessagePart>(1)
                {
                    messagePart
                });
            }

            // Stupid but scared to change it .. remove the -100 when i feel "safe"
            if (session.SplitPartId > short.MaxValue - 100)
            {
                Interlocked.CompareExchange(ref session.SplitPartId, 0, short.MaxValue);
            }

            if (message.ReliabilityHeader.Reliability == Reliability.Unreliable)
            {
                message.ReliabilityHeader.Reliability = Reliability.Reliable;
            }

            int   index        = 0;
            short splitId      = (short)Interlocked.Increment(ref session.SplitPartId);
            var   messageParts = new List <MessagePart>(count);

            foreach ((int from, int length)span in splits)
            {
                var messagePart = MessagePart.CreateObject();
                messagePart.ReliabilityHeader.Reliability           = message.ReliabilityHeader.Reliability;
                messagePart.ReliabilityHeader.ReliableMessageNumber = Interlocked.Increment(ref session.ReliableMessageNumber);
                messagePart.ReliabilityHeader.OrderingChannel       = 0;
                messagePart.ReliabilityHeader.OrderingIndex         = message.ReliabilityHeader.OrderingIndex;
                messagePart.ReliabilityHeader.HasSplit  = count > 1;
                messagePart.ReliabilityHeader.PartCount = count;
                messagePart.ReliabilityHeader.PartId    = splitId;
                messagePart.ReliabilityHeader.PartIndex = index++;
                messagePart.Buffer = encodedMessage.Slice(span.@from, span.length);

                messageParts.Add(messagePart);
            }

            return(messageParts);
        }