Refactored Load IAR: created a generic mechanism to modify the SOG's as they are being loaded

Resolves http://opensimulator.org/mantis/view.php?id=6942
0.8.0.3
Oren Hurvitz 2013-11-18 12:48:23 +02:00
parent 0ff61341e4
commit 5fd9411143
2 changed files with 86 additions and 47 deletions

View File

@ -483,52 +483,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
{ {
if (m_creatorIdForAssetId.ContainsKey(assetId)) if (m_creatorIdForAssetId.ContainsKey(assetId))
{ {
string xmlData = Utils.BytesToString(data); data = SceneObjectSerializer.ModifySerializedObject(assetId, data,
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); sog => {
bool modified = false;
foreach (SceneObjectPart sop in sog.Parts)
{
if (string.IsNullOrEmpty(sop.CreatorData))
{
sop.CreatorID = m_creatorIdForAssetId[assetId];
modified = true;
}
}
return modified;
});
CoalescedSceneObjects coa = null; if (data == null)
if (CoalescedSceneObjectsSerializer.TryFromXml(xmlData, out coa)) return false;
{
// m_log.DebugFormat(
// "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count);
if (coa.Objects.Count == 0)
{
m_log.WarnFormat(
"[INVENTORY ARCHIVE READ REQUEST]: Aborting load of coalesced object from asset {0} as it has zero loaded components",
assetId);
return false;
}
sceneObjects.AddRange(coa.Objects);
}
else
{
SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
if (deserializedObject != null)
{
sceneObjects.Add(deserializedObject);
}
else
{
m_log.WarnFormat(
"[INVENTORY ARCHIVE READ REQUEST]: Aborting load of object from asset {0} as deserialization failed",
assetId);
return false;
}
}
foreach (SceneObjectGroup sog in sceneObjects)
foreach (SceneObjectPart sop in sog.Parts)
if (string.IsNullOrEmpty(sop.CreatorData))
sop.CreatorID = m_creatorIdForAssetId[assetId];
if (coa != null)
data = Utils.StringToBytes(CoalescedSceneObjectsSerializer.ToXml(coa));
else
data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sceneObjects[0]));
} }
} }
@ -550,7 +522,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return false; return false;
} }
} }
/// <summary> /// <summary>
/// Load control file /// Load control file
/// </summary> /// </summary>
@ -656,4 +628,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
m_assetsLoaded = true; m_assetsLoaded = true;
} }
} }
} }

View File

@ -299,6 +299,73 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
} }
} }
/// <summary>
/// Modifies a SceneObjectGroup.
/// </summary>
/// <param name="sog">The object</param>
/// <returns>Whether the object was actually modified</returns>
public delegate bool SceneObjectModifier(SceneObjectGroup sog);
/// <summary>
/// Modifies an object by deserializing it; applying 'modifier' to each SceneObjectGroup; and reserializing.
/// </summary>
/// <param name="assetId">The object's UUID</param>
/// <param name="data">Serialized data</param>
/// <param name="modifier">The function to run on each SceneObjectGroup</param>
/// <returns>The new serialized object's data, or null if an error occurred</returns>
public static byte[] ModifySerializedObject(UUID assetId, byte[] data, SceneObjectModifier modifier)
{
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
CoalescedSceneObjects coa = null;
string xmlData = Utils.BytesToString(data);
if (CoalescedSceneObjectsSerializer.TryFromXml(xmlData, out coa))
{
// m_log.DebugFormat("[SERIALIZER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count);
if (coa.Objects.Count == 0)
{
m_log.WarnFormat("[SERIALIZER]: Aborting load of coalesced object from asset {0} as it has zero loaded components", assetId);
return null;
}
sceneObjects.AddRange(coa.Objects);
}
else
{
SceneObjectGroup deserializedObject = FromOriginalXmlFormat(xmlData);
if (deserializedObject != null)
{
sceneObjects.Add(deserializedObject);
}
else
{
m_log.WarnFormat("[SERIALIZER]: Aborting load of object from asset {0} as deserialization failed", assetId);
return null;
}
}
bool modified = false;
foreach (SceneObjectGroup sog in sceneObjects)
{
if (modifier(sog))
modified = true;
}
if (modified)
{
if (coa != null)
data = Utils.StringToBytes(CoalescedSceneObjectsSerializer.ToXml(coa));
else
data = Utils.StringToBytes(ToOriginalXmlFormat(sceneObjects[0]));
}
return data;
}
#region manual serialization #region manual serialization