diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 7667eb7afc..ecdd3ec8e2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -102,6 +102,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments #region IAttachmentsModule + public void CopyAttachments(IScenePresence sp, AgentData ad) + { + lock (sp.AttachmentsSyncLock) + { + // Attachment objects + List attachments = sp.GetAttachments(); + if (attachments.Count > 0) + { + ad.AttachmentObjects = new List(); + ad.AttachmentObjectStates = new List(); + // IScriptModule se = m_scene.RequestModuleInterface(); + sp.InTransitScriptStates.Clear(); + + foreach (SceneObjectGroup sog in attachments) + { + // We need to make a copy and pass that copy + // because of transfers withn the same sim + ISceneObject clone = sog.CloneForNewScene(); + // Attachment module assumes that GroupPosition holds the offsets...! + ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; + ((SceneObjectGroup)clone).IsAttachment = false; + ad.AttachmentObjects.Add(clone); + string state = sog.GetStateSnapshot(); + ad.AttachmentObjectStates.Add(state); + sp.InTransitScriptStates.Add(state); + // Let's remove the scripts of the original object here + sog.RemoveScriptInstances(true); + } + } + } + } + + public void CopyAttachments(AgentData ad, IScenePresence sp) + { + if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0) + { + lock (sp.AttachmentsSyncLock) + sp.ClearAttachments(); + + int i = 0; + foreach (ISceneObject so in ad.AttachmentObjects) + { + ((SceneObjectGroup)so).LocalId = 0; + ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); + so.SetState(ad.AttachmentObjectStates[i++], m_scene); + m_scene.IncomingCreateObject(Vector3.Zero, so); + } + } + } + /// /// RezAttachments. This should only be called upon login on the first region. /// Attachment rezzings on crossings and TPs are done in a different way. diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index fde5de1561..375d3345a2 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -35,6 +35,20 @@ namespace OpenSim.Region.Framework.Interfaces { public interface IAttachmentsModule { + /// + /// Copy attachment data from a ScenePresence into the AgentData structure for transmission to another simulator + /// + /// + /// + void CopyAttachments(IScenePresence sp, AgentData ad); + + /// + /// Copy attachment data from an AgentData structure into a ScenePresence. + /// + /// + /// + void CopyAttachments(AgentData ad, IScenePresence sp); + /// /// RezAttachments. This should only be called upon login on the first region. /// Attachment rezzings on crossings and TPs are done in a different way. diff --git a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs index 5e43843faf..19a8236427 100644 --- a/OpenSim/Region/Framework/Interfaces/IScenePresence.cs +++ b/OpenSim/Region/Framework/Interfaces/IScenePresence.cs @@ -40,6 +40,12 @@ namespace OpenSim.Region.Framework.Interfaces /// public interface IScenePresence : ISceneAgent { + /// + /// Copy of the script states while the agent is in transit. This state may + /// need to be placed back in case of transfer fail. + /// + List InTransitScriptStates { get; } + /// /// The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remove attachments. /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1488bfacf1..c1ccc2ba60 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3145,31 +3145,8 @@ namespace OpenSim.Region.Framework.Scenes } catch { } - // Attachment objects - List attachments = GetAttachments(); - if (attachments.Count > 0) - { - cAgent.AttachmentObjects = new List(); - cAgent.AttachmentObjectStates = new List(); -// IScriptModule se = m_scene.RequestModuleInterface(); - InTransitScriptStates.Clear(); - - foreach (SceneObjectGroup sog in attachments) - { - // We need to make a copy and pass that copy - // because of transfers withn the same sim - ISceneObject clone = sog.CloneForNewScene(); - // Attachment module assumes that GroupPosition holds the offsets...! - ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; - ((SceneObjectGroup)clone).IsAttachment = false; - cAgent.AttachmentObjects.Add(clone); - string state = sog.GetStateSnapshot(); - cAgent.AttachmentObjectStates.Add(state); - InTransitScriptStates.Add(state); - // Let's remove the scripts of the original object here - sog.RemoveScriptInstances(true); - } - } + if (Scene.AttachmentsModule != null) + Scene.AttachmentsModule.CopyAttachments(this, cAgent); } private void CopyFrom(AgentData cAgent) @@ -3239,18 +3216,8 @@ namespace OpenSim.Region.Framework.Scenes if (cAgent.Anims != null) Animator.Animations.FromArray(cAgent.Anims); - if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0) - { - m_attachments = new List(); - int i = 0; - foreach (ISceneObject so in cAgent.AttachmentObjects) - { - ((SceneObjectGroup)so).LocalId = 0; - ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); - so.SetState(cAgent.AttachmentObjectStates[i++], m_scene); - m_scene.IncomingCreateObject(Vector3.Zero, so); - } - } + if (Scene.AttachmentsModule != null) + Scene.AttachmentsModule.CopyAttachments(cAgent, this); } public bool CopyAgent(out IAgentData agent)