Ejemplo n.º 1
0
 public static bool FindPacketAction(PacketCategory category, int protocol, out Action <ByteBuffer, Connection> action)
 {
     action = null;
     if (!AllPackets.TryGetValue(category, out var Category))
     {
         return(false);
     }
     return(Category.TryGetValue(protocol, out action));
 }
Ejemplo n.º 2
0
        public void SendPacket(UUID agentID, Packet packet, PacketCategory category)
        {
            // Look up the UDPClient this is going to
            UDPClient client;

            if (!clients.TryGetValue(agentID, out client))
            {
                Logger.Log("Attempted to send a packet to unknown UDP client " +
                           agentID.ToString(), Helpers.LogLevel.Warning);
                return;
            }

            SendPacket(client, packet, category, true);
        }
Ejemplo n.º 3
0
        void SendPacket(UDPClient client, Packet packet, PacketCategory category, bool setSequence)
        {
            byte[] buffer;
            int    bytes;

            // Set sequence implies that this is not a resent packet
            if (setSequence)
            {
                // Reset to zero if we've hit the upper sequence number limit
                Interlocked.CompareExchange(ref client.CurrentSequence, 0, 0xFFFFFF);
                // Increment and fetch the current sequence number
                uint sequence = (uint)Interlocked.Increment(ref client.CurrentSequence);
                packet.Header.Sequence = sequence;

                if (packet.Header.Reliable)
                {
                    OutgoingPacket outgoing;

                    if (packet.Header.Resent && client.NeedAcks.TryGetValue(packet.Header.Sequence, out outgoing))
                    {
                        // This packet has already been sent out once, strip any appended ACKs
                        // off it and reinsert them into the outgoing ACK queue under the
                        // assumption that this packet will continually be rejected from the
                        // client or that the appended ACKs are possibly making the delivery fail
                        if (packet.Header.AckList.Length > 0)
                        {
                            Logger.DebugLog(String.Format("Purging ACKs from packet #{0} ({1}) which will be resent.",
                                                          packet.Header.Sequence, packet.GetType()));

                            lock (client.PendingAcks)
                            {
                                foreach (uint ack in packet.Header.AckList)
                                {
                                    if (!client.PendingAcks.ContainsKey(ack))
                                    {
                                        client.PendingAcks[ack] = ack;
                                    }
                                }
                            }

                            packet.Header.AppendedAcks = false;
                            packet.Header.AckList      = new uint[0];
                        }
                    }
                    else
                    {
                        // Wrap this packet in a struct to track timeouts and resends
                        outgoing = new OutgoingPacket(packet);

                        // Add this packet to the list of ACK responses we are waiting on from this client
                        lock (client.NeedAcks)
                            client.NeedAcks[sequence] = outgoing;

                        // This packet is not a resend, check if the conditions are favorable
                        // to ACK appending
                        if (packet.Type != PacketType.PacketAck)
                        {
                            lock (client.PendingAcks)
                            {
                                int count = client.PendingAcks.Count;

                                if (count > 0 && count < 10)
                                {
                                    // Append all of the queued up outgoing ACKs to this packet
                                    packet.Header.AckList = new uint[count];

                                    for (int i = 0; i < count; i++)
                                    {
                                        packet.Header.AckList[i] = client.PendingAcks.Values[i];
                                    }

                                    client.PendingAcks.Clear();
                                    packet.Header.AppendedAcks = true;
                                }
                            }
                        }
                    }

                    // Update the sent time for this packet
                    outgoing.TickCount = Environment.TickCount;
                }
                else if (packet.Header.AckList.Length > 0)
                {
                    // Sanity check for ACKS appended on an unreliable packet, this is bad form
                    Logger.Log("Sending appended ACKs on an unreliable packet", Helpers.LogLevel.Warning);
                }
            }

            // Serialize the packet
            buffer = packet.ToBytes();
            bytes  = buffer.Length;
            //Stats.SentBytes += (ulong)bytes;
            //++Stats.SentPackets;

            UDPPacketBuffer buf = new UDPPacketBuffer(client.Address);

            // Zerocode if needed
            if (packet.Header.Zerocoded)
            {
                bytes = Helpers.ZeroEncode(buffer, bytes, buf.Data);
            }
            else
            {
                Buffer.BlockCopy(buffer, 0, buf.Data, 0, bytes);
            }

            buf.DataLength = bytes;

            AsyncBeginSend(buf);
        }
Ejemplo n.º 4
0
 public void BroadcastPacket(Packet packet, PacketCategory category)
 {
     clients.ForEach(
         delegate(UDPClient client) { SendPacket(client, packet, category, true); });
 }
Ejemplo n.º 5
0
 public void BroadcastPacket(Packet packet, PacketCategory category)
 {
     udpServer.BroadcastPacket(packet, category);
 }
Ejemplo n.º 6
0
 public void SendPacket(UUID agentID, Packet packet, PacketCategory category)
 {
     udpServer.SendPacket(agentID, packet, category);
 }