diff --git a/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs b/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs index 20ec58ad5a..cb122df251 100644 --- a/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs +++ b/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs @@ -26,10 +26,12 @@ * */ +using System.Collections.Generic; using System.IO; using System.Xml; using libsecondlife; using Nini.Config; + using OpenSim.Framework.Console; namespace OpenSim.Framework.Communications.Cache @@ -41,44 +43,62 @@ namespace OpenSim.Framework.Communications.Cache public class LibraryRootFolder : InventoryFolderImpl { private LLUUID libOwner = new LLUUID("11111111-1111-0000-0000-000100bba000"); - private InventoryFolderImpl m_textureFolder; + + /// + /// Holds the root library folder and all its descendents. This is really only used during inventory + /// setup so that we don't have to repeatedly search the tree of library folders. + /// + protected Dictionary libraryFolders + = new Dictionary(); public LibraryRootFolder() { + MainLog.Instance.Verbose("LIBRARYINVENTORY", "Loading library inventory"); + agentID = libOwner; folderID = new LLUUID("00000112-000f-0000-0000-000100bba000"); name = "OpenSim Library"; parentID = LLUUID.Zero; - type = (short) -1; + type = (short) 8; version = (ushort) 1; - - InventoryFolderImpl folderInfo = new InventoryFolderImpl(); - folderInfo.agentID = libOwner; - folderInfo.folderID = new LLUUID("00000112-000f-0000-0000-000100bba001"); - folderInfo.name = "Texture Library"; - folderInfo.parentID = folderID; - folderInfo.type = -1; - folderInfo.version = 1; - SubFolders.Add(folderInfo.folderID, folderInfo); - m_textureFolder = folderInfo; - - CreateLibraryItems(); - - string filePath = Path.Combine(Util.configDir(), "inventory/OpenSimLibrary/OpenSimLibrary.xml"); - if (File.Exists(filePath)) + + libraryFolders.Add(folderID, this); + + string foldersPath = Path.Combine(Util.configDir(), "inventory/OpenSimLibrary/OpenSimLibraryFolders.xml"); + if (File.Exists(foldersPath)) { try { - XmlConfigSource source = new XmlConfigSource(filePath); + XmlConfigSource source = new XmlConfigSource(foldersPath); + ReadFoldersFromFile(source); + } + catch (XmlException e) + { + MainLog.Instance.Error("AGENTINVENTORY", "Error loading " + foldersPath + ": " + e.ToString()); + } + } + + CreateLibraryItems(); + + string itemsPath = Path.Combine(Util.configDir(), "inventory/OpenSimLibrary/OpenSimLibrary.xml"); + if (File.Exists(itemsPath)) + { + try + { + XmlConfigSource source = new XmlConfigSource(itemsPath); ReadItemsFromFile(source); } catch (XmlException e) { - MainLog.Instance.Error("AGENTINVENTORY", "Error loading " + filePath + ": " + e.ToString()); + MainLog.Instance.Error("AGENTINVENTORY", "Error loading " + itemsPath + ": " + e.ToString()); } } } + /// + /// Hardcoded item creation. Please don't add any more items here - future items should be created + /// in the xml in the bin/inventory folder. + /// private void CreateLibraryItems() { InventoryItemBase item = @@ -133,7 +153,51 @@ namespace OpenSim.Framework.Communications.Cache item.inventoryNextPermissions = 0x7FFFFFFF; return item; } + + /// + /// Read library inventory folders from an external source + /// + /// + private void ReadFoldersFromFile(IConfigSource source) + { + for (int i = 0; i < source.Configs.Count; i++) + { + IConfig config = source.Configs[i]; + + InventoryFolderImpl folderInfo = new InventoryFolderImpl(); + + folderInfo.folderID = new LLUUID(config.GetString("folderID", folderID.ToString())); + folderInfo.name = config.GetString("name", "unknown"); + folderInfo.parentID = new LLUUID(config.GetString("parentFolderID", folderID.ToString())); + folderInfo.type = (short)config.GetInt("type", 8); + + folderInfo.agentID = libOwner; + folderInfo.version = 1; + + if (libraryFolders.ContainsKey(folderInfo.parentID)) + { + InventoryFolderImpl parentFolder = libraryFolders[folderInfo.parentID]; + + libraryFolders.Add(folderInfo.folderID, folderInfo); + parentFolder.SubFolders.Add(folderInfo.folderID, folderInfo); + +// MainLog.Instance.Verbose( +// "LIBRARYINVENTORY", "Adding folder {0} ({1})", folderInfo.name, folderInfo.folderID); + } + else + { + MainLog.Instance.Warn( + "LIBRARYINVENTORY", + "Couldn't add folder {0} ({1}) since parent folder with ID {2} does not exist!", + folderInfo.name, folderInfo.folderID, folderInfo.parentID); + } + } + } + /// + /// Read library inventory items metadata from an external source + /// + /// private void ReadItemsFromFile(IConfigSource source) { for (int i = 0; i < source.Configs.Count; i++) @@ -145,7 +209,7 @@ namespace OpenSim.Framework.Communications.Cache new LLUUID(source.Configs[i].GetString("inventoryID", folderID.ToString())); item.assetID = new LLUUID(source.Configs[i].GetString("assetID", LLUUID.Random().ToString())); item.parentFolderID - = new LLUUID(source.Configs[i].GetString("folderID", LLUUID.Random().ToString())); + = new LLUUID(source.Configs[i].GetString("folderID", folderID.ToString())); item.inventoryDescription = source.Configs[i].GetString("description", ""); item.inventoryName = source.Configs[i].GetString("name", ""); item.assetType = source.Configs[i].GetInt("assetType", 0); @@ -155,19 +219,30 @@ namespace OpenSim.Framework.Communications.Cache item.inventoryEveryOnePermissions = (uint) source.Configs[i].GetLong("everyonePermissions", 0x7FFFFFFF); item.inventoryBasePermissions = (uint) source.Configs[i].GetLong("basePermissions", 0x7FFFFFFF); - if (item.parentFolderID == folderID) + if (libraryFolders.ContainsKey(item.parentFolderID)) { - Items.Add(item.inventoryID, item); + InventoryFolderImpl parentFolder = libraryFolders[item.parentFolderID]; + + parentFolder.Items.Add(item.inventoryID, item); } else { - // Very temporary - will only work for immediate child folders - if (SubFolders.ContainsKey(item.parentFolderID)) - { - SubFolders[item.parentFolderID].Items.Add(item.inventoryID, item); - } - } + MainLog.Instance.Warn( + "LIBRARYINVENTORY", + "Couldn't add item {0} ({1}) since parent folder with ID {2} does not exist!", + item.inventoryName, item.inventoryID, item.parentFolderID); + } } } + + /// + /// Looks like a simple getter, but is written like this for some consistency with the other Request + /// methods in the superclass + /// + /// + public Dictionary RequestSelfAndDescendentFolders() + { + return libraryFolders; + } } } diff --git a/OpenSim/Framework/Communications/LoginService.cs b/OpenSim/Framework/Communications/LoginService.cs index bef20f7160..a9d5d8be12 100644 --- a/OpenSim/Framework/Communications/LoginService.cs +++ b/OpenSim/Framework/Communications/LoginService.cs @@ -28,9 +28,12 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Threading; using libsecondlife; using Nwc.XmlRpc; + +using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Console; namespace OpenSim.Framework.UserManagement @@ -40,10 +43,18 @@ namespace OpenSim.Framework.UserManagement protected string m_welcomeMessage = "Welcome to OpenSim"; protected UserManagerBase m_userManager = null; protected Mutex m_loginMutex = new Mutex(false); + + /// + /// Used during login to send the skeleton of the OpenSim Library to the client. + /// + protected LibraryRootFolder m_libraryRootFolder; - public LoginService(UserManagerBase userManager, string welcomeMess) + public LoginService( + UserManagerBase userManager, LibraryRootFolder libraryRootFolder, string welcomeMess) { m_userManager = userManager; + m_libraryRootFolder = libraryRootFolder; + if (welcomeMess != "") { m_welcomeMessage = welcomeMess; @@ -255,30 +266,27 @@ namespace OpenSim.Framework.UserManagement } /// - /// + /// Converts the inventory library skeleton into the form required by the rpc request. /// /// protected virtual ArrayList GetInventoryLibrary() { - //return new ArrayList(); - Hashtable TempHash = new Hashtable(); - TempHash["name"] = "OpenSim Library"; - TempHash["parent_id"] = LLUUID.Zero.ToString(); - TempHash["version"] = 1; - TempHash["type_default"] = -1; - TempHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; - ArrayList temp = new ArrayList(); - temp.Add(TempHash); - - TempHash = new Hashtable(); - TempHash["name"] = "Texture Library"; - TempHash["parent_id"] = "00000112-000f-0000-0000-000100bba000"; - TempHash["version"] = 1; - TempHash["type_default"] = -1; - TempHash["folder_id"] = "00000112-000f-0000-0000-000100bba001"; - temp.Add(TempHash); - - return temp; + Dictionary rootFolders + = m_libraryRootFolder.RequestSelfAndDescendentFolders(); + ArrayList folderHashes = new ArrayList(); + + foreach (InventoryFolderBase folder in rootFolders.Values) + { + Hashtable TempHash = new Hashtable(); + TempHash["name"] = folder.name; + TempHash["parent_id"] = folder.parentID.ToString(); + TempHash["version"] = folder.version; + TempHash["type_default"] = folder.type; + TempHash["folder_id"] = folder.folderID.ToString(); + folderHashes.Add(TempHash); + } + + return folderHashes; } /// diff --git a/OpenSim/Grid/UserServer/Main.cs b/OpenSim/Grid/UserServer/Main.cs index 6e3ccb7eb1..d50558f4ad 100644 --- a/OpenSim/Grid/UserServer/Main.cs +++ b/OpenSim/Grid/UserServer/Main.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.IO; using libsecondlife; using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Console; using OpenSim.Framework.Servers; @@ -89,7 +90,8 @@ namespace OpenSim.Grid.UserServer m_userManager._config = Cfg; m_userManager.AddPlugin(Cfg.DatabaseProvider); - m_loginService = new UserLoginService(m_userManager, Cfg, Cfg.DefaultStartupMsg); + m_loginService = new UserLoginService( + m_userManager, new LibraryRootFolder(), Cfg, Cfg.DefaultStartupMsg); MainLog.Instance.Verbose("REGION", "Starting HTTP process"); BaseHttpServer httpServer = new BaseHttpServer(Cfg.HttpPort); diff --git a/OpenSim/Grid/UserServer/UserLoginService.cs b/OpenSim/Grid/UserServer/UserLoginService.cs index 0eb2db16e4..1a3bf2e06b 100644 --- a/OpenSim/Grid/UserServer/UserLoginService.cs +++ b/OpenSim/Grid/UserServer/UserLoginService.cs @@ -32,7 +32,9 @@ using System.Collections.Generic; using System.Threading; using libsecondlife; using Nwc.XmlRpc; + using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Console; using OpenSim.Framework.Data; using OpenSim.Framework.Servers; @@ -45,8 +47,9 @@ namespace OpenSim.Grid.UserServer { public UserConfig m_config; - public UserLoginService(UserManagerBase userManager, UserConfig config, string welcomeMess) - : base(userManager, welcomeMess) + public UserLoginService( + UserManagerBase userManager, LibraryRootFolder libraryRootFolder, UserConfig config, string welcomeMess) + : base(userManager, libraryRootFolder, welcomeMess) { m_config = config; } diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs index fa2a9892c2..2a3f947def 100644 --- a/OpenSim/Region/Application/OpenSimMain.cs +++ b/OpenSim/Region/Application/OpenSimMain.cs @@ -326,12 +326,25 @@ namespace OpenSim m_moduleLoader = new ModuleLoader(m_log, m_config); - MainLog.Instance.Verbose("Plugins", "Loading OpenSim application plugins"); - foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes("/OpenSim/Startup")) - { + ExtensionNodeList nodes = AddinManager.GetExtensionNodes("/OpenSim/Startup"); + MainLog.Instance.Verbose("PLUGINS", "Loading {0} OpenSim application plugins", nodes.Count); + + foreach (TypeExtensionNode node in nodes) + { IApplicationPlugin plugin = (IApplicationPlugin) node.CreateInstance(); - plugin.Initialise(this); - m_plugins.Add(plugin); + + // Debug code to try and track down a bizzare ubuntu/mono/linux bug on standalone where we + // appear to try and initialize all the plugins twice. Currently disabled +// MainLog.Instance.Verbose("PLUGINS", "Hitting plugin {0}", plugin.ToString()); +// if (m_plugins.Contains(plugin)) +// { +// MainLog.Instance.Verbose("PLUGINS", "Skipping {0}", plugin.ToString()); +// } +// else +// { + plugin.Initialise(this); + m_plugins.Add(plugin); +// } } // Start UDP servers diff --git a/OpenSim/Region/Communications/Local/LocalLoginService.cs b/OpenSim/Region/Communications/Local/LocalLoginService.cs index bf5f205d8c..0fb86af42e 100644 --- a/OpenSim/Region/Communications/Local/LocalLoginService.cs +++ b/OpenSim/Region/Communications/Local/LocalLoginService.cs @@ -30,7 +30,9 @@ using System; using System.Collections; using System.Collections.Generic; using libsecondlife; + using OpenSim.Framework; +using OpenSim.Framework.Communications.Cache; using OpenSim.Framework.Console; using OpenSim.Framework.UserManagement; using InventoryFolder=OpenSim.Framework.InventoryFolder; @@ -52,7 +54,7 @@ namespace OpenSim.Region.Communications.Local public LocalLoginService(UserManagerBase userManager, string welcomeMess, CommunicationsLocal parent, NetworkServersInfo serversInfo, bool authenticate) - : base(userManager, welcomeMess) + : base(userManager, parent.UserProfileCacheService.libraryRoot, welcomeMess) { m_Parent = parent; this.serversInfo = serversInfo; diff --git a/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml b/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml index b46c6ecfb2..7f5baa9eaa 100644 --- a/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml +++ b/bin/inventory/OpenSimLibrary/OpenSimLibrary.xml @@ -1,6 +1,22 @@ + +
@@ -9,10 +25,10 @@ - - - - + + + +
diff --git a/bin/inventory/OpenSimLibrary/OpenSimLibraryFolders.xml b/bin/inventory/OpenSimLibrary/OpenSimLibraryFolders.xml new file mode 100644 index 0000000000..2f377164c5 --- /dev/null +++ b/bin/inventory/OpenSimLibrary/OpenSimLibraryFolders.xml @@ -0,0 +1,18 @@ + + + +
+ + + + +
+ +
diff --git a/bin/inventory/README.txt b/bin/inventory/README.txt index 003a18a913..fdbbbdc04d 100644 --- a/bin/inventory/README.txt +++ b/bin/inventory/README.txt @@ -1,6 +1,14 @@ README -Inventory configuration is carried out here. Currently, you can add new items to OpenSimLibrary/OpenSimLibrary.xml, +The standard common inventory library is configured here. You can add new inventory +folders to the standard library by editing OpenSimLibary/OpenSimLibraryFolders.xml +You can also add new inventory items to OpenSimLibrary/OpenSimLibrary.xml, as long as they have a corresponding asset entry in bin/OpenSimAssetSet.xml. +The same set of folders and items must be present in the configuration of both +the grid servers and all the regions. The reasons for this are historical - +this restriction will probably be lifted in the future, at which point the +inventory items and folders will only need to be configured on the grid inventory +server (assuming you are running in grid mode rather than standalone) + Inventory_Default.xml and Inventory_Library.xml are unused at the moment.