Exemplo n.º 1
0
        // Convert the packet to bytes and stuff it onto the send queue
        //
        public void ProcessOutPacket(LLQueItem item)
        {
            Packet packet = item.Packet;

            // Assign sequence number here to prevent out of order packets
            if (packet.Header.Sequence == 0)
            {
                lock (m_NeedAck)
                {
                    packet.Header.Sequence = NextPacketSequenceNumber();
                    item.Sequence          = packet.Header.Sequence;
                    item.TickCount         = Environment.TickCount;

                    // We want to see that packet arrive if it's reliable
                    if (packet.Header.Reliable)
                    {
                        m_UnackedBytes += item.Length;

                        // Keep track of when this packet was sent out
                        item.TickCount = Environment.TickCount;

                        m_NeedAck[packet.Header.Sequence] = item;
                    }
                }
            }

            // If we sent a killpacket
            if (packet is KillPacket)
            {
                Abort();
            }

            try
            {
                // If this packet has been reused/returned, the ToBytes
                // will blow up in our face.
                // Fail gracefully.
                //

                // Actually make the byte array and send it
                byte[] sendbuffer = item.Packet.ToBytes();

                if (packet.Header.Zerocoded)
                {
                    int packetsize = Helpers.ZeroEncode(sendbuffer,
                                                        sendbuffer.Length, m_ZeroOutBuffer);
                    m_PacketServer.SendPacketTo(m_ZeroOutBuffer, packetsize,
                                                SocketFlags.None, m_Client.CircuitCode);
                }
                else
                {
                    // Need some extra space in case we need to add proxy
                    // information to the message later
                    Buffer.BlockCopy(sendbuffer, 0, m_ZeroOutBuffer, 0,
                                     sendbuffer.Length);
                    m_PacketServer.SendPacketTo(m_ZeroOutBuffer,
                                                sendbuffer.Length, SocketFlags.None, m_Client.CircuitCode);
                }
            }
            catch (NullReferenceException)
            {
                m_log.Debug("[PACKET] Detected reuse of a returned packet");
                m_PacketQueue.Cancel(item.Sequence);
                return;
            }

            // If this is a reliable packet, we are still holding a ref
            // Dont't return in that case
            //
            if (!packet.Header.Reliable)
            {
                m_PacketQueue.Cancel(item.Sequence);
                PacketPool.Instance.ReturnPacket(packet);
            }
        }