From 2ac00b7f96b01cf9494d2a5fef9a84443301a04c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 26 Apr 2010 14:52:22 -0700 Subject: [PATCH 01/27] * Commenting SQLiteNG out of prebuild.xml, because it's making compile fail in Windows. Justin: you forgot to add Mono.Sqlite.dll, and I can't figure out where to grab it from! * IRegionModule.cs wants to be committed too -- EOF. --- OpenSim/Region/Framework/Interfaces/IRegionModule.cs | 4 ++-- prebuild.xml | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IRegionModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionModule.cs index 8365fe300e..e25a6e86dd 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionModule.cs @@ -30,8 +30,8 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Interfaces { - /// - /// DEPRECATED! Use INonSharedRegionModule or ISharedRegionModule instead + /// + /// DEPRECATED! Use INonSharedRegionModule or ISharedRegionModule instead /// public interface IRegionModule { diff --git a/prebuild.xml b/prebuild.xml index 602750ac84..dd163f0238 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2215,6 +2215,7 @@ + + From 2686573b1cfd2a4493d589b6f2987c3a61829b3a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 26 Apr 2010 15:03:47 -0700 Subject: [PATCH 02/27] Uncommenting SQLiteNG project again. I found a Mono.Data.Sqlite.dll that makes the compilation in Windows happy again. Not sure if this is the right dll, Justin -- I grabbed it somewhere from mono 2.4.6 for Windows. --- bin/Mono.Data.Sqlite.dll | Bin 0 -> 169472 bytes prebuild.xml | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) create mode 100644 bin/Mono.Data.Sqlite.dll diff --git a/bin/Mono.Data.Sqlite.dll b/bin/Mono.Data.Sqlite.dll new file mode 100644 index 0000000000000000000000000000000000000000..2b81a44957dcce036ee794bca4bcfa37c8e543f7 GIT binary patch literal 169472 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

TJoGQ2oh&)XCBoIg2M020u^S~H-cM`XO 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 literal 0 HcmV?d00001 diff --git a/prebuild.xml b/prebuild.xml index dd163f0238..123f56955e 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2215,7 +2215,6 @@ - + From 31d040dc1e3126ff10e0ce4a1553cc6fa056b449 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 26 Apr 2010 17:40:00 -0700 Subject: [PATCH 03/27] Better error message. --- .../Servers/HttpServer/SynchronousRestFormsRequester.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index 4543fd5e99..b0cf34d16e 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -81,7 +81,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on sending request {0}", e.Message); + m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: {1}", requestUrl, e.Message); } finally { From 6928ec024060bb7181553206c9ee6a125e7c9a2d Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 27 Apr 2010 00:25:29 +0100 Subject: [PATCH 04/27] Add a parameter to prim inventory update to prevent event firing --- .../Framework/Interfaces/IEntityInventory.cs | 1 + .../Scenes/SceneObjectPartInventory.cs | 41 +++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 2b90960936..fd43923cb3 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -161,6 +161,7 @@ namespace OpenSim.Region.Framework.Interfaces /// in this prim's inventory. /// false if the item did not exist, true if the update occurred successfully bool UpdateInventoryItem(TaskInventoryItem item); + bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents); ///

/// Remove an item from this entity's inventory diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3b1b567557..44c49c58e4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -609,30 +609,37 @@ namespace OpenSim.Region.Framework.Scenes /// false if the item did not exist, true if the update occurred successfully public bool UpdateInventoryItem(TaskInventoryItem item) { - lock (m_items) + return UpdateInventoryItem(item, true); + } + + public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) + { + lock(m_items) { if (m_items.ContainsKey(item.ItemID)) { - item.ParentID = m_part.UUID; - item.ParentPartID = m_part.UUID; - item.Flags = m_items[item.ItemID].Flags; - - // If group permissions have been set on, check that the groupID is up to date in case it has - // changed since permissions were last set. - if (item.GroupPermissions != (uint)PermissionMask.None) - item.GroupID = m_part.GroupID; - - if (item.AssetID == UUID.Zero) + if (m_items.ContainsKey(item.ItemID)) { - item.AssetID = m_items[item.ItemID].AssetID; - } + item.ParentID = m_part.UUID; + item.ParentPartID = m_part.UUID; + item.Flags = m_items[item.ItemID].Flags; + // If group permissions have been set on, check that the groupID is up to date in case it has + // changed since permissions were last set. + if (item.GroupPermissions != (uint)PermissionMask.None) + item.GroupID = m_part.GroupID; + + if (item.AssetID == UUID.Zero) + { + item.AssetID = m_items[item.ItemID].AssetID; + } m_items[item.ItemID] = item; m_inventorySerial++; - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + if (fireScriptEvents) + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; - + m_items.LockItemsForWrite(false); return true; } else @@ -643,9 +650,9 @@ namespace OpenSim.Region.Framework.Scenes item.ItemID, m_part.Name, m_part.UUID, m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } - } - return false; + return false; + } } /// From edde0be0a0902a5f9cf51df7ceb3325d50c95c6e Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 27 Apr 2010 01:11:14 +0100 Subject: [PATCH 05/27] Fix build break. --- .../Scenes/SceneObjectPartInventory.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 44c49c58e4..4da63c0187 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -633,24 +633,24 @@ namespace OpenSim.Region.Framework.Scenes { item.AssetID = m_items[item.ItemID].AssetID; } - m_items[item.ItemID] = item; - m_inventorySerial++; - if (fireScriptEvents) - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - m_items.LockItemsForWrite(false); - return true; - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", - item.ItemID, m_part.Name, m_part.UUID, - m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); - } + m_items[item.ItemID] = item; + m_inventorySerial++; + if (fireScriptEvents) + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + return true; + } + else + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", + item.ItemID, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); + } + } return false; } } From 1e743eab6d620a14876a1ec9b41b3e136af889d3 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 27 Apr 2010 03:48:49 +0100 Subject: [PATCH 06/27] Allow a client to pass a scope id to log into in the login XML / LLSD --- .../Server/Handlers/Login/LLLoginHandlers.cs | 12 ++++- OpenSim/Services/Interfaces/ILoginService.cs | 3 +- .../Services/LLLoginService/LLLoginService.cs | 44 +++++++++++++------ 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs b/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs index aaa958b218..daf27043df 100644 --- a/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs +++ b/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs @@ -72,6 +72,9 @@ namespace OpenSim.Server.Handlers.Login string last = requestData["last"].ToString(); string passwd = requestData["passwd"].ToString(); string startLocation = string.Empty; + UUID scopeID = UUID.Zero; + if (requestData["scope_id"] != null) + scopeID = new UUID(requestData["scope_id"].ToString()); if (requestData.ContainsKey("start")) startLocation = requestData["start"].ToString(); @@ -83,7 +86,7 @@ namespace OpenSim.Server.Handlers.Login m_log.InfoFormat("[LOGIN]: XMLRPC Login Requested for {0} {1}, starting in {2}, using {3}", first, last, startLocation, clientVersion); LoginResponse reply = null; - reply = m_LocalService.Login(first, last, passwd, startLocation, remoteClient); + reply = m_LocalService.Login(first, last, passwd, startLocation, scopeID, remoteClient); XmlRpcResponse response = new XmlRpcResponse(); response.Value = reply.ToHashtable(); @@ -109,10 +112,15 @@ namespace OpenSim.Server.Handlers.Login if (map.ContainsKey("start")) startLocation = map["start"].AsString(); + UUID scopeID = UUID.Zero; + + if (map.ContainsKey("scope_id")) + scopeID = new UUID(map["scope_id"].AsString()); + m_log.Info("[LOGIN]: LLSD Login Requested for: '" + map["first"].AsString() + "' '" + map["last"].AsString() + "' / " + startLocation); LoginResponse reply = null; - reply = m_LocalService.Login(map["first"].AsString(), map["last"].AsString(), map["passwd"].AsString(), startLocation, remoteClient); + reply = m_LocalService.Login(map["first"].AsString(), map["last"].AsString(), map["passwd"].AsString(), startLocation, scopeID, remoteClient); return reply.ToOSDMap(); } diff --git a/OpenSim/Services/Interfaces/ILoginService.cs b/OpenSim/Services/Interfaces/ILoginService.cs index 24bf342742..49efbe2572 100644 --- a/OpenSim/Services/Interfaces/ILoginService.cs +++ b/OpenSim/Services/Interfaces/ILoginService.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Net; using OpenMetaverse.StructuredData; +using OpenMetaverse; namespace OpenSim.Services.Interfaces { @@ -46,7 +47,7 @@ namespace OpenSim.Services.Interfaces public interface ILoginService { - LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, IPEndPoint clientIP); + LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, IPEndPoint clientIP); } diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index c333b5cec0..4d7dfd1eda 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -147,7 +147,7 @@ namespace OpenSim.Services.LLLoginService { } - public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, IPEndPoint clientIP) + public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, IPEndPoint clientIP) { bool success = false; UUID session = UUID.Random(); @@ -157,7 +157,7 @@ namespace OpenSim.Services.LLLoginService // // Get the account and check that it exists // - UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName); + UserAccount account = m_UserAccountService.GetUserAccount(scopeID, firstName, lastName); if (account == null) { m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found"); @@ -170,6 +170,22 @@ namespace OpenSim.Services.LLLoginService return LLFailedLoginResponse.LoginBlockedProblem; } + // If a scope id is requested, check that the account is in + // that scope, or unscoped. + // + if (scopeID != UUID.Zero) + { + if (account.ScopeID != scopeID && account.ScopeID != UUID.Zero) + { + m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: user not found"); + return LLFailedLoginResponse.UserProblem; + } + } + else + { + scopeID = account.ScopeID; + } + // // Authenticate this user // @@ -219,7 +235,7 @@ namespace OpenSim.Services.LLLoginService // Get the home region if ((presence.HomeRegionID != UUID.Zero) && m_GridService != null) { - home = m_GridService.GetRegionByUUID(account.ScopeID, presence.HomeRegionID); + home = m_GridService.GetRegionByUUID(scopeID, presence.HomeRegionID); } } @@ -230,7 +246,7 @@ namespace OpenSim.Services.LLLoginService Vector3 position = Vector3.Zero; Vector3 lookAt = Vector3.Zero; GridRegion gatekeeper = null; - GridRegion destination = FindDestination(account, presence, session, startLocation, out gatekeeper, out where, out position, out lookAt); + GridRegion destination = FindDestination(account, scopeID, presence, session, startLocation, out gatekeeper, out where, out position, out lookAt); if (destination == null) { m_PresenceService.LogoutAgent(session, presence.Position, presence.LookAt); @@ -286,7 +302,7 @@ namespace OpenSim.Services.LLLoginService } } - protected GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt) + protected GridRegion FindDestination(UserAccount account, UUID scopeID, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt) { m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation); @@ -318,7 +334,7 @@ namespace OpenSim.Services.LLLoginService } else { - region = m_GridService.GetRegionByUUID(account.ScopeID, pinfo.HomeRegionID); + region = m_GridService.GetRegionByUUID(scopeID, pinfo.HomeRegionID); if (null == region) { @@ -332,7 +348,7 @@ namespace OpenSim.Services.LLLoginService if (tryDefaults) { - List defaults = m_GridService.GetDefaultRegions(account.ScopeID); + List defaults = m_GridService.GetDefaultRegions(scopeID); if (defaults != null && defaults.Count > 0) { region = defaults[0]; @@ -342,7 +358,7 @@ namespace OpenSim.Services.LLLoginService { m_log.WarnFormat("[LLOGIN SERVICE]: User {0} {1} does not have a valid home and this grid does not have default locations. Attempting to find random region", account.FirstName, account.LastName); - defaults = m_GridService.GetRegionsByName(account.ScopeID, "", 1); + defaults = m_GridService.GetRegionsByName(scopeID, "", 1); if (defaults != null && defaults.Count > 0) { region = defaults[0]; @@ -363,9 +379,9 @@ namespace OpenSim.Services.LLLoginService GridRegion region = null; - if (pinfo.RegionID.Equals(UUID.Zero) || (region = m_GridService.GetRegionByUUID(account.ScopeID, pinfo.RegionID)) == null) + if (pinfo.RegionID.Equals(UUID.Zero) || (region = m_GridService.GetRegionByUUID(scopeID, pinfo.RegionID)) == null) { - List defaults = m_GridService.GetDefaultRegions(account.ScopeID); + List defaults = m_GridService.GetDefaultRegions(scopeID); if (defaults != null && defaults.Count > 0) { region = defaults[0]; @@ -374,7 +390,7 @@ namespace OpenSim.Services.LLLoginService else { m_log.Info("[LLOGIN SERVICE]: Last Region Not Found Attempting to find random region"); - defaults = m_GridService.GetRegionsByName(account.ScopeID, "", 1); + defaults = m_GridService.GetRegionsByName(scopeID, "", 1); if (defaults != null && defaults.Count > 0) { region = defaults[0]; @@ -414,11 +430,11 @@ namespace OpenSim.Services.LLLoginService { if (!regionName.Contains("@")) { - List regions = m_GridService.GetRegionsByName(account.ScopeID, regionName, 1); + List regions = m_GridService.GetRegionsByName(scopeID, regionName, 1); if ((regions == null) || (regions != null && regions.Count == 0)) { m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}. Trying defaults.", startLocation, regionName); - regions = m_GridService.GetDefaultRegions(UUID.Zero); + regions = m_GridService.GetDefaultRegions(scopeID); if (regions != null && regions.Count > 0) { where = "safe"; @@ -461,7 +477,7 @@ namespace OpenSim.Services.LLLoginService } else { - List defaults = m_GridService.GetDefaultRegions(account.ScopeID); + List defaults = m_GridService.GetDefaultRegions(scopeID); if (defaults != null && defaults.Count > 0) { where = "safe"; From 76e87181b2cfd7a9dd7a73367fd4fe5c26ccd6ce Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 26 Apr 2010 20:28:37 -0700 Subject: [PATCH 07/27] RemoteXInventoryServiceConnector, the plugin region module. Not active in default configs yet. --- .../RemoteXInventoryServiceConnector.cs | 324 ++++++++++++++++++ .../Inventory/XInventoryInConnector.cs | 48 ++- .../Inventory/XInventoryConnector.cs | 29 ++ 3 files changed, 400 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs new file mode 100644 index 0000000000..fb353c2893 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -0,0 +1,324 @@ +/* + * 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 log4net; +using System; +using System.Collections.Generic; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Statistics; + +using OpenSim.Services.Connectors; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory +{ + public class RemoteXInventoryServicesConnector : BaseInventoryConnector, ISharedRegionModule, IInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private bool m_Enabled = false; + private bool m_Initialized = false; + private Scene m_Scene; + private XInventoryServicesConnector m_RemoteConnector; + + public Type ReplaceableInterface + { + get { return null; } + } + + public string Name + { + get { return "RemoteXInventoryServicesConnector"; } + } + + public RemoteXInventoryServicesConnector() + { + } + + public RemoteXInventoryServicesConnector(IConfigSource source) + { + Init(source); + } + + protected override void Init(IConfigSource source) + { + m_RemoteConnector = new XInventoryServicesConnector(source); + base.Init(source); + } + + + #region ISharedRegionModule + + public void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("InventoryServices", ""); + if (name == Name) + { + Init(source); + m_Enabled = true; + + m_log.Info("[XINVENTORY CONNECTOR]: Remote XInventory enabled"); + } + } + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + m_Scene = scene; + //m_log.Debug("[XXXX] Adding scene " + m_Scene.RegionInfo.RegionName); + + if (!m_Enabled) + return; + + if (!m_Initialized) + { + m_Initialized = true; + } + + scene.RegisterModuleInterface(this); + m_cache.AddRegion(scene); + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + m_cache.RemoveRegion(scene); + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_log.InfoFormat("[XINVENTORY CONNECTOR]: Enabled remote XInventory for region {0}", scene.RegionInfo.RegionName); + + } + + #endregion ISharedRegionModule + + #region IInventoryService + + public override bool CreateUserInventory(UUID user) + { + return false; + } + + public override List GetInventorySkeleton(UUID userId) + { + return new List(); + } + + public override InventoryCollection GetUserInventory(UUID userID) + { + return null; + } + + public override void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + try + { + m_RemoteConnector.GetUserInventory(userID, callback); + } + catch (Exception e) + { + if (StatsManager.SimExtraStats != null) + StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure(); + + m_log.ErrorFormat("[XINVENTORY CONNECTOR]: Request inventory operation failed, {0} {1}", + e.Source, e.Message); + } + + } + + // inherited. See base class + // public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) + + public override Dictionary GetSystemFolders(UUID userID) + { + return m_RemoteConnector.GetSystemFolders(userID); + } + + public override InventoryCollection GetFolderContent(UUID userID, UUID folderID) + { + try + { + return m_RemoteConnector.GetFolderContent(userID, folderID); + } + catch (Exception e) + { + m_log.ErrorFormat("[XINVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1}", + e.Source, e.Message); + } + InventoryCollection nullCollection = new InventoryCollection(); + nullCollection.Folders = new List(); + nullCollection.Items = new List(); + nullCollection.UserID = userID; + return nullCollection; + } + + public override List GetFolderItems(UUID userID, UUID folderID) + { + return m_RemoteConnector.GetFolderItems(userID, folderID); + } + + public override bool AddFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + return m_RemoteConnector.AddFolder(folder); + } + + public override bool UpdateFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + return m_RemoteConnector.UpdateFolder(folder); + } + + public override bool MoveFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + return m_RemoteConnector.MoveFolder(folder); + } + + public override bool DeleteFolders(UUID ownerID, List folderIDs) + { + if (folderIDs == null) + return false; + if (folderIDs.Count == 0) + return false; + + return m_RemoteConnector.DeleteFolders(ownerID, folderIDs); + } + + + public override bool PurgeFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + return m_RemoteConnector.PurgeFolder(folder); + } + + // public bool AddItem(InventoryItemBase item) inherited + // Uses AddItemPlain + + protected override bool AddItemPlain(InventoryItemBase item) + { + if (item == null) + return false; + + return m_RemoteConnector.AddItem(item); + } + + public override bool UpdateItem(InventoryItemBase item) + { + if (item == null) + return false; + + return m_RemoteConnector.UpdateItem(item); + } + + public override bool MoveItems(UUID ownerID, List items) + { + if (items == null) + return false; + + return m_RemoteConnector.MoveItems(ownerID, items); + } + + + public override bool DeleteItems(UUID ownerID, List itemIDs) + { + if (itemIDs == null) + return false; + if (itemIDs.Count == 0) + return true; + + return m_RemoteConnector.DeleteItems(ownerID, itemIDs); + } + + public override InventoryItemBase GetItem(InventoryItemBase item) + { + if (item == null) + return null; + + return m_RemoteConnector.GetItem(item); + } + + public override InventoryFolderBase GetFolder(InventoryFolderBase folder) + { + if (folder == null) + return null; + + return m_RemoteConnector.GetFolder(folder); + } + + public override bool HasInventoryForUser(UUID userID) + { + return false; + } + + public override List GetActiveGestures(UUID userId) + { + return new List(); + } + + public override int GetAssetPermissions(UUID userID, UUID assetID) + { + return m_RemoteConnector.GetAssetPermissions(userID, assetID); + } + + + #endregion + + + } +} diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index 34f7dccc4e..7164520f14 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -144,6 +144,8 @@ namespace OpenSim.Server.Handlers.Asset return HandleGetActiveGestures(request); case "GETASSETPERMISSIONS": return HandleGetAssetPermissions(request); + case "GETSYSTEMFOLDERS": + return HandleGetSystemFolders(request); } m_log.DebugFormat("[XINVENTORY HANDLER]: unknown method request: {0}", method); } @@ -197,7 +199,7 @@ namespace OpenSim.Server.Handlers.Asset return ms.ToArray(); } - + byte[] HandleCreateUserInventory(Dictionary request) { Dictionary result = new Dictionary(); @@ -540,6 +542,24 @@ namespace OpenSim.Server.Handlers.Asset return encoding.GetBytes(xmlString); } + byte[] HandleGetSystemFolders(Dictionary request) + { + Dictionary result = new Dictionary(); + UUID principal = UUID.Zero; + UUID.TryParse(request["PRINCIPAL"].ToString(), out principal); + + Dictionary sfolders = GetSystemFolders(principal); + + if (sfolders != null) + foreach (KeyValuePair kvp in sfolders) + result[kvp.Key.ToString()] = EncodeFolder(kvp.Value); + + string xmlString = ServerUtils.BuildXmlResponse(result); + m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + UTF8Encoding encoding = new UTF8Encoding(); + return encoding.GetBytes(xmlString); + } + private Dictionary EncodeFolder(InventoryFolderBase f) { Dictionary ret = new Dictionary(); @@ -623,5 +643,31 @@ namespace OpenSim.Server.Handlers.Asset return item; } + + #region Extra + private Dictionary GetSystemFolders(UUID userID) + { + InventoryFolderBase root = m_InventoryService.GetRootFolder(userID); + if (root != null) + { + InventoryCollection content = m_InventoryService.GetFolderContent(userID, root.ID); + if (content != null) + { + Dictionary folders = new Dictionary(); + foreach (InventoryFolderBase folder in content.Folders) + { + if ((folder.Type != (short)AssetType.Folder) && (folder.Type != (short)AssetType.Unknown)) + folders[(AssetType)folder.Type] = folder; + } + // Put the root folder there, as type Folder + folders[AssetType.Folder] = root; + return folders; + } + } + m_log.WarnFormat("[INVENTORY SERVICE]: System folders for {0} not found", userID); + return new Dictionary(); + } + #endregion + } } diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs index 0cc1978a0b..edf224f741 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs @@ -455,6 +455,35 @@ namespace OpenSim.Services.Connectors return int.Parse(ret["RESULT"].ToString()); } + public Dictionary GetSystemFolders(UUID userID) + { + Dictionary ret = MakeRequest("GETSYSTEMFOLDERS", + new Dictionary { + { "PRINCIPAL", userID.ToString() }, + }); + + if (ret == null) + return new Dictionary(); + + Dictionary sfolders = new Dictionary(); + + try + { + foreach (KeyValuePair kvp in ret) + { + InventoryFolderBase folder = BuildFolder((Dictionary)(kvp.Value)); + short type = 0; + if (Int16.TryParse(kvp.Key, out type)) + sfolders.Add((AssetType)type, folder); + } + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: exception {0}", e.Message); + } + + return sfolders; + } // These are either obsolete or unused // From 3f9d38538e4d7f238eb901aced60de7e6673a92e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 27 Apr 2010 11:01:56 -0700 Subject: [PATCH 08/27] XInventory connector/handler showing signs of life. Tested, but needs more testing. --- .../Resources/CoreModulePlugin.addin.xml | 1 + .../RemoteXInventoryServiceConnector.cs | 2 + .../Inventory/XInventoryInConnector.cs | 69 ++++++++-- .../Inventory/XInventoryConnector.cs | 128 +++++++++++------- .../InventoryService/XInventoryService.cs | 8 +- 5 files changed, 139 insertions(+), 69 deletions(-) diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index aaa318cabb..0a5ff3f982 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -45,6 +45,7 @@ + diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index fb353c2893..8504b677c2 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -183,6 +183,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public override InventoryCollection GetFolderContent(UUID userID, UUID folderID) { + m_log.DebugFormat("[XINVENTORY CONNECTOR]: GetFolderContent {0}", folderID); try { return m_RemoteConnector.GetFolderContent(userID, folderID); @@ -295,6 +296,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public override InventoryFolderBase GetFolder(InventoryFolderBase folder) { + m_log.DebugFormat("[XINVENTORY CONNECTOR]: GetFolder {0}", folder.ID); if (folder == null) return null; diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index 7164520f14..c95b4d44e3 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -228,9 +228,17 @@ namespace OpenSim.Server.Handlers.Asset List folders = m_InventoryService.GetInventorySkeleton(new UUID(request["PRINCIPAL"].ToString())); + Dictionary sfolders = new Dictionary(); if (folders != null) + { + int i = 0; foreach (InventoryFolderBase f in folders) - result[f.ID.ToString()] = EncodeFolder(f); + { + sfolders["folder_" + i.ToString()] = EncodeFolder(f); + i++; + } + } + result["FOLDERS"] = sfolders; string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); @@ -246,7 +254,7 @@ namespace OpenSim.Server.Handlers.Asset UUID.TryParse(request["PRINCIPAL"].ToString(), out principal); InventoryFolderBase rfolder = m_InventoryService.GetRootFolder(principal); if (rfolder != null) - result[rfolder.ID.ToString()] = EncodeFolder(rfolder); + result["folder"] = EncodeFolder(rfolder); string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); @@ -263,7 +271,7 @@ namespace OpenSim.Server.Handlers.Asset Int32.TryParse(request["TYPE"].ToString(), out type); InventoryFolderBase folder = m_InventoryService.GetFolderForType(principal, (AssetType)type); if (folder != null) - result[folder.ID.ToString()] = EncodeFolder(folder); + result["folder"] = EncodeFolder(folder); string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); @@ -283,13 +291,21 @@ namespace OpenSim.Server.Handlers.Asset if (icoll != null) { Dictionary folders = new Dictionary(); + int i = 0; foreach (InventoryFolderBase f in icoll.Folders) - folders[f.ID.ToString()] = EncodeFolder(f); + { + folders["folder_" + i.ToString()] = EncodeFolder(f); + i++; + } result["FOLDERS"] = folders; + i = 0; Dictionary items = new Dictionary(); - foreach (InventoryItemBase i in icoll.Items) - items[i.ID.ToString()] = EncodeItem(i); + foreach (InventoryItemBase it in icoll.Items) + { + items["item_" + i.ToString()] = EncodeItem(it); + i++; + } result["ITEMS"] = items; } @@ -308,9 +324,18 @@ namespace OpenSim.Server.Handlers.Asset UUID.TryParse(request["FOLDER"].ToString(), out folderID); List items = m_InventoryService.GetFolderItems(principal, folderID); + Dictionary sitems = new Dictionary(); + if (items != null) + { + int i = 0; foreach (InventoryItemBase item in items) - result[item.ID.ToString()] = EncodeItem(item); + { + sitems["item_" + i.ToString()] = EncodeItem(item); + i++; + } + } + result["ITEMS"] = sitems; string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); @@ -483,7 +508,7 @@ namespace OpenSim.Server.Handlers.Asset InventoryItemBase item = new InventoryItemBase(id); item = m_InventoryService.GetItem(item); if (item != null) - result[item.ID.ToString()] = EncodeItem(item); + result["item"] = EncodeItem(item); string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); @@ -500,7 +525,7 @@ namespace OpenSim.Server.Handlers.Asset InventoryFolderBase folder = new InventoryFolderBase(id); folder = m_InventoryService.GetFolder(folder); if (folder != null) - result[folder.ID.ToString()] = EncodeFolder(folder); + result["folder"] = EncodeFolder(folder); string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); @@ -515,9 +540,17 @@ namespace OpenSim.Server.Handlers.Asset UUID.TryParse(request["PRINCIPAL"].ToString(), out principal); List gestures = m_InventoryService.GetActiveGestures(principal); + Dictionary items = new Dictionary(); if (gestures != null) + { + int i = 0; foreach (InventoryItemBase item in gestures) - result[item.ID.ToString()] = EncodeItem(item); + { + items["item_" + i.ToString()] = EncodeItem(item); + i++; + } + } + result["ITEMS"] = items; string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); @@ -549,10 +582,16 @@ namespace OpenSim.Server.Handlers.Asset UUID.TryParse(request["PRINCIPAL"].ToString(), out principal); Dictionary sfolders = GetSystemFolders(principal); + m_log.DebugFormat("[XXX]: SystemFolders got {0} folders", sfolders.Count); - if (sfolders != null) - foreach (KeyValuePair kvp in sfolders) - result[kvp.Key.ToString()] = EncodeFolder(kvp.Value); + Dictionary folders = new Dictionary(); + int i = 0; + foreach (KeyValuePair kvp in sfolders) + { + folders["folder_" + i.ToString()] = EncodeFolder(kvp.Value); + i++; + } + result["FOLDERS"] = folders; string xmlString = ServerUtils.BuildXmlResponse(result); m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); @@ -589,7 +628,7 @@ namespace OpenSim.Server.Handlers.Asset ret["Flags"] = item.Flags.ToString(); ret["Folder"] = item.Folder.ToString(); ret["GroupID"] = item.GroupID.ToString(); - ret["GroupedOwned"] = item.GroupOwned.ToString(); + ret["GroupOwned"] = item.GroupOwned.ToString(); ret["GroupPermissions"] = item.GroupPermissions.ToString(); ret["ID"] = item.ID.ToString(); ret["InvType"] = item.InvType.ToString(); @@ -664,7 +703,7 @@ namespace OpenSim.Server.Handlers.Asset return folders; } } - m_log.WarnFormat("[INVENTORY SERVICE]: System folders for {0} not found", userID); + m_log.WarnFormat("[XINVENTORY SERVICE]: System folders for {0} not found", userID); return new Dictionary(); } #endregion diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs index edf224f741..52294dab71 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs @@ -112,8 +112,15 @@ namespace OpenSim.Services.Connectors List folders = new List(); - foreach (Object o in ret.Values) - folders.Add(BuildFolder((Dictionary)o)); + try + { + foreach (Object o in ret.Values) + folders.Add(BuildFolder((Dictionary)o)); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping folder list: {0}", e.Message); + } return folders; } @@ -130,7 +137,7 @@ namespace OpenSim.Services.Connectors if (ret.Count == 0) return null; - return BuildFolder(ret); + return BuildFolder((Dictionary)ret["folder"]); } public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) @@ -146,7 +153,7 @@ namespace OpenSim.Services.Connectors if (ret.Count == 0) return null; - return BuildFolder(ret); + return BuildFolder((Dictionary)ret["folder"]); } public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) @@ -173,10 +180,17 @@ namespace OpenSim.Services.Connectors Dictionary items = (Dictionary)ret["ITEMS"]; - foreach (Object o in folders.Values) - inventory.Folders.Add(BuildFolder((Dictionary)o)); - foreach (Object o in items.Values) - inventory.Items.Add(BuildItem((Dictionary)o)); + try + { + foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i + inventory.Folders.Add(BuildFolder((Dictionary)o)); + foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i + inventory.Items.Add(BuildItem((Dictionary)o)); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping content list: {0}", e.Message); + } return inventory; } @@ -194,13 +208,12 @@ namespace OpenSim.Services.Connectors if (ret.Count == 0) return null; - - List items = new List(); - - foreach (Object o in ret.Values) - items.Add(BuildItem((Dictionary)o)); + Dictionary items = (Dictionary)ret["ITEMS"]; + List fitems = new List(); + foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i + fitems.Add(BuildItem((Dictionary)o)); - return items; + return fitems; } public bool AddFolder(InventoryFolderBase folder) @@ -405,7 +418,7 @@ namespace OpenSim.Services.Connectors if (ret.Count == 0) return null; - return BuildItem(ret); + return BuildItem((Dictionary)ret["item"]); } public InventoryFolderBase GetFolder(InventoryFolderBase folder) @@ -420,7 +433,7 @@ namespace OpenSim.Services.Connectors if (ret.Count == 0) return null; - return BuildFolder(ret); + return BuildFolder((Dictionary)ret["folder"]); } public List GetActiveGestures(UUID principalID) @@ -435,8 +448,8 @@ namespace OpenSim.Services.Connectors List items = new List(); - foreach (Object o in ret.Values) - items.Add(BuildItem((Dictionary)o)); + foreach (Object o in ret.Values) // getting the values directly, we don't care about the keys item_i + items.Add(BuildItem((Dictionary)o)); return items; } @@ -469,13 +482,14 @@ namespace OpenSim.Services.Connectors try { - foreach (KeyValuePair kvp in ret) + Dictionary folders = (Dictionary)ret["FOLDERS"]; + + foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i { - InventoryFolderBase folder = BuildFolder((Dictionary)(kvp.Value)); - short type = 0; - if (Int16.TryParse(kvp.Key, out type)) - sfolders.Add((AssetType)type, folder); + InventoryFolderBase folder = BuildFolder((Dictionary)o); + sfolders.Add((AssetType)folder.Type, folder); } + } catch (Exception e) { @@ -522,13 +536,20 @@ namespace OpenSim.Services.Connectors { InventoryFolderBase folder = new InventoryFolderBase(); - folder.ParentID = new UUID(data["ParentID"].ToString()); - folder.Type = short.Parse(data["Type"].ToString()); - folder.Version = ushort.Parse(data["Version"].ToString()); - folder.Name = data["Name"].ToString(); - folder.Owner = new UUID(data["Owner"].ToString()); - folder.ID = new UUID(data["ID"].ToString()); - + try + { + folder.ParentID = new UUID(data["ParentID"].ToString()); + folder.Type = short.Parse(data["Type"].ToString()); + folder.Version = ushort.Parse(data["Version"].ToString()); + folder.Name = data["Name"].ToString(); + folder.Owner = new UUID(data["Owner"].ToString()); + folder.ID = new UUID(data["ID"].ToString()); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building folder: {0}", e.Message); + } + return folder; } @@ -536,26 +557,33 @@ namespace OpenSim.Services.Connectors { InventoryItemBase item = new InventoryItemBase(); - item.AssetID = new UUID(data["AssetID"].ToString()); - item.AssetType = int.Parse(data["AssetType"].ToString()); - item.Name = data["Name"].ToString(); - item.Owner = new UUID(data["Owner"].ToString()); - item.ID = new UUID(data["ID"].ToString()); - item.InvType = int.Parse(data["InvType"].ToString()); - item.Folder = new UUID(data["Folder"].ToString()); - item.CreatorId = data["CreatorId"].ToString(); - item.Description = data["Description"].ToString(); - item.NextPermissions = uint.Parse(data["NextPermissions"].ToString()); - item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString()); - item.BasePermissions = uint.Parse(data["BasePermissions"].ToString()); - item.EveryOnePermissions = uint.Parse(data["EveryOnePermissions"].ToString()); - item.GroupPermissions = uint.Parse(data["GroupPermissions"].ToString()); - item.GroupID = new UUID(data["GroupID"].ToString()); - item.GroupOwned = bool.Parse(data["GroupOwned"].ToString()); - item.SalePrice = int.Parse(data["SalePrice"].ToString()); - item.SaleType = byte.Parse(data["SaleType"].ToString()); - item.Flags = uint.Parse(data["Flags"].ToString()); - item.CreationDate = int.Parse(data["CreationDate"].ToString()); + try + { + item.AssetID = new UUID(data["AssetID"].ToString()); + item.AssetType = int.Parse(data["AssetType"].ToString()); + item.Name = data["Name"].ToString(); + item.Owner = new UUID(data["Owner"].ToString()); + item.ID = new UUID(data["ID"].ToString()); + item.InvType = int.Parse(data["InvType"].ToString()); + item.Folder = new UUID(data["Folder"].ToString()); + item.CreatorId = data["CreatorId"].ToString(); + item.Description = data["Description"].ToString(); + item.NextPermissions = uint.Parse(data["NextPermissions"].ToString()); + item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString()); + item.BasePermissions = uint.Parse(data["BasePermissions"].ToString()); + item.EveryOnePermissions = uint.Parse(data["EveryOnePermissions"].ToString()); + item.GroupPermissions = uint.Parse(data["GroupPermissions"].ToString()); + item.GroupID = new UUID(data["GroupID"].ToString()); + item.GroupOwned = bool.Parse(data["GroupOwned"].ToString()); + item.SalePrice = int.Parse(data["SalePrice"].ToString()); + item.SaleType = byte.Parse(data["SaleType"].ToString()); + item.Flags = uint.Parse(data["Flags"].ToString()); + item.CreationDate = int.Parse(data["CreationDate"].ToString()); + } + catch (Exception e) + { + m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception building item: {0}", e.Message); + } return item; } diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index bbd37d123a..1409a0192d 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -184,7 +184,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryFolder x in allFolders) { - m_log.DebugFormat("[INVENTORY]: Adding folder {0} to skeleton", x.folderName); + m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to skeleton", x.folderName); folders.Add(ConvertToOpenSim(x)); } @@ -221,7 +221,7 @@ namespace OpenSim.Services.InventoryService // connector. So we disregard the principal and look // by ID. // - m_log.DebugFormat("[INVENTORY]: Fetch contents for folder {0}", folderID.ToString()); + m_log.DebugFormat("[XINVENTORY]: Fetch contents for folder {0}", folderID.ToString()); InventoryCollection inventory = new InventoryCollection(); inventory.UserID = principalID; inventory.Folders = new List(); @@ -233,7 +233,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryFolder x in folders) { - m_log.DebugFormat("[INVENTORY]: Adding folder {0} to response", x.folderName); + m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to response", x.folderName); inventory.Folders.Add(ConvertToOpenSim(x)); } @@ -243,7 +243,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryItem i in items) { - m_log.DebugFormat("[INVENTORY]: Adding item {0} to response", i.inventoryName); + m_log.DebugFormat("[XINVENTORY]: Adding item {0} to response", i.inventoryName); inventory.Items.Add(ConvertToOpenSim(i)); } From 6d05ea2a755a5acb4a54b01f2c02ba66a82bc413 Mon Sep 17 00:00:00 2001 From: justincc Date: Tue, 27 Apr 2010 20:44:04 +0100 Subject: [PATCH 09/27] update Mono.Data.Sqlite.dll to the one that shipped with Mono 2.6.3, which is the one known to work in Windows Thanks for the initial library inclusion, Diva. I had it all queued up on my windows test machine but forgot to add it! --- bin/Mono.Data.Sqlite.dll | Bin 169472 -> 169984 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/Mono.Data.Sqlite.dll b/bin/Mono.Data.Sqlite.dll index 2b81a44957dcce036ee794bca4bcfa37c8e543f7..4f69e0d4af194f53d9460b56f5c492b6b24cc452 100644 GIT binary patch literal 169984 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

TJoGQ2oh&)XCBoIg2M020u^S~H-cM`XO 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 From 59ac792e44fef4de1da9fdf5c3be3ed164cae6cf Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 27 Apr 2010 17:11:24 -0700 Subject: [PATCH 10/27] * Thanks cmickeyb, for a patch that corrects an invalid construction of Primitive.TextureEntry (a "blank" texture should be initialized with UUID.Zero, not null) --- OpenSim/Framework/PrimitiveBaseShape.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 1208b97300..4d1de22eeb 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -236,7 +236,7 @@ namespace OpenSim.Framework catch { } m_log.Warn("[SHAPE]: Failed to decode texture, length=" + ((m_textureEntry != null) ? m_textureEntry.Length : 0)); - return new Primitive.TextureEntry(null); + return new Primitive.TextureEntry(UUID.Zero); } set { m_textureEntry = value.GetBytes(); } From e83877692046068735af97eb9f40cea1a09ae66c Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 27 Apr 2010 17:13:54 -0700 Subject: [PATCH 11/27] * Thanks cmickeyb, for a patch that sanity checks if the response from m_Database.GetAsset(assetID) is null in AssetService.cs --- OpenSim/Services/AssetService/AssetService.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index ed87f3f6fc..4e512e729c 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs @@ -106,7 +106,10 @@ namespace OpenSim.Services.AssetService return null; AssetBase asset = m_Database.GetAsset(assetID); - return asset.Metadata; + if (asset != null) + return asset.Metadata; + + return null; } public byte[] GetData(string id) From 044c1cf5f6e38799526be15cc2c7f4a7d0d9350f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 27 Apr 2010 18:37:34 -0700 Subject: [PATCH 12/27] Changed GetToken from protected to public. This is not exposed at the interface. --- .../Services/AuthenticationService/AuthenticationServiceBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs b/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs index 9af61a922a..242aba3670 100644 --- a/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs +++ b/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs @@ -127,7 +127,7 @@ namespace OpenSim.Services.AuthenticationService return true; } - protected string GetToken(UUID principalID, int lifetime) + public string GetToken(UUID principalID, int lifetime) { UUID token = UUID.Random(); From c54bc5094deedecbde2ca2283efefe6df70cc591 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 27 Apr 2010 18:52:15 -0700 Subject: [PATCH 13/27] Putting it back to protected; Melanie doesn't like it to be public. --- .../Services/AuthenticationService/AuthenticationServiceBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs b/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs index 242aba3670..9af61a922a 100644 --- a/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs +++ b/OpenSim/Services/AuthenticationService/AuthenticationServiceBase.cs @@ -127,7 +127,7 @@ namespace OpenSim.Services.AuthenticationService return true; } - public string GetToken(UUID principalID, int lifetime) + protected string GetToken(UUID principalID, int lifetime) { UUID token = UUID.Random(); From 0718748ea4dba1f0de409c0e099a803d8765ae63 Mon Sep 17 00:00:00 2001 From: AlexRa Date: Tue, 27 Apr 2010 13:44:19 +0300 Subject: [PATCH 14/27] Removed from git .../obj directories (created by VStudio) --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index b6b5582b0d..4eca1cff57 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,13 @@ *.pdb *.pidb *.dll.build +*.dll +*/*/obj +*/*/*/obj +*/*/*/*/obj +*/*/*/*/*/obj +*/*/*/*/*/*/obj +*/*/*/*/*/*/*/obj */*/bin */*/*/bin */*/*/*/bin @@ -45,6 +52,7 @@ bin/OpenSim.Grid.InventoryServer.log bin/OpenSim.Grid.MessagingServer.log bin/OpenSim.Grid.UserServer.log bin/OpenSim.log +bin/*.manifest bin/crashes/ Examples/*.dll OpenSim.build From b9c6ee6eb262d74aa42a2b4a76fecf867ed5c414 Mon Sep 17 00:00:00 2001 From: AlexRa Date: Tue, 27 Apr 2010 10:52:22 +0300 Subject: [PATCH 15/27] removed from git *.VisualState.xml (automatically created by NUnit) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 4eca1cff57..8d3f2b266f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ *.pidb *.dll.build *.dll +*.VisualState.xml */*/obj */*/*/obj */*/*/*/obj From 423ff3b94bbbace7092f110b51d8723f7fc25713 Mon Sep 17 00:00:00 2001 From: AlexRa Date: Tue, 27 Apr 2010 10:53:54 +0300 Subject: [PATCH 16/27] Removed unused var from InventoryService.cs (-1 warning) --- OpenSim/Services/InventoryService/InventoryService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/InventoryService/InventoryService.cs b/OpenSim/Services/InventoryService/InventoryService.cs index 0d6577e776..fbcd6634e7 100644 --- a/OpenSim/Services/InventoryService/InventoryService.cs +++ b/OpenSim/Services/InventoryService/InventoryService.cs @@ -109,7 +109,7 @@ namespace OpenSim.Services.InventoryService { existingRootFolder = GetRootFolder(user); } - catch (Exception e) + catch /*(Exception e)*/ { // Munch the exception, it has already been reported // From fb7458be3185802c4511306c0cda7648d702de59 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 25 Apr 2010 10:13:13 +0300 Subject: [PATCH 17/27] Minor spelling corrections in MiniModule: "RetreiveAsset" changed to "RetrieveAsset" and 'm_rootSceene' to m_rootScene'. --- .../Scripting/Minimodule/Interfaces/IInventoryItem.cs | 2 +- .../OptionalModules/Scripting/Minimodule/InventoryItem.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs index 5fac189d09..16cd7e454e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs @@ -39,6 +39,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule { int Type { get; } UUID AssetID { get; } - T RetreiveAsset() where T : Asset, new(); + T RetrieveAsset() where T : Asset, new(); } } diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs index 5bf29d710c..bf85cbcff5 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/InventoryItem.cs @@ -39,11 +39,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule public class InventoryItem : IInventoryItem { TaskInventoryItem m_privateItem; - Scene m_rootSceene; + Scene m_rootScene; public InventoryItem(Scene rootScene, TaskInventoryItem internalItem) { - m_rootSceene = rootScene; + m_rootScene = rootScene; m_privateItem = internalItem; } @@ -82,9 +82,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule public UUID AssetID { get { return m_privateItem.AssetID; } } // This method exposes OpenSim/OpenMetaverse internals and needs to be replaced with a IAsset specific to MRM. - public T RetreiveAsset() where T : OpenMetaverse.Assets.Asset, new() + public T RetrieveAsset() where T : OpenMetaverse.Assets.Asset, new() { - AssetBase a = m_rootSceene.AssetService.Get(AssetID.ToString()); + AssetBase a = m_rootScene.AssetService.Get(AssetID.ToString()); T result = new T(); if ((sbyte)result.AssetType != a.Type) From 806a2555f557e7a05002f67731b1e3105c9aab8b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 25 Apr 2010 17:21:05 +0300 Subject: [PATCH 18/27] Spelling in FriendsModule.cs: "filed to load" -> "failed to load" --- OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 312db38ed0..23d5b3c2ec 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (m_FriendsService == null) { - m_log.Error("[FRIENDS]: No Connector defined in section Friends, or filed to load, cannot continue"); + m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue"); throw new Exception("Connector load error"); } From 8b75302a1e33f1f5cee166dd22d1de44172da509 Mon Sep 17 00:00:00 2001 From: AlexRa Date: Tue, 27 Apr 2010 10:05:17 +0300 Subject: [PATCH 19/27] Just a bit of spellchecking in the comments --- OpenSim/Data/MySQL/MySQLInventoryData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index 192deb298a..e0e9b9cc99 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -145,7 +145,7 @@ namespace OpenSim.Data.MySQL ///

/// Returns a list of the root folders within a users inventory /// - /// The user whos inventory is to be searched + /// The user whose inventory is to be searched /// A list of folder objects public List getUserRootFolders(UUID user) { @@ -284,7 +284,7 @@ namespace OpenSim.Data.MySQL { InventoryItemBase item = new InventoryItemBase(); - // TODO: this is to handle a case where NULLs creep in there, which we are not sure is indemic to the system, or legacy. It would be nice to live fix these. + // TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these. if (reader["creatorID"] == null) { item.CreatorId = UUID.Zero.ToString(); From aa56953411e04c260fe1938f5f184c775fea72b6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 24 Apr 2010 18:52:23 +0300 Subject: [PATCH 20/27] Compiler.cs contained method GetCompilerOutput which, apparently, was not used, but exactly the same path was calculated inline. This patch does some minor refactoring by replacing inline path calculation with GetCompilerOutput. This doesn't actually affect anything, just minor prettifying of the code --- .../Region/ScriptEngine/Shared/CodeTools/Compiler.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index d8c0ba57a5..f7196835bb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -261,13 +261,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // } //} - public object GetCompilerOutput(UUID assetID) + public string GetCompilerOutput(string assetID) { return Path.Combine(ScriptEnginesPath, Path.Combine( m_scriptEngine.World.RegionInfo.RegionID.ToString(), FilePrefix + "_compiled_" + assetID + ".dll")); } + public string GetCompilerOutput(UUID assetID) + { + return GetCompilerOutput(assetID.ToString()); + } + /// /// Converts script from LSL to CS and calls CompileFromCSText /// @@ -279,9 +284,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools linemap = null; m_warnings.Clear(); - assembly = Path.Combine(ScriptEnginesPath, Path.Combine( - m_scriptEngine.World.RegionInfo.RegionID.ToString(), - FilePrefix + "_compiled_" + asset + ".dll")); + assembly = GetCompilerOutput(asset); if (!Directory.Exists(ScriptEnginesPath)) { From b49e9eff562076786f68088155c6a0c8b1192e4a Mon Sep 17 00:00:00 2001 From: AlexRa Date: Wed, 28 Apr 2010 13:11:42 +0300 Subject: [PATCH 21/27] Fixed comments in Migration.cs: wrong argument order (no change to code) --- OpenSim/Data/Migration.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs index 0fb9e783bd..5ca8e4450a 100644 --- a/OpenSim/Data/Migration.cs +++ b/OpenSim/Data/Migration.cs @@ -53,8 +53,8 @@ namespace OpenSim.Data /// When a database driver starts up, it specifies a resource that /// needs to be brought up to the current revision. For instance: /// - /// Migration um = new Migration(Assembly, DbConnection, "Users"); - /// um.Upgrade(); + /// Migration um = new Migration(DbConnection, Assembly, "Users"); + /// um.Update(); /// /// This works out which version Users is at, and applies all the /// revisions past it to it. If there is no users table, all From be1141f0f7994cb068683e07fe99936025361001 Mon Sep 17 00:00:00 2001 From: AlexRa Date: Wed, 28 Apr 2010 13:40:35 +0300 Subject: [PATCH 22/27] Refactoring in Migration.cs: "using()" instead of explicit Dispose() This ensures that 'cmd' gets disposed on errors --- OpenSim/Data/Migration.cs | 108 ++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 52 deletions(-) diff --git a/OpenSim/Data/Migration.cs b/OpenSim/Data/Migration.cs index 5ca8e4450a..06defe4e36 100644 --- a/OpenSim/Data/Migration.cs +++ b/OpenSim/Data/Migration.cs @@ -110,10 +110,11 @@ namespace OpenSim.Data return; // If not, create the migration tables - DbCommand cmd = _conn.CreateCommand(); - cmd.CommandText = _migrations_create; - cmd.ExecuteNonQuery(); - cmd.Dispose(); + using (DbCommand cmd = _conn.CreateCommand()) + { + cmd.CommandText = _migrations_create; + cmd.ExecuteNonQuery(); + } InsertVersion("migrations", 1); } @@ -131,37 +132,37 @@ namespace OpenSim.Data m_log.InfoFormat("[MIGRATIONS] Upgrading {0} to latest revision {1}.", _type, migrations.Keys[migrations.Count - 1]); m_log.Info("[MIGRATIONS] NOTE: this may take a while, don't interupt this process!"); - DbCommand cmd = _conn.CreateCommand(); - foreach (KeyValuePair kvp in migrations) + using (DbCommand cmd = _conn.CreateCommand()) { - int newversion = kvp.Key; - cmd.CommandText = kvp.Value; - // we need to up the command timeout to infinite as we might be doing long migrations. - cmd.CommandTimeout = 0; - try + foreach (KeyValuePair kvp in migrations) { - cmd.ExecuteNonQuery(); - } - catch (Exception e) - { - m_log.DebugFormat("[MIGRATIONS] Cmd was {0}", cmd.CommandText); - m_log.DebugFormat("[MIGRATIONS]: An error has occurred in the migration {0}.\n This may mean you could see errors trying to run OpenSim. If you see database related errors, you will need to fix the issue manually. Continuing.", e.Message); - cmd.CommandText = "ROLLBACK;"; - cmd.ExecuteNonQuery(); - } + int newversion = kvp.Key; + cmd.CommandText = kvp.Value; + // we need to up the command timeout to infinite as we might be doing long migrations. + cmd.CommandTimeout = 0; + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception e) + { + m_log.DebugFormat("[MIGRATIONS] Cmd was {0}", cmd.CommandText); + m_log.DebugFormat("[MIGRATIONS]: An error has occurred in the migration {0}.\n This may mean you could see errors trying to run OpenSim. If you see database related errors, you will need to fix the issue manually. Continuing.", e.Message); + cmd.CommandText = "ROLLBACK;"; + cmd.ExecuteNonQuery(); + } - if (version == 0) - { - InsertVersion(_type, newversion); + if (version == 0) + { + InsertVersion(_type, newversion); + } + else + { + UpdateVersion(_type, newversion); + } + version = newversion; } - else - { - UpdateVersion(_type, newversion); - } - version = newversion; } - - cmd.Dispose(); } // private int MaxVersion() @@ -200,43 +201,46 @@ namespace OpenSim.Data protected virtual int FindVersion(DbConnection conn, string type) { int version = 0; - DbCommand cmd = conn.CreateCommand(); - try + using (DbCommand cmd = conn.CreateCommand()) { - cmd.CommandText = "select version from migrations where name='" + type +"' order by version desc"; - using (IDataReader reader = cmd.ExecuteReader()) + try { - if (reader.Read()) + cmd.CommandText = "select version from migrations where name='" + type + "' order by version desc"; + using (IDataReader reader = cmd.ExecuteReader()) { - version = Convert.ToInt32(reader["version"]); + if (reader.Read()) + { + version = Convert.ToInt32(reader["version"]); + } + reader.Close(); } - reader.Close(); + } + catch + { + // Something went wrong, so we're version 0 } } - catch - { - // Something went wrong, so we're version 0 - } - cmd.Dispose(); return version; } private void InsertVersion(string type, int version) { - DbCommand cmd = _conn.CreateCommand(); - cmd.CommandText = "insert into migrations(name, version) values('" + type + "', " + version + ")"; - m_log.InfoFormat("[MIGRATIONS]: Creating {0} at version {1}", type, version); - cmd.ExecuteNonQuery(); - cmd.Dispose(); + using (DbCommand cmd = _conn.CreateCommand()) + { + cmd.CommandText = "insert into migrations(name, version) values('" + type + "', " + version + ")"; + m_log.InfoFormat("[MIGRATIONS]: Creating {0} at version {1}", type, version); + cmd.ExecuteNonQuery(); + } } private void UpdateVersion(string type, int version) { - DbCommand cmd = _conn.CreateCommand(); - cmd.CommandText = "update migrations set version=" + version + " where name='" + type + "'"; - m_log.InfoFormat("[MIGRATIONS]: Updating {0} to version {1}", type, version); - cmd.ExecuteNonQuery(); - cmd.Dispose(); + using (DbCommand cmd = _conn.CreateCommand()) + { + cmd.CommandText = "update migrations set version=" + version + " where name='" + type + "'"; + m_log.InfoFormat("[MIGRATIONS]: Updating {0} to version {1}", type, version); + cmd.ExecuteNonQuery(); + } } // private SortedList GetAllMigrations() From 2c595227b030221a0fa2ca2765b3bd3f053deac7 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 28 Apr 2010 07:41:16 -0700 Subject: [PATCH 23/27] Commented verbose debug messages from XInventory handler. --- .../Inventory/XInventoryInConnector.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index c95b4d44e3..16b05df9e2 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -91,7 +91,7 @@ namespace OpenSim.Server.Handlers.Asset sr.Close(); body = body.Trim(); - m_log.DebugFormat("[XXX]: query String: {0}", body); + //m_log.DebugFormat("[XXX]: query String: {0}", body); try { @@ -213,7 +213,7 @@ namespace OpenSim.Server.Handlers.Asset result["RESULT"] = "False"; string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -241,7 +241,7 @@ namespace OpenSim.Server.Handlers.Asset result["FOLDERS"] = sfolders; string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -257,7 +257,7 @@ namespace OpenSim.Server.Handlers.Asset result["folder"] = EncodeFolder(rfolder); string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -274,7 +274,7 @@ namespace OpenSim.Server.Handlers.Asset result["folder"] = EncodeFolder(folder); string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -310,7 +310,7 @@ namespace OpenSim.Server.Handlers.Asset } string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -338,7 +338,7 @@ namespace OpenSim.Server.Handlers.Asset result["ITEMS"] = sitems; string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -511,7 +511,7 @@ namespace OpenSim.Server.Handlers.Asset result["item"] = EncodeItem(item); string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -528,7 +528,7 @@ namespace OpenSim.Server.Handlers.Asset result["folder"] = EncodeFolder(folder); string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -553,7 +553,7 @@ namespace OpenSim.Server.Handlers.Asset result["ITEMS"] = items; string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -570,7 +570,7 @@ namespace OpenSim.Server.Handlers.Asset result["RESULT"] = perms.ToString(); string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } @@ -582,7 +582,7 @@ namespace OpenSim.Server.Handlers.Asset UUID.TryParse(request["PRINCIPAL"].ToString(), out principal); Dictionary sfolders = GetSystemFolders(principal); - m_log.DebugFormat("[XXX]: SystemFolders got {0} folders", sfolders.Count); + //m_log.DebugFormat("[XXX]: SystemFolders got {0} folders", sfolders.Count); Dictionary folders = new Dictionary(); int i = 0; @@ -594,7 +594,7 @@ namespace OpenSim.Server.Handlers.Asset result["FOLDERS"] = folders; string xmlString = ServerUtils.BuildXmlResponse(result); - m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetBytes(xmlString); } From 6a4fae123ade98d53e7342309dfb52e254d4b5f2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 29 Apr 2010 11:39:13 -0700 Subject: [PATCH 24/27] Started redoing HGInventoryBroker for XInventory and with multi-protocol in mind. Unfinished. --- .../Inventory/HGInventoryBroker2.cs | 589 ++++++++++++++++++ .../Inventory/InventoryCache.cs | 51 ++ .../RemoteXInventoryServiceConnector.cs | 5 + .../InventoryService/XInventoryService.cs | 6 +- 4 files changed, 648 insertions(+), 3 deletions(-) create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs new file mode 100644 index 0000000000..22aac02c75 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs @@ -0,0 +1,589 @@ +/* + * 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 log4net; +using Nini.Config; +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenSim.Framework; + +using OpenSim.Server.Base; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors; +using OpenMetaverse; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory +{ + public class HGInventoryBroker2 : BaseInventoryConnector, INonSharedRegionModule, IInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private static bool m_Initialized = false; + private static bool m_Enabled = false; + + private static IInventoryService m_LocalGridInventoryService; + private static ISessionAuthInventoryService m_HGService; // obsolete + private Dictionary m_connectors = new Dictionary(); + + + private Scene m_Scene; + private IUserAccountService m_UserAccountService; + + public Type ReplaceableInterface + { + get { return null; } + } + + public string Name + { + get { return "HGInventoryBroker2"; } + } + + public void Initialise(IConfigSource source) + { + if (!m_Initialized) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("InventoryServices", ""); + if (name == Name) + { + IConfig inventoryConfig = source.Configs["InventoryService"]; + if (inventoryConfig == null) + { + m_log.Error("[HG INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); + return; + } + + string localDll = inventoryConfig.GetString("LocalGridInventoryService", + String.Empty); + string HGDll = inventoryConfig.GetString("HypergridInventoryService", + String.Empty); + + if (localDll == String.Empty) + { + m_log.Error("[HG INVENTORY CONNECTOR]: No LocalGridInventoryService named in section InventoryService"); + //return; + throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's"); + } + + if (HGDll == String.Empty) + { + m_log.Error("[HG INVENTORY CONNECTOR]: No HypergridInventoryService named in section InventoryService"); + //return; + throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's"); + } + + Object[] args = new Object[] { source }; + m_LocalGridInventoryService = + ServerUtils.LoadPlugin(localDll, + args); + + m_HGService = + ServerUtils.LoadPlugin(HGDll, + args); + + if (m_LocalGridInventoryService == null) + { + m_log.Error("[HG INVENTORY CONNECTOR]: Can't load local inventory service"); + return; + } + if (m_HGService == null) + { + m_log.Error("[HG INVENTORY CONNECTOR]: Can't load hypergrid inventory service"); + return; + } + + Init(source); + + m_Enabled = true; + m_log.Info("[HG INVENTORY CONNECTOR]: HG inventory broker enabled"); + } + } + m_Initialized = true; + } + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + m_Scene = scene; + m_UserAccountService = m_Scene.UserAccountService; + + scene.RegisterModuleInterface(this); + m_cache.AddRegion(scene); + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + m_cache.RemoveRegion(scene); + } + + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_log.InfoFormat("[HG INVENTORY CONNECTOR]: Enabled HG inventory for region {0}", scene.RegionInfo.RegionName); + + } + + + #region IInventoryService + + public override bool CreateUserInventory(UUID userID) + { + return m_LocalGridInventoryService.CreateUserInventory(userID); + } + + public override List GetInventorySkeleton(UUID userId) + { + return m_LocalGridInventoryService.GetInventorySkeleton(userId); + } + + public override InventoryCollection GetUserInventory(UUID userID) + { + return null; + } + + public override void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + } + + // Inherited. See base + //public override InventoryFolderBase GetFolderForType(UUID userID, AssetType type) + //{ + // if (IsLocalGridUser(userID)) + // return m_GridService.GetFolderForType(userID, type); + // else + // { + // UUID sessionID = GetSessionID(userID); + // string uri = GetUserInventoryURI(userID) + "/" + userID.ToString(); + // // !!!!!! + // return null; + // //return m_HGService.GetFolderForType(uri, sessionID, type); + // } + //} + + public override InventoryCollection GetFolderContent(UUID userID, UUID folderID) + { + m_log.Debug("[HGInventory]: GetFolderContent " + folderID); + string url = string.Empty; + + string invURL = m_cache.GetInventoryServiceURL(userID); + + if (invURL == null) // not there, forward to local inventory connector to resolve + return m_LocalGridInventoryService.GetFolderContent(userID, folderID); + + IInventoryService connector = GetConnector(url); + return connector.GetFolderContent(userID, folderID); + + //if (StringToUrlAndUserID(id, out url, out userID)) + //{ + // ISessionAuthInventoryService connector = GetConnector(url); + // return connector.GetFolderContent(userID, folderID, sessionID); + //} + + //return null; + + ////////// + + //string uri = string.Empty; + //if (!IsForeignUser(userID, out uri)) + // return m_GridService.GetFolderContent(userID, folderID); + //else + //{ + // UUID sessionID = GetSessionID(userID); + // uri = uri + "/" + userID.ToString(); + // return m_HGService.GetFolderContent(uri, folderID, sessionID); + //} + } + + public override Dictionary GetSystemFolders(UUID userID) + { + string uri = string.Empty; + if (!IsForeignUser(userID, out uri)) + { + // This is not pretty, but it will have to do for now + if (m_LocalGridInventoryService is BaseInventoryConnector) + { + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetSystemsFolders redirected to RemoteInventoryServiceConnector module"); + return ((BaseInventoryConnector)m_LocalGridInventoryService).GetSystemFolders(userID); + } + else + { + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetSystemsFolders redirected to GetSystemFoldersLocal"); + return GetSystemFoldersLocal(userID); + } + } + else + { + UUID sessionID = GetSessionID(userID); + uri = uri + "/" + userID.ToString(); + return m_HGService.GetSystemFolders(uri, sessionID); + } + } + + private Dictionary GetSystemFoldersLocal(UUID userID) + { + InventoryFolderBase root = m_LocalGridInventoryService.GetRootFolder(userID); + if (root != null) + { + InventoryCollection content = m_LocalGridInventoryService.GetFolderContent(userID, root.ID); + if (content != null) + { + Dictionary folders = new Dictionary(); + foreach (InventoryFolderBase folder in content.Folders) + { + //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: scanning folder type {0}", (AssetType)folder.Type); + if ((folder.Type != (short)AssetType.Folder) && (folder.Type != (short)AssetType.Unknown)) + folders[(AssetType)folder.Type] = folder; + } + // Put the root folder there, as type Folder + folders[AssetType.Folder] = root; + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: System folders count for {0}: {1}", userID, folders.Count); + return folders; + } + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Root folder content not found for {0}", userID); + + } + + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Root folder not found for {0}", userID); + + return new Dictionary(); + } + + public override List GetFolderItems(UUID userID, UUID folderID) + { + string uri = string.Empty; + if (!IsForeignUser(userID, out uri)) + return m_LocalGridInventoryService.GetFolderItems(userID, folderID); + else + { + UUID sessionID = GetSessionID(userID); + uri = uri + "/" + userID.ToString(); + return m_HGService.GetFolderItems(uri, folderID, sessionID); + } + } + + public override bool AddFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + string uri = string.Empty; + if (!IsForeignUser(folder.Owner, out uri)) + return m_LocalGridInventoryService.AddFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + uri = uri + "/" + folder.Owner.ToString(); + return m_HGService.AddFolder(uri, folder, sessionID); + } + } + + public override bool UpdateFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + string uri = string.Empty; + if (!IsForeignUser(folder.Owner, out uri)) + return m_LocalGridInventoryService.UpdateFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + uri = uri + "/" + folder.Owner.ToString(); + return m_HGService.UpdateFolder(uri, folder, sessionID); + } + } + + public override bool DeleteFolders(UUID ownerID, List folderIDs) + { + if (folderIDs == null) + return false; + if (folderIDs.Count == 0) + return false; + + string uri = string.Empty; + if (!IsForeignUser(ownerID, out uri)) + return m_LocalGridInventoryService.DeleteFolders(ownerID, folderIDs); + else + { + UUID sessionID = GetSessionID(ownerID); + uri = uri + "/" + ownerID.ToString(); + return m_HGService.DeleteFolders(uri, folderIDs, sessionID); + } + } + + public override bool MoveFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + string uri = string.Empty; + if (!IsForeignUser(folder.Owner, out uri)) + return m_LocalGridInventoryService.MoveFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + uri = uri + "/" + folder.Owner.ToString(); + return m_HGService.MoveFolder(uri, folder, sessionID); + } + } + + public override bool PurgeFolder(InventoryFolderBase folder) + { + if (folder == null) + return false; + + string uri = string.Empty; + if (!IsForeignUser(folder.Owner, out uri)) + return m_LocalGridInventoryService.PurgeFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + uri = uri + "/" + folder.Owner.ToString(); + return m_HGService.PurgeFolder(uri, folder, sessionID); + } + } + + // public bool AddItem(InventoryItemBase item) inherited + // Uses AddItemPlain + + protected override bool AddItemPlain(InventoryItemBase item) + { + if (item == null) + return false; + + string uri = string.Empty; + if (!IsForeignUser(item.Owner, out uri)) + { + return m_LocalGridInventoryService.AddItem(item); + } + else + { + UUID sessionID = GetSessionID(item.Owner); + uri = uri + "/" + item.Owner.ToString(); + return m_HGService.AddItem(uri, item, sessionID); + } + } + + public override bool UpdateItem(InventoryItemBase item) + { + if (item == null) + return false; + + string uri = string.Empty; + if (!IsForeignUser(item.Owner, out uri)) + return m_LocalGridInventoryService.UpdateItem(item); + else + { + UUID sessionID = GetSessionID(item.Owner); + uri = uri + "/" + item.Owner.ToString(); + return m_HGService.UpdateItem(uri, item, sessionID); + } + } + + public override bool MoveItems(UUID ownerID, List items) + { + if (items == null) + return false; + if (items.Count == 0) + return true; + + string uri = string.Empty; + if (!IsForeignUser(ownerID, out uri)) + return m_LocalGridInventoryService.MoveItems(ownerID, items); + else + { + UUID sessionID = GetSessionID(ownerID); + uri = uri + "/" + ownerID.ToString(); + return m_HGService.MoveItems(uri, items, sessionID); + } + } + + public override bool DeleteItems(UUID ownerID, List itemIDs) + { + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Delete {0} items for user {1}", itemIDs.Count, ownerID); + + if (itemIDs == null) + return false; + if (itemIDs.Count == 0) + return true; + + string uri = string.Empty; + if (!IsForeignUser(ownerID, out uri)) + return m_LocalGridInventoryService.DeleteItems(ownerID, itemIDs); + else + { + UUID sessionID = GetSessionID(ownerID); + uri = uri + "/" + ownerID.ToString(); + return m_HGService.DeleteItems(uri, itemIDs, sessionID); + } + } + + public override InventoryItemBase GetItem(InventoryItemBase item) + { + if (item == null) + return null; + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetItem {0} for user {1}", item.ID, item.Owner); + string uri = string.Empty; + if (!IsForeignUser(item.Owner, out uri)) + return m_LocalGridInventoryService.GetItem(item); + else + { + UUID sessionID = GetSessionID(item.Owner); + uri = uri + "/" + item.Owner.ToString(); + return m_HGService.QueryItem(uri, item, sessionID); + } + } + + public override InventoryFolderBase GetFolder(InventoryFolderBase folder) + { + if (folder == null) + return null; + + string uri = string.Empty; + if (!IsForeignUser(folder.Owner, out uri)) + return m_LocalGridInventoryService.GetFolder(folder); + else + { + UUID sessionID = GetSessionID(folder.Owner); + uri = uri + "/" + folder.Owner.ToString(); + return m_HGService.QueryFolder(uri, folder, sessionID); + } + } + + public override bool HasInventoryForUser(UUID userID) + { + return false; + } + + public override List GetActiveGestures(UUID userId) + { + return new List(); + } + + public override int GetAssetPermissions(UUID userID, UUID assetID) + { + string uri = string.Empty; + if (!IsForeignUser(userID, out uri)) + return m_LocalGridInventoryService.GetAssetPermissions(userID, assetID); + else + { + UUID sessionID = GetSessionID(userID); + uri = uri + "/" + userID.ToString(); + return m_HGService.GetAssetPermissions(uri, assetID, sessionID); + } + } + + #endregion + + private IInventoryService GetConnector(string url) + { + IInventoryService connector = null; + lock (m_connectors) + { + if (m_connectors.ContainsKey(url)) + { + connector = m_connectors[url]; + } + else + { + // We're instantiating this class explicitly, but this won't + // work in general, because the remote grid may be running + // an inventory server that has a different protocol. + // Eventually we will want a piece of protocol asking + // the remote server about its kind. Definitely cool thing to do! + connector = new RemoteXInventoryServicesConnector(url); + m_connectors.Add(url, connector); + } + } + return connector; + } + + + private UUID GetSessionID(UUID userID) + { + ScenePresence sp = null; + if (m_Scene.TryGetScenePresence(userID, out sp)) + { + return sp.ControllingClient.SessionId; + } + + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: scene presence for {0} not found", userID); + return UUID.Zero; + } + + private bool IsForeignUser(UUID userID, out string inventoryURL) + { + inventoryURL = string.Empty; + UserAccount account = null; + if (m_Scene.UserAccountService != null) + account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, userID); + + if (account == null) // foreign user + { + ScenePresence sp = null; + m_Scene.TryGetScenePresence(userID, out sp); + if (sp != null) + { + AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI")) + { + inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString(); + inventoryURL = inventoryURL.Trim(new char[] { '/' }); + return true; + } + } + } + return false; + } + + + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index 5e06580cce..9c6e1cdd3c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs @@ -51,6 +51,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory // The cache proper protected Dictionary> m_InventoryCache; + // A cache of userIDs --> ServiceURLs, for HGBroker only + protected Dictionary m_InventoryURLs; + public virtual void Init(IConfigSource source, BaseInventoryConnector connector) { m_Scenes = new List(); @@ -89,8 +92,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory // If not, go get them and place them in the cache Dictionary folders = CacheSystemFolders(presence.UUID); + CacheInventoryServiceURL(presence.Scene, presence.UUID); + m_log.DebugFormat("[INVENTORY CACHE]: OnMakeRootAgent in {0}, fetched system folders for {1} {2}: count {3}", presence.Scene.RegionInfo.RegionName, presence.Firstname, presence.Lastname, folders.Count); + } void OnClientClosed(UUID clientID, Scene scene) @@ -113,6 +119,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory "[INVENTORY CACHE]: OnClientClosed in {0}, user {1} out of sim. Dropping system folders", scene.RegionInfo.RegionName, clientID); DropCachedSystemFolders(clientID); + DropInventoryServiceURL(clientID); } } @@ -174,5 +181,49 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return null; } + + /// + /// Gets the user's inventory URL from its serviceURLs, if the user is foreign, + /// and sticks it in the cache + /// + /// + private void CacheInventoryServiceURL(Scene scene, UUID userID) + { + if (scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, userID) == null) + { + // The user does not have a local account; let's cache its service URL + string inventoryURL = string.Empty; + ScenePresence sp = null; + scene.TryGetScenePresence(userID, out sp); + if (sp != null) + { + AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI")) + { + inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString(); + if (inventoryURL != null && inventoryURL != string.Empty) + { + inventoryURL = inventoryURL.Trim(new char[] { '/' }); + m_InventoryURLs.Add(userID, inventoryURL); + } + } + } + } + } + + private void DropInventoryServiceURL(UUID userID) + { + lock (m_InventoryURLs) + if (m_InventoryURLs.ContainsKey(userID)) + m_InventoryURLs.Remove(userID); + } + + public string GetInventoryServiceURL(UUID userID) + { + if (m_InventoryURLs.ContainsKey(userID)) + return m_InventoryURLs[userID]; + + return null; + } } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 8504b677c2..96d0c1c2fd 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -65,6 +65,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { } + public RemoteXInventoryServicesConnector(string url) + { + m_RemoteConnector = new XInventoryServicesConnector(url); + } + public RemoteXInventoryServicesConnector(IConfigSource source) { Init(source); diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 1409a0192d..4d7103bf73 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -184,7 +184,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryFolder x in allFolders) { - m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to skeleton", x.folderName); + //m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to skeleton", x.folderName); folders.Add(ConvertToOpenSim(x)); } @@ -233,7 +233,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryFolder x in folders) { - m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to response", x.folderName); + //m_log.DebugFormat("[XINVENTORY]: Adding folder {0} to response", x.folderName); inventory.Folders.Add(ConvertToOpenSim(x)); } @@ -243,7 +243,7 @@ namespace OpenSim.Services.InventoryService foreach (XInventoryItem i in items) { - m_log.DebugFormat("[XINVENTORY]: Adding item {0} to response", i.inventoryName); + //m_log.DebugFormat("[XINVENTORY]: Adding item {0} to response", i.inventoryName); inventory.Items.Add(ConvertToOpenSim(i)); } From 638dc8d3c25f68e6782d4cdbb202ad2c433bd676 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 29 Apr 2010 20:09:11 -0700 Subject: [PATCH 25/27] Simplified RemoteXInventoryServiceConnector and HGBroker (2) by a lot. --- .../Inventory/HGInventoryBroker2.cs | 477 ++++++++++-------- .../RemoteXInventoryServiceConnector.cs | 92 ++-- 2 files changed, 286 insertions(+), 283 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs index 22aac02c75..3509161daa 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs @@ -41,7 +41,7 @@ using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { - public class HGInventoryBroker2 : BaseInventoryConnector, INonSharedRegionModule, IInventoryService + public class HGInventoryBroker2 : INonSharedRegionModule, IInventoryService { private static readonly ILog m_log = LogManager.GetLogger( @@ -54,8 +54,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory private static ISessionAuthInventoryService m_HGService; // obsolete private Dictionary m_connectors = new Dictionary(); + // A cache of userIDs --> ServiceURLs, for HGBroker only + protected Dictionary m_InventoryURLs; private Scene m_Scene; + private List m_Scenes = new List(); + private IUserAccountService m_UserAccountService; public Type ReplaceableInterface @@ -124,8 +128,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return; } - Init(source); - m_Enabled = true; m_log.Info("[HG INVENTORY CONNECTOR]: HG inventory broker enabled"); } @@ -148,18 +150,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return; m_Scene = scene; + m_Scenes.Add(scene); m_UserAccountService = m_Scene.UserAccountService; scene.RegisterModuleInterface(this); - m_cache.AddRegion(scene); + + scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; + scene.EventManager.OnClientClosed += OnClientClosed; + } public void RemoveRegion(Scene scene) { if (!m_Enabled) return; - - m_cache.RemoveRegion(scene); + + m_Scenes.Remove(scene); } public void RegionLoaded(Scene scene) @@ -171,282 +177,302 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory } + #region Cache + + void OnMakeRootAgent(ScenePresence presence) + { + if (!m_InventoryURLs.ContainsKey(presence.UUID)) + CacheInventoryServiceURL(presence.Scene, presence.UUID); + } + + void OnClientClosed(UUID clientID, Scene scene) + { + if (m_InventoryURLs.ContainsKey(clientID)) // if it's in cache + { + ScenePresence sp = null; + foreach (Scene s in m_Scenes) + { + s.TryGetScenePresence(clientID, out sp); + if ((sp != null) && !sp.IsChildAgent && (s != scene)) + { + m_log.DebugFormat("[INVENTORY CACHE]: OnClientClosed in {0}, but user {1} still in sim. Keeping inventoryURL in cache", + scene.RegionInfo.RegionName, clientID); + return; + } + } + + m_log.DebugFormat( + "[INVENTORY CACHE]: OnClientClosed in {0}, user {1} out of sim. Dropping inventory URL", + scene.RegionInfo.RegionName, clientID); + DropInventoryServiceURL(clientID); + } + } + + /// + /// Gets the user's inventory URL from its serviceURLs, if the user is foreign, + /// and sticks it in the cache + /// + /// + private void CacheInventoryServiceURL(Scene scene, UUID userID) + { + if (scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, userID) == null) + { + // The user does not have a local account; let's cache its service URL + string inventoryURL = string.Empty; + ScenePresence sp = null; + scene.TryGetScenePresence(userID, out sp); + if (sp != null) + { + AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI")) + { + inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString(); + if (inventoryURL != null && inventoryURL != string.Empty) + { + inventoryURL = inventoryURL.Trim(new char[] { '/' }); + m_InventoryURLs.Add(userID, inventoryURL); + } + } + } + } + } + + private void DropInventoryServiceURL(UUID userID) + { + lock (m_InventoryURLs) + if (m_InventoryURLs.ContainsKey(userID)) + m_InventoryURLs.Remove(userID); + } + + public string GetInventoryServiceURL(UUID userID) + { + if (m_InventoryURLs.ContainsKey(userID)) + return m_InventoryURLs[userID]; + + return null; + } + #endregion #region IInventoryService - public override bool CreateUserInventory(UUID userID) + public bool CreateUserInventory(UUID userID) { return m_LocalGridInventoryService.CreateUserInventory(userID); } - public override List GetInventorySkeleton(UUID userId) + public List GetInventorySkeleton(UUID userId) { return m_LocalGridInventoryService.GetInventorySkeleton(userId); } - public override InventoryCollection GetUserInventory(UUID userID) + public InventoryCollection GetUserInventory(UUID userID) { return null; } - public override void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) { } - // Inherited. See base - //public override InventoryFolderBase GetFolderForType(UUID userID, AssetType type) - //{ - // if (IsLocalGridUser(userID)) - // return m_GridService.GetFolderForType(userID, type); - // else - // { - // UUID sessionID = GetSessionID(userID); - // string uri = GetUserInventoryURI(userID) + "/" + userID.ToString(); - // // !!!!!! - // return null; - // //return m_HGService.GetFolderForType(uri, sessionID, type); - // } - //} + public InventoryFolderBase GetRootFolder(UUID userID) + { + m_log.DebugFormat("[HGInventory]: GetRootFolder for {0}", userID); - public override InventoryCollection GetFolderContent(UUID userID, UUID folderID) + string invURL = GetInventoryServiceURL(userID); + + if (invURL == null) // not there, forward to local inventory connector to resolve + return m_LocalGridInventoryService.GetRootFolder(userID); + + IInventoryService connector = GetConnector(invURL); + + return connector.GetRootFolder(userID); + } + + public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) + { + m_log.DebugFormat("[HGInventory]: GetFolderForType {0} type {1}", userID, type); + + string invURL = GetInventoryServiceURL(userID); + + if (invURL == null) // not there, forward to local inventory connector to resolve + return m_LocalGridInventoryService.GetFolderForType(userID, type); + + IInventoryService connector = GetConnector(invURL); + + return connector.GetFolderForType(userID, type); + } + + public InventoryCollection GetFolderContent(UUID userID, UUID folderID) { m_log.Debug("[HGInventory]: GetFolderContent " + folderID); - string url = string.Empty; - string invURL = m_cache.GetInventoryServiceURL(userID); + string invURL = GetInventoryServiceURL(userID); if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.GetFolderContent(userID, folderID); - IInventoryService connector = GetConnector(url); + IInventoryService connector = GetConnector(invURL); + return connector.GetFolderContent(userID, folderID); - //if (StringToUrlAndUserID(id, out url, out userID)) - //{ - // ISessionAuthInventoryService connector = GetConnector(url); - // return connector.GetFolderContent(userID, folderID, sessionID); - //} - - //return null; - - ////////// - - //string uri = string.Empty; - //if (!IsForeignUser(userID, out uri)) - // return m_GridService.GetFolderContent(userID, folderID); - //else - //{ - // UUID sessionID = GetSessionID(userID); - // uri = uri + "/" + userID.ToString(); - // return m_HGService.GetFolderContent(uri, folderID, sessionID); - //} } - public override Dictionary GetSystemFolders(UUID userID) + public List GetFolderItems(UUID userID, UUID folderID) { - string uri = string.Empty; - if (!IsForeignUser(userID, out uri)) - { - // This is not pretty, but it will have to do for now - if (m_LocalGridInventoryService is BaseInventoryConnector) - { - m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetSystemsFolders redirected to RemoteInventoryServiceConnector module"); - return ((BaseInventoryConnector)m_LocalGridInventoryService).GetSystemFolders(userID); - } - else - { - m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetSystemsFolders redirected to GetSystemFoldersLocal"); - return GetSystemFoldersLocal(userID); - } - } - else - { - UUID sessionID = GetSessionID(userID); - uri = uri + "/" + userID.ToString(); - return m_HGService.GetSystemFolders(uri, sessionID); - } - } + m_log.Debug("[HGInventory]: GetFolderItems " + folderID); - private Dictionary GetSystemFoldersLocal(UUID userID) - { - InventoryFolderBase root = m_LocalGridInventoryService.GetRootFolder(userID); - if (root != null) - { - InventoryCollection content = m_LocalGridInventoryService.GetFolderContent(userID, root.ID); - if (content != null) - { - Dictionary folders = new Dictionary(); - foreach (InventoryFolderBase folder in content.Folders) - { - //m_log.DebugFormat("[HG INVENTORY CONNECTOR]: scanning folder type {0}", (AssetType)folder.Type); - if ((folder.Type != (short)AssetType.Folder) && (folder.Type != (short)AssetType.Unknown)) - folders[(AssetType)folder.Type] = folder; - } - // Put the root folder there, as type Folder - folders[AssetType.Folder] = root; - m_log.DebugFormat("[HG INVENTORY CONNECTOR]: System folders count for {0}: {1}", userID, folders.Count); - return folders; - } - m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Root folder content not found for {0}", userID); + string invURL = GetInventoryServiceURL(userID); - } - - m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Root folder not found for {0}", userID); - - return new Dictionary(); - } - - public override List GetFolderItems(UUID userID, UUID folderID) - { - string uri = string.Empty; - if (!IsForeignUser(userID, out uri)) + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.GetFolderItems(userID, folderID); - else - { - UUID sessionID = GetSessionID(userID); - uri = uri + "/" + userID.ToString(); - return m_HGService.GetFolderItems(uri, folderID, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.GetFolderItems(userID, folderID); + } - public override bool AddFolder(InventoryFolderBase folder) + public bool AddFolder(InventoryFolderBase folder) { if (folder == null) return false; - string uri = string.Empty; - if (!IsForeignUser(folder.Owner, out uri)) + m_log.Debug("[HGInventory]: AddFolder " + folder.ID); + + string invURL = GetInventoryServiceURL(folder.Owner); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.AddFolder(folder); - else - { - UUID sessionID = GetSessionID(folder.Owner); - uri = uri + "/" + folder.Owner.ToString(); - return m_HGService.AddFolder(uri, folder, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.AddFolder(folder); } - public override bool UpdateFolder(InventoryFolderBase folder) + public bool UpdateFolder(InventoryFolderBase folder) { if (folder == null) return false; - string uri = string.Empty; - if (!IsForeignUser(folder.Owner, out uri)) + m_log.Debug("[HGInventory]: UpdateFolder " + folder.ID); + + string invURL = GetInventoryServiceURL(folder.Owner); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.UpdateFolder(folder); - else - { - UUID sessionID = GetSessionID(folder.Owner); - uri = uri + "/" + folder.Owner.ToString(); - return m_HGService.UpdateFolder(uri, folder, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.UpdateFolder(folder); } - public override bool DeleteFolders(UUID ownerID, List folderIDs) + public bool DeleteFolders(UUID ownerID, List folderIDs) { if (folderIDs == null) return false; if (folderIDs.Count == 0) return false; - string uri = string.Empty; - if (!IsForeignUser(ownerID, out uri)) + m_log.Debug("[HGInventory]: DeleteFolders for " + ownerID); + + string invURL = GetInventoryServiceURL(ownerID); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.DeleteFolders(ownerID, folderIDs); - else - { - UUID sessionID = GetSessionID(ownerID); - uri = uri + "/" + ownerID.ToString(); - return m_HGService.DeleteFolders(uri, folderIDs, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.DeleteFolders(ownerID, folderIDs); } - public override bool MoveFolder(InventoryFolderBase folder) + public bool MoveFolder(InventoryFolderBase folder) { if (folder == null) return false; - string uri = string.Empty; - if (!IsForeignUser(folder.Owner, out uri)) + m_log.Debug("[HGInventory]: MoveFolder for " + folder.Owner); + + string invURL = GetInventoryServiceURL(folder.Owner); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.MoveFolder(folder); - else - { - UUID sessionID = GetSessionID(folder.Owner); - uri = uri + "/" + folder.Owner.ToString(); - return m_HGService.MoveFolder(uri, folder, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.MoveFolder(folder); } - public override bool PurgeFolder(InventoryFolderBase folder) + public bool PurgeFolder(InventoryFolderBase folder) { if (folder == null) return false; - string uri = string.Empty; - if (!IsForeignUser(folder.Owner, out uri)) + m_log.Debug("[HGInventory]: PurgeFolder for " + folder.Owner); + + string invURL = GetInventoryServiceURL(folder.Owner); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.PurgeFolder(folder); - else - { - UUID sessionID = GetSessionID(folder.Owner); - uri = uri + "/" + folder.Owner.ToString(); - return m_HGService.PurgeFolder(uri, folder, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.PurgeFolder(folder); } - // public bool AddItem(InventoryItemBase item) inherited - // Uses AddItemPlain - - protected override bool AddItemPlain(InventoryItemBase item) + public bool AddItem(InventoryItemBase item) { if (item == null) return false; - string uri = string.Empty; - if (!IsForeignUser(item.Owner, out uri)) - { + m_log.Debug("[HGInventory]: AddItem " + item.ID); + + string invURL = GetInventoryServiceURL(item.Owner); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.AddItem(item); - } - else - { - UUID sessionID = GetSessionID(item.Owner); - uri = uri + "/" + item.Owner.ToString(); - return m_HGService.AddItem(uri, item, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.AddItem(item); } - public override bool UpdateItem(InventoryItemBase item) + public bool UpdateItem(InventoryItemBase item) { if (item == null) return false; - string uri = string.Empty; - if (!IsForeignUser(item.Owner, out uri)) + m_log.Debug("[HGInventory]: UpdateItem " + item.ID); + + string invURL = GetInventoryServiceURL(item.Owner); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.UpdateItem(item); - else - { - UUID sessionID = GetSessionID(item.Owner); - uri = uri + "/" + item.Owner.ToString(); - return m_HGService.UpdateItem(uri, item, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.UpdateItem(item); } - public override bool MoveItems(UUID ownerID, List items) + public bool MoveItems(UUID ownerID, List items) { if (items == null) return false; if (items.Count == 0) return true; - string uri = string.Empty; - if (!IsForeignUser(ownerID, out uri)) + m_log.Debug("[HGInventory]: MoveItems for " + ownerID); + + string invURL = GetInventoryServiceURL(ownerID); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.MoveItems(ownerID, items); - else - { - UUID sessionID = GetSessionID(ownerID); - uri = uri + "/" + ownerID.ToString(); - return m_HGService.MoveItems(uri, items, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.MoveItems(ownerID, items); } - public override bool DeleteItems(UUID ownerID, List itemIDs) + public bool DeleteItems(UUID ownerID, List itemIDs) { m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Delete {0} items for user {1}", itemIDs.Count, ownerID); @@ -455,70 +481,73 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if (itemIDs.Count == 0) return true; - string uri = string.Empty; - if (!IsForeignUser(ownerID, out uri)) + m_log.Debug("[HGInventory]: DeleteItems for " + ownerID); + + string invURL = GetInventoryServiceURL(ownerID); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.DeleteItems(ownerID, itemIDs); - else - { - UUID sessionID = GetSessionID(ownerID); - uri = uri + "/" + ownerID.ToString(); - return m_HGService.DeleteItems(uri, itemIDs, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.DeleteItems(ownerID, itemIDs); } - public override InventoryItemBase GetItem(InventoryItemBase item) + public InventoryItemBase GetItem(InventoryItemBase item) { if (item == null) return null; - m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetItem {0} for user {1}", item.ID, item.Owner); - string uri = string.Empty; - if (!IsForeignUser(item.Owner, out uri)) + m_log.Debug("[HGInventory]: GetItem " + item.ID); + + string invURL = GetInventoryServiceURL(item.Owner); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.GetItem(item); - else - { - UUID sessionID = GetSessionID(item.Owner); - uri = uri + "/" + item.Owner.ToString(); - return m_HGService.QueryItem(uri, item, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.GetItem(item); } - public override InventoryFolderBase GetFolder(InventoryFolderBase folder) + public InventoryFolderBase GetFolder(InventoryFolderBase folder) { if (folder == null) return null; - string uri = string.Empty; - if (!IsForeignUser(folder.Owner, out uri)) + m_log.Debug("[HGInventory]: GetFolder " + folder.ID); + + string invURL = GetInventoryServiceURL(folder.Owner); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.GetFolder(folder); - else - { - UUID sessionID = GetSessionID(folder.Owner); - uri = uri + "/" + folder.Owner.ToString(); - return m_HGService.QueryFolder(uri, folder, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.GetFolder(folder); } - public override bool HasInventoryForUser(UUID userID) + public bool HasInventoryForUser(UUID userID) { return false; } - public override List GetActiveGestures(UUID userId) + public List GetActiveGestures(UUID userId) { return new List(); } - public override int GetAssetPermissions(UUID userID, UUID assetID) + public int GetAssetPermissions(UUID userID, UUID assetID) { - string uri = string.Empty; - if (!IsForeignUser(userID, out uri)) + m_log.Debug("[HGInventory]: GetAssetPermissions " + assetID); + + string invURL = GetInventoryServiceURL(userID); + + if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.GetAssetPermissions(userID, assetID); - else - { - UUID sessionID = GetSessionID(userID); - uri = uri + "/" + userID.ToString(); - return m_HGService.GetAssetPermissions(uri, assetID, sessionID); - } + + IInventoryService connector = GetConnector(invURL); + + return connector.GetAssetPermissions(userID, assetID); } #endregion diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 96d0c1c2fd..ac9e792317 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -41,7 +41,7 @@ using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { - public class RemoteXInventoryServicesConnector : BaseInventoryConnector, ISharedRegionModule, IInventoryService + public class RemoteXInventoryServicesConnector : ISharedRegionModule, IInventoryService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -75,10 +75,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory Init(source); } - protected override void Init(IConfigSource source) + protected void Init(IConfigSource source) { m_RemoteConnector = new XInventoryServicesConnector(source); - base.Init(source); } @@ -122,7 +121,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory } scene.RegisterModuleInterface(this); - m_cache.AddRegion(scene); } public void RemoveRegion(Scene scene) @@ -130,7 +128,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if (!m_Enabled) return; - m_cache.RemoveRegion(scene); } public void RegionLoaded(Scene scene) @@ -146,71 +143,51 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory #region IInventoryService - public override bool CreateUserInventory(UUID user) + public bool CreateUserInventory(UUID user) { return false; } - public override List GetInventorySkeleton(UUID userId) + public List GetInventorySkeleton(UUID userId) { return new List(); } - public override InventoryCollection GetUserInventory(UUID userID) + public InventoryCollection GetUserInventory(UUID userID) { return null; } - public override void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) { - try - { - m_RemoteConnector.GetUserInventory(userID, callback); - } - catch (Exception e) - { - if (StatsManager.SimExtraStats != null) - StatsManager.SimExtraStats.AddInventoryServiceRetrievalFailure(); - - m_log.ErrorFormat("[XINVENTORY CONNECTOR]: Request inventory operation failed, {0} {1}", - e.Source, e.Message); - } - } - // inherited. See base class - // public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) + public InventoryFolderBase GetRootFolder(UUID userID) + { + return m_RemoteConnector.GetRootFolder(userID); + } - public override Dictionary GetSystemFolders(UUID userID) + public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) + { + return m_RemoteConnector.GetFolderForType(userID, type); + } + + public Dictionary GetSystemFolders(UUID userID) { return m_RemoteConnector.GetSystemFolders(userID); } - public override InventoryCollection GetFolderContent(UUID userID, UUID folderID) + public InventoryCollection GetFolderContent(UUID userID, UUID folderID) { - m_log.DebugFormat("[XINVENTORY CONNECTOR]: GetFolderContent {0}", folderID); - try - { - return m_RemoteConnector.GetFolderContent(userID, folderID); - } - catch (Exception e) - { - m_log.ErrorFormat("[XINVENTORY CONNECTOR]: GetFolderContent operation failed, {0} {1}", - e.Source, e.Message); - } - InventoryCollection nullCollection = new InventoryCollection(); - nullCollection.Folders = new List(); - nullCollection.Items = new List(); - nullCollection.UserID = userID; - return nullCollection; + return m_RemoteConnector.GetFolderContent(userID, folderID); } - public override List GetFolderItems(UUID userID, UUID folderID) + public List GetFolderItems(UUID userID, UUID folderID) { return m_RemoteConnector.GetFolderItems(userID, folderID); } - public override bool AddFolder(InventoryFolderBase folder) + public bool AddFolder(InventoryFolderBase folder) { if (folder == null) return false; @@ -218,7 +195,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.AddFolder(folder); } - public override bool UpdateFolder(InventoryFolderBase folder) + public bool UpdateFolder(InventoryFolderBase folder) { if (folder == null) return false; @@ -226,7 +203,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.UpdateFolder(folder); } - public override bool MoveFolder(InventoryFolderBase folder) + public bool MoveFolder(InventoryFolderBase folder) { if (folder == null) return false; @@ -234,7 +211,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.MoveFolder(folder); } - public override bool DeleteFolders(UUID ownerID, List folderIDs) + public bool DeleteFolders(UUID ownerID, List folderIDs) { if (folderIDs == null) return false; @@ -245,7 +222,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory } - public override bool PurgeFolder(InventoryFolderBase folder) + public bool PurgeFolder(InventoryFolderBase folder) { if (folder == null) return false; @@ -253,10 +230,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.PurgeFolder(folder); } - // public bool AddItem(InventoryItemBase item) inherited - // Uses AddItemPlain - - protected override bool AddItemPlain(InventoryItemBase item) + public bool AddItem(InventoryItemBase item) { if (item == null) return false; @@ -264,7 +238,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.AddItem(item); } - public override bool UpdateItem(InventoryItemBase item) + public bool UpdateItem(InventoryItemBase item) { if (item == null) return false; @@ -272,7 +246,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.UpdateItem(item); } - public override bool MoveItems(UUID ownerID, List items) + public bool MoveItems(UUID ownerID, List items) { if (items == null) return false; @@ -281,7 +255,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory } - public override bool DeleteItems(UUID ownerID, List itemIDs) + public bool DeleteItems(UUID ownerID, List itemIDs) { if (itemIDs == null) return false; @@ -291,7 +265,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.DeleteItems(ownerID, itemIDs); } - public override InventoryItemBase GetItem(InventoryItemBase item) + public InventoryItemBase GetItem(InventoryItemBase item) { if (item == null) return null; @@ -299,7 +273,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.GetItem(item); } - public override InventoryFolderBase GetFolder(InventoryFolderBase folder) + public InventoryFolderBase GetFolder(InventoryFolderBase folder) { m_log.DebugFormat("[XINVENTORY CONNECTOR]: GetFolder {0}", folder.ID); if (folder == null) @@ -308,17 +282,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_RemoteConnector.GetFolder(folder); } - public override bool HasInventoryForUser(UUID userID) + public bool HasInventoryForUser(UUID userID) { return false; } - public override List GetActiveGestures(UUID userId) + public List GetActiveGestures(UUID userId) { return new List(); } - public override int GetAssetPermissions(UUID userID, UUID assetID) + public int GetAssetPermissions(UUID userID, UUID assetID) { return m_RemoteConnector.GetAssetPermissions(userID, assetID); } From 22b32171130b557dd83df218a38629589c7cc570 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 30 Apr 2010 11:46:50 +0100 Subject: [PATCH 26/27] Fix link security issue --- OpenSim/Framework/IClientAPI.cs | 2 +- .../ClientStack/LindenUDP/LLClientView.cs | 4 +- .../World/Permissions/PermissionsModule.cs | 6 +-- OpenSim/Region/DataSnapshot/ObjectSnapshot.cs | 2 +- .../Framework/Scenes/Scene.Inventory.cs | 50 +++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 8 +-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 41 ++++----------- 7 files changed, 70 insertions(+), 43 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index af88c4a632..01daeb1402 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -73,7 +73,7 @@ namespace OpenSim.Framework public delegate void LinkObjects(IClientAPI remoteClient, uint parent, List children); - public delegate void DelinkObjects(List primIds); + public delegate void DelinkObjects(List primIds, IClientAPI client); public delegate void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index d7120a5344..1f3582cfba 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -6151,7 +6151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP DelinkObjects handlerDelinkObjects = OnDelinkObjects; if (handlerDelinkObjects != null) { - handlerDelinkObjects(prims); + handlerDelinkObjects(prims, this); } return true; @@ -11820,4 +11820,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(dialog, ThrottleOutPacketType.Task); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 01359f0db9..f6bb3fef29 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1721,7 +1721,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return true; + return GenericObjectPermission(editorID, objectID, false); } private bool CanDelinkObject(UUID userID, UUID objectID) @@ -1729,7 +1729,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return true; + return GenericObjectPermission(editorID, objectID, false); } private bool CanBuyLand(UUID userID, ILandObject parcel, Scene scene) @@ -1894,4 +1894,4 @@ namespace OpenSim.Region.CoreModules.World.Permissions return(false); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs index f441aa9a84..6e699025b1 100644 --- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs +++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs @@ -69,7 +69,7 @@ namespace OpenSim.Region.DataSnapshot.Providers byte RayEndIsIntersection) { this.Stale = true; }; client.OnLinkObjects += delegate (IClientAPI remoteClient, uint parent, List children) { this.Stale = true; }; - client.OnDelinkObjects += delegate(List primIds) { this.Stale = true; }; + client.OnDelinkObjects += delegate(List primIds, IClientAPI clientApi) { this.Stale = true; }; client.OnGrabUpdate += delegate(UUID objectID, Vector3 offset, Vector3 grapPos, IClientAPI remoteClient, List surfaceArgs) { this.Stale = true; }; client.OnObjectAttach += delegate(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 15b523095f..6ebfd31896 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1941,5 +1941,55 @@ namespace OpenSim.Region.Framework.Scenes part.GetProperties(remoteClient); } } + + public void DelinkObjects(List primIds, IClientAPI client) + { + List parts = new List(); + + foreach (uint localID in primIds) + { + SceneObjectPart part = GetSceneObjectPart(localID); + + if (part == null) + continue; + + if (Permissions.CanDelinkObject(client.AgentId, part.ParentGroup.RootPart.UUID)) + parts.Add(part); + } + + m_sceneGraph.DelinkObjects(parts); + } + + public void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) + { + List owners = new List(); + + List children = new List(); + SceneObjectPart root = GetSceneObjectPart(parentPrimId); + + if (Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + return; + + foreach (uint localID in childPrimIds) + { + SceneObjectPart part = GetSceneObjectPart(localID); + + if (part == null) + continue; + + if (!owners.Contains(part.OwnerID)) + owners.Add(part.OwnerID); + + if (Permissions.CanLinkObject(client.AgentId, part.ParentGroup.RootPart.UUID)) + children.Add(part); + } + + // Must be all one owner + // + if (owners.Count > 1) + return; + + m_sceneGraph.LinkObjects(root, children); + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 57587bedd4..61a2956ed8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2721,8 +2721,8 @@ namespace OpenSim.Region.Framework.Scenes client.OnObjectName += m_sceneGraph.PrimName; client.OnObjectClickAction += m_sceneGraph.PrimClickAction; client.OnObjectMaterial += m_sceneGraph.PrimMaterial; - client.OnLinkObjects += m_sceneGraph.LinkObjects; - client.OnDelinkObjects += m_sceneGraph.DelinkObjects; + client.OnLinkObjects += LinkObjects; + client.OnDelinkObjects += DelinkObjects; client.OnObjectDuplicate += m_sceneGraph.DuplicateObject; client.OnObjectDuplicateOnRay += doObjectDuplicateOnRay; client.OnUpdatePrimFlags += m_sceneGraph.UpdatePrimFlags; @@ -2878,8 +2878,8 @@ namespace OpenSim.Region.Framework.Scenes client.OnObjectName -= m_sceneGraph.PrimName; client.OnObjectClickAction -= m_sceneGraph.PrimClickAction; client.OnObjectMaterial -= m_sceneGraph.PrimMaterial; - client.OnLinkObjects -= m_sceneGraph.LinkObjects; - client.OnDelinkObjects -= m_sceneGraph.DelinkObjects; + client.OnLinkObjects -= LinkObjects; + client.OnDelinkObjects -= DelinkObjects; client.OnObjectDuplicate -= m_sceneGraph.DuplicateObject; client.OnObjectDuplicateOnRay -= doObjectDuplicateOnRay; client.OnUpdatePrimFlags -= m_sceneGraph.UpdatePrimFlags; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 1421d0e974..ce11267196 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1463,20 +1463,21 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) + protected internal void LinkObjects(SceneObjectPart root, List children) { Monitor.Enter(m_updateLock); try { - SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); + SceneObjectGroup parentGroup = root.ParentGroup; List childGroups = new List(); if (parentGroup != null) { // We do this in reverse to get the link order of the prims correct - for (int i = childPrimIds.Count - 1; i >= 0; i--) + for (int i = children.Count - 1; i >= 0; i--) { - SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); + SceneObjectGroup child = children[i].ParentGroup; + if (child != null) { // Make sure no child prim is set for sale @@ -1509,17 +1510,6 @@ namespace OpenSim.Region.Framework.Scenes parentGroup.HasGroupChanged = true; parentGroup.ScheduleGroupForFullUpdate(); -// if (client != null) -// { -// parentGroup.GetProperties(client); -// } -// else -// { -// foreach (ScenePresence p in GetScenePresences()) -// { -// parentGroup.GetProperties(p.ControllingClient); -// } -// } } finally { @@ -1531,12 +1521,7 @@ namespace OpenSim.Region.Framework.Scenes /// Delink a linkset ///
/// - protected internal void DelinkObjects(List primIds) - { - DelinkObjects(primIds, true); - } - - protected internal void DelinkObjects(List primIds, bool sendEvents) + protected internal void DelinkObjects(List prims) { Monitor.Enter(m_updateLock); try @@ -1546,9 +1531,8 @@ namespace OpenSim.Region.Framework.Scenes List affectedGroups = new List(); // Look them all up in one go, since that is comparatively expensive // - foreach (uint primID in primIds) + foreach (SceneObjectPart part in prims) { - SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); if (part != null) { if (part.ParentGroup.Children.Count != 1) // Skip single @@ -1563,17 +1547,13 @@ namespace OpenSim.Region.Framework.Scenes affectedGroups.Add(group); } } - else - { - m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); - } } foreach (SceneObjectPart child in childParts) { // Unlink all child parts from their groups // - child.ParentGroup.DelinkFromGroup(child, sendEvents); + child.ParentGroup.DelinkFromGroup(child, true); } foreach (SceneObjectPart root in rootParts) @@ -1628,12 +1608,9 @@ namespace OpenSim.Region.Framework.Scenes List linkIDs = new List(); foreach (SceneObjectPart newChild in newSet) - { newChild.UpdateFlag = 0; - linkIDs.Add(newChild.LocalId); - } - LinkObjects(null, newRoot.LocalId, linkIDs); + LinkObjects(newRoot, newSet); if (!affectedGroups.Contains(newRoot.ParentGroup)) affectedGroups.Add(newRoot.ParentGroup); } From 0ea908291d63125c4c436ec1056af767aac716e6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 30 Apr 2010 12:06:58 +0100 Subject: [PATCH 27/27] Fix some symbol errors --- .../Region/CoreModules/World/Permissions/PermissionsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index f6bb3fef29..69b247c350 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1721,7 +1721,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + return GenericObjectPermission(userID, objectID, false); } private bool CanDelinkObject(UUID userID, UUID objectID) @@ -1729,7 +1729,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + return GenericObjectPermission(userID, objectID, false); } private bool CanBuyLand(UUID userID, ILandObject parcel, Scene scene)