diff --git a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs index 8b44f72421..d5c062b831 100644 --- a/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/WebFetchInventoryDescendents/WebFetchInvDescHandler.cs @@ -162,7 +162,7 @@ namespace OpenSim.Capabilities.Handlers invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version); - if (inv.Folders != null) + if (inv != null && inv.Folders != null) { foreach (InventoryFolderBase invFolder in inv.Folders) { @@ -170,7 +170,7 @@ namespace OpenSim.Capabilities.Handlers } } - if (inv.Items != null) + if (inv != null && inv.Items != null) { foreach (InventoryItemBase invItem in inv.Items) { diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 2c0d8f0f63..ad5af1f5e0 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -662,11 +662,11 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (IOException e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e); + m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e); } catch (Exception e) { - m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw " + e.ToString()); + m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.StackTrace); SendHTML500(response); } finally diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 3118613afa..1004be6393 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -1923,7 +1923,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP folderBlock.FolderID = folder.ID; folderBlock.ParentID = folder.ParentID; - folderBlock.Type = -1; + //folderBlock.Type = -1; + folderBlock.Type = (sbyte)folder.Type; folderBlock.Name = Util.StringToBytes256(folder.Name); return folderBlock; @@ -4360,7 +4361,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP block.OwnerID = sop.OwnerID; block.ItemID = sop.FromUserInventoryItemID; - block.FolderID = UUID.Zero; // sop.FromFolderID ?? + block.FolderID = UUID.Zero; // sog.FromFolderID ?? block.FromTaskID = UUID.Zero; // ??? block.InventorySerial = (short)sop.InventorySerial; @@ -5082,7 +5083,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim if (data.ParentGroup.IsAttachment) { - update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); + update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID); update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); } else diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index c5cec5918d..78ae5e9756 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -285,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // At the moment we can only deal with a single attachment if (attachments.Count != 0) { - UUID oldAttachmentItemID = attachments[0].GetFromItemID(); + UUID oldAttachmentItemID = attachments[0].FromItemID; if (oldAttachmentItemID != UUID.Zero) DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID); @@ -296,7 +296,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } // Add the new attachment to inventory if we don't already have it. - UUID newAttachmentItemID = group.GetFromItemID(); + UUID newAttachmentItemID = group.FromItemID; if (newAttachmentItemID == UUID.Zero) newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; @@ -336,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments List existingAttachments = sp.GetAttachments(); foreach (SceneObjectGroup so in existingAttachments) { - if (so.GetFromItemID() == itemID) + if (so.FromItemID == itemID) { alreadyOn = true; break; @@ -393,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (so.AttachedAvatar != sp.UUID) return; - UUID inventoryID = so.GetFromItemID(); + UUID inventoryID = so.FromItemID; // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", @@ -410,9 +410,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); sp.RemoveAttachment(so); + so.FromItemID = UUID.Zero; SceneObjectPart rootPart = so.RootPart; - rootPart.FromItemID = UUID.Zero; so.AbsolutePosition = sp.AbsolutePosition; so.AttachedAvatar = UUID.Zero; rootPart.SetParentLocalId(0); @@ -526,7 +526,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); - InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), sp.UUID); + InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID); item = m_scene.InventoryService.GetItem(item); if (item != null) @@ -698,7 +698,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments item.CreationDate = Util.UnixTimeSinceEpoch(); // sets itemID so client can show item as 'attached' in inventory - grp.SetFromItemID(item.ID); + grp.FromItemID = item.ID; if (m_scene.AddInventoryItem(item)) { @@ -734,7 +734,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (entity is SceneObjectGroup) { group = (SceneObjectGroup)entity; - if (group.GetFromItemID() == itemID) + if (group.FromItemID == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); sp.RemoveAttachment(group); @@ -946,7 +946,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Calls attach with a Zero position if (AttachObject(sp, part.ParentGroup, AttachmentPt, false)) { - m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); + m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); // Save avatar attachment information m_log.Debug( @@ -969,7 +969,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); if (sp != null && group != null) - DetachSingleAttachmentToInv(sp, group.GetFromItemID()); + DetachSingleAttachmentToInv(sp, group.FromItemID); } private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 86cfb324dc..bfe5e4a37f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -120,8 +120,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That(attSo.IsTemporary, Is.False); // Check item status - Assert.That(m_presence.Appearance.GetAttachpoint( - attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest)); + Assert.That( + m_presence.Appearance.GetAttachpoint(attSo.FromItemID), + Is.EqualTo((int)AttachmentPoint.Chest)); } [Test] diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b64d372280..2b790f45c5 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -562,12 +562,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Finally, kill the agent we just created at the destination. m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); + sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); } protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) { logout = false; - return m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); + bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); + + if (success) + sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); + + return success; } protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 6fc8e4d434..8b5ad237f2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -51,8 +51,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private bool m_Initialized = false; - private bool m_RestrictInventoryAccessAbroad = false; - private GatekeeperServiceConnector m_GatekeeperConnector; #region ISharedRegionModule @@ -71,10 +69,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (name == Name) { InitialiseCommon(source); - IConfig transferConfig = source.Configs["HGEntityTransferModule"]; - if (transferConfig != null) - m_RestrictInventoryAccessAbroad = transferConfig.GetBoolean("RestrictInventoryAccessAbroad", false); - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); } } @@ -94,34 +88,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer client.OnTeleportHomeRequest += TriggerTeleportHome; client.OnTeleportLandmarkRequest += RequestTeleportLandmark; client.OnConnectionClosed += new Action(OnConnectionClosed); - client.OnCompleteMovementToRegion += new Action(OnCompleteMovementToRegion); } - protected void OnCompleteMovementToRegion(IClientAPI client, bool arg2) - { - // HACK HACK -- just seeing how the viewer responds - // Let's send the Suitcase or the real root folder folder for incoming HG agents - // Visiting agents get their suitcase contents; incoming local users get their real root folder's content - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: OnCompleteMovementToRegion of user {0}", client.AgentId); - object sp = null; - if (client.Scene.TryGetScenePresence(client.AgentId, out sp)) - { - if (sp is ScenePresence) - { - AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); - if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) - { - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: ViaHGLogin"); - if (m_RestrictInventoryAccessAbroad) - { - RestoreRootFolderContents(client); - } - } - } - } - } - - public override void RegionLoaded(Scene scene) { base.RegionLoaded(scene); @@ -131,12 +99,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); m_Initialized = true; - scene.AddCommand( - "HG", this, "send inventory", - "send inventory", - "Don't use this", - HandleSendInventory); - } } @@ -209,8 +171,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); logout = success; // flag for later logout from this grid; this is an HG TP - if (success && m_RestrictInventoryAccessAbroad) - RemoveRootFolderContents(sp.ControllingClient); + if (success) + sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); return success; } @@ -221,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } - return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); + return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); } public void TriggerTeleportHome(UUID id, IClientAPI client) @@ -330,15 +292,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } - protected override void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) - { - base.Fail(sp, finalDestination, logout); - if (logout && m_RestrictInventoryAccessAbroad) - { - RestoreRootFolderContents(sp.ControllingClient); - } - } - #endregion #region IUserAgentVerificationModule @@ -393,60 +346,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion - private void RemoveRootFolderContents(IClientAPI client) - { - // TODO tell the viewer to remove the root folder's content - if (client is IClientCore) - { - IClientCore core = (IClientCore)client; - IClientInventory inv; - - if (core.TryGet(out inv)) - { - InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId); - if (root != null) - { - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Removing root inventory for user {0}", client.AgentId); - InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID); - UUID[] ids = new UUID[content.Folders.Count]; - int i = 0; - foreach (InventoryFolderBase f in content.Folders) - ids[i++] = f.ID; - inv.SendRemoveInventoryFolders(ids); - ids = new UUID[content.Items.Count]; - i = 0; - foreach (InventoryItemBase it in content.Items) - ids[i++] = it.ID; - inv.SendRemoveInventoryItems(ids); - } - } - } - } - - private void RestoreRootFolderContents(IClientAPI client) - { - if (client is IClientCore) - { - IClientCore core = (IClientCore)client; - IClientInventory inv; - - if (core.TryGet(out inv)) - { - InventoryFolderBase root = m_Scenes[0].InventoryService.GetRootFolder(client.AgentId); - client.SendBulkUpdateInventory(root); - //if (root != null) - //{ - // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Restoring root inventory for user {0}", client.AgentId); - // InventoryCollection content = m_Scenes[0].InventoryService.GetFolderContent(client.AgentId, root.ID); - // m_log.DebugFormat("[XXX]: Folder name {0}, id {1}, parent {2}", root.Name, root.ID, root.ParentID); - // foreach (InventoryItemBase i in content.Items) - // m_log.DebugFormat("[XXX]: Name={0}, folderID={1}", i.Name, i.Folder); - - // inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray()); - //} - } - } - } private GridRegion MakeRegion(AgentCircuitData aCircuit) { @@ -465,13 +364,5 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return region; } - protected void HandleSendInventory(string module, string[] cmd) - { - m_Scenes[0].ForEachClient(delegate(IClientAPI client) - { - RestoreRootFolderContents(client); - }); - } - } } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index d2fe3888fa..a71584a91b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Reflection; using OpenSim.Framework; +using OpenSim.Framework.Client; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Connectors.Hypergrid; @@ -57,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess private string m_HomeURI; private bool m_OutboundPermission; private string m_ThisGatekeeper; + private bool m_RestrictInventoryAccessAbroad; // private bool m_Initialized = false; @@ -90,6 +92,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI); m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); + m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", false); } else m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); @@ -105,13 +108,79 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess base.AddRegion(scene); m_assMapper = new HGAssetMapper(scene, m_HomeURI); scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; - + scene.EventManager.OnTeleportStart += TeleportStart; + scene.EventManager.OnTeleportFail += TeleportFail; } #endregion #region Event handlers + protected override void OnNewClient(IClientAPI client) + { + base.OnNewClient(client); + client.OnCompleteMovementToRegion += new Action(OnCompleteMovementToRegion); + } + + protected void OnCompleteMovementToRegion(IClientAPI client, bool arg2) + { + //m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: OnCompleteMovementToRegion of user {0}", client.Name); + object sp = null; + if (client.Scene.TryGetScenePresence(client.AgentId, out sp)) + { + if (sp is ScenePresence) + { + AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); + if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) + { + if (m_RestrictInventoryAccessAbroad) + { + IUserManagement uMan = m_Scene.RequestModuleInterface(); + if (uMan.IsLocalGridUser(client.AgentId)) + ProcessInventoryForComingHome(client); + else + ProcessInventoryForArriving(client); + } + } + } + } + } + + protected void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout) + { + if (gridLogout && m_RestrictInventoryAccessAbroad) + { + IUserManagement uMan = m_Scene.RequestModuleInterface(); + if (uMan != null && uMan.IsLocalGridUser(client.AgentId)) + { + // local grid user + ProcessInventoryForHypergriding(client); + } + else + { + // Foreigner + ProcessInventoryForLeaving(client); + } + } + + } + + protected void TeleportFail(IClientAPI client, bool gridLogout) + { + if (gridLogout && m_RestrictInventoryAccessAbroad) + { + IUserManagement uMan = m_Scene.RequestModuleInterface(); + if (uMan.IsLocalGridUser(client.AgentId)) + { + ProcessInventoryForComingHome(client); + } + else + { + ProcessInventoryForArriving(client); + } + } + } + public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) { string userAssetServer = string.Empty; @@ -236,8 +305,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return false; } - #endregion - protected override InventoryItemBase GetItem(UUID agentID, UUID itemID) { InventoryItemBase item = base.GetItem(agentID, itemID); @@ -248,5 +315,84 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return item; } + + #endregion + + #region Inventory manipulation upon arriving/leaving + + // + // These 2 are for local and foreign users coming back, respectively + // + + private void ProcessInventoryForComingHome(IClientAPI client) + { + m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Restoring root folder for local user {0}", client.Name); + if (client is IClientCore) + { + IClientCore core = (IClientCore)client; + IClientInventory inv; + + if (core.TryGet(out inv)) + { + InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId); + InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); + + inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray()); + } + } + } + + private void ProcessInventoryForArriving(IClientAPI client) + { + } + + // + // These 2 are for local and foreign users going away respectively + // + + private void ProcessInventoryForHypergriding(IClientAPI client) + { + if (client is IClientCore) + { + IClientCore core = (IClientCore)client; + IClientInventory inv; + + if (core.TryGet(out inv)) + { + InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId); + if (root != null) + { + m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name); + InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); + List fids = new List(); + List iids = new List(); + List keep = new List(); + + foreach (InventoryFolderBase f in content.Folders) + { + if (f.Name != "My Suitcase") + { + f.Name = f.Name + " (Unavailable)"; + keep.Add(f); + } + } + + // items directly under the root folder + foreach (InventoryItemBase it in content.Items) + it.Name = it.Name + " (Unavailable)"; ; + + // Send the new names + inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray()); + + } + } + } + } + + private void ProcessInventoryForLeaving(IClientAPI client) + { + } + + #endregion } } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index aa996924af..74701a5b98 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -674,9 +674,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) { - if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) + if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) { - InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID); + InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); if (f != null) folder = m_Scene.InventoryService.GetFolder(f); } @@ -1012,7 +1012,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } - rootPart.FromFolderID = item.Folder; + so.FromFolderID = item.Folder; // Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", // rootPart.OwnerID, item.Owner, item.CurrentPermissions); @@ -1071,7 +1071,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess rootPart.TrimPermissions(); if (isAttachment) - so.SetFromItemID(item.ID); + so.FromItemID = item.ID; } return true; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index 4be3804c1f..cf6d2f7905 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs @@ -297,14 +297,35 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return m_LocalGridInventoryService.CreateUserInventory(userID); } - public List GetInventorySkeleton(UUID userId) + public List GetInventorySkeleton(UUID userID) { - return m_LocalGridInventoryService.GetInventorySkeleton(userId); + string invURL = GetInventoryServiceURL(userID); + + if (invURL == null) // not there, forward to local inventory connector to resolve + return m_LocalGridInventoryService.GetInventorySkeleton(userID); + + IInventoryService connector = GetConnector(invURL); + + return connector.GetInventorySkeleton(userID); } public InventoryCollection GetUserInventory(UUID userID) { - return null; + string invURL = GetInventoryServiceURL(userID); + m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetUserInventory for {0} {1}", userID, invURL); + + if (invURL == null) // not there, forward to local inventory connector to resolve + return m_LocalGridInventoryService.GetUserInventory(userID); + + InventoryCollection c = m_Cache.GetUserInventory(userID); + if (c != null) + return c; + + IInventoryService connector = GetConnector(invURL); + c = connector.GetUserInventory(userID); + + m_Cache.Cache(userID, c); + return c; } public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) @@ -362,8 +383,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.GetFolderContent(userID, folderID); - IInventoryService connector = GetConnector(invURL); + InventoryCollection c = m_Cache.GetFolderContent(userID, folderID); + if (c != null) + { + m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderContent found content in cache " + folderID); + return c; + } + IInventoryService connector = GetConnector(invURL); return connector.GetFolderContent(userID, folderID); } @@ -377,8 +404,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if (invURL == null) // not there, forward to local inventory connector to resolve return m_LocalGridInventoryService.GetFolderItems(userID, folderID); - IInventoryService connector = GetConnector(invURL); + List items = m_Cache.GetFolderItems(userID, folderID); + if (items != null) + { + m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems found items in cache " + folderID); + return items; + } + IInventoryService connector = GetConnector(invURL); return connector.GetFolderItems(userID, folderID); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index 0fe778dfa6..1e434b9394 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs @@ -12,6 +12,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory private static ExpiringCache m_RootFolders = new ExpiringCache(); private static ExpiringCache> m_FolderTypes = new ExpiringCache>(); + private static ExpiringCache m_Inventories = new ExpiringCache(); public void Cache(UUID userID, InventoryFolderBase root) { @@ -55,5 +56,55 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory return null; } + + public void Cache(UUID userID, InventoryCollection inv) + { + lock (m_Inventories) + m_Inventories.AddOrUpdate(userID, inv, 120); + } + + public InventoryCollection GetUserInventory(UUID userID) + { + InventoryCollection inv = null; + if (m_Inventories.TryGetValue(userID, out inv)) + return inv; + return null; + } + + public InventoryCollection GetFolderContent(UUID userID, UUID folderID) + { + InventoryCollection inv = null; + InventoryCollection c; + if (m_Inventories.TryGetValue(userID, out inv)) + { + c = new InventoryCollection(); + c.UserID = userID; + + c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f) + { + return f.ParentID == folderID; + }); + c.Items = inv.Items.FindAll(delegate(InventoryItemBase i) + { + return i.Folder == folderID; + }); + return c; + } + return null; + } + + public List GetFolderItems(UUID userID, UUID folderID) + { + InventoryCollection inv = null; + if (m_Inventories.TryGetValue(userID, out inv)) + { + List items = inv.Items.FindAll(delegate(InventoryItemBase i) + { + return i.Folder == folderID; + }); + return items; + } + return null; + } } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 77573c369b..990dffb61a 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -172,7 +172,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public InventoryCollection GetUserInventory(UUID userID) { - return null; + return m_RemoteConnector.GetUserInventory(userID); } public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) @@ -193,16 +193,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); - if (UserManager != null) + if (invCol != null && UserManager != null) { // Protect ourselves against the caller subsequently modifying the items list List items = new List(invCol.Items); - Util.FireAndForget(delegate - { - foreach (InventoryItemBase item in items) - UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); - }); + if (items != null && items.Count > 0) + Util.FireAndForget(delegate + { + foreach (InventoryItemBase item in items) + UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); + }); } return invCol; diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 1f3f07551c..509c4d7e3f 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -464,7 +464,7 @@ namespace OpenSim.Region.CoreModules.World.Land { if (d.GroupID == LandData.GroupID) { - m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout); + m_groupMemberCache.Add(avatar, true, m_groupMemberCacheTimeout); return true; } } @@ -472,10 +472,7 @@ namespace OpenSim.Region.CoreModules.World.Land return false; } - if (!sp.ControllingClient.IsGroupMember(LandData.GroupID)) - return false; - - return true; + return sp.ControllingClient.IsGroupMember(LandData.GroupID); } return false; } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 741d23336e..2365cfe3f7 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -506,6 +506,12 @@ namespace OpenSim.Region.Framework.Scenes public delegate void PrimsLoaded(Scene s); public event PrimsLoaded OnPrimsLoaded; + public delegate void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout); + public event TeleportStart OnTeleportStart; + + public delegate void TeleportFail(IClientAPI client, bool gridLogout); + public event TeleportFail OnTeleportFail; + public class MoneyTransferArgs : EventArgs { public UUID sender; @@ -2487,5 +2493,48 @@ namespace OpenSim.Region.Framework.Scenes } } } + + public void TriggerTeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout) + { + TeleportStart handler = OnTeleportStart; + + if (handler != null) + { + foreach (TeleportStart d in handler.GetInvocationList()) + { + try + { + d(client, destination, finalDestination, teleportFlags, gridLogout); + } + catch (Exception e) + { + m_log.ErrorFormat("[EVENT MANAGER]: Delegate for TeleportStart failed - continuing {0} - {1}", + e.Message, e.StackTrace); + } + } + } + } + + public void TriggerTeleportFail(IClientAPI client, bool gridLogout) + { + TeleportFail handler = OnTeleportFail; + + if (handler != null) + { + foreach (TeleportFail d in handler.GetInvocationList()) + { + try + { + d(client, gridLogout); + } + catch (Exception e) + { + m_log.ErrorFormat("[EVENT MANAGER]: Delegate for TeleportFail failed - continuing {0} - {1}", + e.Message, e.StackTrace); + } + } + } + } + } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6cf1067fc7..0089c7d405 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -36,6 +36,7 @@ using OpenMetaverse.Packets; using log4net; using OpenSim.Framework; using OpenSim.Region.Framework; +using OpenSim.Framework.Client; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes.Serialization; @@ -117,20 +118,43 @@ namespace OpenSim.Region.Framework.Scenes /// public bool AddInventoryItem(InventoryItemBase item) { - InventoryFolderBase folder; - - if (item.Folder == UUID.Zero) + if (item.Folder != UUID.Zero && InventoryService.AddItem(item)) { - folder = InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType); - if (folder == null) + int userlevel = 0; + if (Permissions.IsGod(item.Owner)) { - folder = InventoryService.GetRootFolder(item.Owner); - - if (folder == null) - return false; + userlevel = 1; } + EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel); - item.Folder = folder.ID; + return true; + } + + // OK so either the viewer didn't send a folderID or AddItem failed + UUID originalFolder = item.Folder; + InventoryFolderBase f = InventoryService.GetFolderForType(item.Owner, (AssetType)item.AssetType); + if (f != null) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Found folder {0} type {1} for item {2}", + f.Name, (AssetType)f.Type, item.Name); + + item.Folder = f.ID; + } + else + { + f = InventoryService.GetRootFolder(item.Owner); + if (f != null) + { + item.Folder = f.ID; + } + else + { + m_log.WarnFormat( + "[AGENT INVENTORY]: Could not find root folder for {0} when trying to add item {1} with no parent folder specified", + item.Owner, item.Name); + return false; + } } if (InventoryService.AddItem(item)) @@ -141,7 +165,13 @@ namespace OpenSim.Region.Framework.Scenes userlevel = 1; } EventManager.TriggerOnNewInventoryItemUploadComplete(item.Owner, item.AssetID, item.Name, userlevel); - + + if (originalFolder != UUID.Zero) + { + // Tell the viewer that the item didn't go there + ChangePlacement(item, f); + } + return true; } else @@ -153,7 +183,32 @@ namespace OpenSim.Region.Framework.Scenes return false; } } - + + private void ChangePlacement(InventoryItemBase item, InventoryFolderBase f) + { + ScenePresence sp = GetScenePresence(item.Owner); + if (sp != null) + { + if (sp.ControllingClient is IClientCore) + { + IClientCore core = (IClientCore)sp.ControllingClient; + IClientInventory inv; + + if (core.TryGet(out inv)) + { + InventoryFolderBase parent = new InventoryFolderBase(f.ParentID, f.Owner); + parent = InventoryService.GetFolder(parent); + inv.SendRemoveInventoryItems(new UUID[] { item.ID }); + inv.SendBulkUpdateInventory(new InventoryFolderBase[0], new InventoryItemBase[] { item }); + string message = "The item was placed in folder " + f.Name; + if (parent != null) + message += " under " + parent.Name; + sp.ControllingClient.SendAgentAlertMessage(message, false); + } + } + } + } + /// /// Add the given inventory item to a user's inventory. /// @@ -2085,7 +2140,7 @@ namespace OpenSim.Region.Framework.Scenes item.CreationDate = Util.UnixTimeSinceEpoch(); // sets itemID so client can show item as 'attached' in inventory - grp.SetFromItemID(item.ID); + grp.FromItemID = item.ID; if (AddInventoryItem(item)) remoteClient.SendInventoryItemCreateUpdate(item, 0); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index df37b98a99..a34079ccc8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2248,12 +2248,6 @@ namespace OpenSim.Region.Framework.Scenes part.RemoveFromPhysics(); } } - -// if (rootPart.PhysActor != null) -// { -// PhysicsScene.RemovePrim(rootPart.PhysActor); -// rootPart.PhysActor = null; -// } if (UnlinkSceneObject(group, false)) { @@ -2668,7 +2662,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup grp = sceneObject; m_log.DebugFormat( - "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.GetFromItemID(), grp.UUID); + "[ATTACHMENT]: Received attachment {0}, inworld asset id {1}", grp.FromItemID, grp.UUID); m_log.DebugFormat( "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 54e8d50618..107d9b625f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -775,7 +775,9 @@ namespace OpenSim.Region.Framework.Scenes set { m_LoopSoundSlavePrims = value; } } - // The UUID for the Region this Object is in. + /// + /// The UUID for the region this object is in. + /// public UUID RegionUUID { get @@ -788,6 +790,22 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// The item ID that this object was rezzed from, if applicable. + /// + /// + /// If not applicable will be UUID.Zero + /// + public UUID FromItemID { get; set; } + + /// + /// The folder ID that this object was rezzed from, if applicable. + /// + /// + /// If not applicable will be UUID.Zero + /// + public UUID FromFolderID { get; set; } + #endregion // ~SceneObjectGroup() @@ -851,18 +869,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void SetFromItemID(UUID AssetId) - { - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].FromItemID = AssetId; - } - - public UUID GetFromItemID() - { - return m_rootPart.FromItemID; - } - /// /// Hooks this object up to the backup event so that it is persisted to the database when the update thread executes. /// @@ -1498,7 +1504,7 @@ namespace OpenSim.Region.Framework.Scenes return; detachedpos = avatar.AbsolutePosition; - RootPart.FromItemID = UUID.Zero; + FromItemID = UUID.Zero; AbsolutePosition = detachedpos; AttachedAvatar = UUID.Zero; @@ -3379,6 +3385,7 @@ namespace OpenSim.Region.Framework.Scenes { m_rootPart.AttachedPos = pos; } + if (RootPart.GetStatusSandbox()) { if (Util.GetDistanceTo(RootPart.StatusSandboxPos, pos) > 10) @@ -3389,8 +3396,8 @@ namespace OpenSim.Region.Framework.Scenes ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name, UUID, false); } } - AbsolutePosition = pos; + AbsolutePosition = pos; HasGroupChanged = true; } @@ -4032,7 +4039,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual string ExtraToXmlString() { - return "" + GetFromItemID().ToString() + ""; + return "" + FromItemID.ToString() + ""; } public virtual void ExtraFromXmlString(string xmlstr) @@ -4044,7 +4051,7 @@ namespace OpenSim.Region.Framework.Scenes UUID uuid = UUID.Zero; UUID.TryParse(id, out uuid); - SetFromItemID(uuid); + FromItemID = uuid; } public void ResetOwnerChangeFlag() diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 951e9879c3..969ddafc2a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -126,12 +126,14 @@ namespace OpenSim.Region.Framework.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// - /// Is this sop a root part? + /// Is this a root part? /// - + /// + /// This will return true even if the whole object is attached to an avatar. + /// public bool IsRoot { - get { return ParentGroup.RootPart == this; } + get { return ParentGroup.RootPart == this; } } #region Fields @@ -160,15 +162,7 @@ namespace OpenSim.Region.Framework.Scenes /// If another thread is simultaneously turning physics off on this part then this refernece could become /// null at any time. /// - public PhysicsActor PhysActor - { - get { return m_physActor; } - set - { -// m_log.DebugFormat("[SOP]: PhysActor set to {0} for {1} {2}", value, Name, UUID); - m_physActor = value; - } - } + public PhysicsActor PhysActor { get; set; } //Xantor 20080528 Sound stuff: // Note: This isn't persisted in the database right now, as the fields for that aren't just there yet. @@ -188,10 +182,6 @@ namespace OpenSim.Region.Framework.Scenes public uint TimeStampLastActivity; // Will be used for AutoReturn public uint TimeStampTerse; - - public UUID FromItemID; - - public UUID FromFolderID; // The following two are to hold the attachment data // while an object is inworld @@ -275,7 +265,6 @@ namespace OpenSim.Region.Framework.Scenes private bool m_passTouches; - private PhysicsActor m_physActor; protected Vector3 m_acceleration; protected Vector3 m_angularVelocity; @@ -1149,6 +1138,14 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// The parent ID of this part. + /// + /// + /// If this is a root part which is not attached to an avatar then the value will be 0. + /// If this is a root part which is attached to an avatar then the value is the local id of that avatar. + /// If this is a child part then the value is the local ID of the root part. + /// public uint ParentID { get { return _parentID; } @@ -1847,9 +1844,6 @@ namespace OpenSim.Region.Framework.Scenes // if (VolumeDetectActive) // isPhantom = false; - // Added clarification.. since A rigid body is an object that you can kick around, etc. -// bool RigidBody = isPhysical && !isPhantom; - // The only time the physics scene shouldn't know about the prim is if it's phantom or an attachment, which is phantom by definition // or flexible // if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible)) @@ -1876,7 +1870,6 @@ namespace OpenSim.Region.Framework.Scenes PhysActor = null; } - // Basic Physics can also return null as well as an exception catch. PhysicsActor pa = PhysActor; if (pa != null) @@ -4859,7 +4852,52 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// This removes the part from physics + /// Adds this part to the physics scene. + /// + /// This method also sets the PhysActor property. + /// Add this prim with a rigid body. + /// + /// The physics actor. null if there was a failure. + /// + private PhysicsActor AddToPhysics(bool rigidBody) + { + PhysicsActor pa; + + try + { + pa = ParentGroup.Scene.PhysicsScene.AddPrimShape( + string.Format("{0}/{1}", Name, UUID), + Shape, + AbsolutePosition, + Scale, + RotationOffset, + rigidBody, + m_localId); + } + catch + { + m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); + pa = null; + } + + // FIXME: Ideally we wouldn't set the property here to reduce situations where threads changing physical + // properties can stop on each other. However, DoPhysicsPropertyUpdate() currently relies on PhysActor + // being set. + PhysActor = pa; + + // Basic Physics can also return null as well as an exception catch. + if (pa != null) + { + pa.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info + pa.SetMaterial(Material); + DoPhysicsPropertyUpdate(rigidBody, true); + } + + return pa; + } + + /// + /// This removes the part from the physics scene. /// /// /// This isn't the same as turning off physical, since even without being physical the prim has a physics diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ed3a7f11fa..b51d41be4c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3617,6 +3617,22 @@ namespace OpenSim.Region.Framework.Scenes }); } + /// + /// Gets the mass. + /// + /// + /// The mass. + /// + public float GetMass() + { + PhysicsActor pa = PhysicsActor; + + if (pa != null) + return pa.Mass; + else + return 0; + } + internal void PushForce(Vector3 impulse) { if (PhysicsActor != null) diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 9ff365229c..65bd26c773 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1294,7 +1294,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); - // Need to send a group membership update to the client // UDP version doesn't seem to behave nicely. But we're going to send it out here // with an empty group membership to hopefully remove groups being displayed due @@ -1305,6 +1304,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray); + if (remoteClient.AgentId == dataForAgentID) + remoteClient.RefreshGroupMembership(); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5268adeb01..7cf284d602 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2271,11 +2271,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected LSL_Vector GetPartLocalPos(SceneObjectPart part) { m_host.AddScriptLPS(1); - if (part.ParentID == 0) + + Vector3 pos; + + if (!part.IsRoot) { - return new LSL_Vector(part.AbsolutePosition.X, - part.AbsolutePosition.Y, - part.AbsolutePosition.Z); + pos = part.OffsetPosition; } else { @@ -2287,11 +2288,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - return new LSL_Vector(part.OffsetPosition.X, - part.OffsetPosition.Y, - part.OffsetPosition.Z); + pos = part.AbsolutePosition; } } + +// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); + + return new LSL_Vector(pos.X, pos.Y, pos.Z); } public void llSetRot(LSL_Rotation rot) @@ -3165,7 +3168,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float llGetMass() { m_host.AddScriptLPS(1); - return m_host.GetMass(); + + if (m_host.ParentGroup.IsAttachment) + { + ScenePresence attachedAvatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar); + + if (attachedAvatar != null) + { + return attachedAvatar.GetMass(); + } + else + { + return 0; + } + } + else + { + if (m_host.IsRoot) + { + return m_host.ParentGroup.GetMass(); + } + else + { + return m_host.GetMass(); + } + } } public void llCollisionFilter(string name, string id, int accept) @@ -3334,7 +3361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SceneObjectPart host = (SceneObjectPart)o; SceneObjectGroup grp = host.ParentGroup; - UUID itemID = grp.GetFromItemID(); + UUID itemID = grp.FromItemID; ScenePresence presence = World.GetScenePresence(host.OwnerID); IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; @@ -7782,14 +7809,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api switch (code) { case (int)ScriptBaseClass.PRIM_POSITION: - if (remain < 1) - return; - - v=rules.GetVector3Item(idx++); - positionChanged = true; - currentPosition = GetSetPosTarget(part, v, currentPosition); - - break; case (int)ScriptBaseClass.PRIM_POS_LOCAL: if (remain < 1) return; @@ -11154,6 +11173,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.OBJECT_CREATOR: ret.Add(new LSL_String(UUID.Zero.ToString())); break; + // For the following 8 see the Object version below + case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_SCRIPT_TIME: + ret.Add(new LSL_Float(0)); + break; + case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_SERVER_COST: + ret.Add(new LSL_Float(0)); + break; + case ScriptBaseClass.OBJECT_STREAMING_COST: + ret.Add(new LSL_Float(0)); + break; + case ScriptBaseClass.OBJECT_PHYSICS_COST: + ret.Add(new LSL_Float(0)); + break; + default: + // Invalid or unhandled constant. + ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); + break; } } @@ -11191,6 +11239,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ScriptBaseClass.OBJECT_CREATOR: ret.Add(new LSL_String(obj.CreatorID.ToString())); break; + // The following 8 I have intentionaly coded to return zero. They are part of + // "Land Impact" calculations. These calculations are probably not applicable + // to OpenSim, required figures (cpu/memory usage) are not currently tracked + // I have intentionally left these all at zero rather than return possibly + // missleading numbers + case ScriptBaseClass.OBJECT_RUNNING_SCRIPT_COUNT: + // in SL this currently includes crashed scripts + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_TOTAL_SCRIPT_COUNT: + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_SCRIPT_MEMORY: + // The value returned in SL for mono scripts is 65536 * number of active scripts + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_SCRIPT_TIME: + // Average cpu time per simulator frame expended on all scripts in the objetc + ret.Add(new LSL_Float(0)); + break; + case ScriptBaseClass.OBJECT_PRIM_EQUIVALENCE: + // according to the SL wiki A prim or linkset will have prim + // equivalent of the number of prims in a linkset if it does not + // contain a mesh anywhere in the link set or is not a normal prim + // The value returned in SL for normal prims is prim count + ret.Add(new LSL_Integer(0)); + break; + case ScriptBaseClass.OBJECT_SERVER_COST: + // The value returned in SL for normal prims is prim count + ret.Add(new LSL_Float(0)); + break; + case ScriptBaseClass.OBJECT_STREAMING_COST: + // The value returned in SL for normal prims is prim count * 0.06 + ret.Add(new LSL_Float(0)); + break; + case ScriptBaseClass.OBJECT_PHYSICS_COST: + // The value returned in SL for normal prims is prim count + ret.Add(new LSL_Float(0)); + break; + default: + // Invalid or unhandled constant. + ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); + break; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 4ce3cf19e2..6246b57c93 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -481,6 +481,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int DEBUG_CHANNEL = 0x7FFFFFFF; public const int PUBLIC_CHANNEL = 0x00000000; + // Constants for llGetObjectDetails + public const int OBJECT_UNKNOWN_DETAIL = -1; public const int OBJECT_NAME = 1; public const int OBJECT_DESC = 2; public const int OBJECT_POS = 3; @@ -489,6 +491,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int OBJECT_OWNER = 6; public const int OBJECT_GROUP = 7; public const int OBJECT_CREATOR = 8; + public const int OBJECT_RUNNING_SCRIPT_COUNT = 9; + public const int OBJECT_TOTAL_SCRIPT_COUNT = 10; + public const int OBJECT_SCRIPT_MEMORY = 11; + public const int OBJECT_SCRIPT_TIME = 12; + public const int OBJECT_PRIM_EQUIVALENCE = 13; + public const int OBJECT_SERVER_COST = 14; + public const int OBJECT_STREAMING_COST = 15; + public const int OBJECT_PHYSICS_COST = 16; // Can not be public const? public static readonly vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0); diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index 040c8405b3..cb9b65da77 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -114,6 +114,8 @@ namespace OpenSim.Server.Handlers.Asset return HandleCreateUserInventory(request); case "GETINVENTORYSKELETON": return HandleGetInventorySkeleton(request); + case "GETUSERINVENTORY": + return HandleGetUserInventory(request); case "GETROOTFOLDER": return HandleGetRootFolder(request); case "GETFOLDERFORTYPE": @@ -153,7 +155,7 @@ namespace OpenSim.Server.Handlers.Asset } catch (Exception e) { - m_log.DebugFormat("[XINVENTORY HANDLER]: Exception {0}", e); + m_log.DebugFormat("[XINVENTORY HANDLER]: Exception {0}", e.StackTrace); } return FailureResult(); @@ -248,6 +250,45 @@ namespace OpenSim.Server.Handlers.Asset return encoding.GetBytes(xmlString); } + byte[] HandleGetUserInventory(Dictionary request) + { + Dictionary result = new Dictionary(); + UUID principal = UUID.Zero; + UUID.TryParse(request["PRINCIPAL"].ToString(), out principal); + + InventoryCollection icoll = m_InventoryService.GetUserInventory(principal); + if (icoll != null) + { + Dictionary folders = new Dictionary(); + int i = 0; + if (icoll.Folders != null) + { + foreach (InventoryFolderBase f in icoll.Folders) + { + folders["folder_" + i.ToString()] = EncodeFolder(f); + i++; + } + result["FOLDERS"] = folders; + } + if (icoll.Items != null) + { + i = 0; + Dictionary items = new Dictionary(); + foreach (InventoryItemBase it in icoll.Items) + { + items["item_" + i.ToString()] = EncodeItem(it); + i++; + } + result["ITEMS"] = items; + } + } + + string xmlString = ServerUtils.BuildXmlResponse(result); + //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); + UTF8Encoding encoding = new UTF8Encoding(); + return encoding.GetBytes(xmlString); + } + byte[] HandleGetRootFolder(Dictionary request) { Dictionary result = new Dictionary(); @@ -293,22 +334,27 @@ namespace OpenSim.Server.Handlers.Asset if (icoll != null) { Dictionary folders = new Dictionary(); - int i = 0; - foreach (InventoryFolderBase f in icoll.Folders) + int i = 0; + if (icoll.Folders != null) { - folders["folder_" + i.ToString()] = EncodeFolder(f); - i++; + foreach (InventoryFolderBase f in icoll.Folders) + { + folders["folder_" + i.ToString()] = EncodeFolder(f); + i++; + } + result["FOLDERS"] = folders; } - result["FOLDERS"] = folders; - - i = 0; - Dictionary items = new Dictionary(); - foreach (InventoryItemBase it in icoll.Items) + if (icoll.Items != null) { - items["item_" + i.ToString()] = EncodeItem(it); - i++; + i = 0; + Dictionary items = new Dictionary(); + foreach (InventoryItemBase it in icoll.Items) + { + items["item_" + i.ToString()] = EncodeItem(it); + i++; + } + result["ITEMS"] = items; } - result["ITEMS"] = items; } string xmlString = ServerUtils.BuildXmlResponse(result); diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs index 39e983bfd9..9d96703c1a 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs @@ -111,19 +111,21 @@ namespace OpenSim.Services.Connectors if (ret.Count == 0) return null; - List folders = new List(); + Dictionary folders = (Dictionary)ret["FOLDERS"]; + + List fldrs = new List(); try { - foreach (Object o in ret.Values) - folders.Add(BuildFolder((Dictionary)o)); + foreach (Object o in folders.Values) + fldrs.Add(BuildFolder((Dictionary)o)); } catch (Exception e) { m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping folder list: {0}", e.Message); } - return folders; + return fldrs; } public InventoryFolderBase GetRootFolder(UUID principalID) @@ -492,12 +494,41 @@ namespace OpenSim.Services.Connectors return int.Parse(ret["RESULT"].ToString()); } - - // These are either obsolete or unused - // public InventoryCollection GetUserInventory(UUID principalID) { - return null; + InventoryCollection inventory = new InventoryCollection(); + inventory.Folders = new List(); + inventory.Items = new List(); + inventory.UserID = principalID; + + try + { + Dictionary ret = MakeRequest("GETUSERINVENTORY", + new Dictionary { + { "PRINCIPAL", principalID.ToString() } + }); + + if (ret == null) + return null; + if (ret.Count == 0) + return null; + + Dictionary folders = + (Dictionary)ret["FOLDERS"]; + Dictionary items = + (Dictionary)ret["ITEMS"]; + + 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 in GetUserInventory: {0}", e.Message); + } + + return inventory; } public void GetUserInventory(UUID principalID, InventoryReceiptCallback callback) diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs index b29d803e90..2e9bd40cd2 100644 --- a/OpenSim/Services/HypergridService/HGInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGInventoryService.cs @@ -105,6 +105,12 @@ namespace OpenSim.Services.HypergridService return new List(); } + public override InventoryCollection GetUserInventory(UUID userID) + { + // NOGO for this inventory service + return null; + } + public override InventoryFolderBase GetRootFolder(UUID principalID) { //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID); diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs index cb686e26e6..b6ec558b80 100644 --- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs @@ -59,7 +59,7 @@ namespace OpenSim.Services.HypergridService private UserAccountCache m_Cache; - private ExpiringCache> m_SuitcaseTrees = new ExpiringCache>(); + private ExpiringCache> m_SuitcaseTrees = new ExpiringCache>(); public HGSuitcaseInventoryService(IConfigSource config, string configName) : base(config, configName) @@ -104,11 +104,72 @@ namespace OpenSim.Services.HypergridService return false; } - public override List GetInventorySkeleton(UUID principalID) { - // NOGO for this inventory service - return new List(); + XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); + XInventoryFolder root = GetRootXFolder(principalID); + + List tree = GetFolderTree(suitcase.folderID); + if (tree == null || (tree != null && tree.Count == 0)) + return null; + + List folders = new List(); + foreach (XInventoryFolder x in tree) + { + folders.Add(ConvertToOpenSim(x)); + } + + SetAsRootFolder(suitcase, root); + folders.Add(ConvertToOpenSim(suitcase)); + + return folders; + } + + public override InventoryCollection GetUserInventory(UUID userID) + { + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Get Suitcase inventory for user {0}", userID); + InventoryCollection userInventory = new InventoryCollection(); + userInventory.UserID = userID; + userInventory.Folders = new List(); + userInventory.Items = new List(); + + XInventoryFolder suitcase = GetSuitcaseXFolder(userID); + XInventoryFolder root = GetRootXFolder(userID); + + List tree = GetFolderTree(suitcase.folderID); + if (tree == null || (tree != null && tree.Count == 0)) + { + SetAsRootFolder(suitcase, root); + userInventory.Folders.Add(ConvertToOpenSim(suitcase)); + return userInventory; + } + + List items; + foreach (XInventoryFolder f in tree) + { + // Add the items of this subfolder + items = GetFolderItems(userID, f.folderID); + if (items != null && items.Count > 0) + { + userInventory.Items.AddRange(items); + } + + // Add the folder itself + userInventory.Folders.Add(ConvertToOpenSim(f)); + } + + items = GetFolderItems(userID, suitcase.folderID); + if (items != null && items.Count > 0) + { + userInventory.Items.AddRange(items); + } + + SetAsRootFolder(suitcase, root); + userInventory.Folders.Add(ConvertToOpenSim(suitcase)); + + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetUserInventory for user {0} returning {1} folders and {2} items", + userID, userInventory.Folders.Count, userInventory.Items.Count); + return userInventory; } public override InventoryFolderBase GetRootFolder(UUID principalID) @@ -131,51 +192,92 @@ namespace OpenSim.Services.HypergridService { m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder. Creating it...", principalID); // make one, and let's add it to the user's inventory as a direct child of the root folder + // In the DB we tag it as type 100, but we use -1 (Unknown) outside suitcase = CreateFolder(principalID, root.folderID, 100, "My Suitcase"); if (suitcase == null) m_log.ErrorFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to create suitcase folder"); - m_Database.StoreFolder(suitcase); + + // Create System folders + CreateSystemFolders(principalID, suitcase.folderID); } - // Now let's change the folder ID to match that of the real root folder - SetAsRootFolder(suitcase, root.folderID); + SetAsRootFolder(suitcase, root); return ConvertToOpenSim(suitcase); } + protected void CreateSystemFolders(UUID principalID, UUID rootID) + { + m_log.Debug("[HG SUITCASE INVENTORY SERVICE]: Creating System folders under Suitcase..."); + XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootID); + + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Animation) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Animation, "Animations"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Bodypart) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Bodypart, "Body Parts"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.CallingCard) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.CallingCard, "Calling Cards"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Clothing) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Clothing, "Clothing"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Gesture) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Gesture, "Gestures"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Landmark) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Landmark, "Landmarks"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.LostAndFoundFolder) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.LostAndFoundFolder, "Lost And Found"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Notecard) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Notecard, "Notecards"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Object) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Object, "Objects"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.SnapshotFolder) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.SnapshotFolder, "Photo Album"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.LSLText) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.LSLText, "Scripts"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Sound) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Sound, "Sounds"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Texture) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.Texture, "Textures"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.TrashFolder) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.TrashFolder, "Trash"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.FavoriteFolder) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.FavoriteFolder, "Favorites"); + if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.CurrentOutfitFolder) return true; return false; })) + CreateFolder(principalID, rootID, (int)AssetType.CurrentOutfitFolder, "Current Outfit"); + + } + public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) { //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type); - return GetRootFolder(principalID); + XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); + XInventoryFolder[] folders = m_Database.GetFolders( + new string[] { "agentID", "type", "parentFolderID" }, + new string[] { principalID.ToString(), ((int)type).ToString(), suitcase.folderID.ToString() }); + + if (folders.Length == 0) + { + m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Found no folder for type {0} for user {1}", type, principalID); + return null; + } + + m_log.DebugFormat( + "[HG SUITCASE INVENTORY SERVICE]: Found folder {0} {1} for type {2} for user {3}", + folders[0].folderName, folders[0].folderID, type, principalID); + + return ConvertToOpenSim(folders[0]); } public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID) { InventoryCollection coll = null; XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); - XInventoryFolder root = GetRootXFolder(principalID); - if (!IsWithinSuitcaseTree(folderID, root, suitcase)) + if (!IsWithinSuitcaseTree(folderID, suitcase)) return new InventoryCollection(); - if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase - { - if (suitcase != null) - { - coll = base.GetFolderContent(principalID, suitcase.folderID); - foreach (InventoryFolderBase f in coll.Folders) - f.ParentID = root.folderID; - foreach (InventoryItemBase i in coll.Items) - i.Folder = root.folderID; - m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent for root folder returned content for suitcase folder"); - } - } - else - { - coll = base.GetFolderContent(principalID, folderID); - m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent for non-root folder {0}", folderID); - } + coll = base.GetFolderContent(principalID, folderID); + if (coll == null) { m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Something wrong with user {0}'s suitcase folder", principalID); @@ -188,10 +290,9 @@ namespace OpenSim.Services.HypergridService { // Let's do a bit of sanity checking, more than the base service does // make sure the given folder exists under the suitcase tree of this user - XInventoryFolder root = GetRootXFolder(principalID); XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); - if (!IsWithinSuitcaseTree(folderID, root, suitcase)) + if (!IsWithinSuitcaseTree(folderID, suitcase)) return new List(); return base.GetFolderItems(principalID, folderID); @@ -199,52 +300,40 @@ namespace OpenSim.Services.HypergridService public override bool AddFolder(InventoryFolderBase folder) { + m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder {0} {1}", folder.Name, folder.ParentID); // Let's do a bit of sanity checking, more than the base service does // make sure the given folder's parent folder exists under the suitcase tree of this user - XInventoryFolder root = GetRootXFolder(folder.Owner); XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); - if (!IsWithinSuitcaseTree(folder.ParentID, root, suitcase)) + if (!IsWithinSuitcaseTree(folder.ParentID, suitcase)) return false; // OK, it's legit - // Check if it's under the Root folder directly - if (folder.ParentID == root.folderID) - { - // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead - m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder for root folder for user {0}. Adding in suitcase instead", folder.Owner); - folder.ParentID = suitcase.folderID; - } - return base.AddFolder(folder); - } + } - public bool UpdateFolder(InventoryFolderBase folder) + public override bool UpdateFolder(InventoryFolderBase folder) { - XInventoryFolder root = GetRootXFolder(folder.Owner); XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); - if (!IsWithinSuitcaseTree(folder.ID, root, suitcase)) + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Update folder {0}, version {1}", folder.ID, folder.Version); + if (!IsWithinSuitcaseTree(folder.ID, suitcase)) + { + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: folder {0} not within Suitcase tree", folder.Name); return false; + } + // For all others return base.UpdateFolder(folder); } public override bool MoveFolder(InventoryFolderBase folder) { - XInventoryFolder root = GetRootXFolder(folder.Owner); XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner); - if (!IsWithinSuitcaseTree(folder.ID, root, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, root, suitcase)) + if (!IsWithinSuitcaseTree(folder.ID, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, suitcase)) return false; - if (folder.ParentID == root.folderID) - { - // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead - m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveFolder to root folder for user {0}. Moving it to suitcase instead", folder.Owner); - folder.ParentID = suitcase.folderID; - } - return base.MoveFolder(folder); } @@ -264,31 +353,21 @@ namespace OpenSim.Services.HypergridService { // Let's do a bit of sanity checking, more than the base service does // make sure the given folder's parent folder exists under the suitcase tree of this user - XInventoryFolder root = GetRootXFolder(item.Owner); XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner); - if (!IsWithinSuitcaseTree(item.Folder, root, suitcase)) + if (!IsWithinSuitcaseTree(item.Folder, suitcase)) return false; // OK, it's legit - // Check if it's under the Root folder directly - if (item.Folder == root.folderID) - { - // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead - m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddItem for root folder for user {0}. Adding in suitcase instead", item.Owner); - item.Folder = suitcase.folderID; - } - return base.AddItem(item); } public override bool UpdateItem(InventoryItemBase item) { - XInventoryFolder root = GetRootXFolder(item.Owner); XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner); - if (!IsWithinSuitcaseTree(item.Folder, root, suitcase)) + if (!IsWithinSuitcaseTree(item.Folder, suitcase)) return false; return base.UpdateItem(item); @@ -298,68 +377,64 @@ namespace OpenSim.Services.HypergridService { // Principal is b0rked. *sigh* - XInventoryFolder root = GetRootXFolder(items[0].Owner); XInventoryFolder suitcase = GetSuitcaseXFolder(items[0].Owner); - if (!IsWithinSuitcaseTree(items[0].Folder, root, suitcase)) + if (!IsWithinSuitcaseTree(items[0].Folder, suitcase)) return false; - foreach (InventoryItemBase it in items) - if (it.Folder == root.folderID) - { - // someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead - m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveItem to root folder for user {0}. Moving it to suitcase instead", it.Owner); - it.Folder = suitcase.folderID; - } - return base.MoveItems(principalID, items); } - // Let these pass. Use inherited methods. public override bool DeleteItems(UUID principalID, List itemIDs) { return false; } - public override InventoryItemBase GetItem(InventoryItemBase item) + public new InventoryItemBase GetItem(InventoryItemBase item) { InventoryItemBase it = base.GetItem(item); - XInventoryFolder root = GetRootXFolder(it.Owner); - XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner); - - if (it != null) + if (it == null) { - if (!IsWithinSuitcaseTree(it.Folder, root, suitcase)) - return null; - - if (it.Folder == suitcase.folderID) - it.Folder = root.folderID; - - // UserAccount user = m_Cache.GetUser(it.CreatorId); - - // // Adjust the creator data - // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) - // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName; - //} + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve item {0} ({1}) in folder {2}", + item.Name, item.ID, item.Folder); + return null; } + XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner); + if (suitcase == null) + { + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Root or Suitcase are null for user {0}", + it.Owner); + return null; + } + + if (!IsWithinSuitcaseTree(it.Folder, suitcase)) + { + m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Item {0} (folder {1}) is not within Suitcase", + it.Name, it.Folder); + return null; + } + + // UserAccount user = m_Cache.GetUser(it.CreatorId); + + // // Adjust the creator data + // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) + // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName; + //} return it; } - public override InventoryFolderBase GetFolder(InventoryFolderBase folder) + public new InventoryFolderBase GetFolder(InventoryFolderBase folder) { InventoryFolderBase f = base.GetFolder(folder); - XInventoryFolder root = GetRootXFolder(f.Owner); - XInventoryFolder suitcase = GetSuitcaseXFolder(f.Owner); if (f != null) { - if (!IsWithinSuitcaseTree(f.ID, root, suitcase)) - return null; + XInventoryFolder suitcase = GetSuitcaseXFolder(f.Owner); - if (f.ParentID == suitcase.folderID) - f.ParentID = root.folderID; + if (!IsWithinSuitcaseTree(f.ID, suitcase)) + return null; } return f; @@ -409,20 +484,19 @@ namespace OpenSim.Services.HypergridService return null; } - private void SetAsRootFolder(XInventoryFolder suitcase, UUID rootID) + private void SetAsRootFolder(XInventoryFolder suitcase, XInventoryFolder root) { - suitcase.folderID = rootID; - suitcase.parentFolderID = UUID.Zero; + suitcase.type = (short)AssetType.Folder; } - private List GetFolderTree(UUID root) + private List GetFolderTree(UUID folder) { List t = null; - if (m_SuitcaseTrees.TryGetValue(root, out t)) + if (m_SuitcaseTrees.TryGetValue(folder, out t)) return t; - t = GetFolderTreeRecursive(root); - m_SuitcaseTrees.AddOrUpdate(root, t, 120); + t = GetFolderTreeRecursive(folder); + m_SuitcaseTrees.AddOrUpdate(folder, t, 120); return t; } @@ -447,10 +521,17 @@ namespace OpenSim.Services.HypergridService } - private bool IsWithinSuitcaseTree(UUID folderID, XInventoryFolder root, XInventoryFolder suitcase) + /// + /// Return true if the folderID is a subfolder of the Suitcase or the suitcase folder itself + /// + /// + /// + /// + /// + private bool IsWithinSuitcaseTree(UUID folderID, XInventoryFolder suitcase) { List tree = new List(); - tree.Add(root); // Warp! the tree is the real root folder plus the children of the suitcase folder + tree.Add(suitcase); // Warp! the tree is the real root folder plus the children of the suitcase folder tree.AddRange(GetFolderTree(suitcase.folderID)); XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl) { @@ -463,4 +544,5 @@ namespace OpenSim.Services.HypergridService } #endregion } + } diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 7b2c3a6aff..0e7a3584e2 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService { public class XInventoryService : ServiceBase, IInventoryService { -// private static readonly ILog m_log = -// LogManager.GetLogger( -// MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); protected IXInventoryData m_Database; protected bool m_AllowDelete = true; @@ -113,7 +113,7 @@ namespace OpenSim.Services.InventoryService result = true; } - XInventoryFolder[] sysFolders = GetSystemFolders(principalID); + XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootFolder.ID); if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Animation) return true; return false; })) CreateFolder(principalID, rootFolder.ID, (int)AssetType.Animation, "Animations"); @@ -163,13 +163,13 @@ namespace OpenSim.Services.InventoryService return newFolder; } - protected virtual XInventoryFolder[] GetSystemFolders(UUID principalID) + protected virtual XInventoryFolder[] GetSystemFolders(UUID principalID, UUID rootID) { // m_log.DebugFormat("[XINVENTORY SERVICE]: Getting system folders for {0}", principalID); XInventoryFolder[] allFolders = m_Database.GetFolders( - new string[] { "agentID" }, - new string[] { principalID.ToString() }); + new string[] { "agentID", "parentFolderID" }, + new string[] { principalID.ToString(), rootID.ToString() }); XInventoryFolder[] sysFolders = Array.FindAll( allFolders, @@ -301,16 +301,26 @@ namespace OpenSim.Services.InventoryService public virtual bool AddFolder(InventoryFolderBase folder) { + //m_log.DebugFormat("[XINVENTORY]: Add folder {0} type {1} in parent {2}", folder.Name, folder.Type, folder.ParentID); InventoryFolderBase check = GetFolder(folder); if (check != null) return false; - XInventoryFolder xFolder = ConvertFromOpenSim(folder); - return m_Database.StoreFolder(xFolder); + if (folder.Type == (short)AssetType.Folder || folder.Type == (short)AssetType.Unknown || + GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null) + { + XInventoryFolder xFolder = ConvertFromOpenSim(folder); + return m_Database.StoreFolder(xFolder); + } + else + m_log.DebugFormat("[XINVENTORY]: Folder {0} of type {1} already exists", folder.Name, folder.Type); + + return false; } public virtual bool UpdateFolder(InventoryFolderBase folder) { + //m_log.DebugFormat("[XINVENTORY]: Update folder {0} {1} ({2})", folder.Name, folder.Type, folder.ID); XInventoryFolder xFolder = ConvertFromOpenSim(folder); InventoryFolderBase check = GetFolder(folder); if (check == null) @@ -319,9 +329,13 @@ namespace OpenSim.Services.InventoryService if (check.Type != -1 || xFolder.type != -1) { if (xFolder.version < check.Version) + { + //m_log.DebugFormat("[XINVENTORY]: {0} < {1} can't do", xFolder.version, check.Version); return false; + } check.Version = (ushort)xFolder.version; xFolder = ConvertFromOpenSim(check); + //m_log.DebugFormat("[XINVENTORY]: Storing {0} {1} {2}", xFolder.folderName, xFolder.version, xFolder.type); return m_Database.StoreFolder(xFolder); } @@ -499,13 +513,30 @@ namespace OpenSim.Services.InventoryService return m_Database.GetAssetPermissions(principalID, assetID); } - // CM never needed those. Left unimplemented. - // Obsolete in core - // - public InventoryCollection GetUserInventory(UUID userID) + public virtual InventoryCollection GetUserInventory(UUID userID) { - return null; + InventoryCollection userInventory = new InventoryCollection(); + userInventory.UserID = userID; + userInventory.Folders = new List(); + userInventory.Items = new List(); + + List skel = GetInventorySkeleton(userID); + if (skel != null) + { + foreach (InventoryFolderBase f in skel) + { + InventoryCollection c = GetFolderContent(userID, f.ID); + if (c != null && c.Items != null && c.Items.Count > 0) + userInventory.Items.AddRange(c.Items); + if (c != null && c.Folders != null && c.Folders.Count > 0) + userInventory.Folders.AddRange(c.Folders); + } + } + m_log.DebugFormat("[XINVENTORY SERVICE]: GetUserInventory for user {0} returning {1} folders and {2} items", + userID, userInventory.Folders.Count, userInventory.Items.Count); + return userInventory; } + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) { } @@ -525,6 +556,9 @@ namespace OpenSim.Services.InventoryService newFolder.ParentID = folder.parentFolderID; newFolder.Type = (short)folder.type; + // Viewer can't understand anything that's not in it's LLFolderType enum + if (newFolder.Type == 100) + newFolder.Type = -1; newFolder.Version = (ushort)folder.version; newFolder.Name = folder.folderName; newFolder.Owner = folder.agentID;