diff options
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 92 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 7 |
2 files changed, 46 insertions, 53 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index fcf682b..1fa5ec0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -366,10 +366,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
366 | // At the moment we can only deal with a single attachment | 366 | // At the moment we can only deal with a single attachment |
367 | if (attachments.Count != 0) | 367 | if (attachments.Count != 0) |
368 | { | 368 | { |
369 | UUID oldAttachmentItemID = attachments[0].FromItemID; | 369 | if (attachments[0].FromItemID != UUID.Zero) |
370 | 370 | DetachSingleAttachmentToInvInternal(sp, attachments[0]); | |
371 | if (oldAttachmentItemID != UUID.Zero) | ||
372 | DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID); | ||
373 | else | 371 | else |
374 | m_log.WarnFormat( | 372 | m_log.WarnFormat( |
375 | "[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!", | 373 | "[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!", |
@@ -434,12 +432,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
434 | return null; | 432 | return null; |
435 | } | 433 | } |
436 | 434 | ||
437 | SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); | 435 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); |
438 | |||
439 | if (att == null) | ||
440 | DetachSingleAttachmentToInv(sp, itemID); | ||
441 | |||
442 | return att; | ||
443 | } | 436 | } |
444 | 437 | ||
445 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) | 438 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
@@ -516,18 +509,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
516 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); | 509 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); |
517 | } | 510 | } |
518 | 511 | ||
519 | public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID) | 512 | public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) |
520 | { | 513 | { |
521 | lock (sp.AttachmentsSyncLock) | 514 | lock (sp.AttachmentsSyncLock) |
522 | { | 515 | { |
523 | // Save avatar attachment information | 516 | // Save avatar attachment information |
524 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); | 517 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); |
525 | 518 | ||
526 | bool changed = sp.Appearance.DetachAttachment(itemID); | 519 | if (so.AttachedAvatar != sp.UUID) |
520 | { | ||
521 | m_log.WarnFormat( | ||
522 | "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", | ||
523 | so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); | ||
524 | |||
525 | return; | ||
526 | } | ||
527 | |||
528 | bool changed = sp.Appearance.DetachAttachment(so.FromItemID); | ||
527 | if (changed && m_scene.AvatarFactory != null) | 529 | if (changed && m_scene.AvatarFactory != null) |
528 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 530 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
529 | 531 | ||
530 | DetachSingleAttachmentToInvInternal(sp, itemID); | 532 | DetachSingleAttachmentToInvInternal(sp, so); |
531 | } | 533 | } |
532 | } | 534 | } |
533 | 535 | ||
@@ -794,46 +796,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
794 | return item; | 796 | return item; |
795 | } | 797 | } |
796 | 798 | ||
797 | // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. | 799 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) |
798 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? | ||
799 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID) | ||
800 | { | 800 | { |
801 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); | 801 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); |
802 | 802 | ||
803 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... | 803 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); |
804 | return; | 804 | sp.RemoveAttachment(so); |
805 | 805 | m_scene.DeleteSceneObject(so, false); | |
806 | // We can NOT use the dictionries here, as we are looking | ||
807 | // for an entity by the fromAssetID, which is NOT the prim UUID | ||
808 | EntityBase[] detachEntities = m_scene.GetEntities(); | ||
809 | SceneObjectGroup group; | ||
810 | |||
811 | lock (sp.AttachmentsSyncLock) | ||
812 | { | ||
813 | foreach (EntityBase entity in detachEntities) | ||
814 | { | ||
815 | if (entity is SceneObjectGroup) | ||
816 | { | ||
817 | group = (SceneObjectGroup)entity; | ||
818 | if (group.FromItemID == itemID) | ||
819 | { | ||
820 | m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); | ||
821 | sp.RemoveAttachment(group); | ||
822 | m_scene.DeleteSceneObject(group, false); | ||
823 | |||
824 | // Prepare sog for storage | ||
825 | group.AttachedAvatar = UUID.Zero; | ||
826 | group.RootPart.SetParentLocalId(0); | ||
827 | group.IsAttachment = false; | ||
828 | group.AbsolutePosition = group.RootPart.AttachedPos; | ||
829 | 806 | ||
830 | UpdateKnownItem(sp, group, true); | 807 | // Prepare sog for storage |
808 | so.AttachedAvatar = UUID.Zero; | ||
809 | so.RootPart.SetParentLocalId(0); | ||
810 | so.IsAttachment = false; | ||
811 | so.AbsolutePosition = so.RootPart.AttachedPos; | ||
831 | 812 | ||
832 | return; | 813 | UpdateKnownItem(sp, so, true); |
833 | } | ||
834 | } | ||
835 | } | ||
836 | } | ||
837 | } | 814 | } |
838 | 815 | ||
839 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 816 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
@@ -1047,8 +1024,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1047 | 1024 | ||
1048 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1025 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
1049 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | 1026 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); |
1027 | |||
1050 | if (sp != null && group != null) | 1028 | if (sp != null && group != null) |
1051 | DetachSingleAttachmentToInv(sp, group.FromItemID); | 1029 | DetachSingleAttachmentToInv(sp, group); |
1052 | } | 1030 | } |
1053 | 1031 | ||
1054 | private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) | 1032 | private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) |
@@ -1058,7 +1036,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1058 | 1036 | ||
1059 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1037 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
1060 | if (sp != null) | 1038 | if (sp != null) |
1061 | DetachSingleAttachmentToInv(sp, itemID); | 1039 | { |
1040 | lock (sp.AttachmentsSyncLock) | ||
1041 | { | ||
1042 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
1043 | |||
1044 | foreach (SceneObjectGroup group in attachments) | ||
1045 | { | ||
1046 | if (group.FromItemID == itemID) | ||
1047 | { | ||
1048 | DetachSingleAttachmentToInv(sp, group); | ||
1049 | return; | ||
1050 | } | ||
1051 | } | ||
1052 | } | ||
1053 | } | ||
1062 | } | 1054 | } |
1063 | 1055 | ||
1064 | private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) | 1056 | 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 1c10422..df99d0c 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); |