Пример #1
0
        /// <summary>
        /// Serializes the data stored in the packet class into a byte array ready for sending.
        /// </summary>
        public override void Serialize()
        {               //Packet ID
            Write((UInt16)((TypeID + streamID) << 8));

            //Look through all our infos
            int lastRID = -1;

            foreach (Client.ReliableInfo info in reliables)
            {                   //Make sure it's in sequence
                if (lastRID != -1 && lastRID != UInt16.MaxValue &&
                    info.rid != lastRID + 1)
                {
                    //An out of sync packet!
                    throw new ArgumentException("Reliable boxing error! Packets in reliable queue were out of order, dropping.");
                }

                //Make sure the packet is serialized
                PacketBase packet = info.packet;
                lastRID = info.rid;

                packet.MakeSerialized(_client, _handler);

                //Insert the packet size
                byte[] packetData = packet.Data;

                Write((byte)packetData.Length);

                //Insert the data itself
                Write(packetData);
            }
        }
Пример #2
0
        /// <summary>
        /// Serializes the data stored in the packet class into a byte array ready for sending.
        /// </summary>
        public override void Serialize()
        {               //Packet ID
            Write((UInt16)((TypeID + streamID) << 8));

            //Insert our number
            Write(Flip(rNumber));

            //Make sure our packet is serialized
            packet.MakeSerialized(_client, _handler);

            //Write our packet contents
            Write(packet.Data);
        }
Пример #3
0
        /// <summary>
        /// Sends a packet using the client socket
        /// </summary>
        internal void internalSend(PacketBase packet)
        {       //First, allow the packet to serialize
            packet.MakeSerialized(this, _handler);

            //Do we need to apply the CRC32?
            if (!_CRC_S2C.bActive)
            {
                _handler.sendPacket(packet, packet.Data, _ipe);
            }
            else
            {   //Perform a CRC check and add it to a new buffer
                byte[] packetData = packet.Data;
                byte[] newPacket  = new byte[packetData.Length + _CRCLength];

                Array.Copy(packetData, newPacket, packetData.Length);
                uint checksum = _CRC_S2C.ComputeChecksum(packetData, 0, packetData.Length);

                //Insert a CRC of the appropriate length
                switch (_CRCLength)
                {
                case 1:
                    newPacket[packetData.Length] = (byte)(checksum & 0xFF);
                    break;

                case 2:
                    newPacket[packetData.Length + 1] = (byte)(checksum & 0xFF);
                    newPacket[packetData.Length + 0] = (byte)((checksum >> 8) & 0xFF);
                    break;

                case 3:
                    newPacket[packetData.Length + 2] = (byte)(checksum & 0xFF);
                    newPacket[packetData.Length + 1] = (byte)((checksum >> 8) & 0xFF);
                    newPacket[packetData.Length + 0] = (byte)((checksum >> 16) & 0xFF);
                    break;

                case 4:
                    newPacket[packetData.Length + 3] = (byte)(checksum & 0xFF);
                    newPacket[packetData.Length + 2] = (byte)((checksum >> 8) & 0xFF);
                    newPacket[packetData.Length + 1] = (byte)((checksum >> 16) & 0xFF);
                    newPacket[packetData.Length + 0] = (byte)((checksum >> 24) & 0xFF);
                    break;
                }

                _handler.sendPacket(packet, newPacket, _ipe);
            }

            //Update our statistics
            _packetsSent++;
            _bytesSent += packet._size;
        }
Пример #4
0
        /// <summary>
        /// Sends a reliable packet to the client
        /// </summary>
        public void sendReliable(PacketBase packet, Action completionCallback, int streamID)
        {       //Sync up!
            using (DdMonitor.Lock(_sync))
            {   //Get the relevant stream
                Client.StreamState stream = _streams[streamID];

                //Make sure the packet is serialized
                packet.MakeSerialized(this, _handler);

                //Is the (packet and reliable header) too large to be sent as one?
                if (4 + packet._size + _CRCLength > _C2S_UDPSize)
                {       //Add the stream packet to the reliable queue so we know
                    //when to start streaming it.
                    DataStream   ds = new DataStream();
                    ReliableInfo ri = new ReliableInfo();

                    ds.amountSent = 0;
                    ds.buffer     = packet.Data;
                    if (completionCallback != null)
                    {
                        ds.Completed += completionCallback;
                    }

                    ri.dataStream = ds;

                    //Put it in the reliable queue
                    stream.reliableQueue.Enqueue(ri);
                }
                else
                {       //Jam it in the reliable queue to be parsed
                    ReliableInfo ri = new ReliableInfo();

                    ri.packet = packet;
                    ri.rid    = -1;
                    if (completionCallback != null)
                    {
                        ri.Completed += completionCallback;
                    }

                    //Put it in the reliable queue
                    stream.reliableQueue.Enqueue(ri);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Sends queued packets, grouping them where necessary
        /// </summary>
        public void sendQueuedPackets()
        {       //Are we over threshold?
            if (_bytesWritten > _rateThreshold)
            {
                return;
            }

            //If it's just one packet, there's no need
            int queueCount = _packetQueue.Count;

            if (queueCount == 0)
            {
                return;
            }
            else if (queueCount == 1)
            {
                PacketBase packet = _packetQueue.Dequeue();

                internalSend(packet);
                _bytesWritten += packet._size;
                return;
            }

            //Go through the list, creating boxed packets as we go
            List <PacketBase> boxes = new List <PacketBase>();
            BoxPacket         box   = new BoxPacket();
            int currentSize         = 2 + _CRCLength;   //Header+footer size of a box packet

            //Send as many packets as we can!
            while (queueCount > 0 && _bytesWritten < _rateThreshold)
            {   //Get our next packet
                PacketBase packet = _packetQueue.Dequeue();

                _bytesWritten += packet._size;
                queueCount--;

                //Do not group data packets
                if (packet is DataPacket)
                {
                    boxes.Add(packet);
                    continue;
                }

                //Make sure the packet is serialized before we go comparing size
                packet.MakeSerialized(this, _handler);

                //If the packet exceeds the max limit, send it on it's own
                if (2 + 1 + packet.Length > byte.MaxValue)
                {       //WARNING: This may disrupt the reliable flow?
                    boxes.Add(packet);
                    continue;
                }

                //Do we have space to add this packet?
                if (currentSize + packet.Length + 1 > udpMaxSize)
                {       //There's not enough room. Check if our previous packet is on it's
                    //own and actually warrants a box packet.
                    if (box.packets.Count == 1)
                    {
                        boxes.Add(box.packets[0]);
                    }
                    else
                    {
                        boxes.Add(box);
                    }

                    //Create our new box
                    box         = new BoxPacket();
                    currentSize = 2 + _CRCLength;
                }

                //Add the packet to the box list
                box.packets.Add(packet);
                currentSize += packet.Length + 1;
            }

            //If the last box has more than one packet, keep it
            if (box.packets.Count > 1)
            {
                boxes.Add(box);
            }
            else if (box.packets.Count == 1)
            {
                //If it's only one packet, we don't need the box
                boxes.Add(box.packets[0]);
            }

            //Send all our packets
            foreach (PacketBase packet in boxes)
            {
                internalSend(packet);
            }
        }