aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Attachments
diff options
context:
space:
mode:
authorMelanie2012-07-23 21:08:02 +0200
committerMelanie2012-07-23 21:39:26 +0100
commite126915bc168f16f2c4462492814a1b733aefe87 (patch)
tree86b70efdcf21bf0e44f527bb011cb55f9213a1b3 /OpenSim/Region/CoreModules/Avatar/Attachments
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/CoreModules/Avatar/Attachments')
-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(