diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 301 |
1 files changed, 161 insertions, 140 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 8a3eeaa..3ccf9f4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -241,12 +241,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
241 | 241 | ||
242 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | 242 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); |
243 | 243 | ||
244 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
245 | |||
246 | if (attachments.Count <= 0) | ||
247 | return; | ||
248 | |||
249 | Dictionary<SceneObjectGroup, string> scriptStates = new Dictionary<SceneObjectGroup, string>(); | ||
250 | |||
251 | foreach (SceneObjectGroup so in attachments) | ||
252 | { | ||
253 | // Scripts MUST be snapshotted before the object is | ||
254 | // removed from the scene because doing otherwise will | ||
255 | // clobber the run flag | ||
256 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from | ||
257 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. | ||
258 | scriptStates[so] = PrepareScriptInstanceForSave(so, false); | ||
259 | } | ||
260 | |||
244 | lock (sp.AttachmentsSyncLock) | 261 | lock (sp.AttachmentsSyncLock) |
245 | { | 262 | { |
246 | foreach (SceneObjectGroup so in sp.GetAttachments()) | 263 | foreach (SceneObjectGroup so in attachments) |
247 | { | 264 | UpdateDetachedObject(sp, so, scriptStates[so]); |
248 | UpdateDetachedObject(sp, so); | ||
249 | } | ||
250 | 265 | ||
251 | sp.ClearAttachments(); | 266 | sp.ClearAttachments(); |
252 | } | 267 | } |
@@ -285,32 +300,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
285 | 300 | ||
286 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) | 301 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) |
287 | { | 302 | { |
288 | lock (sp.AttachmentsSyncLock) | ||
289 | { | ||
290 | // m_log.DebugFormat( | 303 | // m_log.DebugFormat( |
291 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", | 304 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", |
292 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); | 305 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); |
293 | 306 | ||
294 | if (group.GetSittingAvatarsCount() != 0) | 307 | if (group.GetSittingAvatarsCount() != 0) |
295 | { | 308 | { |
296 | // m_log.WarnFormat( | 309 | // m_log.WarnFormat( |
297 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", | 310 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", |
298 | // group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | 311 | // group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); |
299 | 312 | ||
300 | return false; | 313 | return false; |
301 | } | 314 | } |
302 | 315 | ||
303 | if (sp.GetAttachments(attachmentPt).Contains(group)) | 316 | if (sp.GetAttachments(attachmentPt).Contains(group)) |
304 | { | 317 | { |
305 | // m_log.WarnFormat( | 318 | // m_log.WarnFormat( |
306 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", | 319 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", |
307 | // group.Name, group.LocalId, sp.Name, AttachmentPt); | 320 | // group.Name, group.LocalId, sp.Name, AttachmentPt); |
308 | 321 | ||
309 | return false; | 322 | return false; |
310 | } | 323 | } |
311 | 324 | ||
325 | // Remove any previous attachments | ||
326 | List<SceneObjectGroup> existingAttachments = sp.GetAttachments(attachmentPt); | ||
327 | string existingAttachmentScriptState = null; | ||
328 | |||
329 | // At the moment we can only deal with a single attachment | ||
330 | if (existingAttachments.Count != 0 && existingAttachments[0].FromItemID != UUID.Zero) | ||
331 | DetachSingleAttachmentToInv(sp, group); | ||
332 | |||
333 | lock (sp.AttachmentsSyncLock) | ||
334 | { | ||
312 | Vector3 attachPos = group.AbsolutePosition; | 335 | Vector3 attachPos = group.AbsolutePosition; |
313 | 336 | ||
314 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should | 337 | // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should |
315 | // be removed when that functionality is implemented in opensim | 338 | // be removed when that functionality is implemented in opensim |
316 | attachmentPt &= 0x7f; | 339 | attachmentPt &= 0x7f; |
@@ -322,14 +345,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
322 | { | 345 | { |
323 | attachPos = Vector3.Zero; | 346 | attachPos = Vector3.Zero; |
324 | } | 347 | } |
325 | 348 | ||
326 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | 349 | // AttachmentPt 0 means the client chose to 'wear' the attachment. |
327 | if (attachmentPt == 0) | 350 | if (attachmentPt == 0) |
328 | { | 351 | { |
329 | // Check object for stored attachment point | 352 | // Check object for stored attachment point |
330 | attachmentPt = group.AttachmentPoint; | 353 | attachmentPt = group.AttachmentPoint; |
331 | } | 354 | } |
332 | 355 | ||
333 | // if we still didn't find a suitable attachment point....... | 356 | // if we still didn't find a suitable attachment point....... |
334 | if (attachmentPt == 0) | 357 | if (attachmentPt == 0) |
335 | { | 358 | { |
@@ -337,13 +360,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
337 | attachmentPt = (uint)AttachmentPoint.LeftHand; | 360 | attachmentPt = (uint)AttachmentPoint.LeftHand; |
338 | attachPos = Vector3.Zero; | 361 | attachPos = Vector3.Zero; |
339 | } | 362 | } |
340 | 363 | ||
341 | group.AttachmentPoint = attachmentPt; | 364 | group.AttachmentPoint = attachmentPt; |
342 | group.AbsolutePosition = attachPos; | 365 | group.AbsolutePosition = attachPos; |
343 | 366 | ||
344 | if (sp.PresenceType != PresenceType.Npc) | 367 | if (sp.PresenceType != PresenceType.Npc) |
345 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); | 368 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); |
346 | 369 | ||
347 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | 370 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); |
348 | } | 371 | } |
349 | 372 | ||
@@ -352,21 +375,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
352 | 375 | ||
353 | private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) | 376 | private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) |
354 | { | 377 | { |
355 | // Remove any previous attachments | ||
356 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | ||
357 | |||
358 | // At the moment we can only deal with a single attachment | ||
359 | if (attachments.Count != 0) | ||
360 | { | ||
361 | if (attachments[0].FromItemID != UUID.Zero) | ||
362 | DetachSingleAttachmentToInvInternal(sp, attachments[0]); | ||
363 | // Error logging commented because UUID.Zero now means temp attachment | ||
364 | // else | ||
365 | // m_log.WarnFormat( | ||
366 | // "[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!", | ||
367 | // attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); | ||
368 | } | ||
369 | |||
370 | // Add the new attachment to inventory if we don't already have it. | 378 | // Add the new attachment to inventory if we don't already have it. |
371 | if (!temp) | 379 | if (!temp) |
372 | { | 380 | { |
@@ -426,12 +434,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
426 | return; | 434 | return; |
427 | 435 | ||
428 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); | 436 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); |
429 | lock (sp.AttachmentsSyncLock) | 437 | |
438 | foreach (KeyValuePair<UUID, uint> rez in rezlist) | ||
430 | { | 439 | { |
431 | foreach (KeyValuePair<UUID, uint> rez in rezlist) | 440 | RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); |
432 | { | ||
433 | RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); | ||
434 | } | ||
435 | } | 441 | } |
436 | } | 442 | } |
437 | 443 | ||
@@ -511,25 +517,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
511 | 517 | ||
512 | public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) | 518 | public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) |
513 | { | 519 | { |
520 | if (so.AttachedAvatar != sp.UUID) | ||
521 | { | ||
522 | m_log.WarnFormat( | ||
523 | "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", | ||
524 | so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); | ||
525 | |||
526 | return; | ||
527 | } | ||
528 | |||
529 | // Scripts MUST be snapshotted before the object is | ||
530 | // removed from the scene because doing otherwise will | ||
531 | // clobber the run flag | ||
532 | // This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from | ||
533 | // scripts performing attachment operations at the same time. Getting object states stops the scripts. | ||
534 | string scriptedState = PrepareScriptInstanceForSave(so, true); | ||
535 | |||
514 | lock (sp.AttachmentsSyncLock) | 536 | lock (sp.AttachmentsSyncLock) |
515 | { | 537 | { |
516 | // Save avatar attachment information | 538 | // Save avatar attachment information |
517 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); | 539 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); |
518 | 540 | ||
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); | 541 | bool changed = sp.Appearance.DetachAttachment(so.FromItemID); |
529 | if (changed && m_scene.AvatarFactory != null) | 542 | if (changed && m_scene.AvatarFactory != null) |
530 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 543 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
531 | 544 | ||
532 | DetachSingleAttachmentToInvInternal(sp, so); | 545 | sp.RemoveAttachment(so); |
546 | UpdateDetachedObject(sp, so, scriptedState); | ||
533 | } | 547 | } |
534 | } | 548 | } |
535 | 549 | ||
@@ -739,8 +753,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
739 | return newItem; | 753 | return newItem; |
740 | } | 754 | } |
741 | 755 | ||
742 | private string GetObjectScriptStates(SceneObjectGroup grp) | 756 | /// <summary> |
757 | /// Prepares the script instance for save. | ||
758 | /// </summary> | ||
759 | /// <remarks> | ||
760 | /// This involves triggering the detach event and getting the script state (which also stops the script) | ||
761 | /// This MUST be done outside sp.AttachmentsSyncLock, since otherwise there is a chance of deadlock if a | ||
762 | /// running script is performing attachment operations. | ||
763 | /// </remarks> | ||
764 | /// <returns> | ||
765 | /// The script state ready for persistence. | ||
766 | /// </returns> | ||
767 | /// <param name='grp'> | ||
768 | /// </param> | ||
769 | /// <param name='fireDetachEvent'> | ||
770 | /// If true, then fire the script event before we save its state. | ||
771 | /// </param> | ||
772 | private string PrepareScriptInstanceForSave(SceneObjectGroup grp, bool fireDetachEvent) | ||
743 | { | 773 | { |
774 | if (fireDetachEvent) | ||
775 | m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero); | ||
776 | |||
744 | using (StringWriter sw = new StringWriter()) | 777 | using (StringWriter sw = new StringWriter()) |
745 | { | 778 | { |
746 | using (XmlTextWriter writer = new XmlTextWriter(sw)) | 779 | using (XmlTextWriter writer = new XmlTextWriter(sw)) |
@@ -752,7 +785,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
752 | } | 785 | } |
753 | } | 786 | } |
754 | 787 | ||
755 | private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so) | 788 | private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so, string scriptedState) |
756 | { | 789 | { |
757 | // Don't save attachments for HG visitors, it | 790 | // Don't save attachments for HG visitors, it |
758 | // messes up their inventory. When a HG visitor logs | 791 | // messes up their inventory. When a HG visitor logs |
@@ -765,11 +798,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
765 | && (m_scene.UserManagementModule == null | 798 | && (m_scene.UserManagementModule == null |
766 | || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID)); | 799 | || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID)); |
767 | 800 | ||
768 | // Scripts MUST be snapshotted before the object is | ||
769 | // removed from the scene because doing otherwise will | ||
770 | // clobber the run flag | ||
771 | string scriptedState = GetObjectScriptStates(so); | ||
772 | |||
773 | // Remove the object from the scene so no more updates | 801 | // Remove the object from the scene so no more updates |
774 | // are sent. Doing this before the below changes will ensure | 802 | // are sent. Doing this before the below changes will ensure |
775 | // updates can't cause "HUD artefacts" | 803 | // updates can't cause "HUD artefacts" |
@@ -793,91 +821,87 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
793 | so.RemoveScriptInstances(true); | 821 | so.RemoveScriptInstances(true); |
794 | } | 822 | } |
795 | 823 | ||
796 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) | ||
797 | { | ||
798 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); | ||
799 | |||
800 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); | ||
801 | sp.RemoveAttachment(so); | ||
802 | |||
803 | UpdateDetachedObject(sp, so); | ||
804 | } | ||
805 | |||
806 | private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 824 | private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
807 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) | 825 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) |
808 | { | 826 | { |
809 | if (m_invAccessModule == null) | 827 | if (m_invAccessModule == null) |
810 | return null; | 828 | return null; |
811 | 829 | ||
812 | lock (sp.AttachmentsSyncLock) | 830 | SceneObjectGroup objatt; |
831 | |||
832 | if (itemID != UUID.Zero) | ||
833 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
834 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
835 | false, false, sp.UUID, true); | ||
836 | else | ||
837 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
838 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
839 | false, false, sp.UUID, true); | ||
840 | |||
841 | if (objatt == null) | ||
813 | { | 842 | { |
814 | SceneObjectGroup objatt; | 843 | m_log.WarnFormat( |
844 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
845 | itemID, sp.Name, attachmentPt); | ||
815 | 846 | ||
816 | if (itemID != UUID.Zero) | 847 | return null; |
817 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | 848 | } |
818 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
819 | false, false, sp.UUID, true); | ||
820 | else | ||
821 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
822 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
823 | false, false, sp.UUID, true); | ||
824 | 849 | ||
825 | if (objatt != null) | 850 | // Remove any previous attachments |
826 | { | 851 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); |
852 | string previousAttachmentScriptedState = null; | ||
853 | |||
854 | // At the moment we can only deal with a single attachment | ||
855 | if (attachments.Count != 0) | ||
856 | DetachSingleAttachmentToInv(sp, attachments[0]); | ||
857 | |||
858 | lock (sp.AttachmentsSyncLock) | ||
859 | { | ||
827 | // m_log.DebugFormat( | 860 | // m_log.DebugFormat( |
828 | // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | 861 | // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", |
829 | // objatt.Name, sp.Name, attachmentPt, m_scene.Name); | 862 | // objatt.Name, sp.Name, attachmentPt, m_scene.Name); |
830 | 863 | ||
831 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | 864 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
832 | objatt.HasGroupChanged = false; | 865 | objatt.HasGroupChanged = false; |
833 | bool tainted = false; | 866 | bool tainted = false; |
834 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | 867 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) |
835 | tainted = true; | 868 | tainted = true; |
836 | 869 | ||
837 | // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal | 870 | // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal |
838 | // course of events. If not, then it's probably not worth trying to recover the situation | 871 | // course of events. If not, then it's probably not worth trying to recover the situation |
839 | // since this is more likely to trigger further exceptions and confuse later debugging. If | 872 | // since this is more likely to trigger further exceptions and confuse later debugging. If |
840 | // exceptions can be thrown in expected error conditions (not NREs) then make this consistent | 873 | // exceptions can be thrown in expected error conditions (not NREs) then make this consistent |
841 | // since other normal error conditions will simply return false instead. | 874 | // since other normal error conditions will simply return false instead. |
842 | // This will throw if the attachment fails | 875 | // This will throw if the attachment fails |
843 | try | 876 | try |
844 | { | 877 | { |
845 | AttachObjectInternal(sp, objatt, attachmentPt, false, false); | 878 | AttachObjectInternal(sp, objatt, attachmentPt, false, false); |
846 | } | 879 | } |
847 | catch (Exception e) | 880 | catch (Exception e) |
848 | { | 881 | { |
849 | m_log.ErrorFormat( | 882 | m_log.ErrorFormat( |
850 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | 883 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", |
851 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | 884 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); |
852 | |||
853 | // Make sure the object doesn't stick around and bail | ||
854 | sp.RemoveAttachment(objatt); | ||
855 | m_scene.DeleteSceneObject(objatt, false); | ||
856 | return null; | ||
857 | } | ||
858 | 885 | ||
859 | if (tainted) | 886 | // Make sure the object doesn't stick around and bail |
860 | objatt.HasGroupChanged = true; | 887 | sp.RemoveAttachment(objatt); |
888 | m_scene.DeleteSceneObject(objatt, false); | ||
889 | return null; | ||
890 | } | ||
861 | 891 | ||
862 | // Fire after attach, so we don't get messy perms dialogs | 892 | if (tainted) |
863 | // 4 == AttachedRez | 893 | objatt.HasGroupChanged = true; |
864 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
865 | objatt.ResumeScripts(); | ||
866 | 894 | ||
867 | // Do this last so that event listeners have access to all the effects of the attachment | 895 | // Fire after attach, so we don't get messy perms dialogs |
868 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | 896 | // 4 == AttachedRez |
897 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
898 | objatt.ResumeScripts(); | ||
869 | 899 | ||
870 | return objatt; | 900 | // Do this last so that event listeners have access to all the effects of the attachment |
871 | } | 901 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); |
872 | else | ||
873 | { | ||
874 | m_log.WarnFormat( | ||
875 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
876 | itemID, sp.Name, attachmentPt); | ||
877 | } | ||
878 | } | ||
879 | 902 | ||
880 | return null; | 903 | return objatt; |
904 | } | ||
881 | } | 905 | } |
882 | 906 | ||
883 | /// <summary> | 907 | /// <summary> |
@@ -1027,17 +1051,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1027 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1051 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
1028 | if (sp != null) | 1052 | if (sp != null) |
1029 | { | 1053 | { |
1030 | lock (sp.AttachmentsSyncLock) | 1054 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
1055 | |||
1056 | foreach (SceneObjectGroup group in attachments) | ||
1031 | { | 1057 | { |
1032 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | 1058 | if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) |
1033 | |||
1034 | foreach (SceneObjectGroup group in attachments) | ||
1035 | { | 1059 | { |
1036 | if (group.FromItemID == itemID && group.FromItemID != UUID.Zero) | 1060 | DetachSingleAttachmentToInv(sp, group); |
1037 | { | 1061 | return; |
1038 | DetachSingleAttachmentToInv(sp, group); | ||
1039 | return; | ||
1040 | } | ||
1041 | } | 1062 | } |
1042 | } | 1063 | } |
1043 | } | 1064 | } |
@@ -1055,4 +1076,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1055 | 1076 | ||
1056 | #endregion | 1077 | #endregion |
1057 | } | 1078 | } |
1058 | } | 1079 | } \ No newline at end of file |