From 6a3455a98cb3b7c910dd2d8d09f69d1c3acf7d2d Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Tue, 12 Feb 2008 18:15:54 +0000 Subject: * Refactoring: Rename AssetTransactions.cs and AssetTransactionsManager and align classes with file names * Small amount of ndoc * This will probably require a prebuild and nant clean --- .../Communications/Cache/AgentAssetTransactions.cs | 509 +++++++++++++++++++++ .../Cache/AgentAssetTransactionsManager.cs | 143 ++++++ .../Cache/AssetTransactionManager.cs | 128 ------ .../Communications/Cache/AssetTransactions.cs | 506 -------------------- .../Communications/CommunicationsManager.cs | 8 +- 5 files changed, 656 insertions(+), 638 deletions(-) create mode 100644 OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs create mode 100644 OpenSim/Framework/Communications/Cache/AgentAssetTransactionsManager.cs delete mode 100644 OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs delete mode 100644 OpenSim/Framework/Communications/Cache/AssetTransactions.cs (limited to 'OpenSim/Framework/Communications') diff --git a/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs b/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs new file mode 100644 index 0000000..e74a06b --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/AgentAssetTransactions.cs @@ -0,0 +1,509 @@ +/* +* 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 OpenSim 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; +using System.Collections.Generic; +using System.IO; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Servers; +using OpenSim.Region.Capabilities; + +namespace OpenSim.Framework.Communications.Cache +{ + /// + /// Manage asset transactions for a single agent. + /// + public class AgentAssetTransactions + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + // Fields + public List CapsUploaders = new List(); + public List NotecardUpdaters = new List(); + public LLUUID UserID; + public Dictionary XferUploaders = new Dictionary(); + public AgentAssetTransactionsManager Manager; + private bool m_dumpAssetsToFile; + + // Methods + public AgentAssetTransactions(LLUUID agentID, AgentAssetTransactionsManager manager, bool dumpAssetsToFile) + { + UserID = agentID; + Manager = manager; + m_dumpAssetsToFile = dumpAssetsToFile; + } + + public AssetCapsUploader RequestCapsUploader() + { + AssetCapsUploader uploader = new AssetCapsUploader(); + CapsUploaders.Add(uploader); + return uploader; + } + + public NoteCardCapsUpdate RequestNoteCardUpdater() + { + NoteCardCapsUpdate update = new NoteCardCapsUpdate(); + NotecardUpdaters.Add(update); + return update; + } + + public AssetXferUploader RequestXferUploader(LLUUID transactionID) + { + if (!XferUploaders.ContainsKey(transactionID)) + { + AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); + + lock (XferUploaders) + { + XferUploaders.Add(transactionID, uploader); + } + + return uploader; + } + return null; + } + + public void HandleXfer(ulong xferID, uint packetID, byte[] data) + { + AssetXferUploader uploaderFound = null; + + lock (XferUploaders) + { + foreach (AssetXferUploader uploader in XferUploaders.Values) + { + if (uploader.XferID == xferID) + { + if (uploader.HandleXferPacket(xferID, packetID, data)) + { + uploaderFound = uploader; + } + + break; + } + } + + // Remove the uploader once the uploader is complete + //[don't think we can be sure a upload has finished from here, uploads are multi part things] + // [or maybe we can if we do more checking like data lenght checks] + if (uploaderFound != null) + { +// m_log.Info( +// String.Format( +// "[ASSET TRANSACTIONS] Removing asset xfer uploader with transfer id {0}, transaction {1}", +// xferID, uploaderFound.TransactionID)); + + // XferUploaders.Remove(uploaderFound.TransactionID); + + //m_log.InfoFormat("[ASSET TRANSACTIONS] Current uploaders: {0}", XferUploaders.Count); + } + } + } + + public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID 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(LLUUID transactionID) + { + if (XferUploaders.ContainsKey(transactionID)) + { + AssetXferUploader uploader = XferUploaders[transactionID]; + AssetBase asset = uploader.GetAssetData(); + + lock (XferUploaders) + { + XferUploaders.Remove(transactionID); + } + + return asset; + } + + return null; + } + + // Nested Types + public class AssetXferUploader + { + // Fields + public bool AddToInventory; + public AssetBase Asset; + public LLUUID InventFolder = LLUUID.Zero; + private IClientAPI ourClient; + public LLUUID TransactionID = LLUUID.Zero; + public bool UploadComplete; + public ulong XferID; + private string m_name = String.Empty; + private string m_description = String.Empty; + private sbyte type = 0; + private sbyte invType = 0; + private uint nextPerm = 0; + private bool m_finished = false; + private bool m_createItem = false; + private AgentAssetTransactions m_userTransactions; + private bool m_storeLocal; + private bool m_dumpAssetToFile; + + public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) + { + m_userTransactions = transactions; + m_dumpAssetToFile = dumpAssetToFile; + } + + /// + /// Process transfer data received from the client. + /// + /// + /// + /// + /// True if the transfer is complete, false otherwise or if the xferID was not valid + public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) + { + if (XferID == xferID) + { + if (Asset.Data.Length > 1) + { + byte[] destinationArray = new byte[Asset.Data.Length + data.Length]; + Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length); + Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length); + Asset.Data = destinationArray; + } + else + { + byte[] buffer2 = new byte[data.Length - 4]; + Array.Copy(data, 4, buffer2, 0, data.Length - 4); + Asset.Data = buffer2; + } + ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); + newPack.XferID.ID = xferID; + newPack.XferID.Packet = packetID; + ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); + if ((packetID & 0x80000000) != 0) + { + SendCompleteMessage(); + return true; + } + } + + return false; + } + + /// + /// Initialise asset transfer from the client + /// + /// + /// + /// + /// True if the transfer is complete, false otherwise + public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, + bool storeLocal, bool tempFile) + { + ourClient = remoteClient; + Asset = new AssetBase(); + Asset.FullID = assetID; + Asset.InvType = type; + Asset.Type = type; + Asset.Data = data; + Asset.Name = "blank"; + Asset.Description = "empty"; + Asset.Local = storeLocal; + Asset.Temporary = tempFile; + + TransactionID = transaction; + m_storeLocal = storeLocal; + if (Asset.Data.Length > 2) + { + SendCompleteMessage(); + return true; + } + else + { + ReqestStartXfer(); + } + + return false; + } + + protected void ReqestStartXfer() + { + UploadComplete = false; + XferID = Util.GetNextXferID(); + RequestXferPacket newPack = new RequestXferPacket(); + newPack.XferID.ID = XferID; + newPack.XferID.VFileType = Asset.Type; + newPack.XferID.VFileID = Asset.FullID; + newPack.XferID.FilePath = 0; + newPack.XferID.Filename = new byte[0]; + ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); + } + + protected void SendCompleteMessage() + { + UploadComplete = true; + AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); + newPack.AssetBlock.Type = Asset.Type; + newPack.AssetBlock.Success = true; + newPack.AssetBlock.UUID = Asset.FullID; + ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); + m_finished = true; + if (m_createItem) + { + DoCreateItem(); + } + else if (m_storeLocal) + { + m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); + } + + // Console.WriteLine("upload complete "+ this.TransactionID); + + if (m_dumpAssetToFile) + { + DateTime now = DateTime.Now; + string filename = + String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, + now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type); + SaveAssetToFile(filename, Asset.Data); + } + } + + ///Left this in and commented in case there are unforseen issues + //private void SaveAssetToFile(string filename, byte[] data) + //{ + // FileStream fs = File.Create(filename); + // BinaryWriter bw = new BinaryWriter(fs); + // bw.Write(data); + // bw.Close(); + // fs.Close(); + //} + private void SaveAssetToFile(string filename, byte[] data) + { + string assetPath = "UserAssets"; + if (!Directory.Exists(assetPath)) + { + Directory.CreateDirectory(assetPath); + } + FileStream fs = File.Create(Path.Combine(assetPath, filename)); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + + public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, + uint callbackID, string description, string name, sbyte invType, + sbyte type, byte wearableType, uint nextOwnerMask) + { + if (TransactionID == transactionID) + { + InventFolder = folderID; + m_name = name; + m_description = description; + this.type = type; + this.invType = invType; + nextPerm = nextOwnerMask; + Asset.Name = name; + Asset.Description = description; + Asset.Type = type; + Asset.InvType = invType; + m_createItem = true; + if (m_finished) + { + DoCreateItem(); + } + } + } + + private void DoCreateItem() + { + //really need to fix this call, if lbsa71 saw this he would die. + m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); + CachedUserInfo userInfo = + m_userTransactions.Manager.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId); + if (userInfo != null) + { + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = ourClient.AgentId; + item.creatorsID = ourClient.AgentId; + item.inventoryID = LLUUID.Random(); + item.assetID = Asset.FullID; + item.inventoryDescription = m_description; + item.inventoryName = m_name; + item.assetType = type; + item.invType = invType; + item.parentFolderID = InventFolder; + item.inventoryBasePermissions = 2147483647; + item.inventoryCurrentPermissions = 2147483647; + item.inventoryNextPermissions = nextPerm; + + userInfo.AddItem(ourClient.AgentId, item); + ourClient.SendInventoryItemCreateUpdate(item); + } + } + + public AssetBase GetAssetData() + { + if (m_finished) + { + return Asset; + } + return null; + } + } + + #region Nested Classes currently not in use (waiting for them to be enabled) + + public class AssetCapsUploader + { + // Fields + private BaseHttpServer httpListener; + private LLUUID inventoryItemID; + private string m_assetDescription = String.Empty; + private string m_assetName = String.Empty; + private LLUUID m_folderID; + private LLUUID newAssetID; + private bool m_dumpImageToFile; + private string uploaderPath = String.Empty; + + // Events + public event UpLoadedAsset OnUpLoad; + + // Methods + public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, + LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile) + { + m_assetName = assetName; + m_assetDescription = assetDescription; + m_folderID = folderID; + newAssetID = assetID; + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + m_dumpImageToFile = dumpImageToFile; + } + + private void SaveImageToFile(string filename, byte[] data) + { + FileStream output = File.Create(filename); + BinaryWriter writer = new BinaryWriter(output); + writer.Write(data); + writer.Close(); + output.Close(); + } + + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inventoryItemID = this.inventoryItemID; + string text = String.Empty; + LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); + complete.new_asset = newAssetID.ToString(); + complete.new_inventory_item = inventoryItemID; + complete.state = "complete"; + text = LLSDHelpers.SerialiseLLSDReply(complete); + httpListener.RemoveStreamHandler("POST", uploaderPath); + if (m_dumpImageToFile) + { + SaveImageToFile(m_assetName + ".jp2", data); + } + if (OnUpLoad != null) + { + OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, String.Empty, String.Empty); + } + return text; + } + } + + public class NoteCardCapsUpdate + { + // Fields + private BaseHttpServer httpListener; + private LLUUID inventoryItemID; + private string m_assetName = String.Empty; + private LLUUID newAssetID; + private bool SaveImages = false; + private string uploaderPath = String.Empty; + + // Events + public event UpLoadedAsset OnUpLoad; + + // Methods + public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer) + { + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + newAssetID = LLUUID.Random(); + } + + private void SaveImageToFile(string filename, byte[] data) + { + FileStream output = File.Create(filename); + BinaryWriter writer = new BinaryWriter(output); + writer.Write(data); + writer.Close(); + output.Close(); + } + + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inventoryItemID = this.inventoryItemID; + string text = String.Empty; + LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); + complete.new_asset = newAssetID.ToString(); + complete.new_inventory_item = inventoryItemID; + complete.state = "complete"; + text = LLSDHelpers.SerialiseLLSDReply(complete); + httpListener.RemoveStreamHandler("POST", uploaderPath); + if (SaveImages) + { + SaveImageToFile(m_assetName + "notecard.txt", data); + } + if (OnUpLoad != null) + { + OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, String.Empty, String.Empty); + } + return text; + } + } + + #endregion + } +} diff --git a/OpenSim/Framework/Communications/Cache/AgentAssetTransactionsManager.cs b/OpenSim/Framework/Communications/Cache/AgentAssetTransactionsManager.cs new file mode 100644 index 0000000..70471cc --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/AgentAssetTransactionsManager.cs @@ -0,0 +1,143 @@ +/* +* 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 OpenSim 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; +using System.Collections.Generic; + +using libsecondlife; + +namespace OpenSim.Framework.Communications.Cache +{ + /// + /// Manage the collection of agent asset transaction collections. Each agent has its own transaction collection + /// + public class AgentAssetTransactionsManager + { + private static readonly log4net.ILog m_log + = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + // Fields + public CommunicationsManager CommsManager; + + /// + /// Each agent has its own singleton collection of transactions + /// + private Dictionary AgentTransactions = + new Dictionary(); + + /// + /// Should we dump uploaded assets to the filesystem? + /// + private bool m_dumpAssetsToFile; + + public AgentAssetTransactionsManager(CommunicationsManager commsManager, bool dumpAssetsToFile) + { + CommsManager = commsManager; + m_dumpAssetsToFile = dumpAssetsToFile; + } + + /// + /// Add a collection of asset transactions for the given user + /// + /// + public void AddUser(LLUUID userID) + { + lock (AgentTransactions) + { + if (!AgentTransactions.ContainsKey(userID)) + { + AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); + AgentTransactions.Add(userID, transactions); + } + } + } + + /// + /// Get the collection of asset transactions for the given user. + /// + /// + /// + public AgentAssetTransactions GetUserTransactions(LLUUID userID) + { + if (AgentTransactions.ContainsKey(userID)) + { + return AgentTransactions[userID]; + } + return null; + } + + public void HandleInventoryFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, + uint callbackID, string description, string name, sbyte invType, + sbyte type, byte wearableType, uint nextOwnerMask) + { + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); + if (transactions != null) + { + transactions.RequestCreateInventoryItem(remoteClient, transactionID, folderID, callbackID, description, + name, invType, type, wearableType, nextOwnerMask); + } + } + + public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, + byte[] data, bool storeLocal, bool tempFile) + { + // Console.WriteLine("asset upload of " + assetID); + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); + if (transactions != null) + { + AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); + if (uploader != null) + { + // Upload has already compelted uploading... + + if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile)) + { + //[commenting out as this removal breaks uploads] + /*lock (transactions.XferUploaders) + { + + // XXX Weak ass way of doing this by directly manipulating this public dictionary, purely temporary + transactions.XferUploaders.Remove(uploader.TransactionID); + + //m_log.InfoFormat("[ASSET TRANSACTIONS] Current uploaders: {0}", transactions.XferUploaders.Count); + }*/ + } + } + } + } + + public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) + { + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); + if (transactions != null) + { + transactions.HandleXfer(xferID, packetID, data); + } + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs b/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs deleted file mode 100644 index e4808a1..0000000 --- a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs +++ /dev/null @@ -1,128 +0,0 @@ -/* -* 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 OpenSim 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; -using System.Collections.Generic; - -using libsecondlife; - -namespace OpenSim.Framework.Communications.Cache -{ - public class AssetTransactionManager - { - private static readonly log4net.ILog m_log - = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - // Fields - public CommunicationsManager CommsManager; - - public Dictionary AgentTransactions = - new Dictionary(); - - private bool m_dumpAssetsToFile; - - public AssetTransactionManager(CommunicationsManager commsManager, bool dumpAssetsToFile) - { - CommsManager = commsManager; - m_dumpAssetsToFile = dumpAssetsToFile; - } - - // Methods - public AgentAssetTransactions AddUser(LLUUID userID) - { - lock (AgentTransactions) - { - if (!AgentTransactions.ContainsKey(userID)) - { - AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this, m_dumpAssetsToFile); - AgentTransactions.Add(userID, transactions); - return transactions; - } - } - return null; - } - - public AgentAssetTransactions GetUserTransActions(LLUUID userID) - { - if (AgentTransactions.ContainsKey(userID)) - { - return AgentTransactions[userID]; - } - return null; - } - - public void HandleInventoryFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, - uint callbackID, string description, string name, sbyte invType, - sbyte type, byte wearableType, uint nextOwnerMask) - { - AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); - if (transactions != null) - { - transactions.RequestCreateInventoryItem(remoteClient, transactionID, folderID, callbackID, description, - name, invType, type, wearableType, nextOwnerMask); - } - } - - public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, - byte[] data, bool storeLocal, bool tempFile) - { - // Console.WriteLine("asset upload of " + assetID); - AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); - if (transactions != null) - { - AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); - if (uploader != null) - { - // Upload has already compelted uploading... - - if (uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile)) - { - //[commenting out as this removal breaks uploads] - /*lock (transactions.XferUploaders) - { - - // XXX Weak ass way of doing this by directly manipulating this public dictionary, purely temporary - transactions.XferUploaders.Remove(uploader.TransactionID); - - //m_log.InfoFormat("[ASSET TRANSACTIONS] Current uploaders: {0}", transactions.XferUploaders.Count); - }*/ - } - } - } - } - - public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) - { - AgentAssetTransactions transactions = GetUserTransActions(remoteClient.AgentId); - if (transactions != null) - { - transactions.HandleXfer(xferID, packetID, data); - } - } - } -} diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs deleted file mode 100644 index 996e5ba..0000000 --- a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs +++ /dev/null @@ -1,506 +0,0 @@ -/* -* 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 OpenSim 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; -using System.Collections.Generic; -using System.IO; -using libsecondlife; -using libsecondlife.Packets; -using OpenSim.Framework.Servers; -using OpenSim.Region.Capabilities; - -namespace OpenSim.Framework.Communications.Cache -{ - public class AgentAssetTransactions - { - private static readonly log4net.ILog m_log - = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - - // Fields - public List CapsUploaders = new List(); - public List NotecardUpdaters = new List(); - public LLUUID UserID; - public Dictionary XferUploaders = new Dictionary(); - public AssetTransactionManager Manager; - private bool m_dumpAssetsToFile; - - // Methods - public AgentAssetTransactions(LLUUID agentID, AssetTransactionManager manager, bool dumpAssetsToFile) - { - UserID = agentID; - Manager = manager; - m_dumpAssetsToFile = dumpAssetsToFile; - } - - public AssetCapsUploader RequestCapsUploader() - { - AssetCapsUploader uploader = new AssetCapsUploader(); - CapsUploaders.Add(uploader); - return uploader; - } - - public NoteCardCapsUpdate RequestNoteCardUpdater() - { - NoteCardCapsUpdate update = new NoteCardCapsUpdate(); - NotecardUpdaters.Add(update); - return update; - } - - public AssetXferUploader RequestXferUploader(LLUUID transactionID) - { - if (!XferUploaders.ContainsKey(transactionID)) - { - AssetXferUploader uploader = new AssetXferUploader(this, m_dumpAssetsToFile); - - lock (XferUploaders) - { - XferUploaders.Add(transactionID, uploader); - } - - return uploader; - } - return null; - } - - public void HandleXfer(ulong xferID, uint packetID, byte[] data) - { - AssetXferUploader uploaderFound = null; - - lock (XferUploaders) - { - foreach (AssetXferUploader uploader in XferUploaders.Values) - { - if (uploader.XferID == xferID) - { - if (uploader.HandleXferPacket(xferID, packetID, data)) - { - uploaderFound = uploader; - } - - break; - } - } - - // Remove the uploader once the uploader is complete - //[don't think we can be sure a upload has finished from here, uploads are multi part things] - // [or maybe we can if we do more checking like data lenght checks] - if (uploaderFound != null) - { -// m_log.Info( -// String.Format( -// "[ASSET TRANSACTIONS] Removing asset xfer uploader with transfer id {0}, transaction {1}", -// xferID, uploaderFound.TransactionID)); - - // XferUploaders.Remove(uploaderFound.TransactionID); - - //m_log.InfoFormat("[ASSET TRANSACTIONS] Current uploaders: {0}", XferUploaders.Count); - } - } - } - - public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID 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(LLUUID transactionID) - { - if (XferUploaders.ContainsKey(transactionID)) - { - AssetXferUploader uploader = XferUploaders[transactionID]; - AssetBase asset = uploader.GetAssetData(); - - lock (XferUploaders) - { - XferUploaders.Remove(transactionID); - } - - return asset; - } - - return null; - } - - // Nested Types - public class AssetXferUploader - { - // Fields - public bool AddToInventory; - public AssetBase Asset; - public LLUUID InventFolder = LLUUID.Zero; - private IClientAPI ourClient; - public LLUUID TransactionID = LLUUID.Zero; - public bool UploadComplete; - public ulong XferID; - private string m_name = String.Empty; - private string m_description = String.Empty; - private sbyte type = 0; - private sbyte invType = 0; - private uint nextPerm = 0; - private bool m_finished = false; - private bool m_createItem = false; - private AgentAssetTransactions m_userTransactions; - private bool m_storeLocal; - private bool m_dumpAssetToFile; - - public AssetXferUploader(AgentAssetTransactions transactions, bool dumpAssetToFile) - { - m_userTransactions = transactions; - m_dumpAssetToFile = dumpAssetToFile; - } - - /// - /// Process transfer data received from the client. - /// - /// - /// - /// - /// True if the transfer is complete, false otherwise or if the xferID was not valid - public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) - { - if (XferID == xferID) - { - if (Asset.Data.Length > 1) - { - byte[] destinationArray = new byte[Asset.Data.Length + data.Length]; - Array.Copy(Asset.Data, 0, destinationArray, 0, Asset.Data.Length); - Array.Copy(data, 0, destinationArray, Asset.Data.Length, data.Length); - Asset.Data = destinationArray; - } - else - { - byte[] buffer2 = new byte[data.Length - 4]; - Array.Copy(data, 4, buffer2, 0, data.Length - 4); - Asset.Data = buffer2; - } - ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); - newPack.XferID.ID = xferID; - newPack.XferID.Packet = packetID; - ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); - if ((packetID & 0x80000000) != 0) - { - SendCompleteMessage(); - return true; - } - } - - return false; - } - - /// - /// Initialise asset transfer from the client - /// - /// - /// - /// - /// True if the transfer is complete, false otherwise - public bool Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data, - bool storeLocal, bool tempFile) - { - ourClient = remoteClient; - Asset = new AssetBase(); - Asset.FullID = assetID; - Asset.InvType = type; - Asset.Type = type; - Asset.Data = data; - Asset.Name = "blank"; - Asset.Description = "empty"; - Asset.Local = storeLocal; - Asset.Temporary = tempFile; - - TransactionID = transaction; - m_storeLocal = storeLocal; - if (Asset.Data.Length > 2) - { - SendCompleteMessage(); - return true; - } - else - { - ReqestStartXfer(); - } - - return false; - } - - protected void ReqestStartXfer() - { - UploadComplete = false; - XferID = Util.GetNextXferID(); - RequestXferPacket newPack = new RequestXferPacket(); - newPack.XferID.ID = XferID; - newPack.XferID.VFileType = Asset.Type; - newPack.XferID.VFileID = Asset.FullID; - newPack.XferID.FilePath = 0; - newPack.XferID.Filename = new byte[0]; - ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); - } - - protected void SendCompleteMessage() - { - UploadComplete = true; - AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); - newPack.AssetBlock.Type = Asset.Type; - newPack.AssetBlock.Success = true; - newPack.AssetBlock.UUID = Asset.FullID; - ourClient.OutPacket(newPack, ThrottleOutPacketType.Asset); - m_finished = true; - if (m_createItem) - { - DoCreateItem(); - } - else if (m_storeLocal) - { - m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); - } - - // Console.WriteLine("upload complete "+ this.TransactionID); - - if (m_dumpAssetToFile) - { - DateTime now = DateTime.Now; - string filename = - String.Format("{6}_{7}_{0:d2}{1:d2}{2:d2}_{3:d2}{4:d2}{5:d2}.dat", now.Year, now.Month, now.Day, - now.Hour, now.Minute, now.Second, Asset.Name, Asset.Type); - SaveAssetToFile(filename, Asset.Data); - } - } - - ///Left this in and commented in case there are unforseen issues - //private void SaveAssetToFile(string filename, byte[] data) - //{ - // FileStream fs = File.Create(filename); - // BinaryWriter bw = new BinaryWriter(fs); - // bw.Write(data); - // bw.Close(); - // fs.Close(); - //} - private void SaveAssetToFile(string filename, byte[] data) - { - string assetPath = "UserAssets"; - if (!Directory.Exists(assetPath)) - { - Directory.CreateDirectory(assetPath); - } - FileStream fs = File.Create(Path.Combine(assetPath, filename)); - BinaryWriter bw = new BinaryWriter(fs); - bw.Write(data); - bw.Close(); - fs.Close(); - } - - public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, - uint callbackID, string description, string name, sbyte invType, - sbyte type, byte wearableType, uint nextOwnerMask) - { - if (TransactionID == transactionID) - { - InventFolder = folderID; - m_name = name; - m_description = description; - this.type = type; - this.invType = invType; - nextPerm = nextOwnerMask; - Asset.Name = name; - Asset.Description = description; - Asset.Type = type; - Asset.InvType = invType; - m_createItem = true; - if (m_finished) - { - DoCreateItem(); - } - } - } - - private void DoCreateItem() - { - //really need to fix this call, if lbsa71 saw this he would die. - m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(Asset); - CachedUserInfo userInfo = - m_userTransactions.Manager.CommsManager.UserProfileCacheService.GetUserDetails(ourClient.AgentId); - if (userInfo != null) - { - InventoryItemBase item = new InventoryItemBase(); - item.avatarID = ourClient.AgentId; - item.creatorsID = ourClient.AgentId; - item.inventoryID = LLUUID.Random(); - item.assetID = Asset.FullID; - item.inventoryDescription = m_description; - item.inventoryName = m_name; - item.assetType = type; - item.invType = invType; - item.parentFolderID = InventFolder; - item.inventoryBasePermissions = 2147483647; - item.inventoryCurrentPermissions = 2147483647; - item.inventoryNextPermissions = nextPerm; - - userInfo.AddItem(ourClient.AgentId, item); - ourClient.SendInventoryItemCreateUpdate(item); - } - } - - public AssetBase GetAssetData() - { - if (m_finished) - { - return Asset; - } - return null; - } - } - - #region Nested Classes currently not in use (waiting for them to be enabled) - - public class AssetCapsUploader - { - // Fields - private BaseHttpServer httpListener; - private LLUUID inventoryItemID; - private string m_assetDescription = String.Empty; - private string m_assetName = String.Empty; - private LLUUID m_folderID; - private LLUUID newAssetID; - private bool m_dumpImageToFile; - private string uploaderPath = String.Empty; - - // Events - public event UpLoadedAsset OnUpLoad; - - // Methods - public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, - LLUUID folderID, string path, BaseHttpServer httpServer, bool dumpImageToFile) - { - m_assetName = assetName; - m_assetDescription = assetDescription; - m_folderID = folderID; - newAssetID = assetID; - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - m_dumpImageToFile = dumpImageToFile; - } - - private void SaveImageToFile(string filename, byte[] data) - { - FileStream output = File.Create(filename); - BinaryWriter writer = new BinaryWriter(output); - writer.Write(data); - writer.Close(); - output.Close(); - } - - public string uploaderCaps(byte[] data, string path, string param) - { - LLUUID inventoryItemID = this.inventoryItemID; - string text = String.Empty; - LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); - complete.new_asset = newAssetID.ToString(); - complete.new_inventory_item = inventoryItemID; - complete.state = "complete"; - text = LLSDHelpers.SerialiseLLSDReply(complete); - httpListener.RemoveStreamHandler("POST", uploaderPath); - if (m_dumpImageToFile) - { - SaveImageToFile(m_assetName + ".jp2", data); - } - if (OnUpLoad != null) - { - OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, String.Empty, String.Empty); - } - return text; - } - } - - public class NoteCardCapsUpdate - { - // Fields - private BaseHttpServer httpListener; - private LLUUID inventoryItemID; - private string m_assetName = String.Empty; - private LLUUID newAssetID; - private bool SaveImages = false; - private string uploaderPath = String.Empty; - - // Events - public event UpLoadedAsset OnUpLoad; - - // Methods - public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer) - { - inventoryItemID = inventoryItem; - uploaderPath = path; - httpListener = httpServer; - newAssetID = LLUUID.Random(); - } - - private void SaveImageToFile(string filename, byte[] data) - { - FileStream output = File.Create(filename); - BinaryWriter writer = new BinaryWriter(output); - writer.Write(data); - writer.Close(); - output.Close(); - } - - public string uploaderCaps(byte[] data, string path, string param) - { - LLUUID inventoryItemID = this.inventoryItemID; - string text = String.Empty; - LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); - complete.new_asset = newAssetID.ToString(); - complete.new_inventory_item = inventoryItemID; - complete.state = "complete"; - text = LLSDHelpers.SerialiseLLSDReply(complete); - httpListener.RemoveStreamHandler("POST", uploaderPath); - if (SaveImages) - { - SaveImageToFile(m_assetName + "notecard.txt", data); - } - if (OnUpLoad != null) - { - OnUpLoad(m_assetName, "description", newAssetID, inventoryItemID, LLUUID.Zero, data, String.Empty, String.Empty); - } - return text; - } - } - - #endregion - } -} diff --git a/OpenSim/Framework/Communications/CommunicationsManager.cs b/OpenSim/Framework/Communications/CommunicationsManager.cs index f6cfda7..3e72d89 100644 --- a/OpenSim/Framework/Communications/CommunicationsManager.cs +++ b/OpenSim/Framework/Communications/CommunicationsManager.cs @@ -73,9 +73,9 @@ namespace OpenSim.Framework.Communications get { return m_userProfileCacheService; } } - protected AssetTransactionManager m_transactionsManager; + protected AgentAssetTransactionsManager m_transactionsManager; - public AssetTransactionManager TransactionsManager + public AgentAssetTransactionsManager TransactionsManager { get { return m_transactionsManager; } } @@ -100,7 +100,7 @@ namespace OpenSim.Framework.Communications m_networkServersInfo = serversInfo; m_assetCache = assetCache; m_userProfileCacheService = new UserProfileCacheService(this); - m_transactionsManager = new AssetTransactionManager(this, dumpAssetsToFile); + m_transactionsManager = new AgentAssetTransactionsManager(this, dumpAssetsToFile); } public void doCreate(string[] cmmdParams) @@ -241,4 +241,4 @@ namespace OpenSim.Framework.Communications #endregion } -} \ No newline at end of file +} -- cgit v1.1