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;
}