Make all the objects in a coalescence reappears after being loaded from an IAR. This still doesn't work proprerly since some required textures/contained item assets might be missing.

From pure code inspection, it looks like the uuid gatherer may get most asset uuids because the scene object serializer naively pulls non-root parts from all contained scene objects into one mega-object.  However, root part uuids may well still be missing, and there may be other odd artifacts from this bug.
It appears that storing the size of the coalescence and the offsets is redundant, since one can work out this information from the position data already in the scene object groups.
bulletsim
Justin Clark-Casey (justincc) 2011-04-15 00:42:06 +01:00
parent 821e67fb95
commit a0d80140f2
10 changed files with 134 additions and 39 deletions

View File

@ -471,16 +471,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (m_creatorIdForAssetId.ContainsKey(assetId))
{
string xmlData = Utils.BytesToString(data);
SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
foreach (SceneObjectPart sop in sog.Parts)
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
CoalescedSceneObjects coa = null;
if (CoalescedSceneObjectsSerializer.TryFromXml(xmlData, out coa))
{
if (sop.CreatorData == null || sop.CreatorData == "")
{
sop.CreatorID = m_creatorIdForAssetId[assetId];
// m_log.DebugFormat(
// "[INVENTORY ARCHIVER]: Loaded coalescence {0} has {1} objects", assetId, coa.Count);
sceneObjects.AddRange(coa.Objects);
}
else
{
sceneObjects.Add(SceneObjectSerializer.FromOriginalXmlFormat(xmlData));
}
data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sog));
foreach (SceneObjectGroup sog in sceneObjects)
foreach (SceneObjectPart sop in sog.Parts)
if (sop.CreatorData == null || sop.CreatorData == "")
sop.CreatorID = m_creatorIdForAssetId[assetId];
if (coa != null)
data = Utils.StringToBytes(CoalescedSceneObjectsSerializer.ToXml(coa));
else
data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sceneObjects[0]));
}
}

View File

@ -143,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
InventoryItemBase coaItem = new InventoryItemBase();
coaItem.Name = m_coaItemName;
coaItem.ID = UUID.Parse("00000000-0000-0000-0000-000000000180");
coaItem.AssetID = asset1.FullID;
coaItem.AssetID = coaAsset.FullID;
coaItem.GroupID = UUID.Random();
coaItem.CreatorIdAsUuid = m_uaLL1.PrincipalID;
coaItem.Owner = m_uaLL1.PrincipalID;

View File

@ -62,10 +62,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
SerialiserModule serialiserModule = new SerialiserModule();
m_archiverModule = new InventoryArchiverModule();
m_scene = SceneSetupHelpers.SetupScene("Inventory");
m_scene = SceneSetupHelpers.SetupScene("asset inventory");
SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
}
[Test]
public void TestLoadCoalesecedItem()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL1, "password");
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
InventoryItemBase coaItem
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName);
Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1");
string assetXml = AssetHelpers.ReadAssetAsString(m_scene.AssetService, coaItem.AssetID);
CoalescedSceneObjects coa;
bool readResult = CoalescedSceneObjectsSerializer.TryFromXml(assetXml, out coa);
Assert.That(readResult, Is.True);
// TODO: Check that the loaded coalesence is valid and that the required scene object assets are around
}
/// <summary>
/// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive
/// (subject to change since there is no fixed format yet).
@ -257,22 +281,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID));
}
[Test]
public void TestLoadCoalesecedItem()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL1, "password");
m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "password", m_iarStream);
InventoryItemBase coaItem
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_coaItemName);
Assert.That(coaItem, Is.Not.Null, "Didn't find loaded item 1");
// TODO: Check that the loaded coalesence is valid and that the required scene object assets are around
}
}
}

View File

@ -195,6 +195,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
public byte[] GetData(string id)
{
// m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id);
AssetBase asset = m_Cache.Get(id);
if (asset != null)

View File

@ -56,10 +56,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
/// <returns></returns>
public static string ToXml(CoalescedSceneObjects coa)
{
// TODO: Should probably return an empty xml serialization rather than a blank string
if (!coa.HasObjects)
return "";
using (StringWriter sw = new StringWriter())
{
using (XmlTextWriter writer = new XmlTextWriter(sw))
@ -105,10 +101,49 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
string output = sw.ToString();
// m_log.Debug(output);
// Console.WriteLine(output);
return output;
}
}
public static bool TryFromXml(string xml, out CoalescedSceneObjects coa)
{
// m_log.DebugFormat("[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() deserializing {0}", xml);
coa = null;
using (StringReader sr = new StringReader(xml))
{
using (XmlTextReader reader = new XmlTextReader(sr))
{
reader.Read();
if (reader.Name != "CoalescedObject")
{
// m_log.DebugFormat(
// "[COALESCED SCENE OBJECTS SERIALIZER]: TryFromXml() root element was {0} so returning false",
// reader.Name);
return false;
}
coa = new CoalescedSceneObjects(UUID.Zero);
reader.Read();
while (reader.NodeType != XmlNodeType.EndElement && reader.Name != "CoalescedObject")
{
if (reader.Name == "SceneObjectGroup")
{
string soXml = reader.ReadOuterXml();
coa.Add(SceneObjectSerializer.FromOriginalXmlFormat(soXml));
}
}
reader.ReadEndElement(); // CoalescedObject
}
}
return true;
}
}
}

View File

@ -89,6 +89,8 @@ namespace OpenSim.Services.AssetService
public virtual AssetBase Get(string id)
{
// m_log.DebugFormat("[ASSET SERVICE]: Get asset for {0}", id);
UUID assetID;
if (!UUID.TryParse(id, out assetID))
@ -107,6 +109,8 @@ namespace OpenSim.Services.AssetService
public virtual AssetMetadata GetMetadata(string id)
{
// m_log.DebugFormat("[ASSET SERVICE]: Get asset metadata for {0}", id);
UUID assetID;
if (!UUID.TryParse(id, out assetID))
@ -121,6 +125,8 @@ namespace OpenSim.Services.AssetService
public virtual byte[] GetData(string id)
{
// m_log.DebugFormat("[ASSET SERVICE]: Get asset data for {0}", id);
UUID assetID;
if (!UUID.TryParse(id, out assetID))
@ -150,7 +156,9 @@ namespace OpenSim.Services.AssetService
public virtual string Store(AssetBase asset)
{
//m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID);
// m_log.DebugFormat(
// "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.ID, asset.Data.Length);
m_Database.StoreAsset(asset);
return asset.ID;

View File

@ -48,6 +48,11 @@ namespace OpenSim.Services.Interfaces
/// <returns></returns>
AssetMetadata GetMetadata(string id);
/// <summary>
/// Get an asset's data, ignoring the metadata.
/// </summary>
/// <param name="id"></param>
/// <returns>null if there is no such asset</returns>
byte[] GetData(string id);
/// <summary>

View File

@ -54,13 +54,19 @@ namespace OpenSim.Tests.Common.Mock
public AssetBase Get(string id)
{
m_log.DebugFormat("[MOCK ASSET SERVICE]: Getting asset with id {0}", id);
// m_log.DebugFormat("[MOCK ASSET SERVICE]: Getting asset with id {0}", id);
AssetBase asset;
if (Assets.ContainsKey(id))
{
asset = Assets[id];
// m_log.DebugFormat(
// "[MOCK ASSET SERVICE]: Got asset {0} {1}, bytes {2}", asset.Name, asset.ID, asset.Data.Length);
}
else
{
asset = null;
}
return asset;
}
@ -77,7 +83,14 @@ namespace OpenSim.Tests.Common.Mock
public byte[] GetData(string id)
{
throw new System.NotImplementedException();
// m_log.DebugFormat("[MOCK ASSET SERVICE]: Requesting data for asset {0}", id);
AssetBase asset = Get(id);
if (asset == null)
return null;
else
return asset.Data;
}
public bool Get(string id, object sender, AssetRetrieved handler)
@ -89,7 +102,8 @@ namespace OpenSim.Tests.Common.Mock
public string Store(AssetBase asset)
{
m_log.DebugFormat("[MOCK ASSET SERVICE]: Storing asset {0}", asset.ID);
// m_log.DebugFormat(
// "[MOCK ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.ID, asset.Data.Length);
Assets[asset.ID] = asset;

View File

@ -30,6 +30,7 @@ using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces;
namespace OpenSim.Tests.Common
{
@ -118,5 +119,11 @@ namespace OpenSim.Tests.Common
asset.Data = data;
return asset;
}
public static string ReadAssetAsString(IAssetService assetService, UUID uuid)
{
byte[] assetData = assetService.GetData(uuid.ToString());
return Encoding.ASCII.GetString(assetData);
}
}
}

View File

@ -169,13 +169,16 @@ namespace OpenSim.Tests.Common.Setup
LocalAssetServicesConnector assetService = new LocalAssetServicesConnector();
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
config.AddConfig("AssetService");
config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
config.AddConfig("AssetService");
if (real)
config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
else
config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:MockAssetService");
config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
assetService.Initialise(config);
assetService.AddRegion(testScene);
assetService.RegionLoaded(testScene);