diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 158 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 10 |
2 files changed, 73 insertions, 95 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b58a1af..6eba249 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 | |||
153 | if (sp.PresenceType == PresenceType.Npc) | 153 | if (sp.PresenceType == PresenceType.Npc) |
154 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); | 154 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); |
155 | else | 155 | else |
156 | RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p); | 156 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p); |
157 | } | 157 | } |
158 | catch (Exception e) | 158 | catch (Exception e) |
159 | { | 159 | { |
@@ -205,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
205 | /// <param name="objectLocalID"></param> | 205 | /// <param name="objectLocalID"></param> |
206 | /// <param name="AttachmentPt"></param> | 206 | /// <param name="AttachmentPt"></param> |
207 | /// <param name="silent"></param> | 207 | /// <param name="silent"></param> |
208 | public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) | 208 | private void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) |
209 | { | 209 | { |
210 | // m_log.DebugFormat( | 210 | // m_log.DebugFormat( |
211 | // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", | 211 | // "[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 | |||
266 | m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); | 266 | m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); |
267 | } | 267 | } |
268 | } | 268 | } |
269 | |||
270 | public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) | ||
271 | { | ||
272 | if (!Enabled) | ||
273 | return false; | ||
274 | |||
275 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | ||
276 | |||
277 | if (sp == null) | ||
278 | { | ||
279 | m_log.ErrorFormat( | ||
280 | "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); | ||
281 | return false; | ||
282 | } | ||
283 | |||
284 | return AttachObject(sp, group, AttachmentPt, silent); | ||
285 | } | ||
286 | 269 | ||
287 | private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) | 270 | public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) |
288 | { | 271 | { |
289 | lock (sp.AttachmentsSyncLock) | 272 | lock (sp.AttachmentsSyncLock) |
290 | { | 273 | { |
@@ -364,29 +347,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
364 | } | 347 | } |
365 | 348 | ||
366 | return true; | 349 | return true; |
350 | } | ||
351 | |||
352 | private void RezMultipleAttachmentsFromInventory(IClientAPI remoteClient, List<KeyValuePair<UUID, uint>> rezlist) | ||
353 | { | ||
354 | if (!Enabled) | ||
355 | return; | ||
356 | |||
357 | ScenePresence sp; | ||
358 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out sp)) | ||
359 | RezMultipleAttachmentsFromInventory(sp, rezlist); | ||
360 | else | ||
361 | m_log.ErrorFormat( | ||
362 | "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", | ||
363 | remoteClient.Name, remoteClient.AgentId); | ||
364 | return; | ||
367 | } | 365 | } |
368 | 366 | ||
369 | public void RezMultipleAttachmentsFromInventory( | 367 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
370 | IClientAPI remoteClient, | ||
371 | List<KeyValuePair<UUID, uint>> rezlist) | ||
372 | { | 368 | { |
373 | if (!Enabled) | 369 | if (!Enabled) |
374 | return; | 370 | return; |
375 | 371 | ||
376 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 372 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); |
377 | |||
378 | if (sp == null) | ||
379 | { | ||
380 | m_log.ErrorFormat( | ||
381 | "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", | ||
382 | remoteClient.Name, remoteClient.AgentId); | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | lock (sp.AttachmentsSyncLock) | 373 | lock (sp.AttachmentsSyncLock) |
387 | { | 374 | { |
388 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); | ||
389 | |||
390 | foreach (KeyValuePair<UUID, uint> rez in rezlist) | 375 | foreach (KeyValuePair<UUID, uint> rez in rezlist) |
391 | { | 376 | { |
392 | RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); | 377 | RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); |
@@ -394,7 +379,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
394 | } | 379 | } |
395 | } | 380 | } |
396 | 381 | ||
397 | public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) | 382 | private ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) |
398 | { | 383 | { |
399 | return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); | 384 | return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); |
400 | } | 385 | } |
@@ -418,7 +403,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
418 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt); | 403 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt); |
419 | } | 404 | } |
420 | 405 | ||
421 | public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt) | 406 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) |
422 | { | 407 | { |
423 | if (!Enabled) | 408 | if (!Enabled) |
424 | return null; | 409 | return null; |
@@ -628,23 +613,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
628 | DetachSingleAttachmentToInv(itemID, presence); | 613 | DetachSingleAttachmentToInv(itemID, presence); |
629 | } | 614 | } |
630 | } | 615 | } |
616 | } | ||
617 | |||
618 | private void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) | ||
619 | { | ||
620 | if (!Enabled) | ||
621 | return; | ||
622 | |||
623 | ScenePresence sp; | ||
624 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out sp)) | ||
625 | DetachSingleAttachmentToGround(sp, soLocalId); | ||
631 | } | 626 | } |
632 | 627 | ||
633 | public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) | 628 | public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) |
634 | { | 629 | { |
635 | if (!Enabled) | 630 | if (!Enabled) |
636 | return; | 631 | return; |
637 | 632 | ||
638 | // m_log.DebugFormat( | 633 | // m_log.DebugFormat( |
639 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", | 634 | // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", |
640 | // remoteClient.Name, soLocalId); | 635 | // sp.UUID, soLocalId); |
641 | 636 | ||
642 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); | 637 | SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); |
643 | 638 | ||
644 | if (so == null) | 639 | if (so == null) |
645 | return; | 640 | return; |
646 | 641 | ||
647 | if (so.AttachedAvatar != remoteClient.AgentId) | 642 | if (so.AttachedAvatar != sp.UUID) |
648 | return; | 643 | return; |
649 | 644 | ||
650 | UUID inventoryID = so.GetFromItemID(); | 645 | UUID inventoryID = so.GetFromItemID(); |
@@ -653,57 +648,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
653 | // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", | 648 | // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", |
654 | // so.Name, so.LocalId, inventoryID); | 649 | // so.Name, so.LocalId, inventoryID); |
655 | 650 | ||
656 | ScenePresence presence; | 651 | lock (sp.AttachmentsSyncLock) |
657 | if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) | ||
658 | { | 652 | { |
659 | lock (presence.AttachmentsSyncLock) | 653 | if (!m_scene.Permissions.CanRezObject( |
660 | { | 654 | so.PrimCount, sp.UUID, sp.AbsolutePosition)) |
661 | if (!m_scene.Permissions.CanRezObject( | 655 | return; |
662 | so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) | 656 | |
663 | return; | 657 | bool changed = sp.Appearance.DetachAttachment(inventoryID); |
664 | 658 | if (changed && m_scene.AvatarFactory != null) | |
665 | bool changed = presence.Appearance.DetachAttachment(inventoryID); | 659 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
666 | if (changed && m_scene.AvatarFactory != null) | 660 | |
667 | m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); | 661 | sp.RemoveAttachment(so); |
668 | 662 | ||
669 | presence.RemoveAttachment(so); | 663 | SceneObjectPart rootPart = so.RootPart; |
670 | DetachSceneObjectToGround(so, presence); | 664 | rootPart.FromItemID = UUID.Zero; |
671 | 665 | so.AbsolutePosition = sp.AbsolutePosition; | |
672 | List<UUID> uuids = new List<UUID>(); | 666 | so.AttachedAvatar = UUID.Zero; |
673 | uuids.Add(inventoryID); | 667 | rootPart.SetParentLocalId(0); |
674 | m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); | 668 | so.ClearPartAttachmentData(); |
675 | remoteClient.SendRemoveInventoryItem(inventoryID); | 669 | rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); |
676 | } | 670 | so.HasGroupChanged = true; |
677 | 671 | rootPart.Rezzed = DateTime.Now; | |
678 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); | 672 | rootPart.RemFlag(PrimFlags.TemporaryOnRez); |
673 | so.AttachToBackup(); | ||
674 | m_scene.EventManager.TriggerParcelPrimCountTainted(); | ||
675 | rootPart.ScheduleFullUpdate(); | ||
676 | rootPart.ClearUndoState(); | ||
677 | |||
678 | List<UUID> uuids = new List<UUID>(); | ||
679 | uuids.Add(inventoryID); | ||
680 | m_scene.InventoryService.DeleteItems(sp.UUID, uuids); | ||
681 | sp.ControllingClient.SendRemoveInventoryItem(inventoryID); | ||
679 | } | 682 | } |
680 | } | ||
681 | 683 | ||
682 | /// <summary> | 684 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); |
683 | /// Detach the given scene object to the ground. | ||
684 | /// </summary> | ||
685 | /// <remarks> | ||
686 | /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc. | ||
687 | /// </remarks> | ||
688 | /// <param name="so">The scene object to detach.</param> | ||
689 | /// <param name="sp">The scene presence from which the scene object is being detached.</param> | ||
690 | private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp) | ||
691 | { | ||
692 | SceneObjectPart rootPart = so.RootPart; | ||
693 | |||
694 | rootPart.FromItemID = UUID.Zero; | ||
695 | so.AbsolutePosition = sp.AbsolutePosition; | ||
696 | so.AttachedAvatar = UUID.Zero; | ||
697 | rootPart.SetParentLocalId(0); | ||
698 | so.ClearPartAttachmentData(); | ||
699 | rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); | ||
700 | so.HasGroupChanged = true; | ||
701 | rootPart.Rezzed = DateTime.Now; | ||
702 | rootPart.RemFlag(PrimFlags.TemporaryOnRez); | ||
703 | so.AttachToBackup(); | ||
704 | m_scene.EventManager.TriggerParcelPrimCountTainted(); | ||
705 | rootPart.ScheduleFullUpdate(); | ||
706 | rootPart.ClearUndoState(); | ||
707 | } | 685 | } |
708 | 686 | ||
709 | // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. | 687 | // 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 ff3358f..832c6eb 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 | |||
106 | 106 | ||
107 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; | 107 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; |
108 | 108 | ||
109 | m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); | 109 | m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false); |
110 | 110 | ||
111 | // Check status on scene presence | 111 | // Check status on scene presence |
112 | Assert.That(m_presence.HasAttachments(), Is.True); | 112 | Assert.That(m_presence.HasAttachments(), Is.True); |
@@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
140 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | 140 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); |
141 | 141 | ||
142 | m_attMod.RezSingleAttachmentFromInventory( | 142 | m_attMod.RezSingleAttachmentFromInventory( |
143 | m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); | 143 | m_presence, attItemId, (uint)AttachmentPoint.Chest); |
144 | 144 | ||
145 | // Check scene presence status | 145 | // Check scene presence status |
146 | Assert.That(m_presence.HasAttachments(), Is.True); | 146 | Assert.That(m_presence.HasAttachments(), Is.True); |
@@ -174,8 +174,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
174 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | 174 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); |
175 | 175 | ||
176 | ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( | 176 | ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( |
177 | m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); | 177 | m_presence, attItemId, (uint)AttachmentPoint.Chest); |
178 | m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient); | 178 | m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId); |
179 | 179 | ||
180 | // Check scene presence status | 180 | // Check scene presence status |
181 | Assert.That(m_presence.HasAttachments(), Is.False); | 181 | Assert.That(m_presence.HasAttachments(), Is.False); |
@@ -208,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
208 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | 208 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); |
209 | 209 | ||
210 | m_attMod.RezSingleAttachmentFromInventory( | 210 | m_attMod.RezSingleAttachmentFromInventory( |
211 | m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); | 211 | m_presence, attItemId, (uint)AttachmentPoint.Chest); |
212 | m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient); | 212 | m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient); |
213 | 213 | ||
214 | // Check status on scene presence | 214 | // Check status on scene presence |