aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs87
1 files changed, 58 insertions, 29 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 860bdcd..b588704 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.IO;
31using System.Xml; 32using System.Xml;
32using log4net; 33using log4net;
33using Mono.Addins; 34using Mono.Addins;
@@ -248,7 +249,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
248 } 249 }
249 } 250 }
250 251
251 public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted) 252 public void DeRezAttachments(IScenePresence sp)
252 { 253 {
253 if (!Enabled) 254 if (!Enabled)
254 return; 255 return;
@@ -259,18 +260,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
259 { 260 {
260 foreach (SceneObjectGroup so in sp.GetAttachments()) 261 foreach (SceneObjectGroup so in sp.GetAttachments())
261 { 262 {
262 // We can only remove the script instances from the script engine after we've retrieved their xml state 263 UpdateDetachedObject(sp, so);
263 // when we update the attachment item.
264 m_scene.DeleteSceneObject(so, false, false);
265
266 if (saveChanged || saveAllScripted)
267 {
268 so.IsAttachment = false;
269 so.AbsolutePosition = so.RootPart.AttachedPos;
270 UpdateKnownItem(sp, so, saveAllScripted);
271 }
272
273 so.RemoveScriptInstances(true);
274 } 264 }
275 265
276 sp.ClearAttachments(); 266 sp.ClearAttachments();
@@ -597,7 +587,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
597 /// <param name="sp"></param> 587 /// <param name="sp"></param>
598 /// <param name="grp"></param> 588 /// <param name="grp"></param>
599 /// <param name="saveAllScripted"></param> 589 /// <param name="saveAllScripted"></param>
600 private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) 590 private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, string scriptedState)
601 { 591 {
602 // Saving attachments for NPCs messes them up for the real owner! 592 // Saving attachments for NPCs messes them up for the real owner!
603 INPCModule module = m_scene.RequestModuleInterface<INPCModule>(); 593 INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
@@ -607,13 +597,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
607 return; 597 return;
608 } 598 }
609 599
610 if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts())) 600 if (grp.HasGroupChanged)
611 { 601 {
612// m_log.DebugFormat( 602// m_log.DebugFormat(
613// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 603// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
614// grp.UUID, grp.AttachmentPoint); 604// grp.UUID, grp.AttachmentPoint);
615 605
616 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 606 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState);
617 607
618 InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID); 608 InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID);
619 item = m_scene.InventoryService.GetItem(item); 609 item = m_scene.InventoryService.GetItem(item);
@@ -752,29 +742,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
752 return newItem; 742 return newItem;
753 } 743 }
754 744
755 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) 745 private string GetObjectScriptStates(SceneObjectGroup grp)
756 { 746 {
757 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); 747 using (StringWriter sw = new StringWriter())
748 {
749 using (XmlTextWriter writer = new XmlTextWriter(sw))
750 {
751 grp.SaveScriptedState(writer);
752 }
758 753
759 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); 754 return sw.ToString();
760 sp.RemoveAttachment(so); 755 }
756 }
757
758 private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so)
759 {
760 // Don't save attachments for HG visitors, it
761 // messes up their inventory. When a HG visitor logs
762 // out on a foreign grid, their attachments will be
763 // reloaded in the state they were in when they left
764 // the home grid. This is best anyway as the visited
765 // grid may use an incompatible script engine.
766 bool saveChanged
767 = sp.PresenceType != PresenceType.Npc
768 && (m_scene.UserManagementModule == null
769 || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
770
771 // Scripts MUST be snapshotted before the object is
772 // removed from the scene because doing otherwise will
773 // clobber the run flag
774 string scriptedState = GetObjectScriptStates(so);
775
776 // Remove the object from the scene so no more updates
777 // are sent. Doing this before the below changes will ensure
778 // updates can't cause "HUD artefacts"
779 m_scene.DeleteSceneObject(so, false, false);
761 780
762 // Prepare sog for storage 781 // Prepare sog for storage
763 so.AttachedAvatar = UUID.Zero; 782 so.AttachedAvatar = UUID.Zero;
764 so.RootPart.SetParentLocalId(0); 783 so.RootPart.SetParentLocalId(0);
765 so.IsAttachment = false; 784 so.IsAttachment = false;
766 785
767 // We cannot use AbsolutePosition here because that would 786 if (saveChanged)
768 // attempt to cross the prim as it is detached 787 {
769 so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; }); 788 // We cannot use AbsolutePosition here because that would
789 // attempt to cross the prim as it is detached
790 so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
791
792 UpdateKnownItem(sp, so, scriptedState);
793 }
794
795 // Now, remove the scripts
796 so.RemoveScriptInstances(true);
797 }
770 798
771 UpdateKnownItem(sp, so, true); 799 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
800 {
801 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
802
803 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
804 sp.RemoveAttachment(so);
772 805
773 // This MUST happen AFTER serialization because it will 806 UpdateDetachedObject(sp, so);
774 // either stop or remove the scripts. Both will cause scripts
775 // to be serialized in a stopped state with the true run
776 // state already lost.
777 m_scene.DeleteSceneObject(so, false, true);
778 } 807 }
779 808
780 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 809 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(