Esempio n. 1
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(NativeSlice <byte> self, int sequence, PacketHeader header, InboundBufferVec data, long timestamp)
        {
            byte *   ptr       = (byte *)self.GetUnsafePtr();
            Context *ctx       = (Context *)ptr;
            int      totalSize = data.buffer1.Length + data.buffer2.Length;

            if (totalSize > 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       = totalSize;
            info->SendTime   = timestamp;

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

            if (data.buffer1.Length > 0)
            {
                UnsafeUtility.MemCpy(dataPtr, data.buffer1.GetUnsafeReadOnlyPtr(), data.buffer1.Length);
            }
            if (data.buffer2.Length > 0)
            {
                UnsafeUtility.MemCpy(&dataPtr + data.buffer1.Length, data.buffer2.GetUnsafeReadOnlyPtr(), data.buffer2.Length);
            }
        }
Esempio n. 2
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);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Resend a packet which we have not received an acknowledgement for in time. Pipeline resume
        /// will be enabled if there are more packets which we need to resend. The send reliability context
        /// will then also be updated to track the next packet we need to resume.
        /// </summary>
        /// <param name="context">Pipeline context, we'll use both the shared reliability context and send context.</param>
        /// <param name="header">Packet header for the packet payload we're resending.</param>
        /// <param name="needsResume">Indicates if a pipeline resume is needed again.</param>
        /// <returns>Buffer slice to packet payload.</returns>
        /// <exception cref="ApplicationException"></exception>
        public static unsafe NativeSlice <byte> ResumeSend(NetworkPipelineContext context, out PacketHeader header, ref bool needsResume)
        {
            SharedContext *reliable = (SharedContext *)context.internalSharedProcessBuffer.GetUnsafePtr();
            Context *      ctx      = (Context *)context.internalProcessBuffer.GetUnsafePtr();

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (ctx->Resume == NullEntry)
            {
                throw new ApplicationException("This function should not be called unless there is data in resume");
            }
#endif

            var sequence = (ushort)ctx->Resume;

            PacketInformation *information;
            information = GetPacketInformation(context.internalProcessBuffer, sequence);
            // Reset the resend timer
            information->SendTime = context.timestamp;

            Packet *packet = GetPacket(context.internalProcessBuffer, sequence);
            header = packet->Header;

            // Update acked/ackmask to latest values
            header.AckedSequenceId = (ushort)reliable->ReceivedPackets.Sequence;
            header.AckMask         = reliable->ReceivedPackets.AckMask;

            var offset = (ctx->DataPtrOffset + ((sequence % ctx->Capacity) * ctx->DataStride)) + UnsafeUtility.SizeOf <PacketHeader>();

            NativeSlice <byte> slice = new NativeSlice <byte>(context.internalProcessBuffer, offset, information->Size);
            reliable->stats.PacketsResent++;

            needsResume = false;
            ctx->Resume = -1;

            // Check if another packet needs to be resent right after this one
            for (int i = sequence + 1; i < reliable->ReceivedPackets.Sequence + 1; i++)
            {
                var timeToResend = CurrentResendTime(context.internalSharedProcessBuffer);
                information = GetPacketInformation(context.internalProcessBuffer, i);
                if (information->SequenceId >= 0 && information->SendTime + timeToResend > context.timestamp)
                {
                    needsResume = true;
                    ctx->Resume = i;
                }
            }
            return(slice);
        }
Esempio n. 4
0
 public static extern void Broadcast(Host *host, byte channelID, Packet *packet);
Esempio n. 5
0
 public static extern int SendPeer(Peer *peer, byte channelID, Packet *packet);
Esempio n. 6
0
 public static extern int ResizePacket(Packet *packet, IntPtr dataLength);
Esempio n. 7
0
 public static extern void DestroyPacket(Packet *packet);