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