* Implement merging of oars in code
* Not fully tested yet and not yet available as an option from the user console0.6.3-post-fixes
parent
879338499f
commit
25bc7a44cd
|
@ -55,22 +55,29 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
private Stream m_loadStream;
|
private Stream m_loadStream;
|
||||||
private string m_errorMessage;
|
private string m_errorMessage;
|
||||||
|
|
||||||
|
/// <value>
|
||||||
|
/// Should the archive being loaded be merged with what is already on the region?
|
||||||
|
/// </value>
|
||||||
|
private bool m_merge;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to cache lookups for valid uuids.
|
/// Used to cache lookups for valid uuids.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private IDictionary<UUID, bool> m_validUserUuids = new Dictionary<UUID, bool>();
|
private IDictionary<UUID, bool> m_validUserUuids = new Dictionary<UUID, bool>();
|
||||||
|
|
||||||
public ArchiveReadRequest(Scene scene, string loadPath)
|
public ArchiveReadRequest(Scene scene, string loadPath, bool merge)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_loadStream = new GZipStream(GetStream(loadPath), CompressionMode.Decompress);
|
m_loadStream = new GZipStream(GetStream(loadPath), CompressionMode.Decompress);
|
||||||
m_errorMessage = String.Empty;
|
m_errorMessage = String.Empty;
|
||||||
|
m_merge = merge;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArchiveReadRequest(Scene scene, Stream loadStream)
|
public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_loadStream = loadStream;
|
m_loadStream = loadStream;
|
||||||
|
m_merge = merge;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -92,8 +99,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
{
|
{
|
||||||
TarArchiveReader archive = new TarArchiveReader(m_loadStream);
|
TarArchiveReader archive = new TarArchiveReader(m_loadStream);
|
||||||
|
|
||||||
//AssetsDearchiver dearchiver = new AssetsDearchiver(m_scene.AssetCache);
|
|
||||||
|
|
||||||
string filePath = "ERROR";
|
string filePath = "ERROR";
|
||||||
|
|
||||||
byte[] data;
|
byte[] data;
|
||||||
|
@ -103,6 +108,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat(
|
//m_log.DebugFormat(
|
||||||
// "[ARCHIVER]: Successfully read {0} ({1} bytes)}", filePath, data.Length);
|
// "[ARCHIVER]: Successfully read {0} ({1} bytes)}", filePath, data.Length);
|
||||||
|
|
||||||
if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
|
if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[ARCHIVER]: Ignoring directory entry {0}",
|
m_log.WarnFormat("[ARCHIVER]: Ignoring directory entry {0}",
|
||||||
|
@ -112,11 +118,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
{
|
{
|
||||||
serialisedSceneObjects.Add(m_asciiEncoding.GetString(data));
|
serialisedSceneObjects.Add(m_asciiEncoding.GetString(data));
|
||||||
}
|
}
|
||||||
// else if (filePath.Equals(ArchiveConstants.ASSETS_METADATA_PATH))
|
|
||||||
// {
|
|
||||||
// string xml = m_asciiEncoding.GetString(data);
|
|
||||||
// dearchiver.AddAssetMetadata(xml);
|
|
||||||
// }
|
|
||||||
else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
|
else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
|
||||||
{
|
{
|
||||||
if (LoadAsset(filePath, data))
|
if (LoadAsset(filePath, data))
|
||||||
|
@ -124,11 +125,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
else
|
else
|
||||||
failedAssetRestores++;
|
failedAssetRestores++;
|
||||||
}
|
}
|
||||||
else if (filePath.StartsWith(ArchiveConstants.TERRAINS_PATH))
|
else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH))
|
||||||
{
|
{
|
||||||
LoadTerrain(filePath, data);
|
LoadTerrain(filePath, data);
|
||||||
}
|
}
|
||||||
else if (filePath.StartsWith(ArchiveConstants.SETTINGS_PATH))
|
else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH))
|
||||||
{
|
{
|
||||||
LoadRegionSettings(filePath, data);
|
LoadRegionSettings(filePath, data);
|
||||||
}
|
}
|
||||||
|
@ -155,8 +156,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores);
|
m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_merge)
|
||||||
|
{
|
||||||
m_log.Info("[ARCHIVER]: Clearing all existing scene objects");
|
m_log.Info("[ARCHIVER]: Clearing all existing scene objects");
|
||||||
m_scene.DeleteAllSceneObjects();
|
m_scene.DeleteAllSceneObjects();
|
||||||
|
}
|
||||||
|
|
||||||
// Reload serialized prims
|
// Reload serialized prims
|
||||||
m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
|
m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
|
||||||
|
@ -182,13 +186,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
|
|
||||||
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
foreach (SceneObjectPart part in sceneObject.Children.Values)
|
||||||
{
|
{
|
||||||
if (!resolveUserUuid(part.CreatorID))
|
if (!ResolveUserUuid(part.CreatorID))
|
||||||
part.CreatorID = masterAvatarId;
|
part.CreatorID = masterAvatarId;
|
||||||
|
|
||||||
if (!resolveUserUuid(part.OwnerID))
|
if (!ResolveUserUuid(part.OwnerID))
|
||||||
part.OwnerID = masterAvatarId;
|
part.OwnerID = masterAvatarId;
|
||||||
|
|
||||||
if (!resolveUserUuid(part.LastOwnerID))
|
if (!ResolveUserUuid(part.LastOwnerID))
|
||||||
part.LastOwnerID = masterAvatarId;
|
part.LastOwnerID = masterAvatarId;
|
||||||
|
|
||||||
// And zap any troublesome sit target information
|
// And zap any troublesome sit target information
|
||||||
|
@ -201,11 +205,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
TaskInventoryDictionary inv = part.TaskInventory;
|
TaskInventoryDictionary inv = part.TaskInventory;
|
||||||
foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
|
foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
|
||||||
{
|
{
|
||||||
if (!resolveUserUuid(kvp.Value.OwnerID))
|
if (!ResolveUserUuid(kvp.Value.OwnerID))
|
||||||
{
|
{
|
||||||
kvp.Value.OwnerID = masterAvatarId;
|
kvp.Value.OwnerID = masterAvatarId;
|
||||||
}
|
}
|
||||||
if (!resolveUserUuid(kvp.Value.CreatorID))
|
if (!ResolveUserUuid(kvp.Value.CreatorID))
|
||||||
{
|
{
|
||||||
kvp.Value.CreatorID = masterAvatarId;
|
kvp.Value.CreatorID = masterAvatarId;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +246,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uuid"></param>
|
/// <param name="uuid"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool resolveUserUuid(UUID uuid)
|
private bool ResolveUserUuid(UUID uuid)
|
||||||
{
|
{
|
||||||
if (!m_validUserUuids.ContainsKey(uuid))
|
if (!m_validUserUuids.ContainsKey(uuid))
|
||||||
{
|
{
|
||||||
|
|
|
@ -80,16 +80,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DearchiveRegion(string loadPath)
|
public void DearchiveRegion(string loadPath)
|
||||||
|
{
|
||||||
|
DearchiveRegion(loadPath, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DearchiveRegion(string loadPath, bool merge)
|
||||||
{
|
{
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath);
|
"[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath);
|
||||||
|
|
||||||
new ArchiveReadRequest(m_scene, loadPath).DearchiveRegion();
|
new ArchiveReadRequest(m_scene, loadPath, merge).DearchiveRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DearchiveRegion(Stream loadStream)
|
public void DearchiveRegion(Stream loadStream)
|
||||||
{
|
{
|
||||||
new ArchiveReadRequest(m_scene, loadStream).DearchiveRegion();
|
DearchiveRegion(loadStream, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DearchiveRegion(Stream loadStream, bool merge)
|
||||||
|
{
|
||||||
|
new ArchiveReadRequest(m_scene, loadStream, merge).DearchiveRegion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,14 +167,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLoadOarV0p2()
|
public void TestLoadOarV0p2()
|
||||||
{
|
{
|
||||||
log4net.Config.XmlConfigurator.Configure();
|
//log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
MemoryStream archiveWriteStream = new MemoryStream();
|
MemoryStream archiveWriteStream = new MemoryStream();
|
||||||
TarArchiveWriter tar = new TarArchiveWriter();
|
TarArchiveWriter tar = new TarArchiveWriter();
|
||||||
|
|
||||||
tar.AddFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
|
tar.AddFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
|
||||||
|
|
||||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000020");
|
|
||||||
string part1Name = "object1";
|
string part1Name = "object1";
|
||||||
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
|
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
|
||||||
Vector3 groupPosition = new Vector3(90, 80, 70);
|
Vector3 groupPosition = new Vector3(90, 80, 70);
|
||||||
|
@ -216,5 +215,84 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
Assert.That(
|
Assert.That(
|
||||||
object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal");
|
object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test merging a V0.2 OpenSim Region Archive into an existing scene
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestMergeOarV0p2()
|
||||||
|
{
|
||||||
|
log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
MemoryStream archiveWriteStream = new MemoryStream();
|
||||||
|
|
||||||
|
string part2Name = "objectMerge";
|
||||||
|
PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
|
||||||
|
Vector3 part2GroupPosition = new Vector3(90, 80, 70);
|
||||||
|
Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
|
||||||
|
Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
|
||||||
|
|
||||||
|
// Create an oar file that we can use for the merge
|
||||||
|
{
|
||||||
|
ArchiverModule archiverModule = new ArchiverModule();
|
||||||
|
SerialiserModule serialiserModule = new SerialiserModule();
|
||||||
|
TerrainModule terrainModule = new TerrainModule();
|
||||||
|
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
|
||||||
|
|
||||||
|
SceneObjectPart part2
|
||||||
|
= new SceneObjectPart(
|
||||||
|
UUID.Zero, part2Shape, part2GroupPosition, part2RotationOffset, part2OffsetPosition);
|
||||||
|
part2.Name = part2Name;
|
||||||
|
SceneObjectGroup object2 = new SceneObjectGroup(part2);
|
||||||
|
|
||||||
|
scene.AddNewSceneObject(object2, false);
|
||||||
|
|
||||||
|
// Write out this scene
|
||||||
|
scene.EventManager.OnOarFileSaved += SaveCompleted;
|
||||||
|
archiverModule.ArchiveRegion(archiveWriteStream);
|
||||||
|
m_waitHandle.WaitOne(60000, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ArchiverModule archiverModule = new ArchiverModule();
|
||||||
|
SerialiserModule serialiserModule = new SerialiserModule();
|
||||||
|
TerrainModule terrainModule = new TerrainModule();
|
||||||
|
|
||||||
|
Scene scene = SceneSetupHelpers.SetupScene();
|
||||||
|
SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
|
||||||
|
|
||||||
|
string part1Name = "objectExisting";
|
||||||
|
PrimitiveBaseShape part1Shape = PrimitiveBaseShape.CreateCylinder();
|
||||||
|
Vector3 part1GroupPosition = new Vector3(80, 70, 60);
|
||||||
|
Quaternion part1RotationOffset = new Quaternion(50, 60, 70, 80);
|
||||||
|
Vector3 part1OffsetPosition = new Vector3(15, 20, 25);
|
||||||
|
|
||||||
|
SceneObjectPart part1
|
||||||
|
= new SceneObjectPart(
|
||||||
|
UUID.Zero, part1Shape, part1GroupPosition, part1RotationOffset, part1OffsetPosition);
|
||||||
|
part1.Name = part1Name;
|
||||||
|
SceneObjectGroup object1 = new SceneObjectGroup(part1);
|
||||||
|
|
||||||
|
scene.AddNewSceneObject(object1, false);
|
||||||
|
|
||||||
|
// Merge in the archive we created earlier
|
||||||
|
byte[] archive = archiveWriteStream.ToArray();
|
||||||
|
MemoryStream archiveReadStream = new MemoryStream(archive);
|
||||||
|
|
||||||
|
archiverModule.DearchiveRegion(archiveReadStream, true);
|
||||||
|
|
||||||
|
SceneObjectPart object1Existing = scene.GetSceneObjectPart(part1Name);
|
||||||
|
Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
|
||||||
|
Assert.That(object1Existing.Name, Is.EqualTo(part1Name), "object1 names not identical after merge");
|
||||||
|
Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1GroupPosition), "object1 group position not equal after merge");
|
||||||
|
|
||||||
|
SceneObjectPart object2PartMerged = scene.GetSceneObjectPart(part2Name);
|
||||||
|
Assert.That(object2PartMerged, Is.Not.Null, "object2 was not present after merge");
|
||||||
|
Assert.That(object2PartMerged.Name, Is.EqualTo(part2Name), "object2 names not identical after merge");
|
||||||
|
Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2GroupPosition), "object2 group position not equal after merge");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
void ArchiveRegion(Stream saveStream);
|
void ArchiveRegion(Stream saveStream);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dearchive the given region archive into the scene
|
/// Dearchive the given region archive. This replaces the existing scene.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
///
|
||||||
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
|
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
|
||||||
|
@ -64,12 +64,38 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
void DearchiveRegion(string loadPath);
|
void DearchiveRegion(string loadPath);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dearchive a region from a stream.
|
/// Dearchive the given region archive. This replaces the existing scene.
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
|
||||||
|
///
|
||||||
|
/// <param name="loadPath"></param>
|
||||||
|
/// <param name="merge">
|
||||||
|
/// If true, the loaded region merges with the existing one rather than replacing it. Any terrain or region
|
||||||
|
/// settings in the archive will be ignored.
|
||||||
|
/// </param>
|
||||||
|
void DearchiveRegion(string loadPath, bool merge);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dearchive a region from a stream. This replaces the existing scene.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
///
|
||||||
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
|
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
|
||||||
///
|
///
|
||||||
/// <param name="loadStream"></param>
|
/// <param name="loadStream"></param>
|
||||||
void DearchiveRegion(Stream loadStream);
|
void DearchiveRegion(Stream loadStream);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dearchive a region from a stream. This replaces the existing scene.
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
|
||||||
|
///
|
||||||
|
/// <param name="loadStream"></param>
|
||||||
|
/// <param name="merge">
|
||||||
|
/// If true, the loaded region merges with the existing one rather than replacing it. Any terrain or region
|
||||||
|
/// settings in the archive will be ignored.
|
||||||
|
/// </param>
|
||||||
|
void DearchiveRegion(Stream loadStream, bool merge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue