Пример #1
0
        private static void Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests requests)
        {
            // Request an update to see if a queued packet needs to be resent later or if an ack packet should be sent
            requests = NetworkPipelineStage.Requests.Update;
            bool needsResume = false;

            var header   = new ReliableUtility.PacketHeader();
            var reliable = (ReliableUtility.Context *)ctx.internalProcessBuffer;

            needsResume = ReliableUtility.ReleaseOrResumePackets(ctx);
            if (needsResume)
            {
                requests |= NetworkPipelineStage.Requests.Resume;
            }

            if (inboundBuffer.bufferLength > 0)
            {
                reliable->LastSentTime = ctx.timestamp;

                ReliableUtility.Write(ctx, inboundBuffer, ref header);
                ctx.header.WriteBytes((byte *)&header, UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>());
                if (reliable->Resume != ReliableUtility.NullEntry)
                {
                    requests |= NetworkPipelineStage.Requests.Resume;
                }

                reliable->PreviousTimestamp = ctx.timestamp;
                return;
            }

            if (reliable->Resume != ReliableUtility.NullEntry)
            {
                reliable->LastSentTime = ctx.timestamp;
                inboundBuffer          = ReliableUtility.ResumeSend(ctx, out header, ref needsResume);
                if (needsResume)
                {
                    requests |= NetworkPipelineStage.Requests.Resume;
                }
                ctx.header.Clear();
                ctx.header.WriteBytes((byte *)&header, UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>());
                reliable->PreviousTimestamp = ctx.timestamp;
                return;
            }

            if (ReliableUtility.ShouldSendAck(ctx))
            {
                reliable->LastSentTime = ctx.timestamp;

                ReliableUtility.WriteAckPacket(ctx, ref header);
                ctx.header.WriteBytes((byte *)&header, UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>());
                reliable->PreviousTimestamp = ctx.timestamp;

                // TODO: Sending dummy byte over since the pipeline won't send an empty payload (ignored on receive)
                inboundBuffer.bufferWithHeadersLength = inboundBuffer.headerPadding + 1;
                inboundBuffer.bufferWithHeaders       = (byte *)UnsafeUtility.Malloc(inboundBuffer.bufferWithHeadersLength, 8, Allocator.Temp);
                inboundBuffer.SetBufferFrombufferWithHeaders();
                return;
            }
            reliable->PreviousTimestamp = ctx.timestamp;
        }
        public InboundBufferVec Send(NetworkPipelineContext ctx, InboundBufferVec inboundBuffer, ref bool needsResume, ref bool needsUpdate)
        {
            // Request an update to see if a queued packet needs to be resent later or if an ack packet should be sent
            needsUpdate = true;

            var header = new ReliableUtility.PacketHeader();

            unsafe
            {
                var reliable = (ReliableUtility.Context *)ctx.internalProcessBuffer.GetUnsafePtr();

                needsResume = ReliableUtility.ReleaseOrResumePackets(ctx);

                if (inboundBuffer.buffer1.Length > 0)
                {
                    reliable->LastSentTime = ctx.timestamp;

                    ReliableUtility.Write(ctx, inboundBuffer, ref header);
                    ctx.header.WriteBytes((byte *)&header, UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>());
                    if (reliable->Resume != ReliableUtility.NullEntry)
                    {
                        needsResume = true;
                    }

                    reliable->PreviousTimestamp = ctx.timestamp;
                    return(inboundBuffer);
                }

                if (reliable->Resume != ReliableUtility.NullEntry)
                {
                    reliable->LastSentTime = ctx.timestamp;
                    var slice = ReliableUtility.ResumeSend(ctx, out header, ref needsResume);
                    ctx.header.Clear();
                    ctx.header.WriteBytes((byte *)&header, UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>());
                    inboundBuffer.buffer1       = slice;
                    inboundBuffer.buffer2       = default(NativeSlice <byte>);
                    reliable->PreviousTimestamp = ctx.timestamp;
                    return(inboundBuffer);
                }

                if (ReliableUtility.ShouldSendAck(ctx))
                {
                    reliable->LastSentTime = ctx.timestamp;

                    ReliableUtility.WriteAckPacket(ctx, ref header);
                    ctx.header.WriteBytes((byte *)&header, UnsafeUtility.SizeOf <ReliableUtility.PacketHeader>());
                    reliable->PreviousTimestamp = ctx.timestamp;

                    // TODO: Sending dummy byte over since the pipeline won't send an empty payload (ignored on receive)
                    inboundBuffer.buffer1 = new NativeSlice <byte>(ctx.internalProcessBuffer, 0, 1);
                    return(inboundBuffer);
                }
                reliable->PreviousTimestamp = ctx.timestamp;
                return(inboundBuffer);
            }
        }