diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a854c116de..c274a5bea5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -101,7 +101,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { -// m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", +// objectLocalID, remoteClient.Name, AttachmentPt, silent); try { @@ -163,8 +165,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return AttachObject(sp, group, AttachmentPt, silent); } - public bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint AttachmentPt, bool silent) + private bool AttachObject(ScenePresence sp, SceneObjectGroup group, uint AttachmentPt, bool silent) { +// m_log.DebugFormat( +// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", +// group.Name, group.LocalId, sp.Name, AttachmentPt, silent); + + if (sp.GetAttachments(AttachmentPt).Contains(group)) + { +// m_log.WarnFormat( +// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", +// group.Name, group.LocalId, sp.Name, AttachmentPt); + + return false; + } + Vector3 attachPos = group.AbsolutePosition; // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should @@ -211,14 +226,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (itemID != UUID.Zero) DetachSingleAttachmentToInv(itemID, sp); - if (group.GetFromItemID() == UUID.Zero) - { + itemID = group.GetFromItemID(); + if (itemID == UUID.Zero) m_scene.attachObjectAssetStore(sp.ControllingClient, group, sp.UUID, out itemID); - } - else - { - itemID = group.GetFromItemID(); - } ShowAttachInUserInventory(sp, AttachmentPt, itemID, group); @@ -548,7 +558,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", grp.UUID, grp.GetAttachmentPoint()); - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); + // If we're being called from a script, then trying to serialize that same script's state will not complete + // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if + // the client/server crashes rather than logging out normally, the attachment's scripts will resume + // without state on relog. Arguably, this is what we want anyway. + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); + InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index afc1a4fce4..94126f0af6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1873,6 +1873,8 @@ namespace OpenSim.Region.Framework.Scenes public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID) { +// m_log.DebugFormat("[SCENE]: Called attachObjectAssetStore for object {0} {1} for {2} {3} {4}", grp.Name, grp.LocalId, remoteClient.Name, remoteClient.AgentId, AgentId); + itemID = UUID.Zero; if (grp != null) { @@ -1881,16 +1883,20 @@ namespace OpenSim.Region.Framework.Scenes ? 250 : grp.AbsolutePosition.X) , - (grp.AbsolutePosition.X > (int)Constants.RegionSize) + (grp.AbsolutePosition.Y > (int)Constants.RegionSize) ? 250 - : grp.AbsolutePosition.X, + : grp.AbsolutePosition.Y, grp.AbsolutePosition.Z); Vector3 originalPosition = grp.AbsolutePosition; grp.AbsolutePosition = inventoryStoredPosition; - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); + // If we're being called from a script, then trying to serialize that same script's state will not complete + // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if + // the client/server crashes rather than logging out normally, the attachment's scripts will resume + // without state on relog. Arguably, this is what we want anyway. + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); grp.AbsolutePosition = originalPosition; @@ -1900,6 +1906,7 @@ namespace OpenSim.Region.Framework.Scenes (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), remoteClient.AgentId); + AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); @@ -1948,6 +1955,7 @@ namespace OpenSim.Region.Framework.Scenes itemID = item.ID; return item.AssetID; } + return UUID.Zero; } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 8fb9fad831..a60ee9bd84 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -126,27 +126,37 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// /// public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject) + { + return ToOriginalXmlFormat(sceneObject, true); + } + + /// + /// Serialize a scene object to the original xml format + /// + /// + /// Control whether script states are also serialized. + /// + public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject, bool doScriptStates) { using (StringWriter sw = new StringWriter()) { using (XmlTextWriter writer = new XmlTextWriter(sw)) { - ToOriginalXmlFormat(sceneObject, writer); + ToOriginalXmlFormat(sceneObject, writer, doScriptStates); } return sw.ToString(); } } - /// /// Serialize a scene object to the original xml format /// /// /// - public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer) + public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates) { - ToOriginalXmlFormat(sceneObject, writer, false); + ToOriginalXmlFormat(sceneObject, writer, doScriptStates, false); } /// @@ -156,10 +166,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// /// If false, don't write the enclosing SceneObjectGroup element /// - public static void ToOriginalXmlFormat(SceneObjectGroup sceneObject, XmlTextWriter writer, bool noRootElement) + public static void ToOriginalXmlFormat( + SceneObjectGroup sceneObject, XmlTextWriter writer, bool doScriptStates, bool noRootElement) { - //m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", Name); - //int time = System.Environment.TickCount; +// m_log.DebugFormat("[SERIALIZER]: Starting serialization of {0}", sceneObject.Name); +// int time = System.Environment.TickCount; if (!noRootElement) writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); @@ -182,12 +193,14 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } writer.WriteEndElement(); // OtherParts - sceneObject.SaveScriptedState(writer); + + if (doScriptStates) + sceneObject.SaveScriptedState(writer); if (!noRootElement) writer.WriteEndElement(); // SceneObjectGroup - //m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time); +// m_log.DebugFormat("[SERIALIZER]: Finished serialization of SOG {0}, {1}ms", sceneObject.Name, System.Environment.TickCount - time); } protected static void ToXmlFormat(SceneObjectPart part, XmlTextWriter writer) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 8b7871bbaa..0cc0fe7d63 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -58,7 +58,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// public interface IScriptInstance { + /// + /// Is this script currently running? + /// bool Running { get; set; } + bool ShuttingDown { get; set; } string State { get; set; } IScriptEngine Engine { get; } @@ -78,7 +82,14 @@ namespace OpenSim.Region.ScriptEngine.Interfaces void Init(); void Start(); + + /// + /// Stop the script. + /// + /// + /// true if the script was successfully stopped, false otherwise bool Stop(int timeout); + void SetState(string state); void PostEvent(EventParams data); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ffa0e24d62..d340ef2a19 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2964,8 +2964,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) - return; +// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) +// return; TaskInventoryItem item; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index d253c6a87d..c44366970e 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1294,9 +1294,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine public string GetXMLState(UUID itemID) { +// m_log.DebugFormat("[XEngine]: Getting XML state for {0}", itemID); + IScriptInstance instance = GetInstance(itemID); if (instance == null) + { +// m_log.DebugFormat("[XEngine]: Found no script for {0}, returning empty string", itemID); return ""; + } + string xml = instance.GetXMLState(); XmlDocument sdoc = new XmlDocument(); @@ -1437,6 +1443,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine mapData.InnerText = map; stateData.AppendChild(mapData); + +// m_log.DebugFormat("[XEngine]: Got XML state for {0}", itemID); + return doc.InnerXml; }