Fix llAttachToAvatar()

Apart from one obvious bug, this was failing because attempting to serialize the script from inside the script (as part of saving the attachment as an inventory asset) was triggering an extremely long delay.
So we now don't do this.  The state will be serialized anyway when the avatar normally logs out.
The worst that can happen is that if the client/server crashes, the attachment scripts start without previous state.
This commit is contained in:
Justin Clark-Casey (justincc)
2011-08-24 20:49:23 +01:00
parent 97b207240e
commit cf3ffe5bb4
6 changed files with 80 additions and 24 deletions

View File

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

View File

@@ -126,27 +126,37 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
/// <param name="sceneObject"></param>
/// <returns></returns>
public static string ToOriginalXmlFormat(SceneObjectGroup sceneObject)
{
return ToOriginalXmlFormat(sceneObject, true);
}
/// <summary>
/// Serialize a scene object to the original xml format
/// </summary>
/// <param name="sceneObject"></param>
/// <param name="doScriptStates">Control whether script states are also serialized.</para>
/// <returns></returns>
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();
}
}
/// <summary>
/// Serialize a scene object to the original xml format
/// </summary>
/// <param name="sceneObject"></param>
/// <returns></returns>
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);
}
/// <summary>
@@ -156,10 +166,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
/// <param name="writer"></param>
/// <param name="noRootElement">If false, don't write the enclosing SceneObjectGroup element</param>
/// <returns></returns>
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)