OpenMetaverse.AssetManager.SendXferPacketHandler C# (CSharp) Method

SendXferPacketHandler() protected method

Process an incoming packet and raise the appropriate events
protected SendXferPacketHandler ( object sender, OpenMetaverse.PacketReceivedEventArgs e ) : void
sender object The sender
e OpenMetaverse.PacketReceivedEventArgs The EventArgs object containing the packet data
return void
        protected void SendXferPacketHandler(object sender, PacketReceivedEventArgs e)
        {
            SendXferPacketPacket xfer = (SendXferPacketPacket)e.Packet;

            // Lame ulong to UUID conversion, please go away Xfer system
            UUID transferID = new UUID(xfer.XferID.ID);
            Transfer transfer;
            XferDownload download = null;

            if (Transfers.TryGetValue(transferID, out transfer))
            {
                download = (XferDownload)transfer;

                // Apply a mask to get rid of the "end of transfer" bit
                uint packetNum = xfer.XferID.Packet & 0x0FFFFFFF;

                // Check for out of order packets, possibly indicating a resend
                if (packetNum != download.PacketNum)
                {
                    if (packetNum == download.PacketNum - 1)
                    {
                        Logger.DebugLog("Resending Xfer download confirmation for packet " + packetNum, Client);
                        SendConfirmXferPacket(download.XferID, packetNum);
                    }
                    else
                    {
                        Logger.Log("Out of order Xfer packet in a download, got " + packetNum + " expecting " + download.PacketNum,
                            Helpers.LogLevel.Warning, Client);
                        // Re-confirm the last packet we actually received
                        SendConfirmXferPacket(download.XferID, download.PacketNum - 1);
                    }

                    return;
                }

                if (packetNum == 0)
                {
                    // This is the first packet received in the download, the first four bytes are a size integer
                    // in little endian ordering
                    byte[] bytes = xfer.DataPacket.Data;
                    download.Size = (bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24));
                    download.AssetData = new byte[download.Size];

                    Logger.DebugLog("Received first packet in an Xfer download of size " + download.Size);

                    Buffer.BlockCopy(xfer.DataPacket.Data, 4, download.AssetData, 0, xfer.DataPacket.Data.Length - 4);
                    download.Transferred += xfer.DataPacket.Data.Length - 4;
                }
                else
                {
                    Buffer.BlockCopy(xfer.DataPacket.Data, 0, download.AssetData, 1000 * (int)packetNum, xfer.DataPacket.Data.Length);
                    download.Transferred += xfer.DataPacket.Data.Length;
                }

                // Increment the packet number to the packet we are expecting next
                download.PacketNum++;

                // Confirm receiving this packet
                SendConfirmXferPacket(download.XferID, packetNum);

                if ((xfer.XferID.Packet & 0x80000000) != 0)
                {
                    // This is the last packet in the transfer
                    if (!String.IsNullOrEmpty(download.Filename))
                        Logger.DebugLog("Xfer download for asset " + download.Filename + " completed", Client);
                    else
                        Logger.DebugLog("Xfer download for asset " + download.VFileID.ToString() + " completed", Client);

                    download.Success = true;
                    lock (Transfers) Transfers.Remove(download.ID);

                    try { OnXferReceived(new XferReceivedEventArgs(download)); }
                    catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); }
                }
            }
        }