OpenMetaverse.AssetManager.TransferPacketHandler C# (CSharp) Method

TransferPacketHandler() protected method

Process an incoming packet and raise the appropriate events
protected TransferPacketHandler ( object sender, OpenMetaverse.PacketReceivedEventArgs e ) : void
sender object The sender
e OpenMetaverse.PacketReceivedEventArgs The EventArgs object containing the packet data
return void
        protected void TransferPacketHandler(object sender, PacketReceivedEventArgs e)
        {
            TransferPacketPacket asset = (TransferPacketPacket)e.Packet;
            Transfer transfer;
            AssetDownload download;

            if (Transfers.TryGetValue(asset.TransferData.TransferID, out transfer))
            {
                download = (AssetDownload)transfer;

                if (download.Size == 0)
                {
                    Logger.DebugLog("TransferPacket received ahead of the transfer header, blocking...", Client);

                    // We haven't received the header yet, block until it's received or times out
                    download.HeaderReceivedEvent.WaitOne(TRANSFER_HEADER_TIMEOUT, false);

                    if (download.Size == 0)
                    {
                        Logger.Log("Timed out while waiting for the asset header to download for " +
                            download.ID.ToString(), Helpers.LogLevel.Warning, Client);

                        // Abort the transfer
                        TransferAbortPacket abort = new TransferAbortPacket();
                        abort.TransferInfo.ChannelType = (int)download.Channel;
                        abort.TransferInfo.TransferID = download.ID;
                        Client.Network.SendPacket(abort, download.Simulator);

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

                        // Fire the event with our transfer that contains Success = false
                        if (download.Callback != null)
                        {
                            try { download.Callback(download, null); }
                            catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); }
                        }

                        return;
                    }
                }

                // This assumes that every transfer packet except the last one is exactly 1000 bytes,
                // hopefully that is a safe assumption to make
                try
                {
                    Buffer.BlockCopy(asset.TransferData.Data, 0, download.AssetData, 1000 * asset.TransferData.Packet,
                        asset.TransferData.Data.Length);
                    download.Transferred += asset.TransferData.Data.Length;
                }
                catch (ArgumentException)
                {
                    Logger.Log(String.Format("TransferPacket handling failed. TransferData.Data.Length={0}, AssetData.Length={1}, TransferData.Packet={2}",
                        asset.TransferData.Data.Length, download.AssetData.Length, asset.TransferData.Packet), Helpers.LogLevel.Error);
                    return;
                }

                //Client.DebugLog(String.Format("Transfer packet {0}, received {1}/{2}/{3} bytes for asset {4}",
                //    asset.TransferData.Packet, asset.TransferData.Data.Length, transfer.Transferred, transfer.Size,
                //    transfer.AssetID.ToString()));

                // Check if we downloaded the full asset
                if (download.Transferred >= download.Size)
                {
                    Logger.DebugLog("Transfer for asset " + download.AssetID.ToString() + " completed", Client);

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

                    // Cache successful asset download
                    Cache.SaveAssetToCache(download.AssetID, download.AssetData);

                    if (download.Callback != null)
                    {
                        try { download.Callback(download, WrapAsset(download)); }
                        catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); }
                    }
                }
            }
        }