aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Attachments
diff options
context:
space:
mode:
authorMelanie2012-07-23 21:08:02 +0200
committerMelanie2012-07-23 21:08:02 +0200
commit9e00e2ddecdafa489de0ae67b78cf6971e55fe80 (patch)
treed2a9fdc3424a7dca00a1612399b25a3db0ac76a5 /OpenSim/Region/CoreModules/Avatar/Attachments
parentFix double-ping on logout by not sending a stop packet to the client (diff)
downloadopensim-SC-9e00e2ddecdafa489de0ae67b78cf6971e55fe80.zip
opensim-SC-9e00e2ddecdafa489de0ae67b78cf6971e55fe80.tar.gz
opensim-SC-9e00e2ddecdafa489de0ae67b78cf6971e55fe80.tar.bz2
opensim-SC-9e00e2ddecdafa489de0ae67b78cf6971e55fe80.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.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 f073c4a..31e8a2e 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);
@@ -750,29 +740,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
750 return newItem; 740 return newItem;
751 } 741 }
752 742
753 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) 743 private string GetObjectScriptStates(SceneObjectGroup grp)
754 { 744 {
755 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); 745 using (StringWriter sw = new StringWriter())
746 {
747 using (XmlTextWriter writer = new XmlTextWriter(sw))
748 {
749 grp.SaveScriptedState(writer);
750 }
756 751
757 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); 752 return sw.ToString();
758 sp.RemoveAttachment(so); 753 }
754 }
755
756 private void UpdateDetachedObject(IScenePresence sp, SceneObjectGroup so)
757 {
758 // Don't save attachments for HG visitors, it
759 // messes up their inventory. When a HG visitor logs
760 // out on a foreign grid, their attachments will be
761 // reloaded in the state they were in when they left
762 // the home grid. This is best anyway as the visited
763 // grid may use an incompatible script engine.
764 bool saveChanged
765 = sp.PresenceType != PresenceType.Npc
766 && (m_scene.UserManagementModule == null
767 || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
768
769 // Scripts MUST be snapshotted before the object is
770 // removed from the scene because doing otherwise will
771 // clobber the run flag
772 string scriptedState = GetObjectScriptStates(so);
773
774 // Remove the object from the scene so no more updates
775 // are sent. Doing this before the below changes will ensure
776 // updates can't cause "HUD artefacts"
777 m_scene.DeleteSceneObject(so, false, false);
759 778
760 // Prepare sog for storage 779 // Prepare sog for storage
761 so.AttachedAvatar = UUID.Zero; 780 so.AttachedAvatar = UUID.Zero;
762 so.RootPart.SetParentLocalId(0); 781 so.RootPart.SetParentLocalId(0);
763 so.IsAttachment = false; 782 so.IsAttachment = false;
764 783
765 // We cannot use AbsolutePosition here because that would 784 if (saveChanged)
766 // attempt to cross the prim as it is detached 785 {
767 so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; }); 786 // We cannot use AbsolutePosition here because that would
787 // attempt to cross the prim as it is detached
788 so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
789
790 UpdateKnownItem(sp, so, scriptedState);
791 }
792
793 // Now, remove the scripts
794 so.RemoveScriptInstances(true);
795 }
768 796
769 UpdateKnownItem(sp, so, true); 797 private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so)
798 {
799 // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name);
800
801 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
802 sp.RemoveAttachment(so);
770 803
771 // This MUST happen AFTER serialization because it will 804 UpdateDetachedObject(sp, so);
772 // either stop or remove the scripts. Both will cause scripts
773 // to be serialized in a stopped state with the true run
774 // state already lost.
775 m_scene.DeleteSceneObject(so, false, true);
776 } 805 }
777 806
778 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 807 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(