diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b58a1afbb5..6eba24985a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (sp.PresenceType == PresenceType.Npc) RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); else - RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p); + RezSingleAttachmentFromInventory(sp, attach.ItemID, p); } catch (Exception e) { @@ -205,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) + private void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", @@ -266,25 +266,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); } } - - public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) - { - if (!Enabled) - return false; - - ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); - - if (sp == null) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); - return false; - } - - return AttachObject(sp, group, AttachmentPt, silent); - } - private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) + public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) { lock (sp.AttachmentsSyncLock) { @@ -364,29 +347,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } return true; + } + + private void RezMultipleAttachmentsFromInventory(IClientAPI remoteClient, List> rezlist) + { + if (!Enabled) + return; + + ScenePresence sp; + if (m_scene.TryGetScenePresence(remoteClient.AgentId, out sp)) + RezMultipleAttachmentsFromInventory(sp, rezlist); + else + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", + remoteClient.Name, remoteClient.AgentId); + return; } - public void RezMultipleAttachmentsFromInventory( - IClientAPI remoteClient, - List> rezlist) + public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) { if (!Enabled) - return; - - ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); - - if (sp == null) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", - remoteClient.Name, remoteClient.AgentId); - return; - } - + return; + +// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); lock (sp.AttachmentsSyncLock) { -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); - foreach (KeyValuePair rez in rezlist) { RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); @@ -394,7 +379,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + private ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); } @@ -418,7 +403,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt); } - public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt) + public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) { if (!Enabled) return null; @@ -628,23 +613,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments DetachSingleAttachmentToInv(itemID, presence); } } + } + + private void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) + { + if (!Enabled) + return; + + ScenePresence sp; + if (m_scene.TryGetScenePresence(remoteClient.AgentId, out sp)) + DetachSingleAttachmentToGround(sp, soLocalId); } - public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) + public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) { if (!Enabled) return; // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", -// remoteClient.Name, soLocalId); +// sp.UUID, soLocalId); SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); if (so == null) return; - if (so.AttachedAvatar != remoteClient.AgentId) + if (so.AttachedAvatar != sp.UUID) return; UUID inventoryID = so.GetFromItemID(); @@ -653,57 +648,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", // so.Name, so.LocalId, inventoryID); - ScenePresence presence; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) + lock (sp.AttachmentsSyncLock) { - lock (presence.AttachmentsSyncLock) - { - if (!m_scene.Permissions.CanRezObject( - so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) - return; + if (!m_scene.Permissions.CanRezObject( + so.PrimCount, sp.UUID, sp.AbsolutePosition)) + return; + + bool changed = sp.Appearance.DetachAttachment(inventoryID); + if (changed && m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); + + sp.RemoveAttachment(so); + + SceneObjectPart rootPart = so.RootPart; + rootPart.FromItemID = UUID.Zero; + so.AbsolutePosition = sp.AbsolutePosition; + so.AttachedAvatar = UUID.Zero; + rootPart.SetParentLocalId(0); + so.ClearPartAttachmentData(); + rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); + so.HasGroupChanged = true; + rootPart.Rezzed = DateTime.Now; + rootPart.RemFlag(PrimFlags.TemporaryOnRez); + so.AttachToBackup(); + m_scene.EventManager.TriggerParcelPrimCountTainted(); + rootPart.ScheduleFullUpdate(); + rootPart.ClearUndoState(); - bool changed = presence.Appearance.DetachAttachment(inventoryID); - if (changed && m_scene.AvatarFactory != null) - m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - - presence.RemoveAttachment(so); - DetachSceneObjectToGround(so, presence); - - List uuids = new List(); - uuids.Add(inventoryID); - m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); - remoteClient.SendRemoveInventoryItem(inventoryID); - } - - m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); + List uuids = new List(); + uuids.Add(inventoryID); + m_scene.InventoryService.DeleteItems(sp.UUID, uuids); + sp.ControllingClient.SendRemoveInventoryItem(inventoryID); } - } - /// - /// Detach the given scene object to the ground. - /// - /// - /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc. - /// - /// The scene object to detach. - /// The scene presence from which the scene object is being detached. - private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp) - { - SceneObjectPart rootPart = so.RootPart; - - rootPart.FromItemID = UUID.Zero; - so.AbsolutePosition = sp.AbsolutePosition; - so.AttachedAvatar = UUID.Zero; - rootPart.SetParentLocalId(0); - so.ClearPartAttachmentData(); - rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); - so.HasGroupChanged = true; - rootPart.Rezzed = DateTime.Now; - rootPart.RemFlag(PrimFlags.TemporaryOnRez); - so.AttachToBackup(); - m_scene.EventManager.TriggerParcelPrimCountTainted(); - rootPart.ScheduleFullUpdate(); - rootPart.ClearUndoState(); + m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); } // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index ff3358f4fe..832c6eba7c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; - m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); + m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false); // Check status on scene presence Assert.That(m_presence.HasAttachments(), Is.True); @@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( - m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + m_presence, attItemId, (uint)AttachmentPoint.Chest); // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.True); @@ -174,8 +174,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( - m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient); + m_presence, attItemId, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId); // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.False); @@ -208,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( - m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + m_presence, attItemId, (uint)AttachmentPoint.Chest); m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient); // Check status on scene presence diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index d7f0a9636a..e2a3fa757b 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -58,17 +58,6 @@ namespace OpenSim.Region.Framework.Interfaces /// void DeleteAttachmentsFromScene(IScenePresence sp, bool silent); - /// - /// Attach an object to an avatar from the world. - /// - /// - /// - /// - /// - /// - void AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent); - /// /// Attach an object to an avatar /// @@ -77,17 +66,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// true if the object was successfully attached, false otherwise - bool AttachObject( - IClientAPI remoteClient, SceneObjectGroup grp, uint AttachmentPt, bool silent); - - /// - /// Rez an attachment from user inventory and change inventory status to match. - /// - /// - /// - /// - /// The scene object that was attached. Null if the scene object could not be found - ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt); + bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent); /// /// Rez an attachment from user inventory and change inventory status to match. @@ -96,7 +75,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// The scene object that was attached. Null if the scene object could not be found - ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt); + ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt); // Same as above, but also load script states from a separate doc ISceneEntity RezSingleAttachmentFromInventory( @@ -105,12 +84,10 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Rez multiple attachments from a user's inventory /// - /// + /// /// /// - void RezMultipleAttachmentsFromInventory( - IClientAPI remoteClient, - List> rezlist); + void RezMultipleAttachmentsFromInventory(IScenePresence sp,List> rezlist); /// /// Detach an object from the avatar. @@ -126,9 +103,9 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Detach the given item to the ground. /// + /// /// - /// - void DetachSingleAttachmentToGround(uint objectLocalID, IClientAPI remoteClient); + void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID); /// /// Detach the given item so that it remains in the user's inventory. diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 9c4757ce9f..b288c8ace9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2528,9 +2528,7 @@ namespace OpenSim.Region.Framework.Scenes RootPrim.RemFlag(PrimFlags.TemporaryOnRez); if (AttachmentsModule != null) - AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); - - m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was found, attaching", sceneObject.UUID); + AttachmentsModule.AttachObject(sp, grp, 0, false); } else { diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 1a0d0c742d..49c06bcfcd 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs @@ -132,11 +132,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests UUID attAssetId = TestHelpers.ParseTail(0x3); string attName = "att"; - UserInventoryHelpers.CreateInventoryItem( - scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object); + UserInventoryHelpers.CreateInventoryItem(scene, attName, attItemId, attAssetId, sp.UUID, InventoryType.Object); - am.RezSingleAttachmentFromInventory( - sp.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest); INPCModule npcModule = scene.RequestModuleInterface(); UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b968bdcb24..fb595fe4fd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3265,10 +3265,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SceneObjectGroup grp = m_host.ParentGroup; ScenePresence presence = World.GetScenePresence(m_host.OwnerID); - if (presence.Scene.AttachmentsModule != null) - { - presence.Scene.AttachmentsModule.AttachObject(presence.ControllingClient, grp, (uint)attachment, false); - } + + IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; + if (attachmentsModule != null) + attachmentsModule.AttachObject(presence, grp, (uint)attachment, false); } }