aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2012-07-23 21:08:02 +0200
committerMelanie2012-07-23 21:39:26 +0100
commite126915bc168f16f2c4462492814a1b733aefe87 (patch)
tree86b70efdcf21bf0e44f527bb011cb55f9213a1b3 /OpenSim/Region
parentCommitting Avination's memleak fix-a-thon, installment #3 (diff)
downloadopensim-SC-e126915bc168f16f2c4462492814a1b733aefe87.zip
opensim-SC-e126915bc168f16f2c4462492814a1b733aefe87.tar.gz
opensim-SC-e126915bc168f16f2c4462492814a1b733aefe87.tar.bz2
opensim-SC-e126915bc168f16f2c4462492814a1b733aefe87.tar.xz
Change attachment handling to remove object from the scene first as per
justincc's original work. Sample scripts before doing so. Also refactor some crucial common code and eliminate parameters that were only ever used with the same constant value.
Diffstat (limited to 'OpenSim/Region')
-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>