2007-03-25 17:34:58 +00:00
using System ;
using System.Collections.Generic ;
using System.Text ;
2007-03-27 18:27:11 +00:00
using OpenSim.Assets ;
2007-03-25 17:34:58 +00:00
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 ;
2007-03-27 18:27:11 +00:00
private AssetCache m_assetCache ;
private InventoryCache m_inventoryCache ;
2007-03-25 17:34:58 +00:00
2007-03-27 18:27:11 +00:00
public AgentAssetUpload ( SimClient client , AssetCache assetCache , InventoryCache inventoryCache )
2007-03-25 17:34:58 +00:00
{
this . ourClient = client ;
2007-03-27 18:27:11 +00:00
m_assetCache = assetCache ;
m_inventoryCache = inventoryCache ;
2007-03-25 17:34:58 +00:00
}
public void AddUpload ( LLUUID transactionID , AssetBase 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
{
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 ;
}
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 ;
2007-03-26 16:51:50 +00:00
}
2007-03-25 17:34:58 +00:00
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 )
{
2007-03-27 18:27:11 +00:00
m_assetCache . AddAsset ( trans . Asset ) ;
m_inventoryCache . AddNewInventoryItem ( this . ourClient , trans . InventFolder , trans . Asset ) ;
2007-03-25 17:34:58 +00:00
}
2007-03-25 20:23:06 +00:00
2007-03-25 17:34:58 +00:00
}
break ;
}
}
}
ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket ( ) ;
confirmXfer . XferID . ID = xferPacket . XferID . ID ;
confirmXfer . XferID . Packet = xferPacket . XferID . Packet ;
this . ourClient . OutPacket ( confirmXfer ) ;
}
# endregion
2007-03-26 16:51:50 +00:00
public AssetBase AddUploadToAssetCache ( LLUUID transactionID )
{
AssetBase asset = null ;
if ( this . transactions . ContainsKey ( transactionID ) )
{
AssetTransaction trans = this . transactions [ transactionID ] ;
if ( trans . UploadComplete )
{
2007-03-27 18:27:11 +00:00
m_assetCache . AddAsset ( trans . Asset ) ;
2007-03-26 16:51:50 +00:00
asset = trans . Asset ;
}
}
return asset ;
}
2007-03-25 17:34:58 +00:00
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
2007-03-27 18:27:11 +00:00
m_assetCache . AddAsset ( trans . Asset ) ;
Console . WriteLine ( "ITem created is " + m_inventoryCache . AddNewInventoryItem ( this . ourClient , packet . InventoryBlock . FolderID , trans . Asset ) . ToStringHyphenated ( ) ) ;
2007-03-25 17:34:58 +00:00
}
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 ( )
{
}
}
}