aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs88
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScenePresence.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs18
5 files changed, 82 insertions, 42 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(
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index 351e603..d5200b7 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -65,7 +65,7 @@ namespace OpenSim.Region.Framework.Interfaces
65 /// <param name="sp">The presence closing</param> 65 /// <param name="sp">The presence closing</param>
66 /// <param name="saveChanged">Save changed attachments.</param> 66 /// <param name="saveChanged">Save changed attachments.</param>
67 /// <param name="saveAllScripted">Save attachments with scripts even if they haven't changed.</para> 67 /// <param name="saveAllScripted">Save attachments with scripts even if they haven't changed.</para>
68 void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted); 68 void DeRezAttachments(IScenePresence sp);
69 69
70 /// <summary> 70 /// <summary>
71 /// Delete all the presence's attachments from the scene 71 /// Delete all the presence's attachments from the scene
diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
index e6b926c..3f68ee0 100644
--- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs
@@ -40,6 +40,8 @@ namespace OpenSim.Region.Framework.Interfaces
40 /// </remarks> 40 /// </remarks>
41 public interface IScenePresence : ISceneAgent 41 public interface IScenePresence : ISceneAgent
42 { 42 {
43 PresenceType PresenceType { get; }
44
43 /// <summary> 45 /// <summary>
44 /// Copy of the script states while the agent is in transit. This state may 46 /// Copy of the script states while the agent is in transit. This state may
45 /// need to be placed back in case of transfer fail. 47 /// need to be placed back in case of transfer fail.
@@ -83,4 +85,4 @@ namespace OpenSim.Region.Framework.Interfaces
83 void RemoveAttachment(SceneObjectGroup gobj); 85 void RemoveAttachment(SceneObjectGroup gobj);
84 void ClearAttachments(); 86 void ClearAttachments();
85 } 87 }
86} \ No newline at end of file 88}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 51a6820..ee34338 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -3297,17 +3297,7 @@ namespace OpenSim.Region.Framework.Scenes
3297 { 3297 {
3298 if (AttachmentsModule != null) 3298 if (AttachmentsModule != null)
3299 { 3299 {
3300 // Don't save attachments for HG visitors, it 3300 AttachmentsModule.DeRezAttachments(avatar);
3301 // messes up their inventory. When a HG visitor logs
3302 // out on a foreign grid, their attachments will be
3303 // reloaded in the state they were in when they left
3304 // the home grid. This is best anyway as the visited
3305 // grid may use an incompatible script engine.
3306 bool saveChanged
3307 = avatar.PresenceType != PresenceType.Npc
3308 && (UserManagementModule == null || UserManagementModule.IsLocalGridUser(avatar.UUID));
3309
3310 AttachmentsModule.DeRezAttachments(avatar, saveChanged, false);
3311 } 3301 }
3312 3302
3313 ForEachClient( 3303 ForEachClient(
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 0b34156..2d4c60a 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -151,6 +151,24 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
151 ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false); 151 ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false);
152 } 152 }
153 153
154 public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject, string scriptedState)
155 {
156 using (StringWriter sw = new StringWriter())
157 {
158 using (XmlTextWriter writer = new XmlTextWriter(sw))
159 {
160 writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty);
161
162 ToOriginalXmlFormat(sceneObject, writer, false, true);
163
164 writer.WriteRaw(scriptedState);
165
166 writer.WriteEndElement();
167 }
168 return sw.ToString();
169 }
170 }
171
154 /// <summary> 172 /// <summary>
155 /// Serialize a scene object to the original xml format 173 /// Serialize a scene object to the original xml format
156 /// </summary> 174 /// </summary>