/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the OpenSimulator Project nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System.Collections.Generic; using System.Reflection; using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { /// /// Manage asset transactions for a single agent. /// public class AgentAssetTransactions { private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); // Fields private bool m_dumpAssetsToFile; private Scene m_Scene; public UUID UserID; public Dictionary XferUploaders = new Dictionary(); // Methods public AgentAssetTransactions(UUID agentID, Scene scene, bool dumpAssetsToFile) { m_Scene = scene; UserID = agentID; m_dumpAssetsToFile = dumpAssetsToFile; } public AssetXferUploader RequestXferUploader(UUID transactionID) { if (!XferUploaders.ContainsKey(transactionID)) { AssetXferUploader uploader = new AssetXferUploader(m_Scene, m_dumpAssetsToFile); lock (XferUploaders) { XferUploaders.Add(transactionID, uploader); } return uploader; } return null; } public void HandleXfer(ulong xferID, uint packetID, byte[] data) { lock (XferUploaders) { foreach (AssetXferUploader uploader in XferUploaders.Values) { if (uploader.XferID == xferID) { uploader.HandleXferPacket(xferID, packetID, data); break; } } } } public void RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) { if (XferUploaders.ContainsKey(transactionID)) { XferUploaders[transactionID].RequestCreateInventoryItem( remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask); } } /// /// Get an uploaded asset. If the data is successfully retrieved, /// the transaction will be removed. /// /// /// The asset if the upload has completed, null if it has not. public AssetBase GetTransactionAsset(UUID transactionID) { if (XferUploaders.ContainsKey(transactionID)) { AssetXferUploader uploader = XferUploaders[transactionID]; AssetBase asset = uploader.GetAssetData(); lock (XferUploaders) { XferUploaders.Remove(transactionID); } return asset; } return null; } public void RequestUpdateTaskInventoryItem(IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) { if (XferUploaders.ContainsKey(transactionID)) { AssetBase asset = GetTransactionAsset(transactionID); // Only legacy viewers use this, and they prefer CAPS, which // we have, so this really never runs. // Allow it, but only for "safe" types. if ((InventoryType)item.InvType != InventoryType.Notecard && (InventoryType)item.InvType != InventoryType.LSL) return; if (asset != null) { asset.FullID = UUID.Random(); asset.Name = item.Name; asset.Description = item.Description; asset.Type = (sbyte)item.Type; item.AssetID = asset.FullID; m_Scene.AssetService.Store(asset); part.Inventory.UpdateInventoryItem(item); } } } public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) { if (XferUploaders.ContainsKey(transactionID)) { m_log.DebugFormat("[XFER]: Asked to update item {0} ({1})", item.Name, item.ID); // Here we need to get the old asset to extract the // texture UUIDs if it's a wearable. if (item.AssetType == (int)AssetType.Bodypart || item.AssetType == (int)AssetType.Clothing) { AssetBase oldAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); if (oldAsset != null) XferUploaders[transactionID].SetOldData(oldAsset.Data); } AssetBase asset = GetTransactionAsset(transactionID); if (asset != null) { asset.FullID = UUID.Random(); asset.Name = item.Name; asset.Description = item.Description; asset.Type = (sbyte)item.AssetType; item.AssetID = asset.FullID; m_Scene.AssetService.Store(asset); IInventoryService invService = m_Scene.InventoryService; invService.UpdateItem(item); m_log.DebugFormat("[XFER]: Updated item {0} ({1}) with asset {2}", item.Name, item.ID, asset.FullID); } } } } }