From ae4b02e1152b775dc1cdccd1abfbff44ab1a8949 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 25 Nov 2010 11:14:16 -0800 Subject: [PATCH 01/11] WARNING: LOTS OF CONFIGURATION CHANGES AFFECTING PRIMARILY HG CONFIGS. Added capability to preserve creator information on HG asset transfers. Added a new HGAssetService that is intended to be the one outside the firewall. It processes and filters the assets that go out of the grid. Also fixed the normal AssetService to do special things for the main instance (console commands, etc). Moved HGInventoryService to OpenSim.Services.HypergridService. Changed the way the login service gets the ServiceURL configs. --- .../InventoryAccess/InventoryAccessModule.cs | 20 ++ .../UserManagement/UserManagementModule.cs | 5 + .../Asset/AssetServiceInConnectorModule.cs | 5 +- .../Framework/Interfaces/IUserManagement.cs | 1 + .../Framework/Scenes/Scene.Inventory.cs | 4 + OpenSim/Region/Framework/Scenes/Scene.cs | 1 + .../Handlers/Asset/AssetServerConnector.cs | 5 +- .../Inventory/XInventoryInConnector.cs | 6 +- OpenSim/Services/AssetService/AssetService.cs | 73 +++---- .../HypergridService/HGAssetService.cs | 181 ++++++++++++++++++ .../HGInventoryService.cs | 47 ++++- .../Services/LLLoginService/LLLoginService.cs | 16 ++ bin/Robust.HG.ini.example | 29 ++- .../StandaloneCommon.ini.example | 16 +- bin/config-include/StandaloneHypergrid.ini | 8 +- prebuild.xml | 2 + 16 files changed, 361 insertions(+), 58 deletions(-) create mode 100644 OpenSim/Services/HypergridService/HGAssetService.cs rename OpenSim/Services/{InventoryService => HypergridService}/HGInventoryService.cs (86%) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 67732ffd75..1ff1a47f00 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -53,6 +53,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess protected bool m_Enabled = false; protected Scene m_Scene; + protected IUserManagement m_UserManagement; + protected IUserManagement UserManagementModule + { + get + { + if (m_UserManagement == null) + m_UserManagement = m_Scene.RequestModuleInterface(); + return m_UserManagement; + } + } + #region INonSharedRegionModule @@ -542,6 +553,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); + Util.FireAndForget(delegate { AddUserData(group); }); + group.RootPart.FromFolderID = item.Folder; // If it's rezzed in world, select it. Much easier to @@ -699,6 +712,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return null; } + protected void AddUserData(SceneObjectGroup sog) + { + UserManagementModule.AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData); + foreach (SceneObjectPart sop in sog.Parts) + UserManagementModule.AddUser(sop.CreatorID, sop.CreatorData); + } + public virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) { } diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 0d94baa2fa..bf84100ef5 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -275,6 +275,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL); } + public void AddUser(UUID uuid, string first, string last, string profileURL) + { + AddUser(uuid, profileURL + ";" + first + " " + last); + } + //public void AddUser(UUID uuid, string userData) //{ // if (m_UserCache.ContainsKey(uuid)) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs index 232438031c..e25700d1f7 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs @@ -91,9 +91,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset { m_Registered = true; - m_log.Info("[RegionAssetService]: Starting..."); + m_log.Info("[HGAssetService]: Starting..."); - Object[] args = new Object[] { m_Config, MainServer.Instance, string.Empty }; + + Object[] args = new Object[] { m_Config, MainServer.Instance, "HGAssetService" }; ServerUtils.LoadPlugin("OpenSim.Server.Handlers.dll:AssetServiceConnector", args); } diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs index 1a5cb7ecd1..2904ee87dc 100644 --- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs +++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs @@ -9,5 +9,6 @@ namespace OpenSim.Region.Framework.Interfaces { string GetUserName(UUID uuid); void AddUser(UUID uuid, string userData); + void AddUser(UUID uuid, string firstName, string lastName, string profileURL); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 06f8ac1ca5..2cf0ced61a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -416,6 +416,10 @@ namespace OpenSim.Region.Framework.Scenes if ((item != null) && (item.Owner == senderId)) { + IUserManagement uman = RequestModuleInterface(); + if (uman != null) + uman.AddUser(item.CreatorIdAsUuid, item.CreatorData); + if (!Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4fc2cbca5e..4d90e1b28f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2616,6 +2616,7 @@ namespace OpenSim.Region.Framework.Scenes } else m_log.DebugFormat("[SCENE]: User Client Verification for {0} {1} in {2} returned true", aCircuit.firstname, aCircuit.lastname, RegionInfo.RegionName); + } } diff --git a/OpenSim/Server/Handlers/Asset/AssetServerConnector.cs b/OpenSim/Server/Handlers/Asset/AssetServerConnector.cs index b6425f4c49..df571fa925 100644 --- a/OpenSim/Server/Handlers/Asset/AssetServerConnector.cs +++ b/OpenSim/Server/Handlers/Asset/AssetServerConnector.cs @@ -53,12 +53,15 @@ namespace OpenSim.Server.Handlers.Asset String.Empty); if (assetService == String.Empty) - throw new Exception("No AssetService in config file"); + throw new Exception("No LocalServiceModule in config file"); Object[] args = new Object[] { config }; m_AssetService = ServerUtils.LoadPlugin(assetService, args); + if (m_AssetService == null) + throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); + bool allowDelete = serverConfig.GetBoolean("AllowRemoteDelete", false); server.AddStreamHandler(new AssetServerGetHandler(m_AssetService)); diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index 22a718a354..00f035c883 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -153,7 +153,7 @@ namespace OpenSim.Server.Handlers.Asset } catch (Exception e) { - m_log.Debug("[XINVENTORY HANDLER]: Exception {0}", e); + m_log.DebugFormat("[XINVENTORY HANDLER]: Exception {0}", e); } return FailureResult(); @@ -604,6 +604,10 @@ namespace OpenSim.Server.Handlers.Asset ret["CreatorId"] = item.CreatorId.ToString(); else ret["CreatorId"] = String.Empty; + if (item.CreatorData != null) + ret["CreatorData"] = item.CreatorData; + else + ret["CreatorData"] = String.Empty; ret["CurrentPermissions"] = item.CurrentPermissions.ToString(); ret["Description"] = item.Description.ToString(); ret["EveryOnePermissions"] = item.EveryOnePermissions.ToString(); diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index 470a4ddcc5..3fd2fcf4d6 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs @@ -43,44 +43,51 @@ namespace OpenSim.Services.AssetService LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); + protected static AssetService m_RootInstance; + public AssetService(IConfigSource config) : base(config) { - MainConsole.Instance.Commands.AddCommand("kfs", false, - "show digest", - "show digest ", - "Show asset digest", HandleShowDigest); - - MainConsole.Instance.Commands.AddCommand("kfs", false, - "delete asset", - "delete asset ", - "Delete asset from database", HandleDeleteAsset); - - if (m_AssetLoader != null) + if (m_RootInstance == null) { - IConfig assetConfig = config.Configs["AssetService"]; - if (assetConfig == null) - throw new Exception("No AssetService configuration"); + m_RootInstance = this; - string loaderArgs = assetConfig.GetString("AssetLoaderArgs", - String.Empty); + MainConsole.Instance.Commands.AddCommand("kfs", false, + "show digest", + "show digest ", + "Show asset digest", HandleShowDigest); - bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true); + MainConsole.Instance.Commands.AddCommand("kfs", false, + "delete asset", + "delete asset ", + "Delete asset from database", HandleDeleteAsset); - if (assetLoaderEnabled) + if (m_AssetLoader != null) { - m_log.InfoFormat("[ASSET]: Loading default asset set from {0}", loaderArgs); - m_AssetLoader.ForEachDefaultXmlAsset(loaderArgs, - delegate(AssetBase a) - { - Store(a); - }); + IConfig assetConfig = config.Configs["AssetService"]; + if (assetConfig == null) + throw new Exception("No AssetService configuration"); + + string loaderArgs = assetConfig.GetString("AssetLoaderArgs", + String.Empty); + + bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true); + + if (assetLoaderEnabled) + { + m_log.InfoFormat("[ASSET]: Loading default asset set from {0}", loaderArgs); + m_AssetLoader.ForEachDefaultXmlAsset(loaderArgs, + delegate(AssetBase a) + { + Store(a); + }); + } + + m_log.Info("[ASSET SERVICE]: Local asset service enabled"); } - - m_log.Info("[ASSET SERVICE]: Local asset service enabled"); } } - public AssetBase Get(string id) + public virtual AssetBase Get(string id) { UUID assetID; @@ -93,12 +100,12 @@ namespace OpenSim.Services.AssetService return m_Database.GetAsset(assetID); } - public AssetBase GetCached(string id) + public virtual AssetBase GetCached(string id) { return Get(id); } - public AssetMetadata GetMetadata(string id) + public virtual AssetMetadata GetMetadata(string id) { UUID assetID; @@ -112,7 +119,7 @@ namespace OpenSim.Services.AssetService return null; } - public byte[] GetData(string id) + public virtual byte[] GetData(string id) { UUID assetID; @@ -123,7 +130,7 @@ namespace OpenSim.Services.AssetService return asset.Data; } - public bool Get(string id, Object sender, AssetRetrieved handler) + public virtual bool Get(string id, Object sender, AssetRetrieved handler) { //m_log.DebugFormat("[AssetService]: Get asset async {0}", id); @@ -141,7 +148,7 @@ namespace OpenSim.Services.AssetService return true; } - public string Store(AssetBase asset) + public virtual string Store(AssetBase asset) { //m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID); m_Database.StoreAsset(asset); @@ -154,7 +161,7 @@ namespace OpenSim.Services.AssetService return false; } - public bool Delete(string id) + public virtual bool Delete(string id) { m_log.DebugFormat("[ASSET SERVICE]: Deleting asset {0}", id); UUID assetID; diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs new file mode 100644 index 0000000000..6e0d4cd47a --- /dev/null +++ b/OpenSim/Services/HypergridService/HGAssetService.cs @@ -0,0 +1,181 @@ +/* + * 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; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Xml; + +using Nini.Config; +using log4net; +using OpenMetaverse; + +using OpenSim.Framework; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Services.AssetService; + +namespace OpenSim.Services.HypergridService +{ + public class HGAssetService : OpenSim.Services.AssetService.AssetService, IAssetService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ProfileServiceURL; + private IUserAccountService m_UserAccountService; + + private UserAccountCache m_Cache; + + public HGAssetService(IConfigSource config) : base(config) + { + m_log.Debug("[HGAsset Service]: Starting"); + IConfig assetConfig = config.Configs["HGAssetService"]; + if (assetConfig == null) + throw new Exception("No HGAssetService configuration"); + + string userAccountsDll = assetConfig.GetString("UserAccountsService", string.Empty); + if (userAccountsDll == string.Empty) + throw new Exception("Please specify UserAccountsService in HGAssetService configuration"); + + Object[] args = new Object[] { config }; + m_UserAccountService = ServerUtils.LoadPlugin(userAccountsDll, args); + if (m_UserAccountService == null) + throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); + + m_ProfileServiceURL = assetConfig.GetString("ProfileServerURI", string.Empty); + + m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); + } + + #region IAssetService overrides + public override AssetBase Get(string id) + { + AssetBase asset = base.Get(id); + + if (asset == null) + return null; + + if (asset.Metadata.Type == (sbyte)AssetType.Object) + asset.Data = AdjustIdentifiers(asset.Data); ; + + AdjustIdentifiers(asset.Metadata); + + return asset; + } + + public override AssetMetadata GetMetadata(string id) + { + AssetMetadata meta = base.GetMetadata(id); + + if (meta == null) + return null; + + AdjustIdentifiers(meta); + + return meta; + } + + public override byte[] GetData(string id) + { + byte[] data = base.GetData(id); + + if (data == null) + return null; + + return AdjustIdentifiers(data); + } + + //public virtual bool Get(string id, Object sender, AssetRetrieved handler) + + public override bool Delete(string id) + { + // NOGO + return false; + } + + #endregion + + protected void AdjustIdentifiers(AssetMetadata meta) + { + UserAccount creator = m_Cache.GetUser(meta.CreatorID); + if (creator != null) + meta.CreatorID = m_ProfileServiceURL + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName; + + } + + protected byte[] AdjustIdentifiers(byte[] data) + { + string xml = Utils.BytesToString(data); + return Utils.StringToBytes(RewriteSOP(xml)); + } + + protected string RewriteSOP(string xml) + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); + XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); + + foreach (XmlNode sop in sops) + { + UserAccount creator = null; + bool hasCreatorData = false; + XmlNodeList nodes = sop.ChildNodes; + foreach (XmlNode node in nodes) + { + if (node.Name == "CreatorID") + creator = m_Cache.GetUser(node.InnerText); + if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty) + hasCreatorData = true; + + //if (node.Name == "OwnerID") + //{ + // UserAccount owner = GetUser(node.InnerText); + // if (owner != null) + // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName; + //} + } + if (!hasCreatorData && creator != null) + { + XmlElement creatorData = doc.CreateElement("CreatorData"); + creatorData.InnerText = m_ProfileServiceURL + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName; + sop.AppendChild(creatorData); + } + } + + using (StringWriter wr = new StringWriter()) + { + doc.Save(wr); + return wr.ToString(); + } + + } + + } + +} diff --git a/OpenSim/Services/InventoryService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs similarity index 86% rename from OpenSim/Services/InventoryService/HGInventoryService.cs rename to OpenSim/Services/HypergridService/HGInventoryService.cs index d62c0089a2..a04f0c4a05 100644 --- a/OpenSim/Services/InventoryService/HGInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGInventoryService.cs @@ -33,10 +33,12 @@ using Nini.Config; using System.Reflection; using OpenSim.Services.Base; using OpenSim.Services.Interfaces; +using OpenSim.Services.InventoryService; using OpenSim.Data; using OpenSim.Framework; +using OpenSim.Server.Base; -namespace OpenSim.Services.InventoryService +namespace OpenSim.Services.HypergridService { public class HGInventoryService : XInventoryService, IInventoryService { @@ -46,9 +48,16 @@ namespace OpenSim.Services.InventoryService protected new IXInventoryData m_Database; + private string m_ProfileServiceURL; + private IUserAccountService m_UserAccountService; + + private UserAccountCache m_Cache; + public HGInventoryService(IConfigSource config) : base(config) { + m_log.Debug("[HGInventory Service]: Starting"); + string dllName = String.Empty; string connString = String.Empty; //string realm = "Inventory"; // OSG version doesn't use this @@ -68,12 +77,25 @@ namespace OpenSim.Services.InventoryService // // Try reading the [InventoryService] section, if it exists // - IConfig authConfig = config.Configs["InventoryService"]; - if (authConfig != null) + IConfig invConfig = config.Configs["HGInventoryService"]; + if (invConfig != null) { - dllName = authConfig.GetString("StorageProvider", dllName); - connString = authConfig.GetString("ConnectionString", connString); + dllName = invConfig.GetString("StorageProvider", dllName); + connString = invConfig.GetString("ConnectionString", connString); + // realm = authConfig.GetString("Realm", realm); + string userAccountsDll = invConfig.GetString("UserAccountsService", string.Empty); + if (userAccountsDll == string.Empty) + throw new Exception("Please specify UserAccountsService in HGInventoryService configuration"); + + Object[] args = new Object[] { config }; + m_UserAccountService = ServerUtils.LoadPlugin(userAccountsDll, args); + if (m_UserAccountService == null) + throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); + + m_ProfileServiceURL = invConfig.GetString("ProfileServerURI", string.Empty); + + m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); } // @@ -282,9 +304,18 @@ namespace OpenSim.Services.InventoryService //{ //} - //public InventoryItemBase GetItem(InventoryItemBase item) - //{ - //} + public override InventoryItemBase GetItem(InventoryItemBase item) + { + InventoryItemBase it = base.GetItem(item); + + UserAccount user = m_Cache.GetUser(it.CreatorId); + + // Adjust the creator data + if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) + it.CreatorData = m_ProfileServiceURL + "/" + it.CreatorId + ";" + user.FirstName + " " + user.LastName; + + return it; + } //public InventoryFolderBase GetFolder(InventoryFolderBase folder) //{ diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index fcfdd1d6d9..f806af32dc 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -762,6 +762,7 @@ namespace OpenSim.Services.LLLoginService if (account.ServiceURLs == null) return; + // Old style: get the service keys from the DB foreach (KeyValuePair kvp in account.ServiceURLs) { if (kvp.Value == null || (kvp.Value != null && kvp.Value.ToString() == string.Empty)) @@ -773,6 +774,21 @@ namespace OpenSim.Services.LLLoginService aCircuit.ServiceURLs[kvp.Key] = kvp.Value; } } + + // New style: service keys start with SRV_; override the previous + string[] keys = m_LoginServerConfig.GetKeys(); + + if (keys.Length > 0) + { + IEnumerable serviceKeys = keys.Where(value => value.StartsWith("SRV_")); + foreach (string serviceKey in serviceKeys) + { + string keyName = serviceKey.Replace("SRV_", ""); + aCircuit.ServiceURLs[keyName] = m_LoginServerConfig.GetString(serviceKey, string.Empty); + m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]); + } + } + } private bool LaunchAgentDirectly(ISimulationService simConnector, GridRegion region, AgentCircuitData aCircuit, out string reason) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index e1627c0534..dbac73b277 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -21,7 +21,7 @@ ; * [[@]/][:] ; * [Startup] -ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector" +ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,HGAssetService@8002/OpenSim.Server.Handlers.dll:AssetServiceConnector,8002/OpenSim.Server.Handlers.dll:HeloServiceInConnector" ; * This is common for all services, it's the network setup for the entire ; * server instance, if none if specified above @@ -154,10 +154,12 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; Defaults for the users, if none is specified in the useraccounts table entry (ServiceURLs) ; CHANGE THIS - HomeURI = "http://127.0.0.1:8002" - GatekeeperURI = "http://127.0.0.1:8002" - InventoryServerURI = "http://127.0.0.1:8002" - AssetServerURI = "http://127.0.0.1:8002" + GatekeeperURI = "http://127.0.0.1:8002" + + SRV_HomeURI = "http://127.0.0.1:8002" + SRV_InventoryServerURI = "http://127.0.0.1:8002" + SRV_AssetServerURI = "http://127.0.0.1:8002" + SRV_ProfileServerURI = "http://127.0.0.1:8002" [GridInfoService] ; These settings are used to return information on a get_grid_info call. @@ -169,7 +171,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; See http://opensimulator.org/wiki/GridInfo ; login uri: for grid this is the login server URI - login = http://127.0.0.1:9000/ + login = http://127.0.0.1:8002/ ; long grid name: the long name of your grid gridname = "the lost continent of hippo" @@ -183,7 +185,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; helper uri: optional: if it exists if will be used to tell the client to use ; this for all economy related things - ;economy = http://127.0.0.1:9000/ + ;economy = http://127.0.0.1:8002/ ; web page of grid: optional: page providing further information about your grid ;about = http://127.0.0.1/about/ @@ -241,4 +243,15 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; * [HGInventoryService] ; For the InventoryServiceInConnector - LocalServiceModule = "OpenSim.Services.InventoryService.dll:HGInventoryService" + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService" + UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" + ProfileServerURI = "http://127.0.0.1:8002/user" + +; * The interface that local users get when they are in other grids. +; * This restricts the access that the rest of the world has to +; * the assets of this world. +; * +[HGAssetService] + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService" + UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" + ProfileServerURI = "http://127.0.0.1:8002/user" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 1fcf043ea2..d002d49ff0 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -25,6 +25,13 @@ DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "assets/AssetSets.xml" +[HGInventoryService] + ProfileServerURI = "http://127.0.0.1:9000/profiles" + +[HGAssetService] + ProfileServerURI = "http://127.0.0.1:9000/profiles" + + [Modules] ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. ;; Copy the config .example file into your own .ini file and change configs there @@ -68,11 +75,12 @@ [LoginService] WelcomeMessage = "Welcome, Avatar!" - - HomeURI = "http://127.0.0.1:9000" GatekeeperURI = "http://127.0.0.1:9000" - InventoryServerURI = "http://127.0.0.1:9000" - AssetServerURI = "http://127.0.0.1:9000" + + SRV_HomeURI = "http://127.0.0.1:9000" + SRV_InventoryServerURI = "http://127.0.0.1:9000" + SRV_AssetServerURI = "http://127.0.0.1:9000" + SRV_ProfileServerURI = "http://127.0.0.1:9000" [GatekeeperService] ExternalName = "http://127.0.0.1:9000" diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index f164d33e1e..68aa7397fc 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -128,8 +128,14 @@ ;; This greatly restricts the inventory operations while in other grids [HGInventoryService] ; For the InventoryServiceInConnector - LocalServiceModule = "OpenSim.Services.InventoryService.dll:HGInventoryService" + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService" + UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" +;; The interface that local users get when they are in other grids +;; This restricts/filters the asset operations from the outside +[HGAssetService] + LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService" + UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" ;; This should always be the very last thing on this file [Includes] diff --git a/prebuild.xml b/prebuild.xml index 00be4f9a37..6f24bfcbed 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1257,6 +1257,8 @@ + + From 3292a2255882018b7fed3e80f430dc26892b92ea Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 26 Nov 2010 22:06:34 -0800 Subject: [PATCH 02/11] Creator information preserved upon HG transfers. --- .../InventoryAccess/HGAssetMapper.cs | 83 +++++++++++++++++-- .../HGInventoryAccessModule.cs | 12 ++- .../HypergridService/HGAssetService.cs | 1 - bin/config-include/GridCommon.ini.example | 8 ++ .../StandaloneCommon.ini.example | 2 + 5 files changed, 97 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index ccb892e1e4..81b65c5727 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs @@ -27,8 +27,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Reflection; using System.Threading; +using System.Xml; + using log4net; using OpenMetaverse; using OpenSim.Framework; @@ -52,14 +55,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // private Dictionary m_inventoryServers = new Dictionary(); private Scene m_scene; + private string m_ProfileServerURI; #endregion #region Constructor - public HGAssetMapper(Scene scene) + public HGAssetMapper(Scene scene, string profileURL) { m_scene = scene; + m_ProfileServerURI = profileURL; } #endregion @@ -95,16 +100,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess try { asset1.ID = url + "/" + asset.ID; -// UUID temp = UUID.Zero; - // TODO: if the creator is local, stick this grid's URL in front - //if (UUID.TryParse(asset.Metadata.CreatorID, out temp)) - // asset1.Metadata.CreatorID = ??? + "/" + asset.Metadata.CreatorID; } catch { m_log.Warn("[HG ASSET MAPPER]: Oops."); } + AdjustIdentifiers(asset1.Metadata); + if (asset1.Metadata.Type == (sbyte)AssetType.Object) + asset1.Data = AdjustIdentifiers(asset.Data); + else + asset1.Data = asset.Data; + m_scene.AssetService.Store(asset1); m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); } @@ -118,7 +125,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess private void Copy(AssetBase from, AssetBase to) { - to.Data = from.Data; + //to.Data = from.Data; // don't copy this, it's copied elsewhere to.Description = from.Description; to.FullID = from.FullID; to.ID = from.ID; @@ -129,6 +136,70 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } + private void AdjustIdentifiers(AssetMetadata meta) + { + if (meta.CreatorID != null && meta.CreatorID != string.Empty) + { + UUID uuid = UUID.Zero; + UUID.TryParse(meta.CreatorID, out uuid); + UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); + if (creator != null) + meta.CreatorID = m_ProfileServerURI + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName; + } + } + + protected byte[] AdjustIdentifiers(byte[] data) + { + string xml = Utils.BytesToString(data); + return Utils.StringToBytes(RewriteSOP(xml)); + } + + protected string RewriteSOP(string xml) + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); + XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); + + foreach (XmlNode sop in sops) + { + UserAccount creator = null; + bool hasCreatorData = false; + XmlNodeList nodes = sop.ChildNodes; + foreach (XmlNode node in nodes) + { + if (node.Name == "CreatorID") + { + UUID uuid = UUID.Zero; + UUID.TryParse(node.InnerText, out uuid); + creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); + } + if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty) + hasCreatorData = true; + + //if (node.Name == "OwnerID") + //{ + // UserAccount owner = GetUser(node.InnerText); + // if (owner != null) + // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName; + //} + } + + if (!hasCreatorData && creator != null) + { + XmlElement creatorData = doc.CreateElement("CreatorData"); + creatorData.InnerText = m_ProfileServerURI + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName; + sop.AppendChild(creatorData); + } + } + + using (StringWriter wr = new StringWriter()) + { + doc.Save(wr); + return wr.ToString(); + } + + } + // TODO: unused // private void Dump(Dictionary lst) // { diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 125a397d0e..34b811428d 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -54,6 +54,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess get { return m_assMapper; } } + private string m_ProfileServerURI; + // private bool m_Initialized = false; #region INonSharedRegionModule @@ -73,6 +75,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { m_Enabled = true; m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name); + + IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; + if (thisModuleConfig != null) + m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); + else + m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); } } } @@ -83,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return; base.AddRegion(scene); - m_assMapper = new HGAssetMapper(scene); + m_assMapper = new HGAssetMapper(scene, m_ProfileServerURI); scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; } @@ -97,7 +105,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess string userAssetServer = string.Empty; if (IsForeignUser(avatarID, out userAssetServer)) { - m_assMapper.Post(assetID, avatarID, userAssetServer); + Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); }); } } diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs index 6e0d4cd47a..9b098a0859 100644 --- a/OpenSim/Services/HypergridService/HGAssetService.cs +++ b/OpenSim/Services/HypergridService/HGAssetService.cs @@ -126,7 +126,6 @@ namespace OpenSim.Services.HypergridService UserAccount creator = m_Cache.GetUser(meta.CreatorID); if (creator != null) meta.CreatorID = m_ProfileServiceURL + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName; - } protected byte[] AdjustIdentifiers(byte[] data) diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index cb771b8d52..762b09a30e 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -78,6 +78,14 @@ ; FriendsServerURI = "http://mygridserver.com:8003" +[HGInventoryAccessModule] + ; + ; === HG ONLY === + ; Change this to your profile server + ; accessible from other grids + ; + ProfileServerURI = "http://mygridserver.com:8002/profiles" + [Modules] ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. ;; Copy the config .example file into your own .ini file and change configs there diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index d002d49ff0..58059f52a1 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -31,6 +31,8 @@ [HGAssetService] ProfileServerURI = "http://127.0.0.1:9000/profiles" +[HGInventoryAccessModule] + ProfileServerURI = "http://127.0.0.1:9000/profiles" [Modules] ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. From ca8d0157333823b549c7ae36b40ea3c05045fc25 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 27 Nov 2010 11:40:54 -0800 Subject: [PATCH 03/11] Changed the parser for InventoryItem deserialization. Moved some utility functions around. --- .../External/UserInventoryItemSerializer.cs | 198 +++++++++++++++--- OpenSim/Framework/Util.cs | 61 ++++++ .../Serialization/SceneObjectSerializer.cs | 122 +++-------- 3 files changed, 260 insertions(+), 121 deletions(-) diff --git a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs index 862cc72f84..df9af329c7 100644 --- a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs +++ b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs @@ -26,9 +26,13 @@ */ using System; +using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Text; using System.Xml; + +using log4net; using OpenMetaverse; using OpenSim.Framework; @@ -40,6 +44,133 @@ namespace OpenSim.Framework.Serialization.External /// XXX: Please do not use yet. public class UserInventoryItemSerializer { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private delegate void InventoryItemXmlProcessor(InventoryItemBase item, XmlTextReader reader); + private static Dictionary m_InventoryItemXmlProcessors = new Dictionary(); + + #region InventoryItemBase Processor initialization + static UserInventoryItemSerializer() + { + m_InventoryItemXmlProcessors.Add("Name", ProcessName); + m_InventoryItemXmlProcessors.Add("ID", ProcessID); + m_InventoryItemXmlProcessors.Add("InvType", ProcessInvType); + m_InventoryItemXmlProcessors.Add("CreatorUUID", ProcessCreatorUUID); + m_InventoryItemXmlProcessors.Add("CreationDate", ProcessCreationDate); + m_InventoryItemXmlProcessors.Add("Owner", ProcessOwner); + m_InventoryItemXmlProcessors.Add("Description", ProcessDescription); + m_InventoryItemXmlProcessors.Add("AssetType", ProcessAssetType); + m_InventoryItemXmlProcessors.Add("AssetID", ProcessAssetID); + m_InventoryItemXmlProcessors.Add("SaleType", ProcessSaleType); + m_InventoryItemXmlProcessors.Add("SalePrice", ProcessSalePrice); + m_InventoryItemXmlProcessors.Add("BasePermissions", ProcessBasePermissions); + m_InventoryItemXmlProcessors.Add("CurrentPermissions", ProcessCurrentPermissions); + m_InventoryItemXmlProcessors.Add("EveryOnePermissions", ProcessEveryOnePermissions); + m_InventoryItemXmlProcessors.Add("NextPermissions", ProcessNextPermissions); + m_InventoryItemXmlProcessors.Add("Flags", ProcessFlags); + m_InventoryItemXmlProcessors.Add("GroupID", ProcessGroupID); + m_InventoryItemXmlProcessors.Add("GroupOwned", ProcessGroupOwned); + } + #endregion + + #region InventoryItemBase Processors + private static void ProcessName(InventoryItemBase item, XmlTextReader reader) + { + item.Name = reader.ReadElementContentAsString("Name", String.Empty); + } + + private static void ProcessID(InventoryItemBase item, XmlTextReader reader) + { + item.ID = Util.ReadUUID(reader, "ID"); + } + + private static void ProcessInvType(InventoryItemBase item, XmlTextReader reader) + { + item.InvType = reader.ReadElementContentAsInt("InvType", String.Empty); + } + + private static void ProcessCreatorUUID(InventoryItemBase item, XmlTextReader reader) + { + item.CreatorId = reader.ReadElementContentAsString("CreatorUUID", String.Empty); + } + + private static void ProcessCreationDate(InventoryItemBase item, XmlTextReader reader) + { + item.CreationDate = reader.ReadElementContentAsInt("CreationDate", String.Empty); + } + + private static void ProcessOwner(InventoryItemBase item, XmlTextReader reader) + { + item.Owner = Util.ReadUUID(reader, "Owner"); + } + + private static void ProcessDescription(InventoryItemBase item, XmlTextReader reader) + { + item.Description = reader.ReadElementContentAsString("Description", String.Empty); + } + + private static void ProcessAssetType(InventoryItemBase item, XmlTextReader reader) + { + item.AssetType = reader.ReadElementContentAsInt("AssetType", String.Empty); + } + + private static void ProcessAssetID(InventoryItemBase item, XmlTextReader reader) + { + item.AssetID = Util.ReadUUID(reader, "AssetID"); + } + + private static void ProcessSaleType(InventoryItemBase item, XmlTextReader reader) + { + item.SaleType = (byte)reader.ReadElementContentAsInt("SaleType", String.Empty); + } + + private static void ProcessSalePrice(InventoryItemBase item, XmlTextReader reader) + { + item.SalePrice = reader.ReadElementContentAsInt("SalePrice", String.Empty); + } + + private static void ProcessBasePermissions(InventoryItemBase item, XmlTextReader reader) + { + item.BasePermissions = (uint)reader.ReadElementContentAsInt("BasePermissions", String.Empty); + } + + private static void ProcessCurrentPermissions(InventoryItemBase item, XmlTextReader reader) + { + item.CurrentPermissions = (uint)reader.ReadElementContentAsInt("CurrentPermissions", String.Empty); + } + + private static void ProcessEveryOnePermissions(InventoryItemBase item, XmlTextReader reader) + { + item.EveryOnePermissions = (uint)reader.ReadElementContentAsInt("EveryOnePermissions", String.Empty); + } + + private static void ProcessNextPermissions(InventoryItemBase item, XmlTextReader reader) + { + item.NextPermissions = (uint)reader.ReadElementContentAsInt("NextPermissions", String.Empty); + } + + private static void ProcessFlags(InventoryItemBase item, XmlTextReader reader) + { + item.Flags = (uint)reader.ReadElementContentAsInt("Flags", String.Empty); + } + + private static void ProcessGroupID(InventoryItemBase item, XmlTextReader reader) + { + item.GroupID = Util.ReadUUID(reader, "GroupID"); + } + + private static void ProcessGroupOwned(InventoryItemBase item, XmlTextReader reader) + { + //item.GroupOwned = reader.ReadElementContentAsBoolean("GroupOwned", String.Empty); + // We don't do that, because ReadElementContentAsBoolean assumes lower case strings, + // and they may not be lower case + reader.ReadStartElement(); // GroupOwned + item.GroupOwned = Boolean.Parse(reader.ReadContentAsString().ToLower()); + reader.ReadEndElement(); + } + + #endregion + /// /// Deserialize item /// @@ -60,37 +191,44 @@ namespace OpenSim.Framework.Serialization.External public static InventoryItemBase Deserialize(string serialization) { InventoryItemBase item = new InventoryItemBase(); - - StringReader sr = new StringReader(serialization); - XmlTextReader xtr = new XmlTextReader(sr); - - xtr.ReadStartElement("InventoryItem"); - - item.Name = xtr.ReadElementString("Name"); - item.ID = UUID.Parse( xtr.ReadElementString("ID")); - item.InvType = Convert.ToInt32( xtr.ReadElementString("InvType")); - item.CreatorId = xtr.ReadElementString("CreatorUUID"); - item.CreationDate = Convert.ToInt32( xtr.ReadElementString("CreationDate")); - item.Owner = UUID.Parse( xtr.ReadElementString("Owner")); - item.Description = xtr.ReadElementString("Description"); - item.AssetType = Convert.ToInt32( xtr.ReadElementString("AssetType")); - item.AssetID = UUID.Parse( xtr.ReadElementString("AssetID")); - item.SaleType = Convert.ToByte( xtr.ReadElementString("SaleType")); - item.SalePrice = Convert.ToInt32( xtr.ReadElementString("SalePrice")); - item.BasePermissions = Convert.ToUInt32( xtr.ReadElementString("BasePermissions")); - item.CurrentPermissions = Convert.ToUInt32( xtr.ReadElementString("CurrentPermissions")); - item.EveryOnePermissions = Convert.ToUInt32( xtr.ReadElementString("EveryOnePermissions")); - item.NextPermissions = Convert.ToUInt32( xtr.ReadElementString("NextPermissions")); - item.Flags = Convert.ToUInt32( xtr.ReadElementString("Flags")); - item.GroupID = UUID.Parse( xtr.ReadElementString("GroupID")); - item.GroupOwned = Convert.ToBoolean(xtr.ReadElementString("GroupOwned")); - - xtr.ReadEndElement(); - - xtr.Close(); - sr.Close(); - + + using (XmlTextReader reader = new XmlTextReader(new StringReader(serialization))) + { + reader.ReadStartElement("InventoryItem"); + + string nodeName = string.Empty; + while (reader.NodeType != XmlNodeType.EndElement) + { + nodeName = reader.Name; + InventoryItemXmlProcessor p = null; + if (m_InventoryItemXmlProcessors.TryGetValue(reader.Name, out p)) + { + //m_log.DebugFormat("[XXX] Processing: {0}", reader.Name); + try + { + p(item, reader); + } + catch (Exception e) + { + m_log.DebugFormat("[InventoryItemSerializer]: exception while parsing {0}: {1}", nodeName, e); + if (reader.NodeType == XmlNodeType.EndElement) + reader.Read(); + } + } + else + { + // m_log.DebugFormat("[InventoryItemSerializer]: caught unknown element {0}", nodeName); + reader.ReadOuterXml(); // ignore + } + + } + + reader.ReadEndElement(); // InventoryItem + } + + //m_log.DebugFormat("[XXX]: parsed InventoryItemBase {0} - {1}", obj.Name, obj.UUID); return item; + } public static string Serialize(InventoryItemBase inventoryItem) diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index e8f8e012de..101ece4044 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1558,5 +1558,66 @@ namespace OpenSim.Framework return string.Empty; } + public static UUID ReadUUID(XmlTextReader reader, string name) + { + UUID id; + string idStr; + + reader.ReadStartElement(name); + + if (reader.Name == "Guid") + idStr = reader.ReadElementString("Guid"); + else if (reader.Name == "UUID") + idStr = reader.ReadElementString("UUID"); + else // no leading tag + idStr = reader.ReadContentAsString(); + UUID.TryParse(idStr, out id); + reader.ReadEndElement(); + + return id; + } + + public static Vector3 ReadVector(XmlTextReader reader, string name) + { + Vector3 vec; + + reader.ReadStartElement(name); + vec.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // X or x + vec.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Y or y + vec.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Z or z + reader.ReadEndElement(); + + return vec; + } + + public static Quaternion ReadQuaternion(XmlTextReader reader, string name) + { + Quaternion quat = new Quaternion(); + + reader.ReadStartElement(name); + while (reader.NodeType != XmlNodeType.EndElement) + { + switch (reader.Name.ToLower()) + { + case "x": + quat.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty); + break; + case "y": + quat.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty); + break; + case "z": + quat.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty); + break; + case "w": + quat.W = reader.ReadElementContentAsFloat(reader.Name, String.Empty); + break; + } + } + + reader.ReadEndElement(); + + return quat; + } + } } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 9cf5a39bf7..da25e80b02 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -414,7 +414,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader) { - obj.CreatorID = ReadUUID(reader, "CreatorID"); + obj.CreatorID = Util.ReadUUID(reader, "CreatorID"); } private static void ProcessCreatorData(SceneObjectPart obj, XmlTextReader reader) @@ -424,7 +424,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessFolderID(SceneObjectPart obj, XmlTextReader reader) { - obj.FolderID = ReadUUID(reader, "FolderID"); + obj.FolderID = Util.ReadUUID(reader, "FolderID"); } private static void ProcessInventorySerial(SceneObjectPart obj, XmlTextReader reader) @@ -439,7 +439,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessUUID(SceneObjectPart obj, XmlTextReader reader) { - obj.UUID = ReadUUID(reader, "UUID"); + obj.UUID = Util.ReadUUID(reader, "UUID"); } private static void ProcessLocalId(SceneObjectPart obj, XmlTextReader reader) @@ -474,32 +474,32 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessGroupPosition(SceneObjectPart obj, XmlTextReader reader) { - obj.GroupPosition = ReadVector(reader, "GroupPosition"); + obj.GroupPosition = Util.ReadVector(reader, "GroupPosition"); } private static void ProcessOffsetPosition(SceneObjectPart obj, XmlTextReader reader) { - obj.OffsetPosition = ReadVector(reader, "OffsetPosition"); ; + obj.OffsetPosition = Util.ReadVector(reader, "OffsetPosition"); ; } private static void ProcessRotationOffset(SceneObjectPart obj, XmlTextReader reader) { - obj.RotationOffset = ReadQuaternion(reader, "RotationOffset"); + obj.RotationOffset = Util.ReadQuaternion(reader, "RotationOffset"); } private static void ProcessVelocity(SceneObjectPart obj, XmlTextReader reader) { - obj.Velocity = ReadVector(reader, "Velocity"); + obj.Velocity = Util.ReadVector(reader, "Velocity"); } private static void ProcessAngularVelocity(SceneObjectPart obj, XmlTextReader reader) { - obj.AngularVelocity = ReadVector(reader, "AngularVelocity"); + obj.AngularVelocity = Util.ReadVector(reader, "AngularVelocity"); } private static void ProcessAcceleration(SceneObjectPart obj, XmlTextReader reader) { - obj.Acceleration = ReadVector(reader, "Acceleration"); + obj.Acceleration = Util.ReadVector(reader, "Acceleration"); } private static void ProcessDescription(SceneObjectPart obj, XmlTextReader reader) @@ -553,7 +553,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader) { - obj.Scale = ReadVector(reader, "Scale"); + obj.Scale = Util.ReadVector(reader, "Scale"); } private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader) @@ -563,22 +563,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessSitTargetOrientation(SceneObjectPart obj, XmlTextReader reader) { - obj.SitTargetOrientation = ReadQuaternion(reader, "SitTargetOrientation"); + obj.SitTargetOrientation = Util.ReadQuaternion(reader, "SitTargetOrientation"); } private static void ProcessSitTargetPosition(SceneObjectPart obj, XmlTextReader reader) { - obj.SitTargetPosition = ReadVector(reader, "SitTargetPosition"); + obj.SitTargetPosition = Util.ReadVector(reader, "SitTargetPosition"); } private static void ProcessSitTargetPositionLL(SceneObjectPart obj, XmlTextReader reader) { - obj.SitTargetPositionLL = ReadVector(reader, "SitTargetPositionLL"); + obj.SitTargetPositionLL = Util.ReadVector(reader, "SitTargetPositionLL"); } private static void ProcessSitTargetOrientationLL(SceneObjectPart obj, XmlTextReader reader) { - obj.SitTargetOrientationLL = ReadQuaternion(reader, "SitTargetOrientationLL"); + obj.SitTargetOrientationLL = Util.ReadQuaternion(reader, "SitTargetOrientationLL"); } private static void ProcessParentID(SceneObjectPart obj, XmlTextReader reader) @@ -614,17 +614,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessGroupID(SceneObjectPart obj, XmlTextReader reader) { - obj.GroupID = ReadUUID(reader, "GroupID"); + obj.GroupID = Util.ReadUUID(reader, "GroupID"); } private static void ProcessOwnerID(SceneObjectPart obj, XmlTextReader reader) { - obj.OwnerID = ReadUUID(reader, "OwnerID"); + obj.OwnerID = Util.ReadUUID(reader, "OwnerID"); } private static void ProcessLastOwnerID(SceneObjectPart obj, XmlTextReader reader) { - obj.LastOwnerID = ReadUUID(reader, "LastOwnerID"); + obj.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID"); } private static void ProcessBaseMask(SceneObjectPart obj, XmlTextReader reader) @@ -663,7 +663,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessCollisionSound(SceneObjectPart obj, XmlTextReader reader) { - obj.CollisionSound = ReadUUID(reader, "CollisionSound"); + obj.CollisionSound = Util.ReadUUID(reader, "CollisionSound"); } private static void ProcessCollisionSoundVolume(SceneObjectPart obj, XmlTextReader reader) @@ -690,7 +690,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization #region TaskInventoryXmlProcessors private static void ProcessTIAssetID(TaskInventoryItem item, XmlTextReader reader) { - item.AssetID = ReadUUID(reader, "AssetID"); + item.AssetID = Util.ReadUUID(reader, "AssetID"); } private static void ProcessTIBasePermissions(TaskInventoryItem item, XmlTextReader reader) @@ -705,7 +705,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessTICreatorID(TaskInventoryItem item, XmlTextReader reader) { - item.CreatorID = ReadUUID(reader, "CreatorID"); + item.CreatorID = Util.ReadUUID(reader, "CreatorID"); } private static void ProcessTICreatorData(TaskInventoryItem item, XmlTextReader reader) @@ -730,7 +730,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessTIGroupID(TaskInventoryItem item, XmlTextReader reader) { - item.GroupID = ReadUUID(reader, "GroupID"); + item.GroupID = Util.ReadUUID(reader, "GroupID"); } private static void ProcessTIGroupPermissions(TaskInventoryItem item, XmlTextReader reader) @@ -745,20 +745,20 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessTIItemID(TaskInventoryItem item, XmlTextReader reader) { - item.ItemID = ReadUUID(reader, "ItemID"); + item.ItemID = Util.ReadUUID(reader, "ItemID"); } private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader) { - ReadUUID(reader, "OldItemID"); + Util.ReadUUID(reader, "OldItemID"); // On deserialization, the old item id MUST BE UUID.Zero!!!!! // Setting this to the saved value will BREAK script persistence! - // item.OldItemID = ReadUUID(reader, "OldItemID"); + // item.OldItemID = Util.ReadUUID(reader, "OldItemID"); } private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader) { - item.LastOwnerID = ReadUUID(reader, "LastOwnerID"); + item.LastOwnerID = Util.ReadUUID(reader, "LastOwnerID"); } private static void ProcessTIName(TaskInventoryItem item, XmlTextReader reader) @@ -773,7 +773,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessTIOwnerID(TaskInventoryItem item, XmlTextReader reader) { - item.OwnerID = ReadUUID(reader, "OwnerID"); + item.OwnerID = Util.ReadUUID(reader, "OwnerID"); } private static void ProcessTICurrentPermissions(TaskInventoryItem item, XmlTextReader reader) @@ -783,17 +783,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessTIParentID(TaskInventoryItem item, XmlTextReader reader) { - item.ParentID = ReadUUID(reader, "ParentID"); + item.ParentID = Util.ReadUUID(reader, "ParentID"); } private static void ProcessTIParentPartID(TaskInventoryItem item, XmlTextReader reader) { - item.ParentPartID = ReadUUID(reader, "ParentPartID"); + item.ParentPartID = Util.ReadUUID(reader, "ParentPartID"); } private static void ProcessTIPermsGranter(TaskInventoryItem item, XmlTextReader reader) { - item.PermsGranter = ReadUUID(reader, "PermsGranter"); + item.PermsGranter = Util.ReadUUID(reader, "PermsGranter"); } private static void ProcessTIPermsMask(TaskInventoryItem item, XmlTextReader reader) @@ -922,7 +922,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessShpScale(PrimitiveBaseShape shp, XmlTextReader reader) { - shp.Scale = ReadVector(reader, "Scale"); + shp.Scale = Util.ReadVector(reader, "Scale"); } private static void ProcessShpState(PrimitiveBaseShape shp, XmlTextReader reader) @@ -950,7 +950,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessShpSculptTexture(PrimitiveBaseShape shp, XmlTextReader reader) { - shp.SculptTexture = ReadUUID(reader, "SculptTexture"); + shp.SculptTexture = Util.ReadUUID(reader, "SculptTexture"); } private static void ProcessShpSculptType(PrimitiveBaseShape shp, XmlTextReader reader) @@ -1459,66 +1459,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization return obj; } - static UUID ReadUUID(XmlTextReader reader, string name) - { - UUID id; - string idStr; - - reader.ReadStartElement(name); - - if (reader.Name == "Guid") - idStr = reader.ReadElementString("Guid"); - else // UUID - idStr = reader.ReadElementString("UUID"); - - UUID.TryParse(idStr, out id); - reader.ReadEndElement(); - - return id; - } - - static Vector3 ReadVector(XmlTextReader reader, string name) - { - Vector3 vec; - - reader.ReadStartElement(name); - vec.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // X or x - vec.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Y or y - vec.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty); // Z or z - reader.ReadEndElement(); - - return vec; - } - - static Quaternion ReadQuaternion(XmlTextReader reader, string name) - { - Quaternion quat = new Quaternion(); - - reader.ReadStartElement(name); - while (reader.NodeType != XmlNodeType.EndElement) - { - switch (reader.Name.ToLower()) - { - case "x": - quat.X = reader.ReadElementContentAsFloat(reader.Name, String.Empty); - break; - case "y": - quat.Y = reader.ReadElementContentAsFloat(reader.Name, String.Empty); - break; - case "z": - quat.Z = reader.ReadElementContentAsFloat(reader.Name, String.Empty); - break; - case "w": - quat.W = reader.ReadElementContentAsFloat(reader.Name, String.Empty); - break; - } - } - - reader.ReadEndElement(); - - return quat; - } - static TaskInventoryDictionary ReadTaskInventory(XmlTextReader reader, string name) { TaskInventoryDictionary tinv = new TaskInventoryDictionary(); From 04ce7de5ed54b0586c3287b6c848dadfb507b132 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 29 Nov 2010 01:15:02 +0000 Subject: [PATCH 04/11] Fix the build break --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 0b51bf0b43..e9c545308c 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -364,7 +364,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice try { //m_log.DebugFormat("[FreeSwitchVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", - request, path, param); + // request, path, param); //XmlElement resp; string agentname = "x" + Convert.ToBase64String(agentID.GetBytes()); @@ -446,7 +446,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); //m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", - scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); + // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); // TODO: EstateSettings don't seem to get propagated... // if (!scene.RegionInfo.EstateSettings.AllowVoice) @@ -697,7 +697,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice } //m_log.DebugFormat("[FreeSwitchVoice]: AUTH, URI: {0}, Content-Type:{1}, Body{2}", uri, contenttype, - requestbody); + // requestbody); Hashtable response = new Hashtable(); response["str_response_string"] = string.Format(@" From f86c438653fc3c8356a8f0c43a055b1928183f02 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 29 Nov 2010 08:43:33 -0800 Subject: [PATCH 05/11] Preservation of creator information now also working in IARs. Cleaned up usage help. Moved Osp around, deleted unnecessary OspInventoryWrapperPlugin, added manipulation of SOP's xml representation in a generic ExternalRepresentationUtils function. --- .../Osp/OspInventoryWrapperPlugin.cs | 104 ----------------- .../External/ExternalRepresentationUtils.cs | 87 +++++++++++++++ .../External}/OspResolver.cs | 2 +- .../External/UserInventoryItemSerializer.cs | 39 +++++-- OpenSim/Framework/Util.cs | 20 ++++ OpenSim/Region/Application/OpenSim.cs | 6 +- .../Archiver/InventoryArchiveReadRequest.cs | 11 +- .../Archiver/InventoryArchiveWriteRequest.cs | 28 +++-- .../Archiver/InventoryArchiverModule.cs | 54 +++++++-- .../Archiver/Tests/InventoryArchiverTests.cs | 5 +- .../InventoryAccess/InventoryAccessModule.cs | 10 +- .../ArchiveWriteRequestPreparation.cs | 11 +- .../World/Archiver/AssetsRequest.cs | 26 ++++- .../Serialization/SceneObjectSerializer.cs | 42 ++----- .../HypergridService/HGAssetService.cs | 44 +------- .../HypergridService/UserAccountCache.cs | 105 ++++++++++++++++++ prebuild.xml | 59 +++++----- 17 files changed, 390 insertions(+), 263 deletions(-) delete mode 100644 OpenSim/Framework/Communications/Osp/OspInventoryWrapperPlugin.cs create mode 100644 OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs rename OpenSim/Framework/{Communications/Osp => Serialization/External}/OspResolver.cs (99%) create mode 100644 OpenSim/Services/HypergridService/UserAccountCache.cs diff --git a/OpenSim/Framework/Communications/Osp/OspInventoryWrapperPlugin.cs b/OpenSim/Framework/Communications/Osp/OspInventoryWrapperPlugin.cs deleted file mode 100644 index bcd1eee05c..0000000000 --- a/OpenSim/Framework/Communications/Osp/OspInventoryWrapperPlugin.cs +++ /dev/null @@ -1,104 +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 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 OpenSim.Data; -using OpenMetaverse; -using OpenSim.Services.Interfaces; - -namespace OpenSim.Framework.Communications.Osp -{ - /// - /// Wrap other inventory data plugins so that we can perform OSP related post processing for items - /// - public class OspInventoryWrapperPlugin : IInventoryDataPlugin - { - protected IInventoryDataPlugin m_wrappedPlugin; - //protected CommunicationsManager m_commsManager; - protected IUserAccountService m_userAccountService; - - public OspInventoryWrapperPlugin(IInventoryDataPlugin wrappedPlugin, IUserAccountService userService) - { - m_wrappedPlugin = wrappedPlugin; - m_userAccountService = userService; - } - - public string Name { get { return "OspInventoryWrapperPlugin"; } } - public string Version { get { return "0.1"; } } - public void Initialise() {} - public void Initialise(string connect) {} - public void Dispose() {} - - public InventoryItemBase getInventoryItem(UUID item) - { - return PostProcessItem(m_wrappedPlugin.getInventoryItem(item)); - } - - // XXX: Why on earth does this exist as it appears to duplicate getInventoryItem? - public InventoryItemBase queryInventoryItem(UUID item) - { - return PostProcessItem(m_wrappedPlugin.queryInventoryItem(item)); - } - - public List getInventoryInFolder(UUID folderID) - { - List items = m_wrappedPlugin.getInventoryInFolder(folderID); - - foreach (InventoryItemBase item in items) - PostProcessItem(item); - - return items; - } - - public List fetchActiveGestures(UUID avatarID) - { - return m_wrappedPlugin.fetchActiveGestures(avatarID); - - // Presuming that no post processing is needed here as gestures don't refer to creator information (?) - } - - protected InventoryItemBase PostProcessItem(InventoryItemBase item) - { - item.CreatorIdAsUuid = OspResolver.ResolveOspa(item.CreatorId, m_userAccountService); - return item; - } - - public List getFolderHierarchy(UUID parentID) { return m_wrappedPlugin.getFolderHierarchy(parentID); } - public List getUserRootFolders(UUID user) { return m_wrappedPlugin.getUserRootFolders(user); } - public InventoryFolderBase getUserRootFolder(UUID user) { return m_wrappedPlugin.getUserRootFolder(user); } - public List getInventoryFolders(UUID parentID) { return m_wrappedPlugin.getInventoryFolders(parentID); } - public InventoryFolderBase getInventoryFolder(UUID folder) { return m_wrappedPlugin.getInventoryFolder(folder); } - public void addInventoryItem(InventoryItemBase item) { m_wrappedPlugin.addInventoryItem(item); } - public void updateInventoryItem(InventoryItemBase item) { m_wrappedPlugin.updateInventoryItem(item); } - public void deleteInventoryItem(UUID item) { m_wrappedPlugin.deleteInventoryItem(item); } - public InventoryFolderBase queryInventoryFolder(UUID folder) { return m_wrappedPlugin.queryInventoryFolder(folder); } - public void addInventoryFolder(InventoryFolderBase folder) { m_wrappedPlugin.addInventoryFolder(folder); } - public void updateInventoryFolder(InventoryFolderBase folder) { m_wrappedPlugin.updateInventoryFolder(folder); } - public void moveInventoryFolder(InventoryFolderBase folder) { m_wrappedPlugin.moveInventoryFolder(folder); } - public void deleteInventoryFolder(UUID folder) { m_wrappedPlugin.deleteInventoryFolder(folder); } - } -} diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs new file mode 100644 index 0000000000..5c0630cf7b --- /dev/null +++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs @@ -0,0 +1,87 @@ +/* + * 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; +using System.Collections.Generic; +using System.IO; +using System.Xml; + +using OpenMetaverse; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Framework.Serialization.External +{ + public class ExternalRepresentationUtils + { + public static string RewriteSOP(string xml, string profileURL, IUserAccountService userService, UUID scopeID) + { + if (xml == string.Empty || profileURL == string.Empty || userService == null) + return xml; + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); + XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); + + foreach (XmlNode sop in sops) + { + UserAccount creator = null; + bool hasCreatorData = false; + XmlNodeList nodes = sop.ChildNodes; + foreach (XmlNode node in nodes) + { + if (node.Name == "CreatorID") + { + UUID uuid = UUID.Zero; + UUID.TryParse(node.InnerText, out uuid); + creator = userService.GetUserAccount(scopeID, uuid); + } + if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty) + hasCreatorData = true; + + //if (node.Name == "OwnerID") + //{ + // UserAccount owner = GetUser(node.InnerText); + // if (owner != null) + // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName; + //} + } + if (!hasCreatorData && creator != null) + { + XmlElement creatorData = doc.CreateElement("CreatorData"); + creatorData.InnerText = profileURL + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName; + sop.AppendChild(creatorData); + } + } + + using (StringWriter wr = new StringWriter()) + { + doc.Save(wr); + return wr.ToString(); + } + + } + } +} diff --git a/OpenSim/Framework/Communications/Osp/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs similarity index 99% rename from OpenSim/Framework/Communications/Osp/OspResolver.cs rename to OpenSim/Framework/Serialization/External/OspResolver.cs index 24ea64d87f..53c35ffb6f 100644 --- a/OpenSim/Framework/Communications/Osp/OspResolver.cs +++ b/OpenSim/Framework/Serialization/External/OspResolver.cs @@ -32,7 +32,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Services.Interfaces; -namespace OpenSim.Framework.Communications.Osp +namespace OpenSim.Framework.Serialization { /// /// Resolves OpenSim Profile Anchors (OSPA). An OSPA is a string used to provide information for diff --git a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs index df9af329c7..d5e84c779e 100644 --- a/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs +++ b/OpenSim/Framework/Serialization/External/UserInventoryItemSerializer.cs @@ -35,6 +35,7 @@ using System.Xml; using log4net; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Services.Interfaces; namespace OpenSim.Framework.Serialization.External { @@ -56,6 +57,8 @@ namespace OpenSim.Framework.Serialization.External m_InventoryItemXmlProcessors.Add("ID", ProcessID); m_InventoryItemXmlProcessors.Add("InvType", ProcessInvType); m_InventoryItemXmlProcessors.Add("CreatorUUID", ProcessCreatorUUID); + m_InventoryItemXmlProcessors.Add("CreatorID", ProcessCreatorID); + m_InventoryItemXmlProcessors.Add("CreatorData", ProcessCreatorData); m_InventoryItemXmlProcessors.Add("CreationDate", ProcessCreationDate); m_InventoryItemXmlProcessors.Add("Owner", ProcessOwner); m_InventoryItemXmlProcessors.Add("Description", ProcessDescription); @@ -94,6 +97,12 @@ namespace OpenSim.Framework.Serialization.External item.CreatorId = reader.ReadElementContentAsString("CreatorUUID", String.Empty); } + private static void ProcessCreatorID(InventoryItemBase item, XmlTextReader reader) + { + // when it exists, this overrides the previous + item.CreatorId = reader.ReadElementContentAsString("CreatorID", String.Empty); + } + private static void ProcessCreationDate(InventoryItemBase item, XmlTextReader reader) { item.CreationDate = reader.ReadElementContentAsInt("CreationDate", String.Empty); @@ -161,12 +170,12 @@ namespace OpenSim.Framework.Serialization.External private static void ProcessGroupOwned(InventoryItemBase item, XmlTextReader reader) { - //item.GroupOwned = reader.ReadElementContentAsBoolean("GroupOwned", String.Empty); - // We don't do that, because ReadElementContentAsBoolean assumes lower case strings, - // and they may not be lower case - reader.ReadStartElement(); // GroupOwned - item.GroupOwned = Boolean.Parse(reader.ReadContentAsString().ToLower()); - reader.ReadEndElement(); + item.GroupOwned = Util.ReadBoolean(reader); + } + + private static void ProcessCreatorData(InventoryItemBase item, XmlTextReader reader) + { + item.CreatorData = reader.ReadElementContentAsString("CreatorData", String.Empty); } #endregion @@ -231,7 +240,7 @@ namespace OpenSim.Framework.Serialization.External } - public static string Serialize(InventoryItemBase inventoryItem) + public static string Serialize(InventoryItemBase inventoryItem, Dictionary options, IUserAccountService userAccountService) { StringWriter sw = new StringWriter(); XmlTextWriter writer = new XmlTextWriter(sw); @@ -250,7 +259,7 @@ namespace OpenSim.Framework.Serialization.External writer.WriteString(inventoryItem.InvType.ToString()); writer.WriteEndElement(); writer.WriteStartElement("CreatorUUID"); - writer.WriteString(inventoryItem.CreatorId); + writer.WriteString(OspResolver.MakeOspa(inventoryItem.CreatorIdAsUuid, userAccountService)); writer.WriteEndElement(); writer.WriteStartElement("CreationDate"); writer.WriteString(inventoryItem.CreationDate.ToString()); @@ -294,6 +303,20 @@ namespace OpenSim.Framework.Serialization.External writer.WriteStartElement("GroupOwned"); writer.WriteString(inventoryItem.GroupOwned.ToString()); writer.WriteEndElement(); + if (inventoryItem.CreatorData != null && inventoryItem.CreatorData != string.Empty) + writer.WriteElementString("CreatorData", inventoryItem.CreatorData); + else if (options.ContainsKey("profile")) + { + if (userAccountService != null) + { + UserAccount account = userAccountService.GetUserAccount(UUID.Zero, inventoryItem.CreatorIdAsUuid); + if (account != null) + { + writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + inventoryItem.CreatorIdAsUuid + ";" + account.FirstName + " " + account.LastName); + } + writer.WriteElementString("CreatorID", inventoryItem.CreatorId); + } + } writer.WriteEndElement(); diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 101ece4044..8d1671a885 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1558,6 +1558,16 @@ namespace OpenSim.Framework return string.Empty; } + #region Xml Serialization Utilities + public static bool ReadBoolean(XmlTextReader reader) + { + reader.ReadStartElement(); + bool result = Boolean.Parse(reader.ReadContentAsString().ToLower()); + reader.ReadEndElement(); + + return result; + } + public static UUID ReadUUID(XmlTextReader reader, string name) { UUID id; @@ -1619,5 +1629,15 @@ namespace OpenSim.Framework return quat; } + public static T ReadEnum(XmlTextReader reader, string name) + { + string value = reader.ReadElementContentAsString(name, String.Empty); + // !!!!! to deal with flags without commas + if (value.Contains(" ") && !value.Contains(",")) + value = value.Replace(" ", ", "); + + return (T)Enum.Parse(typeof(T), value); ; + } + #endregion } } diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 6127c2d6c7..ae2d836a94 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -265,10 +265,10 @@ namespace OpenSim LoadOar); m_console.Commands.AddCommand("region", false, "save oar", - "save oar [-v|--version=N] [-p|--profile=url] []", + "save oar [-v|--version=] [-p|--profile=] []", "Save a region's data to an OAR archive.", - "-v|--version=N generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine - + "-p|--profile=url adds the url of the profile service to the saved user information" + Environment.NewLine + "-v|--version= generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine + + "-p|--profile= adds the url of the profile service to the saved user information" + Environment.NewLine + "The OAR path must be a filesystem path." + " If this is not given then the oar is saved to region.oar in the current directory.", SaveOar); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 046b05f48e..870ead21e9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -37,12 +37,11 @@ using System.Xml.Linq; using log4net; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Osp; using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; using OpenSim.Region.CoreModules.World.Archiver; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver @@ -398,16 +397,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // Don't use the item ID that's in the file item.ID = UUID.Random(); - UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); - if (UUID.Zero != ospResolvedId) + UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); + if (UUID.Zero != ospResolvedId) // The user exists in this grid { item.CreatorIdAsUuid = ospResolvedId; // XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the // database). Instead, replace with the UUID that we found. item.CreatorId = ospResolvedId.ToString(); + + item.CreatorData = string.Empty; } - else + else if (item.CreatorData == null || item.CreatorData == String.Empty) { item.CreatorIdAsUuid = m_userInfo.PrincipalID; } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index d81703a827..cab341dbff 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -36,8 +36,6 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; -using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Osp; using OpenSim.Region.CoreModules.World.Archiver; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; @@ -139,20 +137,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); } - protected void SaveInvItem(InventoryItemBase inventoryItem, string path) + protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary options, IUserAccountService userAccountService) { string filename = path + CreateArchiveItemName(inventoryItem); // Record the creator of this item for user record purposes (which might go away soon) m_userUuids[inventoryItem.CreatorIdAsUuid] = 1; - InventoryItemBase saveItem = (InventoryItemBase)inventoryItem.Clone(); - saveItem.CreatorId = OspResolver.MakeOspa(saveItem.CreatorIdAsUuid, m_scene.UserAccountService); - - string serialization = UserInventoryItemSerializer.Serialize(saveItem); + string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); m_archiveWriter.WriteFile(filename, serialization); - m_assetGatherer.GatherAssetUuids(saveItem.AssetID, (AssetType)saveItem.AssetType, m_assetUuids); + m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); } /// @@ -161,7 +156,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// The inventory folder to save /// The path to which the folder should be saved /// If true, save this folder itself. If false, only saves contents - protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself) + protected void SaveInvFolder(InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, Dictionary options, IUserAccountService userAccountService) { if (saveThisFolderItself) { @@ -176,19 +171,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver foreach (InventoryFolderBase childFolder in contents.Folders) { - SaveInvFolder(childFolder, path, true); + SaveInvFolder(childFolder, path, true, options, userAccountService); } foreach (InventoryItemBase item in contents.Items) { - SaveInvItem(item, path); + SaveInvItem(item, path, options, userAccountService); } } /// /// Execute the inventory write request /// - public void Execute() + public void Execute(Dictionary options, IUserAccountService userAccountService) { try { @@ -266,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); //recurse through all dirs getting dirs and files - SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly); + SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService); } else if (inventoryItem != null) { @@ -274,14 +269,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", inventoryItem.Name, inventoryItem.ID, m_invPath); - SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH); + SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService); } // Don't put all this profile information into the archive right now. //SaveUsers(); new AssetsRequest( - new AssetsArchiver(m_archiveWriter), m_assetUuids, m_scene.AssetService, ReceivedAllAssets).Execute(); + new AssetsArchiver(m_archiveWriter), + m_assetUuids, m_scene.AssetService, + m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, + options, ReceivedAllAssets).Execute(); } catch (Exception) { diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 2eaca499b0..421ea30869 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -75,6 +75,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver private Dictionary m_scenes = new Dictionary(); private Scene m_aScene; + private IUserAccountService m_UserAccountService; + protected IUserAccountService UserAccountService + { + get + { + if (m_UserAccountService == null) + // What a strange thing to do... + foreach (Scene s in m_scenes.Values) + { + m_UserAccountService = s.RequestModuleInterface(); + break; + } + + return m_UserAccountService; + } + } + + public InventoryArchiverModule() {} public InventoryArchiverModule(bool disablePresenceChecks) @@ -106,11 +124,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver scene.AddCommand( this, "save iar", - "save iar []", + "save iar [--p|-profile=] []", "Save user inventory archive (IAR).", " is the user's first name." + Environment.NewLine + " is the user's last name." + Environment.NewLine + " is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine + + "-p|--profile= adds the url of the profile service to the saved user information." + Environment.NewLine + " is the filesystem path at which to save the IAR." + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), HandleSaveInvConsoleCommand); @@ -157,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { try { - new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(); + new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(options, UserAccountService); } catch (EntryPointNotFoundException e) { @@ -197,7 +216,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { try { - new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(); + new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(options, UserAccountService); } catch (EntryPointNotFoundException e) { @@ -368,10 +387,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) { Guid id = Guid.NewGuid(); - + + Dictionary options = new Dictionary(); + + OptionSet ops = new OptionSet(); + //ops.Add("v|version=", delegate(string v) { options["version"] = v; }); + ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); + + List mainParams = ops.Parse(cmdparams); + try { - if (cmdparams.Length < 6) + if (mainParams.Count < 6) { m_log.Error( "[INVENTORY ARCHIVER]: usage is save iar []"); @@ -379,18 +406,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); - - string firstName = cmdparams[2]; - string lastName = cmdparams[3]; - string invPath = cmdparams[4]; - string pass = cmdparams[5]; - string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME); + if (options.ContainsKey("profile")) + m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -profile option if you want to produce a compatible IAR"); + + string firstName = mainParams[2]; + string lastName = mainParams[3]; + string invPath = mainParams[4]; + string pass = mainParams[5]; + string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); m_log.InfoFormat( "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", savePath, invPath, firstName, lastName); - ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary()); + ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); } catch (InventoryArchiverException e) { @@ -518,5 +547,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return false; } + } } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 938886b2d3..1e39c398db 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -38,7 +38,6 @@ using OpenSim.Framework; using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Osp; using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.Framework.Scenes; @@ -103,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests string item1FileName = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); - tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1)); + tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary(), null)); tar.Close(); m_iarStream = new MemoryStream(archiveWriteStream.ToArray()); } @@ -551,7 +550,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests string item1FileName = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); - tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1)); + tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary(), null)); tar.Close(); MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 1ff1a47f00..1ebccd1af1 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -799,9 +799,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID) { IInventoryService invService = m_Scene.RequestModuleInterface(); - InventoryItemBase assetRequestItem = new InventoryItemBase(itemID, agentID); - assetRequestItem = invService.GetItem(assetRequestItem); - return assetRequestItem; + InventoryItemBase item = new InventoryItemBase(itemID, agentID); + item = invService.GetItem(item); + + if (item.CreatorData != null && item.CreatorData != string.Empty) + UserManagementModule.AddUser(item.CreatorIdAsUuid, item.CreatorData); + + return item; } #endregion diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index b987b5ac82..0699407d12 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -190,7 +190,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver new AssetsRequest( new AssetsArchiver(archiveWriter), assetUuids, - m_scene.AssetService, awre.ReceivedAllAssets).Execute(); + m_scene.AssetService, m_scene.UserAccountService, + m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute(); } catch (Exception) { @@ -238,10 +239,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver } m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion); - if (majorVersion == 1) - { - m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); - } + //if (majorVersion == 1) + //{ + // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); + //} StringWriter sw = new StringWriter(); XmlTextWriter xtw = new XmlTextWriter(sw); diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index d4a09b45f7..5da165666d 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs @@ -34,6 +34,7 @@ using log4net; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Serialization; +using OpenSim.Framework.Serialization.External; using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.World.Archiver @@ -100,17 +101,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// Asset service used to request the assets /// protected IAssetService m_assetService; + protected IUserAccountService m_userAccountService; + protected UUID m_scopeID; // the grid ID protected AssetsArchiver m_assetsArchiver; + protected Dictionary m_options; + protected internal AssetsRequest( AssetsArchiver assetsArchiver, IDictionary uuids, - IAssetService assetService, AssetsRequestCallback assetsRequestCallback) + IAssetService assetService, IUserAccountService userService, + UUID scope, Dictionary options, + AssetsRequestCallback assetsRequestCallback) { m_assetsArchiver = assetsArchiver; m_uuids = uuids; m_assetsRequestCallback = assetsRequestCallback; m_assetService = assetService; + m_userAccountService = userService; + m_scopeID = scope; + m_options = options; m_repliesRequired = uuids.Count; m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT); @@ -241,7 +251,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver { // m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id); m_foundAssetUuids.Add(asset.FullID); - m_assetsArchiver.WriteAsset(asset); + + m_assetsArchiver.WriteAsset(PostProcess(asset)); } else { @@ -288,5 +299,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver "[ARCHIVER]: Terminating archive creation since asset requster callback failed with {0}", e); } } + + protected AssetBase PostProcess(AssetBase asset) + { + if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("profile")) + { + //m_log.DebugFormat("[ARCHIVER]: Rewriting object data for {0}", asset.ID); + string xml = ExternalRepresentationUtils.RewriteSOP(Utils.BytesToString(asset.Data), m_options["profile"].ToString(), m_userAccountService, m_scopeID); + asset.Data = Utils.StringToBytes(xml); + } + return asset; + } } } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index da25e80b02..6c9826fcf0 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -409,7 +409,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization #region SOPXmlProcessors private static void ProcessAllowedDrop(SceneObjectPart obj, XmlTextReader reader) { - obj.AllowedDrop = reader.ReadElementContentAsBoolean("AllowedDrop", String.Empty); + obj.AllowedDrop = Util.ReadBoolean(reader); } private static void ProcessCreatorID(SceneObjectPart obj, XmlTextReader reader) @@ -459,7 +459,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessPassTouches(SceneObjectPart obj, XmlTextReader reader) { - obj.PassTouches = reader.ReadElementContentAsBoolean("PassTouches", String.Empty); + obj.PassTouches = Util.ReadBoolean(reader); } private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader) @@ -654,11 +654,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessFlags(SceneObjectPart obj, XmlTextReader reader) { - string value = reader.ReadElementContentAsString("Flags", String.Empty); - // !!!!! to deal with flags without commas - if (value.Contains(" ") && !value.Contains(",")) - value = value.Replace(" ", ", "); - obj.Flags = (PrimFlags)Enum.Parse(typeof(PrimFlags), value); + obj.Flags = Util.ReadEnum(reader, "Flags"); } private static void ProcessCollisionSound(SceneObjectPart obj, XmlTextReader reader) @@ -808,7 +804,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessTIOwnerChanged(TaskInventoryItem item, XmlTextReader reader) { - item.OwnerChanged = reader.ReadElementContentAsBoolean("OwnerChanged", String.Empty); + item.OwnerChanged = Util.ReadBoolean(reader); } #endregion @@ -932,20 +928,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessShpProfileShape(PrimitiveBaseShape shp, XmlTextReader reader) { - string value = reader.ReadElementContentAsString("ProfileShape", String.Empty); - // !!!!! to deal with flags without commas - if (value.Contains(" ") && !value.Contains(",")) - value = value.Replace(" ", ", "); - shp.ProfileShape = (ProfileShape)Enum.Parse(typeof(ProfileShape), value); + shp.ProfileShape = Util.ReadEnum(reader, "ProfileShape"); } private static void ProcessShpHollowShape(PrimitiveBaseShape shp, XmlTextReader reader) { - string value = reader.ReadElementContentAsString("HollowShape", String.Empty); - // !!!!! to deal with flags without commas - if (value.Contains(" ") && !value.Contains(",")) - value = value.Replace(" ", ", "); - shp.HollowShape = (HollowShape)Enum.Parse(typeof(HollowShape), value); + shp.HollowShape = Util.ReadEnum(reader, "HollowShape"); } private static void ProcessShpSculptTexture(PrimitiveBaseShape shp, XmlTextReader reader) @@ -1045,17 +1033,17 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessShpFlexiEntry(PrimitiveBaseShape shp, XmlTextReader reader) { - shp.FlexiEntry = reader.ReadElementContentAsBoolean("FlexiEntry", String.Empty); + shp.FlexiEntry = Util.ReadBoolean(reader); } private static void ProcessShpLightEntry(PrimitiveBaseShape shp, XmlTextReader reader) { - shp.LightEntry = reader.ReadElementContentAsBoolean("LightEntry", String.Empty); + shp.LightEntry = Util.ReadBoolean(reader); } private static void ProcessShpSculptEntry(PrimitiveBaseShape shp, XmlTextReader reader) { - shp.SculptEntry = reader.ReadElementContentAsBoolean("SculptEntry", String.Empty); + shp.SculptEntry = Util.ReadBoolean(reader); } private static void ProcessShpMedia(PrimitiveBaseShape shp, XmlTextReader reader) @@ -1220,16 +1208,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization static void WriteFlags(XmlTextWriter writer, string name, string flagsStr, Dictionary options) { - // Older versions of serialization can't cope with commas - if (options.ContainsKey("version")) - { - float version = 0.5F; - float.TryParse(options["version"].ToString(), out version); - if (version < 0.5) - flagsStr = flagsStr.Replace(",", ""); - } - - writer.WriteElementString(name, flagsStr); + // Older versions of serialization can't cope with commas, so we eliminate the commas + writer.WriteElementString(name, flagsStr.Replace(",", "")); } static void WriteTaskInventory(XmlTextWriter writer, TaskInventoryDictionary tinv, Dictionary options, Scene scene) diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs index 9b098a0859..584ab6fdb3 100644 --- a/OpenSim/Services/HypergridService/HGAssetService.cs +++ b/OpenSim/Services/HypergridService/HGAssetService.cs @@ -35,6 +35,7 @@ using log4net; using OpenMetaverse; using OpenSim.Framework; +using OpenSim.Framework.Serialization.External; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using OpenSim.Services.AssetService; @@ -131,48 +132,7 @@ namespace OpenSim.Services.HypergridService protected byte[] AdjustIdentifiers(byte[] data) { string xml = Utils.BytesToString(data); - return Utils.StringToBytes(RewriteSOP(xml)); - } - - protected string RewriteSOP(string xml) - { - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); - XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); - - foreach (XmlNode sop in sops) - { - UserAccount creator = null; - bool hasCreatorData = false; - XmlNodeList nodes = sop.ChildNodes; - foreach (XmlNode node in nodes) - { - if (node.Name == "CreatorID") - creator = m_Cache.GetUser(node.InnerText); - if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty) - hasCreatorData = true; - - //if (node.Name == "OwnerID") - //{ - // UserAccount owner = GetUser(node.InnerText); - // if (owner != null) - // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName; - //} - } - if (!hasCreatorData && creator != null) - { - XmlElement creatorData = doc.CreateElement("CreatorData"); - creatorData.InnerText = m_ProfileServiceURL + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName; - sop.AppendChild(creatorData); - } - } - - using (StringWriter wr = new StringWriter()) - { - doc.Save(wr); - return wr.ToString(); - } - + return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, m_ProfileServiceURL, m_Cache, UUID.Zero)); } } diff --git a/OpenSim/Services/HypergridService/UserAccountCache.cs b/OpenSim/Services/HypergridService/UserAccountCache.cs new file mode 100644 index 0000000000..3e9aea10eb --- /dev/null +++ b/OpenSim/Services/HypergridService/UserAccountCache.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +using log4net; +using OpenMetaverse; + +using OpenSim.Services.Interfaces; + +namespace OpenSim.Services.HypergridService +{ + public class UserAccountCache : IUserAccountService + { + private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours! + + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + private ExpiringCache m_UUIDCache; + + private IUserAccountService m_UserAccountService; + + private static UserAccountCache m_Singleton; + + public static UserAccountCache CreateUserAccountCache(IUserAccountService u) + { + if (m_Singleton == null) + m_Singleton = new UserAccountCache(u); + + return m_Singleton; + } + + private UserAccountCache(IUserAccountService u) + { + m_UUIDCache = new ExpiringCache(); + m_UserAccountService = u; + } + + public void Cache(UUID userID, UserAccount account) + { + // Cache even null accounts + m_UUIDCache.AddOrUpdate(userID, account, CACHE_EXPIRATION_SECONDS); + + //m_log.DebugFormat("[USER CACHE]: cached user {0}", userID); + } + + public UserAccount Get(UUID userID, out bool inCache) + { + UserAccount account = null; + inCache = false; + if (m_UUIDCache.TryGetValue(userID, out account)) + { + //m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName); + inCache = true; + return account; + } + + return null; + } + + public UserAccount GetUser(string id) + { + UUID uuid = UUID.Zero; + UUID.TryParse(id, out uuid); + bool inCache = false; + UserAccount account = Get(uuid, out inCache); + if (!inCache) + { + account = m_UserAccountService.GetUserAccount(UUID.Zero, uuid); + Cache(uuid, account); + } + + return account; + } + + #region IUserAccountService + public UserAccount GetUserAccount(UUID scopeID, UUID userID) + { + return GetUser(userID.ToString()); + } + + public UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName) + { + return null; + } + + public UserAccount GetUserAccount(UUID scopeID, string Email) + { + return null; + } + + public List GetUserAccounts(UUID scopeID, string query) + { + return null; + } + + public bool StoreUserAccount(UserAccount data) + { + return false; + } + #endregion + + } + +} diff --git a/prebuild.xml b/prebuild.xml index 6f24bfcbed..9f2ef432d0 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -175,6 +175,34 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + @@ -194,6 +222,7 @@ + @@ -631,35 +660,6 @@ - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - - @@ -1253,6 +1253,7 @@ + From 49b59fffee54bb7aa7db2382ba564c99368945d4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 29 Nov 2010 09:57:41 -0800 Subject: [PATCH 06/11] Fix unit test. --- .../Framework/Serialization/External/OspResolver.cs | 6 ++++++ .../Archiver/InventoryArchiveReadRequest.cs | 2 +- .../Inventory/Archiver/InventoryArchiverModule.cs | 10 +++++++--- .../Archiver/Tests/InventoryArchiverTests.cs | 13 ++++++++----- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/OpenSim/Framework/Serialization/External/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs index 53c35ffb6f..7e3dd1b79b 100644 --- a/OpenSim/Framework/Serialization/External/OspResolver.cs +++ b/OpenSim/Framework/Serialization/External/OspResolver.cs @@ -57,6 +57,12 @@ namespace OpenSim.Framework.Serialization /// The OSPA. Null if a user with the given UUID could not be found. public static string MakeOspa(UUID userId, IUserAccountService userService) { + if (userService == null) + { + m_log.Warn("[OSP RESOLVER]: UserService is null"); + return userId.ToString(); + } + UserAccount account = userService.GetUserAccount(UUID.Zero, userId); if (account != null) return MakeOspa(account.FirstName, account.LastName); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 870ead21e9..acf2c3ef97 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -412,7 +412,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { item.CreatorIdAsUuid = m_userInfo.PrincipalID; } - + item.Owner = m_userInfo.PrincipalID; // Reset folder ID to the one in which we want to load it diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 421ea30869..b33c2b1af5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -254,14 +254,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (m_scenes.Count > 0) { UserAccount userInfo = GetUserInfo(firstName, lastName, pass); - + if (userInfo != null) { if (CheckPresence(userInfo.PrincipalID)) { + InventoryArchiveReadRequest request; bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); - + try { request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge); @@ -275,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver return false; } - + UpdateClientWithLoadedNodes(userInfo, request.Execute()); return true; @@ -287,6 +288,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver userInfo.FirstName, userInfo.LastName, userInfo.PrincipalID); } } + else + m_log.ErrorFormat("[INVENTORY ARCHIVER]: User {0} {1} not found", + firstName, lastName); } return false; diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index 1e39c398db..2747e157be 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -95,14 +95,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests item1.Name = m_item1Name; item1.AssetID = UUID.Random(); item1.GroupID = UUID.Random(); - item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName); + //item1.CreatorId = OspResolver.MakeOspa(m_ua2.FirstName, m_ua2.LastName); //item1.CreatorId = userUuid.ToString(); - //item1.CreatorId = "00000000-0000-0000-0000-000000000444"; + item1.CreatorId = m_ua2.PrincipalID.ToString(); item1.Owner = UUID.Zero; - + + Scene scene = SceneSetupHelpers.SetupScene("Inventory"); + UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire"); + string item1FileName = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItemName); - tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary(), null)); + tar.WriteFile(item1FileName, UserInventoryItemSerializer.Serialize(item1, new Dictionary(), scene.UserAccountService)); tar.Close(); m_iarStream = new MemoryStream(archiveWriteStream.ToArray()); } @@ -385,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Scene scene = SceneSetupHelpers.SetupScene("inventory"); SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); - + UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood"); UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire"); From 7d24dbca3c85cafe182648139ab132563e3e1cdd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 1 Dec 2010 16:01:22 -0800 Subject: [PATCH 07/11] Added some comments. Better than listening to the boring speaker... --- .../External/ExternalRepresentationUtils.cs | 12 ++++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 ++++- OpenSim/Services/HypergridService/HGAssetService.cs | 5 +++++ .../Services/HypergridService/HGInventoryService.cs | 7 +++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs index 5c0630cf7b..6e8c2ee173 100644 --- a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs +++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs @@ -34,8 +34,20 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Framework.Serialization.External { + /// + /// Utilities for manipulating external representations of data structures in OpenSim + /// public class ExternalRepresentationUtils { + /// + /// Takes a XML representation of a SceneObjectPart and returns another XML representation + /// with creator data added to it. + /// + /// The SceneObjectPart represented in XML2 + /// The URL of the profile service for the creator + /// The service for retrieving user account information + /// The scope of the user account information (Grid ID) + /// The SceneObjectPart represented in XML2 public static string RewriteSOP(string xml, string profileURL, IUserAccountService userService, UUID scopeID) { if (xml == string.Empty || profileURL == string.Empty || userService == null) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ba592c4afa..f87056e48e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -449,7 +449,10 @@ namespace OpenSim.Region.Framework.Scenes } } - public string CreatorData // = ; + /// + /// Data about the creator in the form profile_url;name + /// + public string CreatorData { get { return m_creatorData; } set { m_creatorData = value; } diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs index 584ab6fdb3..a82d0d191f 100644 --- a/OpenSim/Services/HypergridService/HGAssetService.cs +++ b/OpenSim/Services/HypergridService/HGAssetService.cs @@ -42,6 +42,11 @@ using OpenSim.Services.AssetService; namespace OpenSim.Services.HypergridService { + /// + /// Hypergrid asset service. It serves the IAssetService interface, + /// but implements it in ways that are appropriate for inter-grid + /// asset exchanges. + /// public class HGAssetService : OpenSim.Services.AssetService.AssetService, IAssetService { private static readonly ILog m_log = diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs index a04f0c4a05..9ee1ae4c5f 100644 --- a/OpenSim/Services/HypergridService/HGInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGInventoryService.cs @@ -40,6 +40,13 @@ using OpenSim.Server.Base; namespace OpenSim.Services.HypergridService { + /// + /// Hypergrid inventory service. It serves the IInventoryService interface, + /// but implements it in ways that are appropriate for inter-grid + /// inventory exchanges. Specifically, it does not performs deletions + /// and it responds to GetRootFolder requests with the ID of the + /// Suitcase folder, not the actual "My Inventory" folder. + /// public class HGInventoryService : XInventoryService, IInventoryService { private static readonly ILog m_log = From f1a7847532f822728e1320cc51fa1bc25c37356b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 1 Dec 2010 16:19:27 -0800 Subject: [PATCH 08/11] Deleted obsolete config files from old OpenSim.Grid. --- bin/OpenSim.Grid.GridServer.addin.xml | 9 ------- bin/OpenSim.Grid.GridServer.exe.config | 28 --------------------- bin/OpenSim.Grid.MessagingServer.exe.config | 28 --------------------- bin/OpenSim.Grid.ScriptServer.exe.config | 28 --------------------- bin/OpenSim.Grid.UserServer.exe.config | 28 --------------------- 5 files changed, 121 deletions(-) delete mode 100644 bin/OpenSim.Grid.GridServer.addin.xml delete mode 100644 bin/OpenSim.Grid.GridServer.exe.config delete mode 100644 bin/OpenSim.Grid.MessagingServer.exe.config delete mode 100644 bin/OpenSim.Grid.ScriptServer.exe.config delete mode 100644 bin/OpenSim.Grid.UserServer.exe.config diff --git a/bin/OpenSim.Grid.GridServer.addin.xml b/bin/OpenSim.Grid.GridServer.addin.xml deleted file mode 100644 index 85742a16d2..0000000000 --- a/bin/OpenSim.Grid.GridServer.addin.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/bin/OpenSim.Grid.GridServer.exe.config b/bin/OpenSim.Grid.GridServer.exe.config deleted file mode 100644 index efc486f137..0000000000 --- a/bin/OpenSim.Grid.GridServer.exe.config +++ /dev/null @@ -1,28 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Grid.MessagingServer.exe.config b/bin/OpenSim.Grid.MessagingServer.exe.config deleted file mode 100644 index 481ce4b978..0000000000 --- a/bin/OpenSim.Grid.MessagingServer.exe.config +++ /dev/null @@ -1,28 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Grid.ScriptServer.exe.config b/bin/OpenSim.Grid.ScriptServer.exe.config deleted file mode 100644 index 5cae2b00eb..0000000000 --- a/bin/OpenSim.Grid.ScriptServer.exe.config +++ /dev/null @@ -1,28 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenSim.Grid.UserServer.exe.config b/bin/OpenSim.Grid.UserServer.exe.config deleted file mode 100644 index 315e69d6d1..0000000000 --- a/bin/OpenSim.Grid.UserServer.exe.config +++ /dev/null @@ -1,28 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - From 26569a7cd02a03ea41e8febc69e659b670a9e031 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 1 Dec 2010 22:23:42 +0000 Subject: [PATCH 09/11] minor: add some method doc --- .../Region/ClientStack/LindenUDP/LLUDPClient.cs | 8 ++++++++ .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index c4db5da2da..5bf36e6f1d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -399,6 +399,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP return data; } + /// + /// Queue an outgoing packet if appropriate. + /// + /// + /// + /// true if the packet has been queued, + /// false if the packet has not been queued and should be sent immediately. + /// public bool EnqueueOutgoing(OutgoingPacket packet) { int category = (int)packet.Category; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index b5d8ec8dc5..ff4abf8997 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -312,6 +312,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + /// + /// Start the process of sending a packet to the client. + /// + /// + /// + /// + /// public void SendPacket(LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting) { // CoarseLocationUpdate packets cannot be split in an automated way @@ -339,6 +346,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + /// + /// Start the process of sending a packet to the client. + /// + /// + /// + /// + /// public void SendPacketData(LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category) { int dataLength = data.Length; From 5246d98b8df3cc613a199851c3ac33ec753f522a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 2 Dec 2010 01:55:49 +0000 Subject: [PATCH 10/11] Stop LLUDPServer sending updates after object deletes by always queueing deletes If an LL 1.23.5 client (and possibly earlier and later) receives an object update after a kill object packet, it leaves the deleted prim in the scene until client relog This is possible in LLUDPServer if an object update packet is queued but a kill packet sent immediately. Beyond invasive tracking of kill sending, most expedient solution is to always queue kills, so that they always arrive after updates. In tests, this doesn't appear to affect performance. There is probably still an issue present where an update packet might not be acked and then resent after the kill packet. --- .../ClientStack/LindenUDP/LLClientView.cs | 32 +++++++++++-------- .../ClientStack/LindenUDP/LLUDPClient.cs | 7 ++-- .../ClientStack/LindenUDP/LLUDPServer.cs | 8 +++-- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 7851c4d5ad..f125822604 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3562,24 +3562,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP EntityUpdate update; while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) { - // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client - // will never receive an update after a prim kill. Even then, keeping the kill record may be a good - // safety measure. - // - // Receiving updates after kills results in undeleteable prims that persist until relog and - // currently occurs because prims can be deleted before all queued updates are sent. - if (m_killRecord.Contains(update.Entity.LocalId)) - { -// m_log.WarnFormat( -// "[CLIENT]: Preventing full update for prim with local id {0} after client for user {1} told it was deleted", -// update.Entity.LocalId, Name); - continue; - } - if (update.Entity is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart)update.Entity; + // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client + // will never receive an update after a prim kill. Even then, keeping the kill record may be a good + // safety measure. + // + // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update + // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs + // updates and kills on different threads with different scheduling strategies, hence this protection. + // + // This doesn't appear to apply to child prims - a client will happily ignore these updates + // after the root prim has been deleted. + if (m_killRecord.Contains(part.LocalId)) + { + // m_log.WarnFormat( + // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", + // part.LocalId, Name); + continue; + } + if (part.ParentGroup.IsAttachment && m_disableFacelights) { if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 5bf36e6f1d..e02783ad4d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -403,11 +403,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Queue an outgoing packet if appropriate. ///
/// + /// Always queue the packet if at all possible. /// /// true if the packet has been queued, /// false if the packet has not been queued and should be sent immediately. /// - public bool EnqueueOutgoing(OutgoingPacket packet) + public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue) { int category = (int)packet.Category; @@ -416,14 +417,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP OpenSim.Framework.LocklessQueue queue = m_packetOutboxes[category]; TokenBucket bucket = m_throttleCategories[category]; - if (bucket.RemoveTokens(packet.Buffer.DataLength)) + if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength)) { // Enough tokens were removed from the bucket, the packet will not be queued return false; } else { - // Not enough tokens in the bucket, queue this packet + // Force queue specified or not enough tokens in the bucket, queue this packet queue.Enqueue(packet); return true; } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index ff4abf8997..e54cfc21ea 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -410,7 +410,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); - if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) + // If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will + // continue to display the deleted object until relog. Therefore, we need to always queue a kill object + // packet so that it isn't sent before a queued update packet. + bool requestQueue = type == PacketType.KillObject; + if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue)) SendPacketFinal(outgoingPacket); #endregion Queue or Send @@ -503,7 +507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //Interlocked.Increment(ref Stats.ResentPackets); // Requeue or resend the packet - if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) + if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false)) SendPacketFinal(outgoingPacket); } } From 7e72afcb3e9d5467ad4dd2e6ba5d1e0632d77877 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 3 Dec 2010 00:08:58 +0000 Subject: [PATCH 11/11] Only force prim persistence before delete if the prim is the result of an unpersisted delink This considerably improves delete performance for objects with large linksets --- OpenSim/Region/Framework/Scenes/Scene.cs | 11 +++++++---- .../Region/Framework/Scenes/SceneObjectGroup.cs | 15 +++++++++++++-- .../Scenes/Tests/SceneObjectLinkingTests.cs | 8 ++++++-- bin/OpenSim.exe.config | 2 ++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 90223b134f..66c6924bcc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1997,7 +1997,7 @@ namespace OpenSim.Region.Framework.Scenes /// Object Id /// Suppress broadcasting changes to other clients. public void DeleteSceneObject(SceneObjectGroup group, bool silent) - { + { // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); //SceneObjectPart rootPart = group.GetChildPart(group.UUID); @@ -2038,7 +2038,7 @@ namespace OpenSim.Region.Framework.Scenes group.DeleteGroupFromScene(silent); -// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); +// m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); } /// @@ -2057,9 +2057,12 @@ namespace OpenSim.Region.Framework.Scenes // Force a database update so that the scene object group ID is accurate. It's possible that the // group has recently been delinked from another group but that this change has not been persisted // to the DB. - ForceSceneObjectBackup(so); + // This is an expensive thing to do so only do it if absolutely necessary. + if (so.HasGroupChangedDueToDelink) + ForceSceneObjectBackup(so); + so.DetachFromBackup(); - SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID); + SimulationDataService.RemoveObject(so.UUID, m_regInfo.RegionID); } // We need to keep track of this state in case this group is still queued for further backup. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 4ec530e1de..f17fb28f8d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -119,10 +119,19 @@ namespace OpenSim.Region.Framework.Scenes timeFirstChanged = DateTime.Now.Ticks; } m_hasGroupChanged = value; + +// m_log.DebugFormat( +// "[SCENE OBJECT GROUP]: HasGroupChanged set to {0} for {1} {2}", m_hasGroupChanged, Name, LocalId); } get { return m_hasGroupChanged; } } + + /// + /// Has the group changed due to an unlink operation? We record this in order to optimize deletion, since + /// an unlinked group currently has to be persisted to the database before we can perform an unlink operation. + /// + public bool HasGroupChangedDueToDelink { get; private set; } private bool isTimeToPersist() { @@ -1330,6 +1339,7 @@ namespace OpenSim.Region.Framework.Scenes backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; backup_group.RootPart.ParticleSystem = RootPart.ParticleSystem; HasGroupChanged = false; + HasGroupChangedDueToDelink = false; m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this); datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); @@ -2208,8 +2218,9 @@ namespace OpenSim.Region.Framework.Scenes linkPart.Rezzed = RootPart.Rezzed; - //HasGroupChanged = true; - //ScheduleGroupForFullUpdate(); + // When we delete a group, we currently have to force persist to the database if the object id has changed + // (since delete works by deleting all rows which have a given object id) + objectGroup.HasGroupChangedDueToDelink = true; return objectGroup; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index f57cf98b37..b84298f2fa 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -121,13 +121,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests "Not exactly sure what this is asserting..."); // Delink part 2 - grp1.DelinkFromGroup(part2.LocalId); + SceneObjectGroup grp3 = grp1.DelinkFromGroup(part2.LocalId); if (debugtest) m_log.Debug("Group2: Prim2: OffsetPosition:" + part2.AbsolutePosition + ", OffsetRotation:" + part2.RotationOffset); Assert.That(grp1.Parts.Length, Is.EqualTo(1), "Group 1 still contained part2 after delink."); Assert.That(part2.AbsolutePosition == Vector3.Zero, "The absolute position should be zero"); + Assert.That(grp3.HasGroupChangedDueToDelink, Is.True); } [Test] @@ -325,7 +326,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectGroup sog = new SceneObjectGroup(rootPart); sog.AddPart(linkPart); - scene.AddNewSceneObject(sog, true); + scene.AddNewSceneObject(sog, true); // In a test, we have to crank the backup handle manually. Normally this would be done by the timer invoked // scene backup thread. @@ -333,7 +334,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests // These changes should occur immediately without waiting for a backup pass SceneObjectGroup groupToDelete = sog.DelinkFromGroup(linkPart, false); + + Assert.That(groupToDelete.HasGroupChangedDueToDelink, Is.True); scene.DeleteSceneObject(groupToDelete, false); + Assert.That(groupToDelete.HasGroupChangedDueToDelink, Is.False); List storedObjects = scene.SimulationDataService.LoadObjects(scene.RegionInfo.RegionID); diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index 3c7adf5419..eece04092f 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -13,6 +13,8 @@ + +