From: Alan Webb <alan_webb@us.ibm.com>
Changes to enable script state persistence across non-restart serialization situations (inventory/OAR/attachments) Also fixing test cases for OAR and IAR so they don't barf with the new code.0.6.5-rc1
parent
d455d579d0
commit
7dbcf0570f
|
@ -120,6 +120,7 @@ namespace OpenSim.Framework
|
|||
private UUID _permsGranter;
|
||||
private int _permsMask;
|
||||
private int _type = 0;
|
||||
private UUID _oldID;
|
||||
|
||||
public UUID AssetID {
|
||||
get {
|
||||
|
@ -220,6 +221,15 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
|
||||
public UUID OldItemID {
|
||||
get {
|
||||
return _oldID;
|
||||
}
|
||||
set {
|
||||
_oldID = value;
|
||||
}
|
||||
}
|
||||
|
||||
public UUID LastOwnerID {
|
||||
get {
|
||||
return _lastOwnerID;
|
||||
|
@ -327,6 +337,7 @@ namespace OpenSim.Framework
|
|||
/// <param name="partID">The new part ID to which this item belongs</param>
|
||||
public void ResetIDs(UUID partID)
|
||||
{
|
||||
_oldID = _itemID;
|
||||
_itemID = UUID.Random();
|
||||
_parentPartID = partID;
|
||||
_parentID = partID;
|
||||
|
|
|
@ -96,6 +96,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
|||
part1.Name = partName;
|
||||
|
||||
object1 = new SceneObjectGroup(part1);
|
||||
scene.AddNewSceneObject(object1, false);
|
||||
}
|
||||
|
||||
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
|
||||
|
|
|
@ -201,11 +201,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
|
||||
Vector3 offsetPosition = new Vector3(20, 25, 30);
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
ArchiverModule archiverModule = new ArchiverModule();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
SceneObjectPart part1
|
||||
= new SceneObjectPart(
|
||||
UUID.Zero, shape, groupPosition, rotationOffset, offsetPosition);
|
||||
part1.Name = part1Name;
|
||||
SceneObjectGroup object1 = new SceneObjectGroup(part1);
|
||||
scene.AddNewSceneObject(object1, false);
|
||||
|
||||
string object1FileName = string.Format(
|
||||
"{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
|
||||
|
@ -218,11 +225,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
|
||||
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
ArchiverModule archiverModule = new ArchiverModule();
|
||||
// SerialiserModule serialiserModule = new SerialiserModule();
|
||||
// ArchiverModule archiverModule = new ArchiverModule();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
// Scene scene = SceneSetupHelpers.SetupScene();
|
||||
// SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
archiverModule.DearchiveRegion(archiveReadStream);
|
||||
|
||||
|
|
|
@ -169,6 +169,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
private bool m_scriptListens_atTarget = false;
|
||||
private bool m_scriptListens_notAtTarget = false;
|
||||
|
||||
internal Dictionary<UUID, string> m_savedScriptState = null;
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
|
@ -423,6 +425,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </param>
|
||||
public SceneObjectGroup(UUID fromUserInventoryItemID, string xmlData, bool isOriginalXmlFormat)
|
||||
{
|
||||
|
||||
if (!isOriginalXmlFormat)
|
||||
throw new Exception("This constructor must specify the xml is in OpenSim's original format");
|
||||
|
||||
|
@ -436,50 +439,60 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// Handle Nested <UUID><UUID> property
|
||||
xmlData = xmlData.Replace("<Guid><Guid>", "<UUID><Guid>");
|
||||
xmlData = xmlData.Replace("</Guid></Guid>", "</Guid></UUID>");
|
||||
StringReader sr = new StringReader(xmlData);
|
||||
XmlTextReader reader = new XmlTextReader(sr);
|
||||
|
||||
try
|
||||
{
|
||||
reader.Read();
|
||||
reader.ReadStartElement("SceneObjectGroup");
|
||||
reader.ReadStartElement("RootPart");
|
||||
SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader));
|
||||
|
||||
reader.ReadEndElement();
|
||||
StringReader sr;
|
||||
XmlTextReader reader;
|
||||
XmlNodeList parts;
|
||||
XmlDocument doc;
|
||||
int linkNum;
|
||||
|
||||
while (reader.Read())
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(xmlData);
|
||||
parts = doc.GetElementsByTagName("RootPart");
|
||||
|
||||
if(parts.Count == 0)
|
||||
{
|
||||
switch (reader.NodeType)
|
||||
{
|
||||
case XmlNodeType.Element:
|
||||
if (reader.Name == "Part")
|
||||
{
|
||||
reader.Read();
|
||||
SceneObjectPart part = SceneObjectPart.FromXml(reader);
|
||||
|
||||
// We reset the link number in order to make sure that the persisted linkset order is
|
||||
int linkNum = part.LinkNum;
|
||||
AddPart(part);
|
||||
part.LinkNum = linkNum;
|
||||
|
||||
part.TrimPermissions();
|
||||
part.StoreUndoState();
|
||||
}
|
||||
break;
|
||||
|
||||
case XmlNodeType.EndElement:
|
||||
break;
|
||||
}
|
||||
throw new Exception("[SCENE] Invalid Xml format - no root part");
|
||||
}
|
||||
else
|
||||
{
|
||||
sr = new StringReader(parts[0].InnerXml);
|
||||
reader = new XmlTextReader(sr);
|
||||
SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader));
|
||||
reader.Close();
|
||||
sr.Close();
|
||||
}
|
||||
|
||||
parts = doc.GetElementsByTagName("Part");
|
||||
|
||||
for (int i=0; i<parts.Count ; i++)
|
||||
{
|
||||
sr = new StringReader(parts[i].InnerXml);
|
||||
reader = new XmlTextReader(sr);
|
||||
SceneObjectPart part = SceneObjectPart.FromXml(reader);
|
||||
linkNum = part.LinkNum;
|
||||
AddPart(part);
|
||||
part.LinkNum = linkNum;
|
||||
part.TrimPermissions();
|
||||
part.StoreUndoState();
|
||||
reader.Close();
|
||||
sr.Close();
|
||||
}
|
||||
|
||||
// Script state may, or may not, exist. Not having any, is NOT
|
||||
// ever a problem.
|
||||
|
||||
LoadScriptState(doc);
|
||||
|
||||
}
|
||||
catch (XmlException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENE]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData);
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
sr.Close();
|
||||
//m_log.DebugFormat("[SOG]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
|
||||
}
|
||||
|
||||
|
@ -493,6 +506,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
protected void SetFromXml(string xmlData)
|
||||
{
|
||||
|
||||
//m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
|
||||
//int time = System.Environment.TickCount;
|
||||
|
||||
|
@ -504,42 +518,46 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
xmlData = xmlData.Replace("<Guid><Guid>", "<UUID><Guid>");
|
||||
xmlData = xmlData.Replace("</Guid></Guid>", "</Guid></UUID>");
|
||||
|
||||
StringReader sr = new StringReader(xmlData);
|
||||
XmlTextReader reader = new XmlTextReader(sr);
|
||||
reader.Read();
|
||||
|
||||
reader.ReadStartElement("SceneObjectGroup");
|
||||
SetRootPart(CreatePartFromXml(reader));
|
||||
|
||||
reader.Read();
|
||||
bool more = true;
|
||||
|
||||
while (more)
|
||||
try
|
||||
{
|
||||
switch (reader.NodeType)
|
||||
{
|
||||
case XmlNodeType.Element:
|
||||
if (reader.Name == "SceneObjectPart")
|
||||
{
|
||||
SceneObjectPart part = CreatePartFromXml(reader);
|
||||
AddPart(part);
|
||||
part.StoreUndoState();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("found unexpected element: " + reader.Name);
|
||||
reader.Read();
|
||||
}
|
||||
break;
|
||||
case XmlNodeType.EndElement:
|
||||
reader.Read();
|
||||
break;
|
||||
}
|
||||
more = !reader.EOF;
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
sr.Close();
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.LoadXml(xmlData);
|
||||
|
||||
XmlNodeList parts = doc.GetElementsByTagName("SceneObjectPart");
|
||||
|
||||
// Process the root part first
|
||||
if(parts.Count > 0)
|
||||
{
|
||||
StringReader sr = new StringReader(parts[0].OuterXml);
|
||||
XmlTextReader reader = new XmlTextReader(sr);
|
||||
SetRootPart(CreatePartFromXml(reader));
|
||||
reader.Close();
|
||||
sr.Close();
|
||||
}
|
||||
|
||||
// Then deal with the rest
|
||||
for(int i=1; i<parts.Count; i++)
|
||||
{
|
||||
StringReader sr = new StringReader(parts[i].OuterXml);
|
||||
XmlTextReader reader = new XmlTextReader(sr);
|
||||
SceneObjectPart part = CreatePartFromXml(reader);
|
||||
AddPart(part);
|
||||
part.StoreUndoState();
|
||||
reader.Close();
|
||||
sr.Close();
|
||||
}
|
||||
|
||||
// Script state may, or may not, exist. Not having any, is NOT
|
||||
// ever a problem.
|
||||
|
||||
LoadScriptState(doc);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENE]: Deserialization of xml failed with {0}. xml was {1}", e, xmlData);
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[SOG]: Finished deserialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
|
||||
}
|
||||
|
@ -567,6 +585,23 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
}
|
||||
|
||||
private void LoadScriptState(XmlDocument doc)
|
||||
{
|
||||
XmlNodeList nodes = doc.GetElementsByTagName("SavedScriptState");
|
||||
if(nodes.Count > 0)
|
||||
{
|
||||
m_savedScriptState = new Dictionary<UUID, string>();
|
||||
foreach(XmlNode node in nodes)
|
||||
{
|
||||
if(node.Attributes["UUID"] != null)
|
||||
{
|
||||
UUID itemid = new UUID(node.Attributes["UUID"].Value);
|
||||
m_savedScriptState.Add(itemid, node.InnerXml);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFromAssetID(UUID AssetId)
|
||||
{
|
||||
lock (m_parts)
|
||||
|
@ -748,8 +783,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // OtherParts
|
||||
SaveScriptedState(writer);
|
||||
writer.WriteEndElement(); // SceneObjectGroup
|
||||
|
||||
//m_log.DebugFormat("[SOG]: Finished serialization of SOG {0}, {1}ms", Name, System.Environment.TickCount - time);
|
||||
}
|
||||
|
@ -769,6 +805,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public void ToXml2(XmlTextWriter writer)
|
||||
{
|
||||
|
||||
//m_log.DebugFormat("[SOG]: Starting serialization of SOG {0} to XML2", Name);
|
||||
//int time = System.Environment.TickCount;
|
||||
|
||||
|
@ -787,9 +824,48 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement();
|
||||
writer.WriteEndElement(); // End of OtherParts
|
||||
SaveScriptedState(writer);
|
||||
writer.WriteEndElement(); // End of SceneObjectGroup
|
||||
|
||||
//m_log.DebugFormat("[SOG]: Finished serialization of SOG {0} to XML2, {1}ms", Name, System.Environment.TickCount - time);
|
||||
|
||||
}
|
||||
|
||||
private void SaveScriptedState(XmlTextWriter writer)
|
||||
{
|
||||
|
||||
XmlDocument doc = new XmlDocument();
|
||||
Dictionary<UUID,string> states = new Dictionary<UUID,string>();
|
||||
|
||||
// Capture script state while holding the lock
|
||||
lock (m_parts)
|
||||
{
|
||||
foreach (SceneObjectPart part in m_parts.Values)
|
||||
{
|
||||
Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
|
||||
foreach (UUID itemid in pstates.Keys)
|
||||
{
|
||||
states.Add(itemid, pstates[itemid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(states.Count > 0)
|
||||
{
|
||||
// Now generate the necessary XML wrappings
|
||||
writer.WriteStartElement(String.Empty, "GroupScriptStates", String.Empty);
|
||||
foreach(UUID itemid in states.Keys)
|
||||
{
|
||||
doc.LoadXml(states[itemid]);
|
||||
writer.WriteStartElement(String.Empty, "SavedScriptState", String.Empty);
|
||||
writer.WriteAttributeString(String.Empty, "UUID", String.Empty, itemid.ToString());
|
||||
writer.WriteRaw(doc.DocumentElement.OuterXml); // Writes ScriptState element
|
||||
writer.WriteEndElement(); // End of SavedScriptState
|
||||
}
|
||||
writer.WriteEndElement(); // End of GroupScriptStates
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using OpenMetaverse;
|
||||
|
@ -264,6 +265,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
else
|
||||
{
|
||||
if(m_part.ParentGroup.m_savedScriptState != null)
|
||||
RestoreSavedScriptState(item.OldItemID, item.ItemID);
|
||||
m_items[item.ItemID].PermsMask = 0;
|
||||
m_items[item.ItemID].PermsGranter = UUID.Zero;
|
||||
string script = Utils.BytesToString(asset.Data);
|
||||
|
@ -276,6 +279,22 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
|
||||
|
||||
private void RestoreSavedScriptState(UUID oldID, UUID newID)
|
||||
{
|
||||
if(m_part.ParentGroup.m_savedScriptState.ContainsKey(oldID))
|
||||
{
|
||||
string fpath = Path.Combine("ScriptEngines/"+m_part.ParentGroup.Scene.RegionInfo.RegionID.ToString(),
|
||||
newID.ToString()+".state");
|
||||
FileStream fs = File.Create(fpath);
|
||||
Byte[] buffer = enc.GetBytes(m_part.ParentGroup.m_savedScriptState[oldID]);
|
||||
fs.Write(buffer,0,buffer.Length);
|
||||
fs.Close();
|
||||
m_part.ParentGroup.m_savedScriptState.Remove(oldID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start a script which is in this prim's inventory.
|
||||
/// </summary>
|
||||
|
|
Loading…
Reference in New Issue