public void StoreFragmentData(byte channelID, ushort sequence, ushort ack, uint ackBits, int fragmentID, int fragmentSize, byte[] fragmentData, int fragmentBytes)
        {
            int copyOffset = 0;

            if (fragmentID == 0)
            {
                byte[] packetHeader = BufferPool.GetBuffer(Defines.MAX_PACKET_HEADER_BYTES);
                this.PacketHeaderBytes = PacketIO.WritePacketHeader(packetHeader, channelID, sequence, ack, ackBits);

                this.PacketDataBuffer.SetSize(this.PacketHeaderBytes + fragmentSize);

                this.PacketDataBuffer.BufferCopy(packetHeader, 0, 0, this.PacketHeaderBytes);
                copyOffset = this.PacketHeaderBytes;

                fragmentBytes -= this.PacketHeaderBytes;

                BufferPool.ReturnBuffer(packetHeader);
            }

            int writePos = this.PacketHeaderBytes + fragmentID * fragmentSize;
            int end      = writePos + fragmentBytes;

            this.PacketDataBuffer.SetSize(end);

            if (fragmentID == NumFragmentsTotal - 1)
            {
                this.PacketBytes = (this.NumFragmentsTotal - 1) * fragmentSize + fragmentBytes;
            }

            this.PacketDataBuffer.BufferCopy(fragmentData, copyOffset, this.PacketHeaderBytes + fragmentID * fragmentSize, fragmentBytes);
        }
        public void StoreFragmentData(byte channelID, ushort sequence, ushort ack, uint ackBits, int fragmentID, int fragmentSize, byte[] fragmentData, int fragmentBytes)
        {
            int src = 0;

            if (fragmentID == 0)
            {
                byte[] buffer = BufferPool.GetBuffer(10);
                int    num    = PacketIO.WritePacketHeader(buffer, channelID, sequence, ack, ackBits);
                HeaderOffset = 10 - num;
                if (PacketDataBuffer.Length < 10 + fragmentSize)
                {
                    PacketDataBuffer.SetSize(10 + fragmentSize);
                }
                PacketDataBuffer.BufferCopy(buffer, 0, HeaderOffset, num);
                src            = num;
                fragmentBytes -= num;
                BufferPool.ReturnBuffer(buffer);
            }
            int num2 = 10 + fragmentID * fragmentSize;
            int num3 = num2 + fragmentBytes;

            if (PacketDataBuffer.Length < num3)
            {
                PacketDataBuffer.SetSize(num3);
            }
            if (fragmentID == NumFragmentsTotal - 1)
            {
                PacketBytes = (NumFragmentsTotal - 1) * fragmentSize + fragmentBytes;
            }
            PacketDataBuffer.BufferCopy(fragmentData, src, 10 + fragmentID * fragmentSize, fragmentBytes);
        }
        public ushort SendPacket(byte[] packetData, int position, int length, byte channelID)
        {
            if (length > config.MaxPacketSize)
            {
                throw new ArgumentOutOfRangeException("Packet is too large to send, max packet size is " + config.MaxPacketSize + " bytes");
            }

            if (length < 1)
            {
                throw new ArgumentOutOfRangeException("Packet is too small; minimum packet size is 1 byte.");
            }

            var  compressedBuffer = LZ4Codec.Wrap(packetData, position, length);
            bool compressed       = false;
            int  bytesSaved       = length - compressedBuffer.Length;

            if (bytesSaved > 0)
            {
                packetData = compressedBuffer;
                position   = 0;
                length     = compressedBuffer.Length;
                compressed = true;
            }

            ushort sequence = this.sequence++;
            ushort ack;
            uint   ackBits;

            lock (receivedPackets)
                receivedPackets.GenerateAckBits(out ack, out ackBits);

            SentPacketData sentPacketData = sentPackets.Insert(sequence);

            sentPacketData.time        = this.time;
            sentPacketData.packetBytes = (uint)(config.PacketHeaderSize + length);
            sentPacketData.acked       = false;

            if (length <= config.FragmentThreshold)
            {
                // regular packet

                byte[] transmitData         = BufferPool.GetBuffer(2048);
                int    headerBytes          = PacketIO.WritePacketHeader(transmitData, channelID, sequence, ack, ackBits, compressed);
                int    transmitBufferLength = length + headerBytes;

                Buffer.BlockCopy(packetData, position, transmitData, headerBytes, length);

                config.TransmitPacketCallback(transmitData, transmitBufferLength);

                BufferPool.ReturnBuffer(transmitData);
            }
            else
            {
                // fragmented packet

                byte[] packetHeader = BufferPool.GetBuffer(Defines.MAX_PACKET_HEADER_BYTES);

                int packetHeaderBytes = 0;

                try {
                    packetHeaderBytes = PacketIO.WritePacketHeader(packetHeader, channelID, sequence, ack, ackBits, compressed);
                }
                catch {
                    throw;
                }

                int numFragments = (length / config.FragmentSize) + ((length % config.FragmentSize) != 0 ? 1 : 0);
                //int fragmentBufferSize = Defines.FRAGMENT_HEADER_BYTES + Defines.MAX_PACKET_HEADER_BYTES + config.FragmentSize;

                byte[] fragmentPacketData = BufferPool.GetBuffer(2048);
                int    qpos = 0;

                byte prefixByte = 1;
                prefixByte |= (byte)((channelID & 0x03) << 6);

                for (int fragmentID = 0; fragmentID < numFragments; fragmentID++)
                {
                    using (var writer = ByteArrayReaderWriter.Get(fragmentPacketData)) {
                        writer.Write(prefixByte);
                        writer.Write(channelID);
                        writer.Write(sequence);
                        writer.Write((byte)fragmentID);
                        writer.Write((byte)(numFragments - 1));
                        writer.Write(compressed ? (byte)1 : (byte)0);

                        if (fragmentID == 0)
                        {
                            writer.WriteBuffer(packetHeader, 0, packetHeaderBytes);
                        }

                        int bytesToCopy = config.FragmentSize;
                        if (qpos + bytesToCopy > length)
                        {
                            bytesToCopy = length - qpos;
                        }

                        for (int i = 0; i < bytesToCopy; i++)
                        {
                            writer.Write(packetData[position + qpos++]);
                        }

                        int fragmentPacketBytes = (int)writer.WritePosition;
                        config.TransmitPacketCallback(fragmentPacketData, fragmentPacketBytes);
                    }
                }

                BufferPool.ReturnBuffer(packetHeader);
                BufferPool.ReturnBuffer(fragmentPacketData);
            }

            return(sequence);
        }
Beispiel #4
0
        public ushort SendPacket(byte[] packetData, int length, byte channelID)
        {
            if (length > config.MaxPacketSize)
            {
                throw new ArgumentOutOfRangeException("Packet is too large to send, max packet size is " + config.MaxPacketSize + " bytes");
            }
            ushort num = sequence++;
            ushort ack;
            uint   ackBits;

            lock (receivedPackets)
            {
                receivedPackets.GenerateAckBits(out ack, out ackBits);
            }
            SentPacketData sentPacketData = sentPackets.Insert(num);

            sentPacketData.time        = time;
            sentPacketData.packetBytes = (uint)(config.PacketHeaderSize + length);
            sentPacketData.acked       = false;
            if (length <= config.FragmentThreshold)
            {
                byte[] buffer = BufferPool.GetBuffer(2048);
                int    num2   = PacketIO.WritePacketHeader(buffer, channelID, num, ack, ackBits);
                int    arg    = length + num2;
                Buffer.BlockCopy(packetData, 0, buffer, num2, length);
                config.TransmitPacketCallback(buffer, arg);
                BufferPool.ReturnBuffer(buffer);
            }
            else
            {
                byte[] buffer2 = BufferPool.GetBuffer(10);
                int    num3    = 0;
                try
                {
                    num3 = PacketIO.WritePacketHeader(buffer2, channelID, num, ack, ackBits);
                }
                catch
                {
                    throw;
                }
                int    num4    = length / config.FragmentSize + ((length % config.FragmentSize != 0) ? 1 : 0);
                byte[] buffer3 = BufferPool.GetBuffer(2048);
                int    num5    = 0;
                byte   b       = 1;
                b = (byte)(b | (byte)((channelID & 3) << 6));
                for (int i = 0; i < num4; i++)
                {
                    using (ByteArrayReaderWriter byteArrayReaderWriter = ByteArrayReaderWriter.Get(buffer3))
                    {
                        byteArrayReaderWriter.Write(b);
                        byteArrayReaderWriter.Write(channelID);
                        byteArrayReaderWriter.Write(num);
                        byteArrayReaderWriter.Write((byte)i);
                        byteArrayReaderWriter.Write((byte)(num4 - 1));
                        if (i == 0)
                        {
                            byteArrayReaderWriter.WriteBuffer(buffer2, num3);
                        }
                        int num6 = config.FragmentSize;
                        if (num5 + num6 > length)
                        {
                            num6 = length - num5;
                        }
                        for (int j = 0; j < num6; j++)
                        {
                            byteArrayReaderWriter.Write(packetData[num5++]);
                        }
                        int arg2 = (int)byteArrayReaderWriter.WritePosition;
                        config.TransmitPacketCallback(buffer3, arg2);
                    }
                }
                BufferPool.ReturnBuffer(buffer2);
                BufferPool.ReturnBuffer(buffer3);
            }
            return(num);
        }