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.cs88
1 files changed, 59 insertions, 29 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 0f3b1e8..464dfd3 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -28,6 +28,8 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.IO;
32using System.Xml;
31using log4net; 33using log4net;
32using Mono.Addins; 34using Mono.Addins;
33using Nini.Config; 35using Nini.Config;
@@ -202,7 +204,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
202 } 204 }
203 } 205 }
204 206
205 public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted) 207 public void DeRezAttachments(IScenePresence sp)
206 { 208 {
207 if (!Enabled) 209 if (!Enabled)
208 return; 210 return;
@@ -213,18 +215,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
213 { 215 {
214 foreach (SceneObjectGroup so in sp.GetAttachments()) 216 foreach (SceneObjectGroup so in sp.GetAttachments())
215 { 217 {
216 // We can only remove the script instances from the script engine after we've retrieved their xml state 218 UpdateDetachedObject(sp, so);
217 // when we update the attachment item.
218 m_scene.DeleteSceneObject(so, false, false);
219
220 if (saveChanged || saveAllScripted)
221 {
222 so.IsAttachment = false;
223 so.AbsolutePosition = so.RootPart.AttachedPos;
224 UpdateKnownItem(sp, so, saveAllScripted);
225 }
226
227 so.RemoveScriptInstances(true);
228 } 219 }
229 220
230 sp.ClearAttachments(); 221 sp.ClearAttachments();
@@ -528,7 +519,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
528 /// <param name="sp"></param> 519 /// <param name="sp"></param>
529 /// <param name="grp"></param> 520 /// <param name="grp"></param>
530 /// <param name="saveAllScripted"></param> 521 /// <param name="saveAllScripted"></param>
531 private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) 522 private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, string scriptedState)
532 { 523 {
533 // Saving attachments for NPCs messes them up for the real owner! 524 // Saving attachments for NPCs messes them up for the real owner!
534 INPCModule module = m_scene.RequestModuleInterface<INPCModule>(); 525 INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
@@ -538,13 +529,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
538 return; 529 return;
539 } 530 }
540 531
541 if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts())) 532 if (grp.HasGroupChanged)
542 { 533 {
543// m_log.DebugFormat( 534// m_log.DebugFormat(
544// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 535// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
545// grp.UUID, grp.AttachmentPoint); 536// grp.UUID, grp.AttachmentPoint);
546 537
547 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); 538 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState);
548 539
549 InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID); 540 InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID);
550 item = m_scene.InventoryService.GetItem(item); 541 item = m_scene.InventoryService.GetItem(item);
@@ -683,29 +674,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
683 return newItem; 674 return newItem;
684 } 675 }
685 676
686 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) 677 private string GetObjectScriptStates(SceneObjectGroup grp)
687 { 678 {
688 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); 679 using (StringWriter sw = new StringWriter())
680 {
681 using (XmlTextWriter writer = new XmlTextWriter(sw))
682 {
683 grp.SaveScriptedState(writer);
684 }
689 685
690 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); 686 return sw.ToString();
691 sp.RemoveAttachment(so); 687 }
688 }
689
690 private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so)
691 {
692 // Don't save attachments for HG visitors, it
693 // messes up their inventory. When a HG visitor logs
694 // out on a foreign grid, their attachments will be
695 // reloaded in the state they were in when they left
696 // the home grid. This is best anyway as the visited
697 // grid may use an incompatible script engine.
698 bool saveChanged
699 = sp.PresenceType != PresenceType.Npc
700 && (m_scene.UserManagementModule == null
701 || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
702
703 // Scripts MUST be snapshotted before the object is
704 // removed from the scene because doing otherwise will
705 // clobber the run flag
706 string scriptedState = GetObjectScriptStates(so);
707
708 // Remove the object from the scene so no more updates
709 // are sent. Doing this before the below changes will ensure
710 // updates can't cause "HUD artefacts"
711 m_scene.DeleteSceneObject(so, false, false);
692 712
693 // Prepare sog for storage 713 // Prepare sog for storage
694 so.AttachedAvatar = UUID.Zero; 714 so.AttachedAvatar = UUID.Zero;
695 so.RootPart.SetParentLocalId(0); 715 so.RootPart.SetParentLocalId(0);
696 so.IsAttachment = false; 716 so.IsAttachment = false;
697 717
698 // We cannot use AbsolutePosition here because that would 718 if (saveChanged)
699 // attempt to cross the prim as it is detached 719 {
700 so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; }); 720 // We cannot use AbsolutePosition here because that would
721 // attempt to cross the prim as it is detached
722 so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
723
724 UpdateKnownItem(sp, so, scriptedState);
725 }
726
727 // Now, remove the scripts
728 so.RemoveScriptInstances(true);
729 }
701 730
702 UpdateKnownItem(sp, so, true); 731 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
732 {
733 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
734
735 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
736 sp.RemoveAttachment(so);
703 737
704 // This MUST happen AFTER serialization because it will 738 UpdateDetachedObject(sp, so);
705 // either stop or remove the scripts. Both will cause scripts
706 // to be serialized in a stopped state with the true run
707 // state already lost.
708 m_scene.DeleteSceneObject(so, false, true);
709 } 739 }
710 740
711 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 741 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(