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); }
}
}
}
}