示例#1
0
        public unsafe bool DelayPacket(ref NetworkPipelineContext ctx, InboundSendBuffer inboundBuffer,
                                       ref NetworkPipelineStage.Requests requests,
                                       long timestamp)
        {
            // Find empty slot in bookkeeping data space to track this packet
            int  packetPayloadOffset = 0;
            int  packetDataOffset    = 0;
            var  processBufferPtr    = (byte *)ctx.internalProcessBuffer;
            bool foundSlot           = GetEmptyDataSlot(processBufferPtr, ref packetPayloadOffset, ref packetDataOffset);

            if (!foundSlot)
            {
                //UnityEngine.Debug.LogWarning("No space left for delaying packet (" + m_PacketCount + " packets in queue)");
                return(false);
            }

            UnsafeUtility.MemCpy(ctx.internalProcessBuffer + packetPayloadOffset + inboundBuffer.headerPadding, inboundBuffer.buffer, inboundBuffer.bufferLength);

            var param = (SimulatorUtility.Context *)ctx.internalSharedProcessBuffer;
            // Add tracking for this packet so we can resurrect later
            DelayedPacket packet;

            packet.delayUntil          = timestamp + m_PacketDelayMs + param->Random.NextInt(m_PacketJitterMs * 2) - m_PacketJitterMs;
            packet.processBufferOffset = packetPayloadOffset;
            packet.packetSize          = (ushort)(inboundBuffer.headerPadding + inboundBuffer.bufferLength);
            packet.packetHeaderPadding = (ushort)inboundBuffer.headerPadding;
            byte *packetPtr = (byte *)&packet;

            UnsafeUtility.MemCpy(processBufferPtr + packetDataOffset, packetPtr, UnsafeUtility.SizeOf <DelayedPacket>());

            // Schedule an update call so packet can be resurrected later
            requests |= NetworkPipelineStage.Requests.Update;
            return(true);
        }
示例#2
0
        private static unsafe void Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests request)
        {
            var len = inboundBuffer.bufferLength;

            for (int i = 0; i < len; ++i)
            {
                ctx.internalProcessBuffer[inboundBuffer.headerPadding + i] = (byte)(inboundBuffer.buffer[i] ^ 0xff);
            }
            var nextInbound = default(InboundSendBuffer);

            nextInbound.bufferWithHeaders       = ctx.internalProcessBuffer;
            nextInbound.bufferWithHeadersLength = len + inboundBuffer.headerPadding;
            nextInbound.SetBufferFrombufferWithHeaders();
            inboundBuffer = nextInbound;
        }
示例#3
0
        private static void Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests request)
        {
            var sendData = (int *)ctx.internalProcessBuffer;

            for (int i = 1; i <= 3; ++i)
            {
                Assert.AreEqual(*sendData, i * 10);
                sendData++;
            }
            var sharedData = (int *)ctx.internalSharedProcessBuffer;

            for (int i = 7; i <= 8; ++i)
            {
                Assert.AreEqual(*sharedData, i * 10);
                sharedData++;
            }
        }
示例#4
0
        private static int Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests request)
        {
            var sendData = (int *)ctx.internalProcessBuffer;

            for (int i = 1; i <= 3; ++i)
            {
                Assert.AreEqual(*sendData, i);
                sendData++;
            }
            var sharedData = (int *)ctx.internalSharedProcessBuffer;

            for (int i = 7; i <= 8; ++i)
            {
                Assert.AreEqual(*sharedData, i);
                sharedData++;
            }
            return((int)Error.StatusCode.Success);
        }
示例#5
0
        public unsafe void FuzzPacket(Context *ctx, ref InboundSendBuffer inboundBuffer)
        {
            int fuzzFactor = ctx->FuzzFactor;
            int fuzzOffset = ctx->FuzzOffset;
            int rand       = ctx->Random.NextInt(0, 100);

            if (rand > fuzzFactor)
            {
                return;
            }

            var length = inboundBuffer.bufferLength;

            for (int i = fuzzOffset; i < length; ++i)
            {
                for (int j = 0; j < 8; ++j)
                {
                    if (fuzzFactor > ctx->Random.NextInt(0, 100))
                    {
                        inboundBuffer.buffer[i] ^= (byte)(1 << j);
                    }
                }
            }
        }
示例#6
0
 private static void Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests request)
 {
     ctx.header.WriteInt((int)2);
 }
示例#7
0
        public unsafe bool GetDelayedPacket(ref NetworkPipelineContext ctx, ref InboundSendBuffer delayedPacket,
                                            ref NetworkPipelineStage.Requests requests, long currentTimestamp)
        {
            requests = NetworkPipelineStage.Requests.None;

            var   dataSize          = UnsafeUtility.SizeOf <DelayedPacket>();
            byte *processBufferPtr  = (byte *)ctx.internalProcessBuffer;
            var   simCtx            = (Context *)ctx.internalSharedProcessBuffer;
            int   oldestPacketIndex = -1;
            long  oldestTime        = long.MaxValue;
            int   readyPackets      = 0;
            int   packetsInQueue    = 0;

            for (int i = 0; i < m_PacketCount; i++)
            {
                DelayedPacket *packet = (DelayedPacket *)(processBufferPtr + dataSize * i);
                if ((int)packet->delayUntil == 0)
                {
                    continue;
                }
                packetsInQueue++;

                if (packet->delayUntil > currentTimestamp)
                {
                    continue;
                }
                readyPackets++;

                if (oldestTime <= packet->delayUntil)
                {
                    continue;
                }
                oldestPacketIndex = i;
                oldestTime        = packet->delayUntil;
            }

            simCtx->ReadyPackets   = readyPackets;
            simCtx->WaitingPackets = packetsInQueue;
            simCtx->NextPacketTime = oldestTime;
            simCtx->StatsTime      = currentTimestamp;

            // If more than one item has expired timer we need to resume this pipeline stage
            if (readyPackets > 1)
            {
                requests |= NetworkPipelineStage.Requests.Resume;
            }
            // If more than one item is present (but doesn't have expired timer) we need to re-run the pipeline
            // in a later update call
            else if (packetsInQueue > 0)
            {
                requests |= NetworkPipelineStage.Requests.Update;
            }

            if (oldestPacketIndex >= 0)
            {
                DelayedPacket *packet = (DelayedPacket *)(processBufferPtr + dataSize * oldestPacketIndex);
                packet->delayUntil = 0;

                delayedPacket.bufferWithHeaders       = ctx.internalProcessBuffer + packet->processBufferOffset;
                delayedPacket.bufferWithHeadersLength = packet->packetSize;
                delayedPacket.headerPadding           = packet->packetHeaderPadding;
                delayedPacket.SetBufferFrombufferWithHeaders();
                return(true);
            }

            return(false);
        }
示例#8
0
        /// <summary>
        /// Write packet, packet header and tracking information to the given buffer space. This buffer
        /// should contain the reliability Context at the front, that contains the capacity of the buffer
        /// and pointer offsets needed to find the slots we can copy the packet to.
        /// </summary>
        /// <param name="self">Buffer space where we can store packets.</param>
        /// <param name="sequence">The sequence ID of the packet, this is used to find a slot inside the buffer.</param>
        /// <param name="header">The packet header which we'll store with the packet payload.</param>
        /// <param name="data">The packet data which we're storing.</param>
        /// <exception cref="OverflowException"></exception>
        public static unsafe void SetHeaderAndPacket(byte *self, int sequence, PacketHeader header, InboundSendBuffer data, long timestamp)
        {
            Context *ctx       = (Context *)self;
            int      totalSize = data.bufferLength + data.headerPadding;

            if (totalSize + UnsafeUtility.SizeOf <PacketHeader>() > ctx->DataStride)
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            { throw new OverflowException(); }
#else
            { return; }
#endif
            var index = sequence % ctx->Capacity;

            PacketInformation *info = GetPacketInformation(self, sequence);
            info->SequenceId    = sequence;
            info->Size          = (ushort)totalSize;
            info->HeaderPadding = (ushort)data.headerPadding;
            info->SendTime      = timestamp;

            Packet *packet = GetPacket(self, sequence);
            packet->Header = header;
            var   offset  = (ctx->DataPtrOffset + (index * ctx->DataStride)) + UnsafeUtility.SizeOf <PacketHeader>();
            void *dataPtr = (self + offset);

            if (data.bufferLength > 0)
            {
                UnsafeUtility.MemCpy((byte *)dataPtr + data.headerPadding, data.buffer, data.bufferLength);
            }
        }
示例#9
0
 private static int Send(ref NetworkPipelineContext ctx, ref InboundSendBuffer inboundBuffer, ref NetworkPipelineStage.Requests request)
 {
     return((int)Error.StatusCode.Success);
 }