diff options
5 files changed, 58 insertions, 52 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index e9f0488..af30a8e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -302,10 +302,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
302 | // At the moment we can only deal with a single attachment | 302 | // At the moment we can only deal with a single attachment |
303 | if (attachments.Count != 0) | 303 | if (attachments.Count != 0) |
304 | { | 304 | { |
305 | UUID oldAttachmentItemID = attachments[0].FromItemID; | 305 | if (attachments[0].FromItemID != UUID.Zero) |
306 | 306 | DetachSingleAttachmentToInvInternal(sp, attachments[0]); | |
307 | if (oldAttachmentItemID != UUID.Zero) | ||
308 | DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID); | ||
309 | else | 307 | else |
310 | m_log.WarnFormat( | 308 | m_log.WarnFormat( |
311 | "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", | 309 | "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", |
@@ -442,18 +440,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
442 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); | 440 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); |
443 | } | 441 | } |
444 | 442 | ||
445 | public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID) | 443 | public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) |
446 | { | 444 | { |
447 | lock (sp.AttachmentsSyncLock) | 445 | lock (sp.AttachmentsSyncLock) |
448 | { | 446 | { |
449 | // Save avatar attachment information | 447 | // Save avatar attachment information |
450 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); | 448 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); |
451 | 449 | ||
452 | bool changed = sp.Appearance.DetachAttachment(itemID); | 450 | if (so.AttachedAvatar != sp.UUID) |
451 | { | ||
452 | m_log.WarnFormat( | ||
453 | "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", | ||
454 | so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); | ||
455 | |||
456 | return; | ||
457 | } | ||
458 | |||
459 | bool changed = sp.Appearance.DetachAttachment(so.FromItemID); | ||
453 | if (changed && m_scene.AvatarFactory != null) | 460 | if (changed && m_scene.AvatarFactory != null) |
454 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 461 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
455 | 462 | ||
456 | DetachSingleAttachmentToInvInternal(sp, itemID); | 463 | DetachSingleAttachmentToInvInternal(sp, so); |
457 | } | 464 | } |
458 | } | 465 | } |
459 | 466 | ||
@@ -657,39 +664,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
657 | return newItem; | 664 | return newItem; |
658 | } | 665 | } |
659 | 666 | ||
660 | // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. | 667 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) |
661 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? | ||
662 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID) | ||
663 | { | 668 | { |
664 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); | 669 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); |
665 | 670 | ||
666 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... | 671 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); |
667 | return; | 672 | sp.RemoveAttachment(so); |
668 | 673 | m_scene.DeleteSceneObject(so, false); | |
669 | lock (sp.AttachmentsSyncLock) | ||
670 | { | ||
671 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
672 | |||
673 | foreach (SceneObjectGroup group in attachments) | ||
674 | { | ||
675 | if (group.FromItemID == itemID) | ||
676 | { | ||
677 | m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); | ||
678 | sp.RemoveAttachment(group); | ||
679 | m_scene.DeleteSceneObject(group, false); | ||
680 | |||
681 | // Prepare sog for storage | ||
682 | group.AttachedAvatar = UUID.Zero; | ||
683 | group.RootPart.SetParentLocalId(0); | ||
684 | group.IsAttachment = false; | ||
685 | group.AbsolutePosition = group.RootPart.AttachedPos; | ||
686 | 674 | ||
687 | UpdateKnownItem(sp, group, true); | 675 | // Prepare sog for storage |
676 | so.AttachedAvatar = UUID.Zero; | ||
677 | so.RootPart.SetParentLocalId(0); | ||
678 | so.IsAttachment = false; | ||
679 | so.AbsolutePosition = so.RootPart.AttachedPos; | ||
688 | 680 | ||
689 | return; | 681 | UpdateKnownItem(sp, so, true); |
690 | } | ||
691 | } | ||
692 | } | ||
693 | } | 682 | } |
694 | 683 | ||
695 | private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 684 | private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
@@ -897,8 +886,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
897 | 886 | ||
898 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 887 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
899 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | 888 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); |
889 | |||
900 | if (sp != null && group != null) | 890 | if (sp != null && group != null) |
901 | DetachSingleAttachmentToInv(sp, group.FromItemID); | 891 | DetachSingleAttachmentToInv(sp, group); |
902 | } | 892 | } |
903 | 893 | ||
904 | private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) | 894 | private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) |
@@ -908,7 +898,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
908 | 898 | ||
909 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 899 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
910 | if (sp != null) | 900 | if (sp != null) |
911 | DetachSingleAttachmentToInv(sp, itemID); | 901 | { |
902 | lock (sp.AttachmentsSyncLock) | ||
903 | { | ||
904 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
905 | |||
906 | foreach (SceneObjectGroup group in attachments) | ||
907 | { | ||
908 | if (group.FromItemID == itemID) | ||
909 | { | ||
910 | DetachSingleAttachmentToInv(sp, group); | ||
911 | return; | ||
912 | } | ||
913 | } | ||
914 | } | ||
915 | } | ||
912 | } | 916 | } |
913 | 917 | ||
914 | private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) | 918 | private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 65722fe..b0c087f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -227,9 +227,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
227 | 227 | ||
228 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); | 228 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
229 | 229 | ||
230 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( | 230 | SceneObjectGroup so |
231 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | 231 | = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
232 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, attItem.ID); | 232 | sp, attItem.ID, (uint)AttachmentPoint.Chest); |
233 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so); | ||
233 | 234 | ||
234 | // Check status on scene presence | 235 | // Check status on scene presence |
235 | Assert.That(sp.HasAttachments(), Is.False); | 236 | Assert.That(sp.HasAttachments(), Is.False); |
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 375d334..ba35a41 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | |||
@@ -109,11 +109,11 @@ namespace OpenSim.Region.Framework.Interfaces | |||
109 | void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID); | 109 | void DetachSingleAttachmentToGround(IScenePresence sp, uint objectLocalID); |
110 | 110 | ||
111 | /// <summary> | 111 | /// <summary> |
112 | /// Detach the given item so that it remains in the user's inventory. | 112 | /// Detach the given attachment so that it remains in the user's inventory. |
113 | /// </summary> | 113 | /// </summary> |
114 | /// <param name="sp">/param> | 114 | /// <param name="sp">/param> |
115 | /// <param name="itemID"></param> | 115 | /// <param name="grp">The attachment to detach.</param> |
116 | void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID); | 116 | void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup grp); |
117 | 117 | ||
118 | /// <summary> | 118 | /// <summary> |
119 | /// Update the position of an attachment. | 119 | /// Update the position of an attachment. |
diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index 19a8236..e6b926c 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs | |||
@@ -72,6 +72,10 @@ namespace OpenSim.Region.Framework.Interfaces | |||
72 | /// <returns></returns> | 72 | /// <returns></returns> |
73 | List<SceneObjectGroup> GetAttachments(uint attachmentPoint); | 73 | List<SceneObjectGroup> GetAttachments(uint attachmentPoint); |
74 | 74 | ||
75 | /// <summary> | ||
76 | /// Does this avatar have any attachments? | ||
77 | /// </summary> | ||
78 | /// <returns></returns> | ||
75 | bool HasAttachments(); | 79 | bool HasAttachments(); |
76 | 80 | ||
77 | // Don't use these methods directly. Instead, use the AttachmentsModule | 81 | // Don't use these methods directly. Instead, use the AttachmentsModule |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a8679e2..12eb098 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2990,15 +2990,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2990 | 2990 | ||
2991 | private void DetachWrapper(object o) | 2991 | private void DetachWrapper(object o) |
2992 | { | 2992 | { |
2993 | SceneObjectPart host = (SceneObjectPart)o; | 2993 | if (World.AttachmentsModule != null) |
2994 | 2994 | { | |
2995 | SceneObjectGroup grp = host.ParentGroup; | 2995 | SceneObjectPart host = (SceneObjectPart)o; |
2996 | UUID itemID = grp.FromItemID; | 2996 | ScenePresence presence = World.GetScenePresence(host.OwnerID); |
2997 | ScenePresence presence = World.GetScenePresence(host.OwnerID); | 2997 | World.AttachmentsModule.DetachSingleAttachmentToInv(presence, host.ParentGroup); |
2998 | 2998 | } | |
2999 | IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; | ||
3000 | if (attachmentsModule != null) | ||
3001 | attachmentsModule.DetachSingleAttachmentToInv(presence, itemID); | ||
3002 | } | 2999 | } |
3003 | 3000 | ||
3004 | public void llAttachToAvatar(int attachmentPoint) | 3001 | public void llAttachToAvatar(int attachmentPoint) |