diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs
index 43d28e799c..66da564e37 100644
--- a/OpenSim/Framework/TaskInventoryItem.cs
+++ b/OpenSim/Framework/TaskInventoryItem.cs
@@ -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
/// The new part ID to which this item belongs
public void ResetIDs(UUID partID)
{
+ _oldID = _itemID;
_itemID = UUID.Random();
_parentPartID = partID;
_parentID = partID;
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index 01e5ae0c89..8e6b461788 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -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");
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 3ffabbdbd2..a25b25ffd3 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -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);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 2552a3d229..364da72c45 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -169,6 +169,8 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_scriptListens_atTarget = false;
private bool m_scriptListens_notAtTarget = false;
+ internal Dictionary m_savedScriptState = null;
+
#region Properties
///
@@ -423,6 +425,7 @@ namespace OpenSim.Region.Framework.Scenes
///
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 property
xmlData = xmlData.Replace("", "");
xmlData = xmlData.Replace("", "");
- 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", "");
xmlData = xmlData.Replace("", "");
- 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 0)
+ {
+ m_savedScriptState = new Dictionary();
+ 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 states = new Dictionary();
+
+ // Capture script state while holding the lock
+ lock (m_parts)
+ {
+ foreach (SceneObjectPart part in m_parts.Values)
+ {
+ Dictionary 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
+ }
+
}
///
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 966652501b..e952799874 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -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);
+ }
+ }
+
///
/// Start a script which is in this prim's inventory.
///