OpenSimMirror/OpenSim.RegionServer/AgentAssetUpload.cs

213 lines
8.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using OpenSim.Framework.Assets;
using OpenSim.Framework.Utilities;
using libsecondlife;
using libsecondlife.Packets;
namespace OpenSim
{
public class AgentAssetUpload
{
private Dictionary<LLUUID, AssetTransaction> transactions = new Dictionary<LLUUID, AssetTransaction>();
private SimClient ourClient;
public AgentAssetUpload(SimClient client)
{
this.ourClient = client;
}
public void AddUpload(LLUUID transactionID, AssetBase asset)
{
Console.WriteLine("adding upload asset");
AssetTransaction upload = new AssetTransaction();
lock (this.transactions)
{
upload.Asset = asset;
upload.TransactionID = transactionID;
this.transactions.Add(transactionID, upload);
}
if (upload.Asset.Data.Length > 2)
{
//is complete
upload.UploadComplete = true;
AssetUploadCompletePacket response = new AssetUploadCompletePacket();
response.AssetBlock.Type = asset.Type;
response.AssetBlock.Success = true;
response.AssetBlock.UUID = transactionID.Combine(this.ourClient.SecureSessionID);
this.ourClient.OutPacket(response);
}
else
{
Console.WriteLine(" no data in upload request so use xfer system");
upload.UploadComplete = false;
upload.XferID = Util.GetNextXferID();
RequestXferPacket xfer = new RequestXferPacket();
xfer.XferID.ID = upload.XferID;
xfer.XferID.VFileType = upload.Asset.Type;
xfer.XferID.VFileID = transactionID.Combine(this.ourClient.SecureSessionID);
xfer.XferID.FilePath = 0;
xfer.XferID.Filename = new byte[0];
this.ourClient.OutPacket(xfer);
}
}
public AssetBase GetUpload(LLUUID transactionID)
{
if (this.transactions.ContainsKey(transactionID))
{
return this.transactions[transactionID].Asset;
}
return null;
}
public void HandleUploadPacket(AssetUploadRequestPacket pack, LLUUID assetID)
{
AssetBase asset = null;
if (pack.AssetBlock.Type == 0)
{
//first packet for transaction
asset = new AssetBase();
asset.FullID = assetID;
asset.Type = pack.AssetBlock.Type;
asset.InvType = asset.Type;
asset.Name = "UploadedTexture" + Util.RandomClass.Next(1, 1000).ToString("000");
asset.Data = pack.AssetBlock.AssetData;
}
/* for now we will only support uploading of textures
else if (pack.AssetBlock.Type == 13 | pack.AssetBlock.Type == 5)
{
asset = new AssetBase();
asset.FullID = assetID;
Console.WriteLine("skin asset id is " + assetID.ToStringHyphenated());
asset.Type = pack.AssetBlock.Type;
asset.InvType = asset.Type;
asset.Name = "NewClothing" + Util.RandomClass.Next(1, 1000).ToString("000");
asset.Data = pack.AssetBlock.AssetData;
}*/
if (asset != null)
{
this.AddUpload(pack.AssetBlock.TransactionID, asset);
}
else
{
//currently we don't support this asset type
//so lets just tell the client that the upload is complete
AssetUploadCompletePacket response = new AssetUploadCompletePacket();
response.AssetBlock.Type = pack.AssetBlock.Type;
response.AssetBlock.Success = true;
response.AssetBlock.UUID = pack.AssetBlock.TransactionID.Combine(this.ourClient.SecureSessionID);
this.ourClient.OutPacket(response);
}
}
#region Xfer packet system for larger uploads
public void HandleXferPacket(SendXferPacketPacket xferPacket)
{
lock (this.transactions)
{
foreach (AssetTransaction trans in this.transactions.Values)
{
if (trans.XferID == xferPacket.XferID.ID)
{
if (trans.Asset.Data.Length > 1)
{
byte[] newArray = new byte[trans.Asset.Data.Length + xferPacket.DataPacket.Data.Length];
Array.Copy(trans.Asset.Data, 0, newArray, 0, trans.Asset.Data.Length);
Array.Copy(xferPacket.DataPacket.Data, 0, newArray, trans.Asset.Data.Length, xferPacket.DataPacket.Data.Length);
trans.Asset.Data = newArray;
}
else
{
byte[] newArray = new byte[xferPacket.DataPacket.Data.Length-4];
Array.Copy(xferPacket.DataPacket.Data, 4, newArray, 0, xferPacket.DataPacket.Data.Length-4);
trans.Asset.Data = newArray;
}
if ((xferPacket.XferID.Packet & 2147483648) != 0)
{
//end of transfer
trans.UploadComplete = true;
AssetUploadCompletePacket response = new AssetUploadCompletePacket();
response.AssetBlock.Type = trans.Asset.Type;
response.AssetBlock.Success = true;
response.AssetBlock.UUID = trans.TransactionID.Combine(this.ourClient.SecureSessionID);
this.ourClient.OutPacket(response);
//check if we should add it to inventory
if (trans.AddToInventory)
{
OpenSimRoot.Instance.AssetCache.AddAsset(trans.Asset);
OpenSimRoot.Instance.InventoryCache.AddNewInventoryItem(this.ourClient, trans.InventFolder, trans.Asset);
}
Console.WriteLine(Helpers.FieldToString(trans.Asset.Data));
}
break;
}
}
}
ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket();
confirmXfer.XferID.ID = xferPacket.XferID.ID;
confirmXfer.XferID.Packet = xferPacket.XferID.Packet;
this.ourClient.OutPacket(confirmXfer);
}
#endregion
public void CreateInventoryItem(CreateInventoryItemPacket packet)
{
if(this.transactions.ContainsKey(packet.InventoryBlock.TransactionID))
{
AssetTransaction trans = this.transactions[packet.InventoryBlock.TransactionID];
trans.Asset.Description = Helpers.FieldToString(packet.InventoryBlock.Description);
trans.Asset.Name = Helpers.FieldToString(packet.InventoryBlock.Name);
trans.Asset.Type = packet.InventoryBlock.Type;
if (trans.UploadComplete)
{
//already complete so we can add it to the inventory
OpenSimRoot.Instance.AssetCache.AddAsset(trans.Asset);
OpenSimRoot.Instance.InventoryCache.AddNewInventoryItem(this.ourClient, packet.InventoryBlock.FolderID, trans.Asset);
}
else
{
trans.AddToInventory = true;
trans.InventFolder = packet.InventoryBlock.FolderID;
}
}
}
}
public class AssetTransaction
{
public uint XferID;
public AssetBase Asset;
public bool AddToInventory;
public LLUUID InventFolder = LLUUID.Zero;
public bool UploadComplete = false;
public LLUUID TransactionID = LLUUID.Zero;
public AssetTransaction()
{
}
}
}