From 8143c597fc5f62ec0d931d2d5b887730e06aec04 Mon Sep 17 00:00:00 2001 From: lbsa71 Date: Thu, 27 Sep 2007 13:25:45 +0000 Subject: * Tleiades grid mode inventory (#444) - thanx Tleiades! * updated to rev 1413 on libsecondlife.dll and libsecondlife.dll.config (#423) --- .../Communications/InventoryServiceBase.cs | 255 ++++++++++++++++----- 1 file changed, 201 insertions(+), 54 deletions(-) (limited to 'OpenSim/Framework/Communications/InventoryServiceBase.cs') diff --git a/OpenSim/Framework/Communications/InventoryServiceBase.cs b/OpenSim/Framework/Communications/InventoryServiceBase.cs index da7a0ce..6283b60 100644 --- a/OpenSim/Framework/Communications/InventoryServiceBase.cs +++ b/OpenSim/Framework/Communications/InventoryServiceBase.cs @@ -1,4 +1,9 @@ using System; +using System.Text; +using System.IO; +using System.Xml; +using System.Xml.Serialization; +using System.Collections; using System.Collections.Generic; using System.Reflection; using libsecondlife; @@ -6,21 +11,20 @@ using OpenSim.Framework.Communications; using OpenSim.Framework.Console; using OpenSim.Framework.Data; using InventoryFolder=OpenSim.Framework.Communications.Caches.InventoryFolder; +using InventoryCategory = OpenSim.Framework.Data.InventoryCategory; namespace OpenSim.Framework.Communications { - public abstract class InventoryServiceBase : IInventoryServices + public abstract class InventoryServiceBase : MarshalByRefObject, IInventoryServices { - protected Dictionary m_plugins = new Dictionary(); - //protected IAssetServer m_assetServer; + protected IInventoryData _databasePlugin; public InventoryServiceBase() { - //m_assetServer = assetServer; } /// - /// Adds a new user server plugin - plugins will be requested in the order they were loaded. + /// Adds a new inventory data server plugin /// /// The filename to the user server plugin DLL public void AddPlugin(string FileName) @@ -41,8 +45,13 @@ namespace OpenSim.Framework.Communications IInventoryData plug = (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); plug.Initialise(); - this.m_plugins.Add(plug.getName(), plug); + this._databasePlugin = plug; + + //TODO! find a better place to create inventory skeletons + loadInventoryFromXmlFile(InventoryCategory.Library, "Inventory_Library.xml"); + loadInventoryFromXmlFile(InventoryCategory.Default, "Inventory_Default.xml"); MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface"); + break; } } } @@ -54,20 +63,20 @@ namespace OpenSim.Framework.Communications /// /// /// - public List RequestFirstLevelFolders(LLUUID userID) + public List RequestFirstLevelFolders(LLUUID folderID) { - List inventoryList = new List(); - foreach (KeyValuePair plugin in m_plugins) + InventoryFolderBase root = _databasePlugin.getInventoryFolder(folderID); + + List folders = new List(); + if (root != null) { - InventoryFolderBase rootFolder = plugin.Value.getUserRootFolder(userID); - if (rootFolder != null) - { - inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID); - inventoryList.Insert(0, rootFolder); - return inventoryList; - } + folders.Add(root); + + List subFolders = _databasePlugin.getInventoryFolders(root.folderID); + foreach (InventoryFolderBase f in subFolders) + folders.Add(f); } - return inventoryList; + return folders; } /// @@ -75,11 +84,7 @@ namespace OpenSim.Framework.Communications /// public InventoryFolderBase RequestUsersRoot(LLUUID userID) { - foreach (KeyValuePair plugin in m_plugins) - { - return plugin.Value.getUserRootFolder(userID); - } - return null; + return _databasePlugin.getInventoryFolder(userID); // the id of the root folder, is the user id } /// @@ -89,47 +94,27 @@ namespace OpenSim.Framework.Communications /// public List RequestSubFolders(LLUUID parentFolderID) { - List inventoryList = new List(); - foreach (KeyValuePair plugin in m_plugins) - { - return plugin.Value.getInventoryFolders(parentFolderID); - } - return inventoryList; + return _databasePlugin.getInventoryFolders(parentFolderID); } public List RequestFolderItems(LLUUID folderID) { - List itemsList = new List(); - foreach (KeyValuePair plugin in m_plugins) - { - itemsList = plugin.Value.getInventoryInFolder(folderID); - return itemsList; - } - return itemsList; + return _databasePlugin.getInventoryInFolder(folderID); } public void AddFolder(InventoryFolderBase folder) { - foreach (KeyValuePair plugin in m_plugins) - { - plugin.Value.addInventoryFolder(folder); - } + _databasePlugin.addInventoryFolder(folder); } public void AddItem(InventoryItemBase item) { - foreach (KeyValuePair plugin in m_plugins) - { - plugin.Value.addInventoryItem(item); - } + _databasePlugin.addInventoryItem(item); } public void deleteItem(InventoryItemBase item) { - foreach (KeyValuePair plugin in m_plugins) - { - plugin.Value.deleteInventoryItem(item); - } + _databasePlugin.deleteInventoryItem(item); } /// @@ -144,11 +129,53 @@ namespace OpenSim.Framework.Communications } } - public void CreateNewUserInventory(LLUUID user) + public void CreateNewUserInventory(LLUUID defaultFolders, LLUUID user) { - UsersInventory inven = new UsersInventory(); - inven.CreateNewInventorySet(user); - this.AddNewInventorySet(inven); + try + { + // Get Default folder set from the database + //TODO! We need to get the whole hierachy and not just one level down + List folders = this.RequestFirstLevelFolders(LLUUID.Parse("00000112-000f-0000-0000-000100bba000")); + + // create an index list, where each of the elements has the index of its parent in the hierachy + // this algorithm is pretty shoddy O(n^2), but it is only executed once per user. + int[] parentIdx = new int[folders.Count]; + for (int i = 0; i < folders.Count; i++) + parentIdx[i] = -1; + + for (int i = 0; i < folders.Count; i++) + for (int j = 0; j < folders.Count; j++) + if (folders[i].folderID == folders[j].parentID) + parentIdx[j] = i; + + + //assign a new owerid and a new to the folders + foreach (InventoryFolderBase ifb in folders) + { + if (ifb.parentID == LLUUID.Zero) + ifb.folderID = user; + else + ifb.folderID = LLUUID.Random(); + + ifb.agentID = user; + ifb.category = InventoryCategory.User; + } + + // correct the parent id + for (int i = 0; i < folders.Count; i++) + { + if (folders[i].parentID != LLUUID.Zero) + folders[i].parentID = folders[parentIdx[i]].folderID; // root folder id is the same as the user id + } + + // the list is structurally sound, using new folder id's, so save it + foreach (InventoryFolderBase ifb in folders) + _databasePlugin.addInventoryFolder(ifb); + } + catch (Exception e) + { + MainLog.Instance.Error(e.ToString()); + } } public class UsersInventory @@ -166,10 +193,11 @@ namespace OpenSim.Framework.Communications InventoryFolderBase folder = new InventoryFolderBase(); folder.parentID = LLUUID.Zero; folder.agentID = user; - folder.folderID = LLUUID.Random(); + folder.folderID = user; // id of root folder is the same as the agent id folder.name = "My Inventory"; folder.type = 8; folder.version = 1; + folder.category = InventoryCategory.User; Folders.Add(folder.folderID, folder); LLUUID rootFolder = folder.folderID; @@ -181,6 +209,7 @@ namespace OpenSim.Framework.Communications folder.name = "Textures"; folder.type = 0; folder.version = 1; + folder.category = InventoryCategory.User; Folders.Add(folder.folderID, folder); folder = new InventoryFolderBase(); @@ -190,6 +219,7 @@ namespace OpenSim.Framework.Communications folder.name = "Objects"; folder.type = 6; folder.version = 1; + folder.category = InventoryCategory.User; Folders.Add(folder.folderID, folder); folder = new InventoryFolderBase(); @@ -199,13 +229,130 @@ namespace OpenSim.Framework.Communications folder.name = "Clothes"; folder.type = 5; folder.version = 1; + folder.category = InventoryCategory.User; Folders.Add(folder.folderID, folder); } } + + public void GetRootFoldersForUser(LLUUID user, out LLUUID libraryFolder, out LLUUID personalFolder) + { + List folders = _databasePlugin.getUserRootFolders(user); + libraryFolder = LLUUID.Zero; + personalFolder = LLUUID.Zero; + + for (int i = 0; i < folders.Count; i++) + { + if (folders[i].category == InventoryCategory.Library) + libraryFolder = folders[i].folderID; + else if (folders[i].category == InventoryCategory.User) + personalFolder = folders[i].folderID; + } + } + + /* + * Dot net has some issues, serializing a dictionary, so we cannot reuse the InventoryFolder + * class defined in Communications.Framework.Communications.Caches. So we serialize/deserialize + * into this simpler class, and then use that. + */ + [XmlRoot(ElementName = "inventory", IsNullable = true)] + public class SerializedInventory + { + [XmlRoot(ElementName = "folder", IsNullable = true)] + public class SerializedFolder : InventoryFolderBase + { + [XmlArray(ElementName = "folders", IsNullable = true)] + [XmlArrayItem(ElementName = "folder", IsNullable = true, Type = typeof(SerializedFolder))] + public ArrayList SubFolders; + + [XmlArray(ElementName = "items", IsNullable = true)] + [XmlArrayItem(ElementName = "item", IsNullable = true, Type = typeof(InventoryItemBase))] + public ArrayList Items; + } + + [XmlElement(ElementName = "folder", IsNullable = true)] + public SerializedFolder root; + } + + public void uploadInventory(SerializedInventory.SerializedFolder folder) + { + foreach (InventoryItemBase iib in folder.Items) + { + // assign default values, if they haven't assigned + iib.avatarID = folder.agentID; + if (iib.assetID == LLUUID.Zero) + iib.assetID = LLUUID.Random(); + if (iib.creatorsID == LLUUID.Zero) + iib.creatorsID = folder.agentID; + if (iib.inventoryID == LLUUID.Zero) + iib.inventoryID = LLUUID.Random(); + if (iib.inventoryName == null || iib.inventoryName.Length == 0) + iib.inventoryName = "new item"; + iib.parentFolderID = folder.folderID; + + _databasePlugin.addInventoryItem(iib); + } + + foreach (SerializedInventory.SerializedFolder sf in folder.SubFolders) + { + // assign default values, if they haven't assigned + sf.agentID = folder.agentID; + sf.category = folder.category; + if (sf.folderID == LLUUID.Zero) + sf.folderID = LLUUID.Random(); + if (sf.name == null || sf.name.Length == 0) + sf.name = "new folder"; + sf.parentID = folder.folderID; + + _databasePlugin.addInventoryFolder(sf); + uploadInventory(sf); + } + } + + public void loadInventoryFromXmlFile(InventoryCategory inventoryCategory, string fileName) + { + _databasePlugin.deleteInventoryCategory(inventoryCategory); + + FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); + XmlReader reader = new XmlTextReader(fs); + XmlSerializer x = new XmlSerializer(typeof(SerializedInventory)); + SerializedInventory inventory = (SerializedInventory)x.Deserialize(reader); + + // the library and default inventories has no owner, so we use a random guid. + if (inventory.root.category == InventoryCategory.Library || inventory.root.category == InventoryCategory.Default) + { + if (inventory.root.folderID != LLUUID.Zero) + inventory.root.agentID = inventory.root.folderID; + else + inventory.root.agentID = LLUUID.Random(); + } + else if (inventory.root.category == InventoryCategory.User) + { + if (inventory.root.agentID == LLUUID.Zero) + inventory.root.agentID = LLUUID.Random(); + } + + inventory.root.folderID = inventory.root.agentID; // the root folder always has the same id as the owning agent + inventory.root.parentID = LLUUID.Zero; + inventory.root.version = 0; + inventory.root.category = inventoryCategory; + + _databasePlugin.addInventoryFolder(inventory.root); + uploadInventory(inventory.root); + } + + protected void saveInventoryToXmlFile(SerializedInventory inventory, string fileName) + { + FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write); + XmlTextWriter writer = new XmlTextWriter(fs, Encoding.UTF8); + writer.Formatting = Formatting.Indented; + XmlSerializer x = new XmlSerializer(typeof(SerializedInventory)); + x.Serialize(writer, inventory); + } + public abstract void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); - public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder); + public abstract void AddNewInventoryFolder(LLUUID userID, InventoryFolderBase folder); public abstract void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); public abstract void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); } -} \ No newline at end of file +} -- cgit v1.1