aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Archiver
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs363
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs4
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs122
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs93
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs1
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs232
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs39
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs209
-rwxr-xr-x[-rw-r--r--]OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wavbin211648 -> 211648 bytes
10 files changed, 622 insertions, 452 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 9c6706f..41515c0 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -40,6 +40,7 @@ using OpenSim.Framework.Monitoring;
40using OpenSim.Framework.Serialization; 40using OpenSim.Framework.Serialization;
41using OpenSim.Framework.Serialization.External; 41using OpenSim.Framework.Serialization.External;
42using OpenSim.Region.CoreModules.World.Terrain; 42using OpenSim.Region.CoreModules.World.Terrain;
43using OpenSim.Region.CoreModules.World.Land;
43using OpenSim.Region.Framework.Interfaces; 44using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes; 45using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.Framework.Scenes.Serialization; 46using OpenSim.Region.Framework.Scenes.Serialization;
@@ -76,14 +77,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
76 SceneObjects = new List<SceneObjectGroup>(); 77 SceneObjects = new List<SceneObjectGroup>();
77 } 78 }
78 } 79 }
79 80
80 81
81 /// <summary> 82 /// <summary>
82 /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version 83 /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version
83 /// bumps here should be compatible. 84 /// bumps here should be compatible.
84 /// </summary> 85 /// </summary>
85 public static int MAX_MAJOR_VERSION = 1; 86 public static int MAX_MAJOR_VERSION = 1;
86 87
87 /// <summary> 88 /// <summary>
88 /// Has the control file been loaded for this archive? 89 /// Has the control file been loaded for this archive?
89 /// </summary> 90 /// </summary>
@@ -126,12 +127,29 @@ namespace OpenSim.Region.CoreModules.World.Archiver
126 /// </value> 127 /// </value>
127 protected float m_rotation = 0f; 128 protected float m_rotation = 0f;
128 129
130 /// <value>
131 /// original oar region size. not using Constants.RegionSize
132 /// </value>
133 protected Vector3 m_incomingRegionSize = new Vector3(256f, 256f, float.MaxValue);
134
135 /// <value>
136 /// Center around which to apply the rotation relative to the original oar position
137 /// </value>
138 protected Vector3 m_rotationCenter = new Vector3(128f, 128f, 0f);
139
140 /// <value>
141 /// Corner 1 of a bounding cuboid which specifies which objects we load from the oar
142 /// </value>
143 protected Vector3 m_boundingOrigin = Vector3.Zero;
144
129 /// <value> 145 /// <value>
130 /// Center around which to apply the rotation relative to the origional oar position 146 /// Size of a bounding cuboid which specifies which objects we load from the oar
131 /// </value> 147 /// </value>
132 protected Vector3 m_rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f); 148 protected Vector3 m_boundingSize = new Vector3(Constants.MaximumRegionSize, Constants.MaximumRegionSize, float.MaxValue);
133 149
134 protected bool m_noObjects = false; 150 protected bool m_noObjects = false;
151 protected bool m_boundingBox = false;
152 protected bool m_debug = false;
135 153
136 /// <summary> 154 /// <summary>
137 /// Used to cache lookups for valid uuids. 155 /// Used to cache lookups for valid uuids.
@@ -160,10 +178,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
160 178
161 private IAssetService m_assetService = null; 179 private IAssetService m_assetService = null;
162 180
163
164 private UUID m_defaultUser; 181 private UUID m_defaultUser;
165 182
166 public ArchiveReadRequest(Scene scene, string loadPath, Guid requestId, Dictionary<string,object>options) 183 public ArchiveReadRequest(Scene scene, string loadPath, Guid requestId, Dictionary<string, object> options)
167 { 184 {
168 m_rootScene = scene; 185 m_rootScene = scene;
169 186
@@ -172,7 +189,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
172 m_defaultUser = (UUID)options["default-user"]; 189 m_defaultUser = (UUID)options["default-user"];
173 m_log.InfoFormat("Using User {0} as default user", m_defaultUser.ToString()); 190 m_log.InfoFormat("Using User {0} as default user", m_defaultUser.ToString());
174 } 191 }
175 else 192 else
176 { 193 {
177 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner; 194 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner;
178 } 195 }
@@ -189,8 +206,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
189 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?"); 206 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
190 m_log.Error(e); 207 m_log.Error(e);
191 } 208 }
192 209
193 m_errorMessage = String.Empty; 210 m_errorMessage = String.Empty;
211
194 m_merge = options.ContainsKey("merge"); 212 m_merge = options.ContainsKey("merge");
195 m_forceTerrain = options.ContainsKey("force-terrain"); 213 m_forceTerrain = options.ContainsKey("force-terrain");
196 m_forceParcels = options.ContainsKey("force-parcels"); 214 m_forceParcels = options.ContainsKey("force-parcels");
@@ -199,10 +217,45 @@ namespace OpenSim.Region.CoreModules.World.Archiver
199 m_requestId = requestId; 217 m_requestId = requestId;
200 m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero; 218 m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero;
201 m_rotation = options.ContainsKey("rotation") ? (float)options["rotation"] : 0f; 219 m_rotation = options.ContainsKey("rotation") ? (float)options["rotation"] : 0f;
202 m_rotationCenter = options.ContainsKey("rotation-center") ? (Vector3)options["rotation-center"]
203 : new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 0f);
204 220
205 // Zero can never be a valid user or group id 221 m_boundingOrigin = Vector3.Zero;
222 m_boundingSize = new Vector3(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY, float.MaxValue);
223
224 if (options.ContainsKey("bounding-origin"))
225 {
226 Vector3 boOption = (Vector3)options["bounding-origin"];
227 if (boOption != m_boundingOrigin)
228 {
229 m_boundingOrigin = boOption;
230 }
231 m_boundingBox = true;
232 }
233
234 if (options.ContainsKey("bounding-size"))
235 {
236 Vector3 bsOption = (Vector3)options["bounding-size"];
237 bool clip = false;
238 if (bsOption.X <= 0 || bsOption.X > m_boundingSize.X)
239 {
240 bsOption.X = m_boundingSize.X;
241 clip = true;
242 }
243 if (bsOption.Y <= 0 || bsOption.Y > m_boundingSize.Y)
244 {
245 bsOption.Y = m_boundingSize.Y;
246 clip = true;
247 }
248 if (bsOption != m_boundingSize)
249 {
250 m_boundingSize = bsOption;
251 m_boundingBox = true;
252 }
253 if (clip) m_log.InfoFormat("[ARCHIVER]: The bounding cube specified is larger than the destination region! Clipping to {0}.", m_boundingSize.ToString());
254 }
255
256 m_debug = options.ContainsKey("debug");
257
258 // Zero can never be a valid user id (or group)
206 m_validUserUuids[UUID.Zero] = false; 259 m_validUserUuids[UUID.Zero] = false;
207 m_validGroupUuids[UUID.Zero] = false; 260 m_validGroupUuids[UUID.Zero] = false;
208 261
@@ -210,7 +263,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
210 m_assetService = m_rootScene.AssetService; 263 m_assetService = m_rootScene.AssetService;
211 } 264 }
212 265
213 public ArchiveReadRequest(Scene scene, Stream loadStream, Guid requestId, Dictionary<string, object>options) 266 public ArchiveReadRequest(Scene scene, Stream loadStream, Guid requestId, Dictionary<string, object> options)
214 { 267 {
215 m_rootScene = scene; 268 m_rootScene = scene;
216 m_loadPath = null; 269 m_loadPath = null;
@@ -220,7 +273,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
220 m_requestId = requestId; 273 m_requestId = requestId;
221 274
222 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner; 275 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner;
223 276
224 // Zero can never be a valid user id 277 // Zero can never be a valid user id
225 m_validUserUuids[UUID.Zero] = false; 278 m_validUserUuids[UUID.Zero] = false;
226 279
@@ -233,6 +286,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
233 /// </summary> 286 /// </summary>
234 public void DearchiveRegion() 287 public void DearchiveRegion()
235 { 288 {
289 DearchiveRegion(true);
290 }
291
292 public void DearchiveRegion(bool shouldStartScripts)
293 {
236 int successfulAssetRestores = 0; 294 int successfulAssetRestores = 0;
237 int failedAssetRestores = 0; 295 int failedAssetRestores = 0;
238 296
@@ -255,7 +313,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
255 { 313 {
256 //m_log.DebugFormat( 314 //m_log.DebugFormat(
257 // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length); 315 // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length);
258 316
259 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) 317 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
260 continue; 318 continue;
261 319
@@ -301,11 +359,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
301 else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) 359 else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH))
302 { 360 {
303 LoadRegionSettings(scene, filePath, data, dearchivedScenes); 361 LoadRegionSettings(scene, filePath, data, dearchivedScenes);
304 } 362 }
305 else if (filePath.StartsWith(ArchiveConstants.LANDDATA_PATH) && (!m_merge || m_forceParcels)) 363 else if (filePath.StartsWith(ArchiveConstants.LANDDATA_PATH) && (!m_merge || m_forceParcels))
306 { 364 {
307 sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data)); 365 sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data));
308 } 366 }
309 else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) 367 else if (filePath == ArchiveConstants.CONTROL_FILE_PATH)
310 { 368 {
311 // Ignore, because we already read the control file 369 // Ignore, because we already read the control file
@@ -353,7 +411,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
353 { 411 {
354 LoadParcels(sceneContext.Scene, sceneContext.SerialisedParcels); 412 LoadParcels(sceneContext.Scene, sceneContext.SerialisedParcels);
355 LoadObjects(sceneContext.Scene, sceneContext.SerialisedSceneObjects, sceneContext.SceneObjects); 413 LoadObjects(sceneContext.Scene, sceneContext.SerialisedSceneObjects, sceneContext.SceneObjects);
356 414
357 // Inform any interested parties that the region has changed. We waited until now so that all 415 // Inform any interested parties that the region has changed. We waited until now so that all
358 // of the region's objects will be loaded when we send this notification. 416 // of the region's objects will be loaded when we send this notification.
359 IEstateModule estateModule = sceneContext.Scene.RequestModuleInterface<IEstateModule>(); 417 IEstateModule estateModule = sceneContext.Scene.RequestModuleInterface<IEstateModule>();
@@ -372,22 +430,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver
372 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so 430 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so
373 // that users can enter the scene. If we allow the scripts to start in the loop above 431 // that users can enter the scene. If we allow the scripts to start in the loop above
374 // then they significantly increase the time until the OAR finishes loading. 432 // then they significantly increase the time until the OAR finishes loading.
375 WorkManager.RunInThread(o => 433 if (shouldStartScripts)
376 { 434 {
377 Thread.Sleep(15000); 435 WorkManager.RunInThread(o =>
378 m_log.Info("[ARCHIVER]: Starting scripts in scene objects");
379
380 foreach (DearchiveContext sceneContext in sceneContexts.Values)
381 { 436 {
382 foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects) 437 Thread.Sleep(15000);
438 m_log.Info("[ARCHIVER]: Starting scripts in scene objects");
439
440 foreach (DearchiveContext sceneContext in sceneContexts.Values)
383 { 441 {
384 sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart 442 foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects)
385 sceneObject.ResumeScripts(); 443 {
386 } 444 sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart
445 sceneObject.ResumeScripts();
446 }
387 447
388 sceneContext.SceneObjects.Clear(); 448 sceneContext.SceneObjects.Clear();
389 } 449 }
390 }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId)); 450 }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId));
451 }
391 452
392 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); 453 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive");
393 454
@@ -418,7 +479,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
418 { 479 {
419 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) 480 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
420 continue; 481 continue;
421 482
422 if (filePath == ArchiveConstants.CONTROL_FILE_PATH) 483 if (filePath == ArchiveConstants.CONTROL_FILE_PATH)
423 { 484 {
424 LoadControlFile(filePath, data, dearchivedScenes); 485 LoadControlFile(filePath, data, dearchivedScenes);
@@ -435,7 +496,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
435 // If the control file wasn't the first file then reset the read pointer 496 // If the control file wasn't the first file then reset the read pointer
436 if (!firstFile) 497 if (!firstFile)
437 { 498 {
438 m_log.Warn("Control file wasn't the first file in the archive"); 499 m_log.Warn("[ARCHIVER]: Control file wasn't the first file in the archive");
439 if (m_loadStream.CanSeek) 500 if (m_loadStream.CanSeek)
440 { 501 {
441 m_loadStream.Seek(0, SeekOrigin.Begin); 502 m_loadStream.Seek(0, SeekOrigin.Begin);
@@ -452,7 +513,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
452 else 513 else
453 { 514 {
454 // There isn't currently a scenario where this happens, but it's best to add a check just in case 515 // There isn't currently a scenario where this happens, but it's best to add a check just in case
455 throw new Exception("Error reading archive: control file wasn't the first file, and the input stream doesn't allow seeking"); 516 throw new Exception("[ARCHIVER]: Error reading archive: control file wasn't the first file, and the input stream doesn't allow seeking");
456 } 517 }
457 } 518 }
458 519
@@ -462,9 +523,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
462 firstFile = false; 523 firstFile = false;
463 } 524 }
464 525
465 throw new Exception("Control file not found"); 526 throw new Exception("[ARCHIVER]: Control file not found");
466 } 527 }
467 528
468 /// <summary> 529 /// <summary>
469 /// Load serialized scene objects. 530 /// Load serialized scene objects.
470 /// </summary> 531 /// </summary>
@@ -473,12 +534,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
473 // Reload serialized prims 534 // Reload serialized prims
474 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); 535 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
475 536
476 OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, m_rotation); 537 // Convert rotation to radians
538 double rotation = Math.PI * m_rotation / 180f;
539
540 OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, (float)rotation);
477 541
478 UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; 542 UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject;
479 543
480 IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>(); 544 IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>();
481 int sceneObjectsLoadedCount = 0; 545 int sceneObjectsLoadedCount = 0;
546 Vector3 boundingExtent = new Vector3(m_boundingOrigin.X + m_boundingSize.X, m_boundingOrigin.Y + m_boundingSize.Y, m_boundingOrigin.Z + m_boundingSize.Z);
482 547
483 foreach (string serialisedSceneObject in serialisedSceneObjects) 548 foreach (string serialisedSceneObject in serialisedSceneObjects)
484 { 549 {
@@ -488,7 +553,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
488 // Really large xml files (multi megabyte) appear to cause 553 // Really large xml files (multi megabyte) appear to cause
489 // memory problems 554 // memory problems
490 // when loading the xml. But don't enable this check yet 555 // when loading the xml. But don't enable this check yet
491 556
492 if (serialisedSceneObject.Length > 5000000) 557 if (serialisedSceneObject.Length > 5000000)
493 { 558 {
494 m_log.Error("[ARCHIVER]: Ignoring xml since size > 5000000);"); 559 m_log.Error("[ARCHIVER]: Ignoring xml since size > 5000000);");
@@ -498,31 +563,52 @@ namespace OpenSim.Region.CoreModules.World.Archiver
498 563
499 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); 564 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject);
500 565
566 Vector3 pos = sceneObject.AbsolutePosition;
567 if (m_debug)
568 m_log.DebugFormat("[ARCHIVER]: Loading object from OAR with original scene position {0}.", pos.ToString());
569
501 // Happily this does not do much to the object since it hasn't been added to the scene yet 570 // Happily this does not do much to the object since it hasn't been added to the scene yet
502 if (!sceneObject.IsAttachment) 571 if (!sceneObject.IsAttachment)
503 { 572 {
504 if (m_displacement != Vector3.Zero || m_rotation != 0f) 573 if (m_rotation != 0f)
505 { 574 {
506 Vector3 pos = sceneObject.AbsolutePosition; 575 //fix the rotation center to the middle of the incoming region now as it's otherwise hopelessly confusing on varRegions
507 if (m_rotation != 0f) 576 //as it only works with objects and terrain (using old Merge method) and not parcels
508 { 577 m_rotationCenter.X = m_incomingRegionSize.X / 2;
509 // Rotate the object 578 m_rotationCenter.Y = m_incomingRegionSize.Y / 2;
510 sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation; 579
511 // Get object position relative to rotation axis 580 // Rotate the object
512 Vector3 offset = pos - m_rotationCenter; 581 sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation;
513 // Rotate the object position 582 // Get object position relative to rotation axis
514 offset *= rot; 583 Vector3 offset = pos - m_rotationCenter;
515 // Restore the object position back to relative to the region 584 // Rotate the object position
516 pos = m_rotationCenter + offset; 585 offset *= rot;
517 } 586 // Restore the object position back to relative to the region
518 if (m_displacement != Vector3.Zero) 587 pos = m_rotationCenter + offset;
588 if (m_debug) m_log.DebugFormat("[ARCHIVER]: After rotation, object from OAR is at scene position {0}.", pos.ToString());
589 }
590 if (m_boundingBox)
591 {
592 if (pos.X < m_boundingOrigin.X || pos.X >= boundingExtent.X
593 || pos.Y < m_boundingOrigin.Y || pos.Y >= boundingExtent.Y
594 || pos.Z < m_boundingOrigin.Z || pos.Z >= boundingExtent.Z)
519 { 595 {
520 pos += m_displacement; 596 if (m_debug) m_log.DebugFormat("[ARCHIVER]: Skipping object from OAR in scene because it's position {0} is outside of bounding cube.", pos.ToString());
597 continue;
521 } 598 }
522 sceneObject.AbsolutePosition = pos; 599 //adjust object position to be relative to <0,0> so we can apply the displacement
600 pos.X -= m_boundingOrigin.X;
601 pos.Y -= m_boundingOrigin.Y;
602 }
603 if (m_displacement != Vector3.Zero)
604 {
605 pos += m_displacement;
606 if (m_debug) m_log.DebugFormat("[ARCHIVER]: After displacement, object from OAR is at scene position {0}.", pos.ToString());
523 } 607 }
608 sceneObject.AbsolutePosition = pos;
524 } 609 }
525 610 if (m_debug)
611 m_log.DebugFormat("[ARCHIVER]: Placing object from OAR in scene at position {0}. ", pos.ToString());
526 612
527 bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero); 613 bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero);
528 614
@@ -554,11 +640,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
554 int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; 640 int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount;
555 641
556 if (ignoredObjects > 0) 642 if (ignoredObjects > 0)
557 m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); 643 m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene or were out of bounds", ignoredObjects);
558 644
559 if (oldTelehubUUID != UUID.Zero) 645 if (oldTelehubUUID != UUID.Zero)
560 { 646 {
561 m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); 647 m_log.WarnFormat("[ARCHIVER]: Telehub object not found: {0}", oldTelehubUUID);
562 scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; 648 scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero;
563 scene.RegionInfo.RegionSettings.ClearSpawnPoints(); 649 scene.RegionInfo.RegionSettings.ClearSpawnPoints();
564 } 650 }
@@ -600,6 +686,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
600 // being no copy/no mod for everyone 686 // being no copy/no mod for everyone
601 lock (part.TaskInventory) 687 lock (part.TaskInventory)
602 { 688 {
689/* avination code disabled for opensim
690 // And zap any troublesome sit target information
691 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
692 part.SitTargetPosition = new Vector3(0, 0, 0);
693*/
694 // Fix ownership/creator of inventory items
695 // Not doing so results in inventory items
696 // being no copy/no mod for everyone
697 part.TaskInventory.LockItemsForRead(true);
698
603 TaskInventoryDictionary inv = part.TaskInventory; 699 TaskInventoryDictionary inv = part.TaskInventory;
604 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) 700 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
605 { 701 {
@@ -620,11 +716,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
620 if (!ResolveGroupUuid(kvp.Value.GroupID)) 716 if (!ResolveGroupUuid(kvp.Value.GroupID))
621 kvp.Value.GroupID = UUID.Zero; 717 kvp.Value.GroupID = UUID.Zero;
622 } 718 }
719 part.TaskInventory.LockItemsForRead(false);
720
623 } 721 }
624 } 722 }
625 } 723 }
626 724
627
628 /// <summary> 725 /// <summary>
629 /// Load serialized parcels. 726 /// Load serialized parcels.
630 /// </summary> 727 /// </summary>
@@ -635,17 +732,88 @@ namespace OpenSim.Region.CoreModules.World.Archiver
635 // Reload serialized parcels 732 // Reload serialized parcels
636 m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); 733 m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count);
637 List<LandData> landData = new List<LandData>(); 734 List<LandData> landData = new List<LandData>();
735 ILandObject landObject = scene.RequestModuleInterface<ILandObject>();
736 List<ILandObject> parcels;
737 Vector3 parcelDisp = new Vector3(m_displacement.X, m_displacement.Y, 0f);
738 Vector2 displacement = new Vector2(m_displacement.X, m_displacement.Y);
739 Vector2 boundingOrigin = new Vector2(m_boundingOrigin.X, m_boundingOrigin.Y);
740 Vector2 boundingSize = new Vector2(m_boundingSize.X, m_boundingSize.Y);
741 Vector2 regionSize = new Vector2(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY);
742
743 // Gather any existing parcels before we add any more. Later as we add parcels we can check if the new parcel
744 // data overlays any of the old data, and we can modify and remove (if empty) the old parcel so that there's no conflict
745 parcels = scene.LandChannel.AllParcels();
746
638 foreach (string serialisedParcel in serialisedParcels) 747 foreach (string serialisedParcel in serialisedParcels)
639 { 748 {
640 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); 749 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
750 bool overrideRegionSize = true; //use the src land parcel data size not the dst region size
751 bool isEmptyNow;
752 Vector3 AABBMin;
753 Vector3 AABBMax;
754
755 // create a new LandObject that we can use to manipulate the incoming source parcel data
756 // this is ok, but just beware that some of the LandObject functions (that we haven't used here) still
757 // assume we're always using the destination region size
758 LandData ld = new LandData();
759 landObject = new LandObject(ld, scene);
760 landObject.LandData = parcel;
761
762 bool[,] srcLandBitmap = landObject.ConvertBytesToLandBitmap(overrideRegionSize);
763 if (landObject.IsLandBitmapEmpty(srcLandBitmap))
764 {
765 m_log.InfoFormat("[ARCHIVER]: Skipping source parcel {0} with GlobalID: {1} LocalID: {2} that has no claimed land.",
766 parcel.Name, parcel.GlobalID, parcel.LocalID);
767 continue;
768 }
769 //m_log.DebugFormat("[ARCHIVER]: Showing claimed land for source parcel: {0} with GlobalID: {1} LocalID: {2}.",
770 // parcel.Name, parcel.GlobalID, parcel.LocalID);
771 //landObject.DebugLandBitmap(srcLandBitmap);
772
773 bool[,] dstLandBitmap = landObject.RemapLandBitmap(srcLandBitmap, displacement, m_rotation, boundingOrigin, boundingSize, regionSize, out isEmptyNow, out AABBMin, out AABBMax);
774 if (isEmptyNow)
775 {
776 m_log.WarnFormat("[ARCHIVER]: Not adding destination parcel {0} with GlobalID: {1} LocalID: {2} because, after applying rotation, bounding and displacement, it has no claimed land.",
777 parcel.Name, parcel.GlobalID, parcel.LocalID);
778 continue;
779 }
780 //m_log.DebugFormat("[ARCHIVER]: Showing claimed land for destination parcel: {0} with GlobalID: {1} LocalID: {2} after applying rotation, bounding and displacement.",
781 // parcel.Name, parcel.GlobalID, parcel.LocalID);
782 //landObject.DebugLandBitmap(dstLandBitmap);
783
784 landObject.LandBitmap = dstLandBitmap;
785 parcel.Bitmap = landObject.ConvertLandBitmapToBytes();
786 parcel.AABBMin = AABBMin;
787 parcel.AABBMax = AABBMax;
641 788
642 if (m_displacement != Vector3.Zero) 789 if (m_merge)
643 { 790 {
644 Vector3 parcelDisp = new Vector3(m_displacement.X, m_displacement.Y, 0f); 791 // give the remapped parcel a new GlobalID, in case we're using the same OAR twice and a bounding cube, displacement and --merge
645 parcel.AABBMin += parcelDisp; 792 parcel.GlobalID = UUID.Random();
646 parcel.AABBMax += parcelDisp; 793
794 //now check if the area of this new incoming parcel overlays an area in any existing parcels
795 //and if so modify or lose the existing parcels
796 for (int i = 0; i < parcels.Count; i++)
797 {
798 if (parcels[i] != null)
799 {
800 bool[,] modLandBitmap = parcels[i].ConvertBytesToLandBitmap(overrideRegionSize);
801 modLandBitmap = parcels[i].RemoveFromLandBitmap(modLandBitmap, dstLandBitmap, out isEmptyNow, out AABBMin, out AABBMax);
802 if (isEmptyNow)
803 {
804 parcels[i] = null;
805 }
806 else
807 {
808 parcels[i].LandBitmap = modLandBitmap;
809 parcels[i].LandData.Bitmap = parcels[i].ConvertLandBitmapToBytes();
810 parcels[i].LandData.AABBMin = AABBMin;
811 parcels[i].LandData.AABBMax = AABBMax;
812 }
813 }
814 }
647 } 815 }
648 816
649 // Validate User and Group UUID's 817 // Validate User and Group UUID's
650 818
651 if (!ResolveGroupUuid(parcel.GroupID)) 819 if (!ResolveGroupUuid(parcel.GroupID))
@@ -679,19 +847,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver
679 } 847 }
680 parcel.ParcelAccessList = accessList; 848 parcel.ParcelAccessList = accessList;
681 849
682// m_log.DebugFormat( 850 if (m_debug) m_log.DebugFormat("[ARCHIVER]: Adding parcel {0}, local id {1}, owner {2}, group {3}, isGroupOwned {4}, area {5}",
683// "[ARCHIVER]: Adding parcel {0}, local id {1}, owner {2}, group {3}, isGroupOwned {4}, area {5}", 851 parcel.Name, parcel.LocalID, parcel.OwnerID, parcel.GroupID, parcel.IsGroupOwned, parcel.Area);
684// parcel.Name, parcel.LocalID, parcel.OwnerID, parcel.GroupID, parcel.IsGroupOwned, parcel.Area); 852
685
686 landData.Add(parcel); 853 landData.Add(parcel);
687 } 854 }
688 855
689 if (!m_merge) 856 if (m_merge)
690 { 857 {
691 bool setupDefaultParcel = (landData.Count == 0); 858 for (int i = 0; i < parcels.Count; i++) //if merging then we need to also add back in any existing parcels
692 scene.LandChannel.Clear(setupDefaultParcel); 859 {
860 if (parcels[i] != null) landData.Add(parcels[i].LandData);
861 }
693 } 862 }
694 863
864 m_log.InfoFormat("[ARCHIVER]: Clearing {0} parcels.", parcels.Count);
865 bool setupDefaultParcel = (landData.Count == 0);
866 scene.LandChannel.Clear(setupDefaultParcel);
695 scene.EventManager.TriggerIncomingLandDataFromStorage(landData); 867 scene.EventManager.TriggerIncomingLandDataFromStorage(landData);
696 m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); 868 m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count);
697 } 869 }
@@ -772,6 +944,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
772 944
773 if (m_assetService.GetMetadata(uuid) != null) 945 if (m_assetService.GetMetadata(uuid) != null)
774 { 946 {
947 sbyte asype = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
948 if(asype == -2)
949 {
950
951 }
952
775 // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); 953 // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid);
776 return true; 954 return true;
777 } 955 }
@@ -780,6 +958,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
780 { 958 {
781 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; 959 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
782 960
961 if(assetType == -2)
962 {
963
964 }
783 if (assetType == (sbyte)AssetType.Unknown) 965 if (assetType == (sbyte)AssetType.Unknown)
784 { 966 {
785 m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); 967 m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid);
@@ -792,7 +974,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
792 ModifySceneObject(m_rootScene, sog); 974 ModifySceneObject(m_rootScene, sog);
793 return true; 975 return true;
794 }); 976 });
795 977
796 if (data == null) 978 if (data == null)
797 return false; 979 return false;
798 } 980 }
@@ -898,7 +1080,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
898 currentRegionSettings.Save(); 1080 currentRegionSettings.Save();
899 1081
900 scene.TriggerEstateSunUpdate(); 1082 scene.TriggerEstateSunUpdate();
901 1083
902 IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>(); 1084 IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
903 if (estateModule != null) 1085 if (estateModule != null)
904 estateModule.sendRegionHandshakeToAll(); 1086 estateModule.sendRegionHandshakeToAll();
@@ -918,13 +1100,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
918 private bool LoadTerrain(Scene scene, string terrainPath, byte[] data) 1100 private bool LoadTerrain(Scene scene, string terrainPath, byte[] data)
919 { 1101 {
920 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); 1102 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
921
922 using (MemoryStream ms = new MemoryStream(data)) 1103 using (MemoryStream ms = new MemoryStream(data))
923 { 1104 {
924 if (m_displacement != Vector3.Zero || m_rotation != 0f) 1105 if (m_displacement != Vector3.Zero || m_rotation != 0f || m_boundingBox)
925 { 1106 {
926 Vector2 rotationCenter = new Vector2(m_rotationCenter.X, m_rotationCenter.Y); 1107 Vector2 boundingOrigin = new Vector2(m_boundingOrigin.X, m_boundingOrigin.Y);
927 terrainModule.LoadFromStream(terrainPath, m_displacement, m_rotation, rotationCenter, ms); 1108 Vector2 boundingSize = new Vector2(m_boundingSize.X, m_boundingSize.Y);
1109 terrainModule.LoadFromStream(terrainPath, m_displacement, m_rotation, boundingOrigin, boundingSize, ms); ;
928 } 1110 }
929 else 1111 else
930 { 1112 {
@@ -948,6 +1130,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
948 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); 1130 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
949 XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); 1131 XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None);
950 XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context); 1132 XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context);
1133 xtr.ProhibitDtd = true;
951 1134
952 // Loaded metadata will be empty if no information exists in the archive 1135 // Loaded metadata will be empty if no information exists in the archive
953 dearchivedScenes.LoadedCreationDateTime = 0; 1136 dearchivedScenes.LoadedCreationDateTime = 0;
@@ -955,16 +1138,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
955 1138
956 bool multiRegion = false; 1139 bool multiRegion = false;
957 1140
958 while (xtr.Read()) 1141 while (xtr.Read())
959 { 1142 {
960 if (xtr.NodeType == XmlNodeType.Element) 1143 if (xtr.NodeType == XmlNodeType.Element)
961 { 1144 {
962 if (xtr.Name.ToString() == "archive") 1145 if (xtr.Name.ToString() == "archive")
963 { 1146 {
964 int majorVersion = int.Parse(xtr["major_version"]); 1147 int majorVersion = int.Parse(xtr["major_version"]);
965 int minorVersion = int.Parse(xtr["minor_version"]); 1148 int minorVersion = int.Parse(xtr["minor_version"]);
966 string version = string.Format("{0}.{1}", majorVersion, minorVersion); 1149 string version = string.Format("{0}.{1}", majorVersion, minorVersion);
967 1150
968 if (majorVersion > MAX_MAJOR_VERSION) 1151 if (majorVersion > MAX_MAJOR_VERSION)
969 { 1152 {
970 throw new Exception( 1153 throw new Exception(
@@ -972,15 +1155,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
972 "The OAR you are trying to load has major version number of {0} but this version of OpenSim can only load OARs with major version number {1} and below", 1155 "The OAR you are trying to load has major version number of {0} but this version of OpenSim can only load OARs with major version number {1} and below",
973 majorVersion, MAX_MAJOR_VERSION)); 1156 majorVersion, MAX_MAJOR_VERSION));
974 } 1157 }
975 1158
976 m_log.InfoFormat("[ARCHIVER]: Loading OAR with version {0}", version); 1159 m_log.InfoFormat("[ARCHIVER]: Loading OAR with version {0}", version);
977 } 1160 }
978 if (xtr.Name.ToString() == "datetime") 1161 else if (xtr.Name.ToString() == "datetime")
979 { 1162 {
980 int value; 1163 int value;
981 if (Int32.TryParse(xtr.ReadElementContentAsString(), out value)) 1164 if (Int32.TryParse(xtr.ReadElementContentAsString(), out value))
982 dearchivedScenes.LoadedCreationDateTime = value; 1165 dearchivedScenes.LoadedCreationDateTime = value;
983 } 1166 }
984 else if (xtr.Name.ToString() == "row") 1167 else if (xtr.Name.ToString() == "row")
985 { 1168 {
986 multiRegion = true; 1169 multiRegion = true;
@@ -994,13 +1177,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver
994 { 1177 {
995 string id = xtr.ReadElementContentAsString(); 1178 string id = xtr.ReadElementContentAsString();
996 dearchivedScenes.DefaultOriginalID = id; 1179 dearchivedScenes.DefaultOriginalID = id;
997 if (multiRegion) 1180 if(multiRegion)
998 dearchivedScenes.SetRegionOriginalID(id); 1181 dearchivedScenes.SetRegionOriginalID(id);
999 } 1182 }
1000 else if (xtr.Name.ToString() == "dir") 1183 else if (xtr.Name.ToString() == "dir")
1001 { 1184 {
1002 dearchivedScenes.SetRegionDirectory(xtr.ReadElementContentAsString()); 1185 dearchivedScenes.SetRegionDirectory(xtr.ReadElementContentAsString());
1003 } 1186 }
1187 else if (xtr.Name.ToString() == "size_in_meters")
1188 {
1189 Vector3 value;
1190 string size = "<" + xtr.ReadElementContentAsString() + ",0>";
1191 if (Vector3.TryParse(size, out value))
1192 {
1193 m_incomingRegionSize = value;
1194 if(multiRegion)
1195 dearchivedScenes.SetRegionSize(m_incomingRegionSize);
1196 m_log.DebugFormat("[ARCHIVER]: Found region_size info {0}",
1197 m_incomingRegionSize.ToString());
1198 }
1199 }
1004 } 1200 }
1005 } 1201 }
1006 1202
@@ -1012,9 +1208,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
1012 dearchivedScenes.StartRegion(); 1208 dearchivedScenes.StartRegion();
1013 dearchivedScenes.SetRegionOriginalID(dearchivedScenes.DefaultOriginalID); 1209 dearchivedScenes.SetRegionOriginalID(dearchivedScenes.DefaultOriginalID);
1014 dearchivedScenes.SetRegionDirectory(""); 1210 dearchivedScenes.SetRegionDirectory("");
1211 dearchivedScenes.SetRegionSize(m_incomingRegionSize);
1015 } 1212 }
1016 1213
1017 ControlFileLoaded = true; 1214 ControlFileLoaded = true;
1215 if(xtr != null)
1216 xtr.Close();
1018 1217
1019 return dearchivedScenes; 1218 return dearchivedScenes;
1020 } 1219 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
index d8dace2..2fb4426 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
50 /// The inner dictionaries contain each row's regions (key: X coordinate). 50 /// The inner dictionaries contain each row's regions (key: X coordinate).
51 /// </summary> 51 /// </summary>
52 public SortedDictionary<uint, SortedDictionary<uint, Scene>> Regions { get; set; } 52 public SortedDictionary<uint, SortedDictionary<uint, Scene>> Regions { get; set; }
53 53
54 /// <summary> 54 /// <summary>
55 /// The subdirectory where each region is stored in the archive. 55 /// The subdirectory where each region is stored in the archive.
56 /// </summary> 56 /// </summary>
@@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
152 } 152 }
153 } 153 }
154 } 154 }
155 155
156 /// <summary> 156 /// <summary>
157 /// Returns the scene at position 'location'. 157 /// Returns the scene at position 'location'.
158 /// </summary> 158 /// </summary>
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
index cb2c7f1..11c53d7 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -60,8 +60,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
60 /// <summary> 60 /// <summary>
61 /// The minimum major version of OAR that we can write. 61 /// The minimum major version of OAR that we can write.
62 /// </summary> 62 /// </summary>
63 public static int MIN_MAJOR_VERSION = 0; 63 public static int MIN_MAJOR_VERSION = 0;
64 64
65 /// <summary> 65 /// <summary>
66 /// The maximum major version of OAR that we can write. 66 /// The maximum major version of OAR that we can write.
67 /// </summary> 67 /// </summary>
@@ -112,7 +112,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
112 m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace); 112 m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
113 } 113 }
114 } 114 }
115 115
116 /// <summary> 116 /// <summary>
117 /// Constructor. 117 /// Constructor.
118 /// </summary> 118 /// </summary>
@@ -181,11 +181,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
181 // Archive the regions 181 // Archive the regions
182 182
183 Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>(); 183 Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>();
184 HashSet<UUID> failedIDs = new HashSet<UUID>();
185 HashSet<UUID> uncertainAssetsUUIDs = new HashSet<UUID>();
184 186
185 scenesGroup.ForEachScene(delegate(Scene scene) 187 scenesGroup.ForEachScene(delegate(Scene scene)
186 { 188 {
187 string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : ""; 189 string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : "";
188 ArchiveOneRegion(scene, regionDir, assetUuids); 190 ArchiveOneRegion(scene, regionDir, assetUuids, failedIDs, uncertainAssetsUUIDs);
189 }); 191 });
190 192
191 // Archive the assets 193 // Archive the assets
@@ -193,23 +195,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver
193 if (SaveAssets) 195 if (SaveAssets)
194 { 196 {
195 m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count); 197 m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count);
196 198
197 // Asynchronously request all the assets required to perform this archive operation 199 AssetsRequest ar = new AssetsRequest(
198 AssetsRequest ar
199 = new AssetsRequest(
200 new AssetsArchiver(m_archiveWriter), assetUuids, 200 new AssetsArchiver(m_archiveWriter), assetUuids,
201 failedIDs.Count,
201 m_rootScene.AssetService, m_rootScene.UserAccountService, 202 m_rootScene.AssetService, m_rootScene.UserAccountService,
202 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); 203 m_rootScene.RegionInfo.ScopeID, options, null);
203 204 ar.Execute();
204 WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request"); 205 assetUuids = null;
205
206 // CloseArchive() will be called from ReceivedAllAssets()
207 } 206 }
208 else 207 else
209 { 208 {
210 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); 209 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
211 CloseArchive(string.Empty); 210// CloseArchive(string.Empty);
212 } 211 }
212 CloseArchive(string.Empty);
213 } 213 }
214 catch (Exception e) 214 catch (Exception e)
215 { 215 {
@@ -218,7 +218,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
218 } 218 }
219 } 219 }
220 220
221 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids) 221 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids,
222 HashSet<UUID> failedIDs, HashSet<UUID> uncertainAssetsUUIDs)
222 { 223 {
223 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name); 224 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name);
224 225
@@ -226,7 +227,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
226 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 227 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
227 228
228 int numObjectsSkippedPermissions = 0; 229 int numObjectsSkippedPermissions = 0;
229 230
230 // Filter entities so that we only have scene objects. 231 // Filter entities so that we only have scene objects.
231 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods 232 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
232 // end up having to do this 233 // end up having to do this
@@ -237,7 +238,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
237 { 238 {
238 SceneObjectGroup sceneObject = (SceneObjectGroup)entity; 239 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
239 240
240 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) 241 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment && !sceneObject.IsTemporary && !sceneObject.inTransit)
241 { 242 {
242 if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, FilterContent, permissionsModule)) 243 if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, FilterContent, permissionsModule))
243 { 244 {
@@ -254,17 +255,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver
254 255
255 if (SaveAssets) 256 if (SaveAssets)
256 { 257 {
257 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids); 258 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids, failedIDs, uncertainAssetsUUIDs);
258 int prevAssets = assetUuids.Count; 259 int prevAssets = assetUuids.Count;
259 260
260 foreach (SceneObjectGroup sceneObject in sceneObjects) 261 foreach (SceneObjectGroup sceneObject in sceneObjects)
262 {
263 int curErrorCntr = assetGatherer.ErrorCount;
264 int possible = assetGatherer.possibleNotAssetCount;
261 assetGatherer.AddForInspection(sceneObject); 265 assetGatherer.AddForInspection(sceneObject);
266 assetGatherer.GatherAll();
267 curErrorCntr = assetGatherer.ErrorCount - curErrorCntr;
268 possible = assetGatherer.possibleNotAssetCount - possible;
269 if(curErrorCntr > 0)
270 {
271 m_log.ErrorFormat("[ARCHIVER]: object {0} '{1}', at {2}, contains {3} references to missing or damaged assets",
272 sceneObject.UUID, sceneObject.Name ,sceneObject.AbsolutePosition.ToString(), curErrorCntr);
273 if(possible > 0)
274 m_log.WarnFormat("[ARCHIVER Warning]: object also contains {0} references that may be to missing or damaged assets or not a problem", possible);
275 }
276 else if(possible > 0)
277 {
278 m_log.WarnFormat("[ARCHIVER Warning]: object {0} '{1}', at {2}, contains {3} references that may be to missing or damaged assets or not a problem",
279 sceneObject.UUID, sceneObject.Name ,sceneObject.AbsolutePosition.ToString(), possible);
280 }
281 }
262 282
263 assetGatherer.GatherAll(); 283 assetGatherer.GatherAll();
264 284
285 int errors = assetGatherer.FailedUUIDs.Count;
265 m_log.DebugFormat( 286 m_log.DebugFormat(
266 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", 287 "[ARCHIVER]: {0} region scene objects to save reference {1} possible assets",
267 sceneObjects.Count, assetUuids.Count - prevAssets); 288 sceneObjects.Count, assetUuids.Count - prevAssets + errors);
289 if(errors > 0)
290 m_log.DebugFormat("[ARCHIVER]: {0} of these have problems or are not assets and will be ignored", errors);
268 } 291 }
269 292
270 if (numObjectsSkippedPermissions > 0) 293 if (numObjectsSkippedPermissions > 0)
@@ -276,16 +299,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
276 299
277 // Make sure that we also request terrain texture assets 300 // Make sure that we also request terrain texture assets
278 RegionSettings regionSettings = scene.RegionInfo.RegionSettings; 301 RegionSettings regionSettings = scene.RegionInfo.RegionSettings;
279 302
280 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) 303 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
281 assetUuids[regionSettings.TerrainTexture1] = (sbyte)AssetType.Texture; 304 assetUuids[regionSettings.TerrainTexture1] = (sbyte)AssetType.Texture;
282 305
283 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) 306 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
284 assetUuids[regionSettings.TerrainTexture2] = (sbyte)AssetType.Texture; 307 assetUuids[regionSettings.TerrainTexture2] = (sbyte)AssetType.Texture;
285 308
286 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) 309 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
287 assetUuids[regionSettings.TerrainTexture3] = (sbyte)AssetType.Texture; 310 assetUuids[regionSettings.TerrainTexture3] = (sbyte)AssetType.Texture;
288 311
289 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) 312 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
290 assetUuids[regionSettings.TerrainTexture4] = (sbyte)AssetType.Texture; 313 assetUuids[regionSettings.TerrainTexture4] = (sbyte)AssetType.Texture;
291 314
@@ -398,18 +421,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
398// string[] parts = m_options["version"].ToString().Split('.'); 421// string[] parts = m_options["version"].ToString().Split('.');
399// if (parts.Length >= 1) 422// if (parts.Length >= 1)
400// { 423// {
401// majorVersion = Int32.Parse(parts[0]); 424// majorVersion = Int32.Parse(parts[0]);
402// 425//
403// if (parts.Length >= 2) 426// if (parts.Length >= 2)
404// minorVersion = Int32.Parse(parts[1]); 427// minorVersion = Int32.Parse(parts[1]);
405// } 428// }
406// } 429// }
407// 430//
408// if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION) 431// if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION)
409// { 432// {
410// throw new Exception( 433// throw new Exception(
411// string.Format( 434// string.Format(
412// "OAR version number for save must be between {0} and {1}", 435// "OAR version number for save must be between {0} and {1}",
413// MIN_MAJOR_VERSION, MAX_MAJOR_VERSION)); 436// MIN_MAJOR_VERSION, MAX_MAJOR_VERSION));
414// } 437// }
415// else if (majorVersion == MAX_MAJOR_VERSION) 438// else if (majorVersion == MAX_MAJOR_VERSION)
@@ -420,9 +443,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
420// else if (majorVersion == MIN_MAJOR_VERSION) 443// else if (majorVersion == MIN_MAJOR_VERSION)
421// { 444// {
422// // Force 0.4 445// // Force 0.4
423// minorVersion = 4; 446// minorVersion = 4;
424// } 447// }
425 448
426 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion); 449 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
427 if (majorVersion == 1) 450 if (majorVersion == 1)
428 { 451 {
@@ -430,7 +453,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
430 } 453 }
431 454
432 String s; 455 String s;
433 456
434 using (StringWriter sw = new StringWriter()) 457 using (StringWriter sw = new StringWriter())
435 { 458 {
436 using (XmlTextWriter xtw = new XmlTextWriter(sw)) 459 using (XmlTextWriter xtw = new XmlTextWriter(sw))
@@ -440,7 +463,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
440 xtw.WriteStartElement("archive"); 463 xtw.WriteStartElement("archive");
441 xtw.WriteAttributeString("major_version", majorVersion.ToString()); 464 xtw.WriteAttributeString("major_version", majorVersion.ToString());
442 xtw.WriteAttributeString("minor_version", minorVersion.ToString()); 465 xtw.WriteAttributeString("minor_version", minorVersion.ToString());
443 466
444 xtw.WriteStartElement("creation_info"); 467 xtw.WriteStartElement("creation_info");
445 DateTime now = DateTime.UtcNow; 468 DateTime now = DateTime.UtcNow;
446 TimeSpan t = now - new DateTime(1970, 1, 1); 469 TimeSpan t = now - new DateTime(1970, 1, 1);
@@ -448,7 +471,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
448 if (!MultiRegionFormat) 471 if (!MultiRegionFormat)
449 xtw.WriteElementString("id", m_rootScene.RegionInfo.RegionID.ToString()); 472 xtw.WriteElementString("id", m_rootScene.RegionInfo.RegionID.ToString());
450 xtw.WriteEndElement(); 473 xtw.WriteEndElement();
451 474
452 xtw.WriteElementString("assets_included", SaveAssets.ToString()); 475 xtw.WriteElementString("assets_included", SaveAssets.ToString());
453 476
454 if (MultiRegionFormat) 477 if (MultiRegionFormat)
@@ -463,7 +486,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
463 } 486 }
464 487
465 xtw.WriteEndElement(); 488 xtw.WriteEndElement();
466 489
467 xtw.Flush(); 490 xtw.Flush();
468 } 491 }
469 492
@@ -522,22 +545,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
522 545
523 protected static void WriteRegionInfo(Scene scene, XmlTextWriter xtw) 546 protected static void WriteRegionInfo(Scene scene, XmlTextWriter xtw)
524 { 547 {
525 bool isMegaregion;
526 Vector2 size; 548 Vector2 size;
527 549
528 IRegionCombinerModule rcMod = scene.RequestModuleInterface<IRegionCombinerModule>(); 550 size = new Vector2((float)scene.RegionInfo.RegionSizeX, (float)scene.RegionInfo.RegionSizeY);
529 551
530 if (rcMod != null)
531 isMegaregion = rcMod.IsRootForMegaregion(scene.RegionInfo.RegionID);
532 else
533 isMegaregion = false;
534
535 if (isMegaregion)
536 size = rcMod.GetSizeOfMegaregion(scene.RegionInfo.RegionID);
537 else
538 size = new Vector2((float)scene.RegionInfo.RegionSizeX, (float)scene.RegionInfo.RegionSizeY);
539
540 xtw.WriteElementString("is_megaregion", isMegaregion.ToString());
541 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); 552 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
542 } 553 }
543 554
@@ -560,7 +571,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
560 foreach (ILandObject lo in landObjects) 571 foreach (ILandObject lo in landObjects)
561 { 572 {
562 LandData landData = lo.LandData; 573 LandData landData = lo.LandData;
563 string landDataPath 574 string landDataPath
564 = String.Format("{0}{1}", regionDir, ArchiveConstants.CreateOarLandDataPath(landData)); 575 = String.Format("{0}{1}", regionDir, ArchiveConstants.CreateOarLandDataPath(landData));
565 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options)); 576 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
566 } 577 }
@@ -584,17 +595,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
584 foreach (SceneObjectGroup sceneObject in sceneObjects) 595 foreach (SceneObjectGroup sceneObject in sceneObjects)
585 { 596 {
586 //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType()); 597 //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());
587 598 if(sceneObject.IsDeleted || sceneObject.inTransit)
599 continue;
588 string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options); 600 string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options);
589 string objectPath = string.Format("{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject)); 601 string objectPath = string.Format("{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject));
590 m_archiveWriter.WriteFile(objectPath, serializedObject); 602 m_archiveWriter.WriteFile(objectPath, serializedObject);
591 } 603 }
592 } 604 }
593 605
594 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut) 606 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut)
595 { 607 {
596 string errorMessage; 608 string errorMessage;
597 609
598 if (timedOut) 610 if (timedOut)
599 { 611 {
600 errorMessage = "Loading assets timed out"; 612 errorMessage = "Loading assets timed out";
@@ -612,10 +624,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
612 624
613 errorMessage = String.Empty; 625 errorMessage = String.Empty;
614 } 626 }
615 627
616 CloseArchive(errorMessage); 628 CloseArchive(errorMessage);
617 } 629 }
618 630
619 /// <summary> 631 /// <summary>
620 /// Closes the archive and notifies that we're done. 632 /// Closes the archive and notifies that we're done.
621 /// </summary> 633 /// </summary>
@@ -634,7 +646,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
634 if (errorMessage == string.Empty) 646 if (errorMessage == string.Empty)
635 errorMessage = e.Message; 647 errorMessage = e.Message;
636 } 648 }
637 649
638 m_log.InfoFormat("[ARCHIVER]: Finished writing out OAR for {0}", m_rootScene.RegionInfo.RegionName); 650 m_log.InfoFormat("[ARCHIVER]: Finished writing out OAR for {0}", m_rootScene.RegionInfo.RegionName);
639 651
640 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage); 652 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage);
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index 6a09caf..1305545 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -49,24 +49,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ArchiverModule")] 49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ArchiverModule")]
50 public class ArchiverModule : INonSharedRegionModule, IRegionArchiverModule 50 public class ArchiverModule : INonSharedRegionModule, IRegionArchiverModule
51 { 51 {
52 private static readonly ILog m_log = 52 private static readonly ILog m_log =
53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 54
55 public Scene Scene { get; private set; } 55 public Scene Scene { get; private set; }
56 public IRegionCombinerModule RegionCombinerModule { get; private set; }
57 56
58 /// <value> 57 /// <value>
59 /// The file used to load and save an opensimulator archive if no filename has been specified 58 /// The file used to load and save an opensimulator archive if no filename has been specified
60 /// </value> 59 /// </value>
61 protected const string DEFAULT_OAR_BACKUP_FILENAME = "region.oar"; 60 protected const string DEFAULT_OAR_BACKUP_FILENAME = "region.oar";
62 61
63 public string Name 62 public string Name
64 { 63 {
65 get { return "RegionArchiverModule"; } 64 get { return "RegionArchiverModule"; }
66 } 65 }
67 66
68 public Type ReplaceableInterface 67 public Type ReplaceableInterface
69 { 68 {
70 get { return null; } 69 get { return null; }
71 } 70 }
72 71
@@ -85,7 +84,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
85 84
86 public void RegionLoaded(Scene scene) 85 public void RegionLoaded(Scene scene)
87 { 86 {
88 RegionCombinerModule = scene.RequestModuleInterface<IRegionCombinerModule>();
89 } 87 }
90 88
91 public void RemoveRegion(Scene scene) 89 public void RemoveRegion(Scene scene)
@@ -110,18 +108,22 @@ namespace OpenSim.Region.CoreModules.World.Archiver
110 Vector3 displacement = new Vector3(0f, 0f, 0f); 108 Vector3 displacement = new Vector3(0f, 0f, 0f);
111 String defaultUser = ""; 109 String defaultUser = "";
112 float rotation = 0f; 110 float rotation = 0f;
113 Vector3 rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0); 111 Vector3 rotationCenter = new Vector3(Scene.RegionInfo.RegionSizeX / 2f, Scene.RegionInfo.RegionSizeY / 2f, 0);
114 112 Vector3 boundingOrigin = new Vector3(0f, 0f, 0f);
113 Vector3 boundingSize = new Vector3(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY, float.MaxValue);
114 bool debug = false;
115
115 OptionSet options = new OptionSet(); 116 OptionSet options = new OptionSet();
116 options.Add("m|merge", delegate (string v) { mergeOar = (v != null); }); 117 options.Add("m|merge", delegate(string v) { mergeOar = (v != null); });
117 options.Add("s|skip-assets", delegate (string v) { skipAssets = (v != null); }); 118 options.Add("s|skip-assets", delegate(string v) { skipAssets = (v != null); });
118 options.Add("force-terrain", delegate (string v) { forceTerrain = (v != null); }); 119 options.Add("force-terrain", delegate(string v) { forceTerrain = (v != null); });
119 options.Add("forceterrain", delegate (string v) { forceTerrain = (v != null); }); // downward compatibility 120 options.Add("forceterrain", delegate(string v) { forceTerrain = (v != null); }); // downward compatibility
120 options.Add("force-parcels", delegate (string v) { forceParcels = (v != null); }); 121 options.Add("force-parcels", delegate(string v) { forceParcels = (v != null); });
121 options.Add("forceparcels", delegate (string v) { forceParcels = (v != null); }); // downward compatibility 122 options.Add("forceparcels", delegate(string v) { forceParcels = (v != null); }); // downward compatibility
122 options.Add("no-objects", delegate (string v) { noObjects = (v != null); }); 123 options.Add("no-objects", delegate(string v) { noObjects = (v != null); });
123 options.Add("default-user=", delegate(string v) { defaultUser = (v == null) ? "" : v; }); 124 options.Add("default-user=", delegate(string v) { defaultUser = (v == null) ? "" : v; });
124 options.Add("displacement=", delegate (string v) { 125 options.Add("displacement=", delegate(string v)
126 {
125 try 127 try
126 { 128 {
127 displacement = v == null ? Vector3.Zero : Vector3.Parse(v); 129 displacement = v == null ? Vector3.Zero : Vector3.Parse(v);
@@ -145,12 +147,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
145 m_log.ErrorFormat("[ARCHIVER MODULE] Must be an angle in degrees between -360 and +360: --rotation 45"); 147 m_log.ErrorFormat("[ARCHIVER MODULE] Must be an angle in degrees between -360 and +360: --rotation 45");
146 return; 148 return;
147 } 149 }
148 // Convert to radians for internals 150 //pass this in as degrees now, convert to radians later during actual work phase
149 rotation = Util.Clamp<float>(rotation, -359f, 359f) / 180f * (float)Math.PI; 151 rotation = Util.Clamp<float>(rotation, -359f, 359f);
150 }); 152 });
151 options.Add("rotation-center=", delegate (string v) { 153 options.Add("rotation-center=", delegate(string v)
154 {
152 try 155 try
153 { 156 {
157 m_log.Info("[ARCHIVER MODULE] Warning: --rotation-center no longer does anything and will be removed soon!");
154 rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v); 158 rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v);
155 } 159 }
156 catch 160 catch
@@ -160,6 +164,33 @@ namespace OpenSim.Region.CoreModules.World.Archiver
160 return; 164 return;
161 } 165 }
162 }); 166 });
167 options.Add("bounding-origin=", delegate(string v)
168 {
169 try
170 {
171 boundingOrigin = v == null ? Vector3.Zero : Vector3.Parse(v);
172 }
173 catch
174 {
175 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing bounding cube origin");
176 m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as vector3: --bounding-origin \"<128,128,0>\"");
177 return;
178 }
179 });
180 options.Add("bounding-size=", delegate(string v)
181 {
182 try
183 {
184 boundingSize = v == null ? new Vector3(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY, float.MaxValue) : Vector3.Parse(v);
185 }
186 catch
187 {
188 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing bounding cube size");
189 m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as a positive vector3: --bounding-size \"<256,256,4096>\"");
190 return;
191 }
192 });
193 options.Add("d|debug", delegate(string v) { debug = (v != null); });
163 194
164 // Send a message to the region ready module 195 // Send a message to the region ready module
165 /* bluewall* Disable this for the time being 196 /* bluewall* Disable this for the time being
@@ -170,9 +201,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
170 rready.OarLoadingAlert("load"); 201 rready.OarLoadingAlert("load");
171 } 202 }
172 */ 203 */
173 204
174 List<string> mainParams = options.Parse(cmdparams); 205 List<string> mainParams = options.Parse(cmdparams);
175 206
176// m_log.DebugFormat("MERGE OAR IS [{0}]", mergeOar); 207// m_log.DebugFormat("MERGE OAR IS [{0}]", mergeOar);
177// 208//
178// foreach (string param in mainParams) 209// foreach (string param in mainParams)
@@ -208,6 +239,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
208 archiveOptions.Add("displacement", displacement); 239 archiveOptions.Add("displacement", displacement);
209 archiveOptions.Add("rotation", rotation); 240 archiveOptions.Add("rotation", rotation);
210 archiveOptions.Add("rotation-center", rotationCenter); 241 archiveOptions.Add("rotation-center", rotationCenter);
242 archiveOptions.Add("bounding-origin", boundingOrigin);
243 archiveOptions.Add("bounding-size", boundingSize);
244 if (debug) archiveOptions.Add("debug", null);
211 245
212 if (mainParams.Count > 2) 246 if (mainParams.Count > 2)
213 { 247 {
@@ -254,7 +288,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
254 288
255 ArchiveRegion(path, options); 289 ArchiveRegion(path, options);
256 } 290 }
257 291
258 public void ArchiveRegion(string savePath, Dictionary<string, object> options) 292 public void ArchiveRegion(string savePath, Dictionary<string, object> options)
259 { 293 {
260 ArchiveRegion(savePath, Guid.Empty, options); 294 ArchiveRegion(savePath, Guid.Empty, options);
@@ -264,7 +298,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
264 { 298 {
265 m_log.InfoFormat( 299 m_log.InfoFormat(
266 "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); 300 "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath);
267 301
268 new ArchiveWriteRequest(Scene, savePath, requestId).ArchiveRegion(options); 302 new ArchiveWriteRequest(Scene, savePath, requestId).ArchiveRegion(options);
269 } 303 }
270 304
@@ -288,21 +322,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver
288 Dictionary<string, object> archiveOptions = new Dictionary<string, object>(); 322 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
289 DearchiveRegion(loadPath, Guid.Empty, archiveOptions); 323 DearchiveRegion(loadPath, Guid.Empty, archiveOptions);
290 } 324 }
291 325
292 public void DearchiveRegion(string loadPath, Guid requestId, Dictionary<string,object> options) 326 public void DearchiveRegion(string loadPath, Guid requestId, Dictionary<string, object> options)
293 { 327 {
294 m_log.InfoFormat( 328 m_log.InfoFormat(
295 "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath); 329 "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath);
296 330
297 new ArchiveReadRequest(Scene, loadPath, requestId, options).DearchiveRegion(); 331 new ArchiveReadRequest(Scene, loadPath, requestId, options).DearchiveRegion();
298 } 332 }
299 333
300 public void DearchiveRegion(Stream loadStream) 334 public void DearchiveRegion(Stream loadStream)
301 { 335 {
302 Dictionary<string, object> archiveOptions = new Dictionary<string, object>(); 336 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
303 DearchiveRegion(loadStream, Guid.Empty, archiveOptions); 337 DearchiveRegion(loadStream, Guid.Empty, archiveOptions);
304 } 338 }
305
306 public void DearchiveRegion(Stream loadStream, Guid requestId, Dictionary<string, object> options) 339 public void DearchiveRegion(Stream loadStream, Guid requestId, Dictionary<string, object> options)
307 { 340 {
308 new ArchiveReadRequest(Scene, loadStream, requestId, options).DearchiveRegion(); 341 new ArchiveReadRequest(Scene, loadStream, requestId, options).DearchiveRegion();
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
index bc6a97d..3092fe0 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
@@ -46,13 +46,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
46 /// <value> 46 /// <value>
47 /// Post a message to the log every x assets as a progress bar 47 /// Post a message to the log every x assets as a progress bar
48 /// </value> 48 /// </value>
49 protected static int LOG_ASSET_LOAD_NOTIFICATION_INTERVAL = 50; 49 protected static int LOG_ASSET_LOAD_NOTIFICATION_INTERVAL = 100;
50 50
51 /// <value> 51 /// <value>
52 /// Keep a count of the number of assets written so that we can provide status updates 52 /// Keep a count of the number of assets written so that we can provide status updates
53 /// </value> 53 /// </value>
54 protected int m_assetsWritten; 54 protected int m_assetsWritten;
55 55
56 protected TarArchiveWriter m_archiveWriter; 56 protected TarArchiveWriter m_archiveWriter;
57 57
58 public AssetsArchiver(TarArchiveWriter archiveWriter) 58 public AssetsArchiver(TarArchiveWriter archiveWriter)
@@ -143,6 +143,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
143 asset.Data); 143 asset.Data);
144 144
145 m_assetsWritten++; 145 m_assetsWritten++;
146
147 //m_log.DebugFormat("[ARCHIVER]: Added asset {0}", m_assetsWritten);
148
149 if (m_assetsWritten % LOG_ASSET_LOAD_NOTIFICATION_INTERVAL == 0)
150 m_log.InfoFormat("[ARCHIVER]: Added {0} assets to archive", m_assetsWritten);
146 } 151 }
147 152
148 } 153 }
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs
index 8c0ef88..5d3be62 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs
@@ -93,6 +93,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
93 93
94 StringReader sr = new StringReader(xml); 94 StringReader sr = new StringReader(xml);
95 XmlTextReader reader = new XmlTextReader(sr); 95 XmlTextReader reader = new XmlTextReader(sr);
96 reader.ProhibitDtd = true;
96 97
97 reader.ReadStartElement("assets"); 98 reader.ReadStartElement("assets");
98 reader.Read(); 99 reader.Read();
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index db66c83..91f4dc3 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -60,29 +60,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
60 Completed, 60 Completed,
61 Aborted 61 Aborted
62 }; 62 };
63
64 /// <value>
65 /// Timeout threshold if we still need assets or missing asset notifications but have stopped receiving them
66 /// from the asset service
67 /// </value>
68 protected const int TIMEOUT = 60 * 1000;
69
70 /// <value>
71 /// If a timeout does occur, limit the amount of UUID information put to the console.
72 /// </value>
73 protected const int MAX_UUID_DISPLAY_ON_TIMEOUT = 3;
74
75 protected System.Timers.Timer m_requestCallbackTimer;
76 63
77 /// <value> 64 /// <value>
78 /// State of this request
79 /// </value>
80 private RequestState m_requestState = RequestState.Initial;
81
82 /// <value>
83 /// uuids to request 65 /// uuids to request
84 /// </value> 66 /// </value>
85 protected IDictionary<UUID, sbyte> m_uuids; 67 protected IDictionary<UUID, sbyte> m_uuids;
68 private int m_previousErrorsCount;
86 69
87 /// <value> 70 /// <value>
88 /// Callback used when all the assets requested have been received. 71 /// Callback used when all the assets requested have been received.
@@ -93,7 +76,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
93 /// List of assets that were found. This will be passed back to the requester. 76 /// List of assets that were found. This will be passed back to the requester.
94 /// </value> 77 /// </value>
95 protected List<UUID> m_foundAssetUuids = new List<UUID>(); 78 protected List<UUID> m_foundAssetUuids = new List<UUID>();
96 79
97 /// <value> 80 /// <value>
98 /// Maintain a list of assets that could not be found. This will be passed back to the requester. 81 /// Maintain a list of assets that could not be found. This will be passed back to the requester.
99 /// </value> 82 /// </value>
@@ -104,217 +87,114 @@ namespace OpenSim.Region.CoreModules.World.Archiver
104 /// </value> 87 /// </value>
105 private int m_repliesRequired; 88 private int m_repliesRequired;
106 89
90 private System.Timers.Timer m_timeOutTimer;
91 private bool m_timeout;
92
107 /// <value> 93 /// <value>
108 /// Asset service used to request the assets 94 /// Asset service used to request the assets
109 /// </value> 95 /// </value>
110 protected IAssetService m_assetService; 96 protected IAssetService m_assetService;
111 protected IUserAccountService m_userAccountService; 97 protected IUserAccountService m_userAccountService;
112 protected UUID m_scopeID; // the grid ID 98 protected UUID m_scopeID; // the grid ID
113 99
114 protected AssetsArchiver m_assetsArchiver; 100 protected AssetsArchiver m_assetsArchiver;
115 101
116 protected Dictionary<string, object> m_options; 102 protected Dictionary<string, object> m_options;
117 103
118 protected internal AssetsRequest( 104 protected internal AssetsRequest(
119 AssetsArchiver assetsArchiver, IDictionary<UUID, sbyte> uuids, 105 AssetsArchiver assetsArchiver, IDictionary<UUID, sbyte> uuids,
120 IAssetService assetService, IUserAccountService userService, 106 int previousErrorsCount,
121 UUID scope, Dictionary<string, object> options, 107 IAssetService assetService, IUserAccountService userService,
108 UUID scope, Dictionary<string, object> options,
122 AssetsRequestCallback assetsRequestCallback) 109 AssetsRequestCallback assetsRequestCallback)
123 { 110 {
124 m_assetsArchiver = assetsArchiver; 111 m_assetsArchiver = assetsArchiver;
125 m_uuids = uuids; 112 m_uuids = uuids;
113 m_previousErrorsCount = previousErrorsCount;
126 m_assetsRequestCallback = assetsRequestCallback; 114 m_assetsRequestCallback = assetsRequestCallback;
127 m_assetService = assetService; 115 m_assetService = assetService;
128 m_userAccountService = userService; 116 m_userAccountService = userService;
129 m_scopeID = scope; 117 m_scopeID = scope;
130 m_options = options; 118 m_options = options;
131 m_repliesRequired = uuids.Count; 119 m_repliesRequired = uuids.Count;
132
133 // FIXME: This is a really poor way of handling the timeout since it will always leave the original requesting thread
134 // hanging. Need to restructure so an original request thread waits for a ManualResetEvent on asset received
135 // so we can properly abort that thread. Or request all assets synchronously, though that would be a more
136 // radical change
137 m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT);
138 m_requestCallbackTimer.AutoReset = false;
139 m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout);
140 } 120 }
141 121
142 protected internal void Execute() 122 protected internal void Execute()
143 { 123 {
144 m_requestState = RequestState.Running; 124 Culture.SetCurrentCulture();
145
146 m_log.DebugFormat("[ARCHIVER]: AssetsRequest executed looking for {0} possible assets", m_repliesRequired);
147
148 // We can stop here if there are no assets to fetch 125 // We can stop here if there are no assets to fetch
149 if (m_repliesRequired == 0) 126 if (m_repliesRequired == 0)
150 { 127 {
151 m_requestState = RequestState.Completed;
152 PerformAssetsRequestCallback(false); 128 PerformAssetsRequestCallback(false);
153 return; 129 return;
154 } 130 }
155 131
156 m_requestCallbackTimer.Enabled = true; 132 m_timeOutTimer = new System.Timers.Timer(60000);
133 m_timeOutTimer .AutoReset = false;
134 m_timeOutTimer.Elapsed += OnTimeout;
135 m_timeout = false;
157 136
158 foreach (KeyValuePair<UUID, sbyte> kvp in m_uuids) 137 foreach (KeyValuePair<UUID, sbyte> kvp in m_uuids)
159 { 138 {
160// m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key); 139 string thiskey = kvp.Key.ToString();
161 140 try
162// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); 141 {
163 AssetBase asset = m_assetService.Get(kvp.Key.ToString()); 142 m_timeOutTimer.Enabled = true;
164 PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset); 143 AssetBase asset = m_assetService.Get(thiskey);
165 } 144 if(m_timeout)
166 } 145 break;
146
147 m_timeOutTimer.Enabled = false;
167 148
168 protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) 149 if(asset == null)
169 { 150 {
170 bool timedOut = true; 151 m_notFoundAssetUuids.Add(new UUID(thiskey));
152 continue;
153 }
171 154
172 try 155 sbyte assetType = kvp.Value;
173 { 156 if (asset != null && assetType == (sbyte)AssetType.Unknown)
174 lock (this)
175 {
176 // Take care of the possibilty that this thread started but was paused just outside the lock before
177 // the final request came in (assuming that such a thing is possible)
178 if (m_requestState == RequestState.Completed)
179 { 157 {
180 timedOut = false; 158 m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", thiskey, SLUtil.AssetTypeFromCode(assetType));
181 return; 159 asset.Type = assetType;
182 } 160 }
183
184 m_requestState = RequestState.Aborted;
185 }
186 161
187 // Calculate which uuids were not found. This is an expensive way of doing it, but this is a failure 162 m_foundAssetUuids.Add(asset.FullID);
188 // case anyway. 163 m_assetsArchiver.WriteAsset(PostProcess(asset));
189 List<UUID> uuids = new List<UUID>();
190 foreach (UUID uuid in m_uuids.Keys)
191 {
192 uuids.Add(uuid);
193 } 164 }
194 165
195 foreach (UUID uuid in m_foundAssetUuids) 166 catch (Exception e)
196 {
197 uuids.Remove(uuid);
198 }
199
200 foreach (UUID uuid in m_notFoundAssetUuids)
201 { 167 {
202 uuids.Remove(uuid); 168 m_log.ErrorFormat("[ARCHIVER]: Execute failed with {0}", e);
203 }
204
205 m_log.ErrorFormat(
206 "[ARCHIVER]: Asset service failed to return information about {0} requested assets", uuids.Count);
207
208 int i = 0;
209 foreach (UUID uuid in uuids)
210 {
211 m_log.ErrorFormat("[ARCHIVER]: No information about asset {0} received", uuid);
212
213 if (++i >= MAX_UUID_DISPLAY_ON_TIMEOUT)
214 break;
215 } 169 }
216
217 if (uuids.Count > MAX_UUID_DISPLAY_ON_TIMEOUT)
218 m_log.ErrorFormat(
219 "[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT);
220
221 m_log.Error("[ARCHIVER]: Archive save aborted. PLEASE DO NOT USE THIS ARCHIVE, IT WILL BE INCOMPLETE.");
222 }
223 catch (Exception e)
224 {
225 m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}{1}", e.Message, e.StackTrace);
226 } 170 }
227 finally
228 {
229 if (timedOut)
230 WorkManager.RunInThread(PerformAssetsRequestCallback, true, "Archive Assets Request Callback");
231 }
232 }
233 171
234 protected void PreAssetRequestCallback(string fetchedAssetID, object assetType, AssetBase fetchedAsset) 172 m_timeOutTimer.Dispose();
235 { 173 int totalerrors = m_notFoundAssetUuids.Count + m_previousErrorsCount;
236 // Check for broken asset types and fix them with the AssetType gleaned by UuidGatherer
237 if (fetchedAsset != null && fetchedAsset.Type == (sbyte)AssetType.Unknown)
238 {
239 m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", fetchedAsset.ID, SLUtil.AssetTypeFromCode((sbyte)assetType));
240 fetchedAsset.Type = (sbyte)assetType;
241 }
242 174
243 AssetRequestCallback(fetchedAssetID, this, fetchedAsset); 175 if(m_timeout)
244 } 176 m_log.DebugFormat("[ARCHIVER]: Aborted because AssetService request timeout. Successfully added {0} assets", m_foundAssetUuids.Count);
177 else if(totalerrors == 0)
178 m_log.DebugFormat("[ARCHIVER]: Successfully added all {0} assets", m_foundAssetUuids.Count);
179 else
180 m_log.DebugFormat("[ARCHIVER]: Successfully added {0} assets ({1} of total possible assets requested were not found, were damaged or were not assets)",
181 m_foundAssetUuids.Count, totalerrors);
245 182
246 /// <summary> 183 PerformAssetsRequestCallback(m_timeout);
247 /// Called back by the asset cache when it has the asset 184 }
248 /// </summary> 185
249 /// <param name="assetID"></param> 186 private void OnTimeout(object source, ElapsedEventArgs args)
250 /// <param name="asset"></param>
251 public void AssetRequestCallback(string id, object sender, AssetBase asset)
252 { 187 {
253 Culture.SetCurrentCulture(); 188 m_timeout = true;
254
255 try
256 {
257 lock (this)
258 {
259 //m_log.DebugFormat("[ARCHIVER]: Received callback for asset {0}", id);
260
261 m_requestCallbackTimer.Stop();
262
263 if ((m_requestState == RequestState.Aborted) || (m_requestState == RequestState.Completed))
264 {
265 m_log.WarnFormat(
266 "[ARCHIVER]: Received information about asset {0} while in state {1}. Ignoring.",
267 id, m_requestState);
268
269 return;
270 }
271
272 if (asset != null)
273 {
274 if (m_options.ContainsKey("verbose"))
275 m_log.InfoFormat("[ARCHIVER]: Writing asset {0}", id);
276
277 m_foundAssetUuids.Add(asset.FullID);
278
279 m_assetsArchiver.WriteAsset(PostProcess(asset));
280 }
281 else
282 {
283 if (m_options.ContainsKey("verbose"))
284 m_log.InfoFormat("[ARCHIVER]: Recording asset {0} as not found", id);
285
286 m_notFoundAssetUuids.Add(new UUID(id));
287 }
288
289 if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count >= m_repliesRequired)
290 {
291 m_requestState = RequestState.Completed;
292
293 m_log.DebugFormat(
294 "[ARCHIVER]: Successfully added {0} assets ({1} assets not found but these may be expected invalid references)",
295 m_foundAssetUuids.Count, m_notFoundAssetUuids.Count);
296
297 // We want to stop using the asset cache thread asap
298 // as we now need to do the work of producing the rest of the archive
299 WorkManager.RunInThread(PerformAssetsRequestCallback, false, "Archive Assets Request Callback");
300 }
301 else
302 {
303 m_requestCallbackTimer.Start();
304 }
305 }
306 }
307 catch (Exception e)
308 {
309 m_log.ErrorFormat("[ARCHIVER]: AssetRequestCallback failed with {0}", e);
310 }
311 } 189 }
312 190
313 /// <summary> 191 /// <summary>
314 /// Perform the callback on the original requester of the assets 192 /// Perform the callback on the original requester of the assets
315 /// </summary> 193 /// </summary>
316 protected void PerformAssetsRequestCallback(object o) 194 private void PerformAssetsRequestCallback(object o)
317 { 195 {
196 if(m_assetsRequestCallback == null)
197 return;
318 Culture.SetCurrentCulture(); 198 Culture.SetCurrentCulture();
319 199
320 Boolean timedOut = (Boolean)o; 200 Boolean timedOut = (Boolean)o;
@@ -330,7 +210,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
330 } 210 }
331 } 211 }
332 212
333 protected AssetBase PostProcess(AssetBase asset) 213 private AssetBase PostProcess(AssetBase asset)
334 { 214 {
335 if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home")) 215 if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home"))
336 { 216 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
index 3dcc020..809d863 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
@@ -70,6 +70,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
70 /// If null then the region doesn't have a corresponding scene, and it won't be loaded. 70 /// If null then the region doesn't have a corresponding scene, and it won't be loaded.
71 /// </summary> 71 /// </summary>
72 public Scene Scene { get; set; } 72 public Scene Scene { get; set; }
73
74 /// <summary>
75 /// The size of the region being loaded.
76 /// </summary>
77 public Vector3 RegionSize { get; set; }
78
79 public RegionInfo()
80 {
81 RegionSize = new Vector3(256f,256f,float.MaxValue);
82 }
73 } 83 }
74 84
75 /// <summary> 85 /// <summary>
@@ -113,23 +123,34 @@ namespace OpenSim.Region.CoreModules.World.Archiver
113 public void StartRegion() 123 public void StartRegion()
114 { 124 {
115 m_curX = (m_curX == null) ? 0 : m_curX + 1; 125 m_curX = (m_curX == null) ? 0 : m_curX + 1;
116 // Note: this doesn't mean we have a real region in this location; this could just be a "hole" 126 // Note: this doesn't mean we have a real region in this location; this could just be a "hole"
117 } 127 }
118 128
119 public void SetRegionOriginalID(string id) 129 public void SetRegionOriginalID(string id)
120 { 130 {
121 m_curRegion = new RegionInfo(); 131 m_curRegion = new RegionInfo();
122 m_curRegion.Location = new Point((int)m_curX, (int)m_curY); 132 int x = (int)((m_curX == null) ? 0 : m_curX);
133 int y = (int)((m_curY == null) ? 0 : m_curY);
134
135 m_curRegion.Location = new Point(x, y);
123 m_curRegion.OriginalID = id; 136 m_curRegion.OriginalID = id;
124 // 'curRegion' will be saved in 'm_directory2region' when SetRegionDir() is called 137 // 'curRegion' will be saved in 'm_directory2region' when SetRegionDir() is called
125 } 138 }
126 139
127 public void SetRegionDirectory(string directory) 140 public void SetRegionDirectory(string directory)
128 { 141 {
129 m_curRegion.Directory = directory; 142 if(m_curRegion != null)
130 m_directory2region[directory] = m_curRegion; 143 {
144 m_curRegion.Directory = directory;
145 m_directory2region[directory] = m_curRegion;
146 }
131 } 147 }
132 148
149 public void SetRegionSize(Vector3 size)
150 {
151 if(m_curRegion != null)
152 m_curRegion.RegionSize = size;
153 }
133 154
134 /// <summary> 155 /// <summary>
135 /// Sets all the scenes present in the simulator. 156 /// Sets all the scenes present in the simulator.
@@ -145,7 +166,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
145 { 166 {
146 foreach (RegionInfo archivedRegion in m_directory2region.Values) 167 foreach (RegionInfo archivedRegion in m_directory2region.Values)
147 { 168 {
148 Point location = new Point((int)rootScene.RegionInfo.RegionLocX, (int)rootScene.RegionInfo.RegionLocY); 169 Point location = new Point((int)rootScene.RegionInfo.RegionLocX,
170 (int)rootScene.RegionInfo.RegionLocY);
171
149 location.Offset(archivedRegion.Location); 172 location.Offset(archivedRegion.Location);
150 173
151 Scene scene; 174 Scene scene;
@@ -191,7 +214,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
191 return false; 214 return false;
192 string regionDirectory = parts[1]; 215 string regionDirectory = parts[1];
193 relativePath = parts[2]; 216 relativePath = parts[2];
194 217
195 RegionInfo region; 218 RegionInfo region;
196 if (m_directory2region.TryGetValue(regionDirectory, out region)) 219 if (m_directory2region.TryGetValue(regionDirectory, out region))
197 { 220 {
@@ -228,5 +251,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
228 return m_newId2region.Keys.ToList(); 251 return m_newId2region.Keys.ToList();
229 } 252 }
230 253
254 public int GetScenesCount()
255 {
256 return m_directory2region.Count;
257 }
231 } 258 }
232} 259}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 9f197f5..6885299 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -65,7 +65,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
65 protected SerialiserModule m_serialiserModule; 65 protected SerialiserModule m_serialiserModule;
66 66
67 protected TaskInventoryItem m_soundItem; 67 protected TaskInventoryItem m_soundItem;
68 68
69 private AutoResetEvent m_oarEvent = new AutoResetEvent(false);
70
69 [SetUp] 71 [SetUp]
70 public override void SetUp() 72 public override void SetUp()
71 { 73 {
@@ -87,11 +89,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
87 m_lastRequestId = requestId; 89 m_lastRequestId = requestId;
88 m_lastErrorMessage = errorMessage; 90 m_lastErrorMessage = errorMessage;
89 Console.WriteLine("About to pulse ArchiverTests on LoadCompleted"); 91 Console.WriteLine("About to pulse ArchiverTests on LoadCompleted");
90 92 m_oarEvent.Set();
91 Monitor.PulseAll(this);
92 } 93 }
93 } 94 }
94 95
95 private void SaveCompleted(Guid requestId, string errorMessage) 96 private void SaveCompleted(Guid requestId, string errorMessage)
96 { 97 {
97 lock (this) 98 lock (this)
@@ -99,7 +100,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
99 m_lastRequestId = requestId; 100 m_lastRequestId = requestId;
100 m_lastErrorMessage = errorMessage; 101 m_lastErrorMessage = errorMessage;
101 Console.WriteLine("About to pulse ArchiverTests on SaveCompleted"); 102 Console.WriteLine("About to pulse ArchiverTests on SaveCompleted");
102 Monitor.PulseAll(this); 103 m_oarEvent.Set();
103 } 104 }
104 } 105 }
105 106
@@ -110,6 +111,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
110 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); 111 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
111 Vector3 groupPosition = new Vector3(10, 20, 30); 112 Vector3 groupPosition = new Vector3(10, 20, 30);
112 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); 113 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
114 rotationOffset.Normalize();
113// Vector3 offsetPosition = new Vector3(5, 10, 15); 115// Vector3 offsetPosition = new Vector3(5, 10, 15);
114 116
115 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, Vector3.Zero) { Name = partName }; 117 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, Vector3.Zero) { Name = partName };
@@ -122,11 +124,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
122 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder(); 124 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
123 Vector3 groupPosition = new Vector3(90, 80, 70); 125 Vector3 groupPosition = new Vector3(90, 80, 70);
124 Quaternion rotationOffset = new Quaternion(60, 70, 80, 90); 126 Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
127 rotationOffset.Normalize();
125 Vector3 offsetPosition = new Vector3(20, 25, 30); 128 Vector3 offsetPosition = new Vector3(20, 25, 30);
126 129
127 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName }; 130 return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
128 } 131 }
129 132
130 private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid) 133 private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid)
131 { 134 {
132 SceneObjectPart part1 = CreateSceneObjectPart1(); 135 SceneObjectPart part1 = CreateSceneObjectPart1();
@@ -192,17 +195,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
192 m_scene.EventManager.OnOarFileSaved += SaveCompleted; 195 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
193 196
194 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080"); 197 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
195 198
196 lock (this) 199 m_oarEvent.Reset();
197 { 200 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId);
198 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId); 201 //AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
199 //AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer; 202 //while (assetServer.HasWaitingRequests())
200 //while (assetServer.HasWaitingRequests()) 203 // assetServer.ProcessNextRequest();
201 // assetServer.ProcessNextRequest(); 204
202 205 m_oarEvent.WaitOne(60000);
203 Monitor.Wait(this, 60000); 206
204 }
205
206 Assert.That(m_lastRequestId, Is.EqualTo(requestId)); 207 Assert.That(m_lastRequestId, Is.EqualTo(requestId));
207 208
208 byte[] archive = archiveWriteStream.ToArray(); 209 byte[] archive = archiveWriteStream.ToArray();
@@ -210,7 +211,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
210 TarArchiveReader tar = new TarArchiveReader(archiveReadStream); 211 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
211 212
212 bool gotNcAssetFile = false; 213 bool gotNcAssetFile = false;
213 214
214 string expectedNcAssetFileName = string.Format("{0}_{1}", ncAssetUuid, "notecard.txt"); 215 string expectedNcAssetFileName = string.Format("{0}_{1}", ncAssetUuid, "notecard.txt");
215 216
216 List<string> foundPaths = new List<string>(); 217 List<string> foundPaths = new List<string>();
@@ -219,7 +220,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
219 expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2)); 220 expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2));
220 221
221 string filePath; 222 string filePath;
222 TarArchiveReader.TarEntryType tarEntryType; 223 TarArchiveReader.TarEntryType tarEntryType;
223 224
224 byte[] data = tar.ReadEntry(out filePath, out tarEntryType); 225 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
225 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 226 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
@@ -227,9 +228,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
227 Dictionary<string, object> archiveOptions = new Dictionary<string, object>(); 228 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
228 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions); 229 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions);
229 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo()); 230 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
230 231
231 Assert.That(arr.ControlFileLoaded, Is.True); 232 Assert.That(arr.ControlFileLoaded, Is.True);
232 233
233 while (tar.ReadEntry(out filePath, out tarEntryType) != null) 234 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
234 { 235 {
235 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) 236 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
@@ -265,7 +266,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
265 m_scene.AddNewSceneObject(sog1, false); 266 m_scene.AddNewSceneObject(sog1, false);
266 267
267 SceneObjectPart part2 = CreateSceneObjectPart2(); 268 SceneObjectPart part2 = CreateSceneObjectPart2();
268 269
269 AssetNotecard nc = new AssetNotecard(); 270 AssetNotecard nc = new AssetNotecard();
270 nc.BodyText = "Hello World!"; 271 nc.BodyText = "Hello World!";
271 nc.Encode(); 272 nc.Encode();
@@ -275,10 +276,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
275 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); 276 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
276 m_scene.AssetService.Store(ncAsset); 277 m_scene.AssetService.Store(ncAsset);
277 SceneObjectGroup sog2 = new SceneObjectGroup(part2); 278 SceneObjectGroup sog2 = new SceneObjectGroup(part2);
278 TaskInventoryItem ncItem 279 TaskInventoryItem ncItem
279 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid }; 280 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
280 part2.Inventory.AddInventoryItem(ncItem, true); 281 part2.Inventory.AddInventoryItem(ncItem, true);
281 282
282 m_scene.AddNewSceneObject(sog2, false); 283 m_scene.AddNewSceneObject(sog2, false);
283 284
284 MemoryStream archiveWriteStream = new MemoryStream(); 285 MemoryStream archiveWriteStream = new MemoryStream();
@@ -287,6 +288,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
287 288
288 Dictionary<string, Object> options = new Dictionary<string, Object>(); 289 Dictionary<string, Object> options = new Dictionary<string, Object>();
289 options.Add("noassets", true); 290 options.Add("noassets", true);
291
290 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options); 292 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
291 293
292 // Don't wait for completion - with --noassets save oar happens synchronously 294 // Don't wait for completion - with --noassets save oar happens synchronously
@@ -304,7 +306,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
304 expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2)); 306 expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2));
305 307
306 string filePath; 308 string filePath;
307 TarArchiveReader.TarEntryType tarEntryType; 309 TarArchiveReader.TarEntryType tarEntryType;
308 310
309 byte[] data = tar.ReadEntry(out filePath, out tarEntryType); 311 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
310 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 312 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
@@ -312,9 +314,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
312 Dictionary<string, object> archiveOptions = new Dictionary<string, object>(); 314 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
313 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions); 315 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions);
314 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo()); 316 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
315 317
316 Assert.That(arr.ControlFileLoaded, Is.True); 318 Assert.That(arr.ControlFileLoaded, Is.True);
317 319
318 while (tar.ReadEntry(out filePath, out tarEntryType) != null) 320 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
319 { 321 {
320 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) 322 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
@@ -343,11 +345,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
343 345
344 MemoryStream archiveWriteStream = new MemoryStream(); 346 MemoryStream archiveWriteStream = new MemoryStream();
345 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); 347 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
346 348
347 // Put in a random blank directory to check that this doesn't upset the load process 349 // Put in a random blank directory to check that this doesn't upset the load process
348 tar.WriteDir("ignoreme"); 350 tar.WriteDir("ignoreme");
349 351
350 // Also check that direct entries which will also have a file entry containing that directory doesn't 352 // Also check that direct entries which will also have a file entry containing that directory doesn't
351 // upset load 353 // upset load
352 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 354 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
353 355
@@ -390,17 +392,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
390 Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z), 392 Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
391 part1.UUID); 393 part1.UUID);
392 tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1)); 394 tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1));
393 395
394 tar.Close(); 396 tar.Close();
395 397
396 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 398 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
397 399
398 lock (this) 400 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
399 { 401 m_oarEvent.Reset();
400 m_scene.EventManager.OnOarFileLoaded += LoadCompleted; 402 m_archiverModule.DearchiveRegion(archiveReadStream);
401 m_archiverModule.DearchiveRegion(archiveReadStream); 403
402 } 404 m_oarEvent.WaitOne(60000);
403 405
404 Assert.That(m_lastErrorMessage, Is.Null); 406 Assert.That(m_lastErrorMessage, Is.Null);
405 407
406 TestLoadedRegion(part1, soundItemName, soundData); 408 TestLoadedRegion(part1, soundItemName, soundData);
@@ -444,11 +446,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
444 446
445 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 447 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
446 448
447 lock (this) 449 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
448 { 450 m_oarEvent.Reset();
449 m_scene.EventManager.OnOarFileLoaded += LoadCompleted; 451 m_archiverModule.DearchiveRegion(archiveReadStream);
450 m_archiverModule.DearchiveRegion(archiveReadStream); 452
451 } 453 m_oarEvent.WaitOne(60000);
452 454
453 Assert.That(m_lastErrorMessage, Is.Null); 455 Assert.That(m_lastErrorMessage, Is.Null);
454 456
@@ -473,35 +475,33 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
473 m_scene.AddNewSceneObject(sog1, false); 475 m_scene.AddNewSceneObject(sog1, false);
474 476
475 SceneObjectPart part2 = CreateSceneObjectPart2(); 477 SceneObjectPart part2 = CreateSceneObjectPart2();
476 478
477 AssetNotecard nc = new AssetNotecard(); 479 AssetNotecard nc = new AssetNotecard();
478 nc.BodyText = "Hello World!"; 480 nc.BodyText = "Hello World!";
479 nc.Encode(); 481 nc.Encode();
480 UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); 482 UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
481 UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); 483 UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
482 AssetBase ncAsset 484 AssetBase ncAsset
483 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); 485 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
484 m_scene.AssetService.Store(ncAsset); 486 m_scene.AssetService.Store(ncAsset);
485 SceneObjectGroup sog2 = new SceneObjectGroup(part2); 487 SceneObjectGroup sog2 = new SceneObjectGroup(part2);
486 TaskInventoryItem ncItem 488 TaskInventoryItem ncItem
487 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid }; 489 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
488 part2.Inventory.AddInventoryItem(ncItem, true); 490 part2.Inventory.AddInventoryItem(ncItem, true);
489 491
490 m_scene.AddNewSceneObject(sog2, false); 492 m_scene.AddNewSceneObject(sog2, false);
491 493
492 MemoryStream archiveWriteStream = new MemoryStream(); 494 MemoryStream archiveWriteStream = new MemoryStream();
493 m_scene.EventManager.OnOarFileSaved += SaveCompleted; 495 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
494 496
495 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080"); 497 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
496 498
497 lock (this) 499 m_oarEvent.Reset();
498 { 500 m_archiverModule.ArchiveRegion(
499 m_archiverModule.ArchiveRegion(
500 archiveWriteStream, requestId, new Dictionary<string, Object>() { { "wipe-owners", Boolean.TrueString } }); 501 archiveWriteStream, requestId, new Dictionary<string, Object>() { { "wipe-owners", Boolean.TrueString } });
501 502
502 Monitor.Wait(this, 60000); 503 m_oarEvent.WaitOne(60000);
503 } 504
504
505 Assert.That(m_lastRequestId, Is.EqualTo(requestId)); 505 Assert.That(m_lastRequestId, Is.EqualTo(requestId));
506 506
507 byte[] archive = archiveWriteStream.ToArray(); 507 byte[] archive = archiveWriteStream.ToArray();
@@ -526,11 +526,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
526 526
527 scene2.RegionInfo.EstateSettings.EstateOwner = estateOwner; 527 scene2.RegionInfo.EstateSettings.EstateOwner = estateOwner;
528 528
529 lock (this) 529 scene2.EventManager.OnOarFileLoaded += LoadCompleted;
530 { 530 m_oarEvent.Reset();
531 scene2.EventManager.OnOarFileLoaded += LoadCompleted; 531 archiverModule.DearchiveRegion(archiveReadStream);
532 archiverModule.DearchiveRegion(archiveReadStream); 532
533 } 533 m_oarEvent.WaitOne(60000);
534 534
535 Assert.That(m_lastErrorMessage, Is.Null); 535 Assert.That(m_lastErrorMessage, Is.Null);
536 536
@@ -557,16 +557,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
557 MockGroupsServicesConnector groupsService = new MockGroupsServicesConnector(); 557 MockGroupsServicesConnector groupsService = new MockGroupsServicesConnector();
558 558
559 IConfigSource configSource = new IniConfigSource(); 559 IConfigSource configSource = new IniConfigSource();
560 IConfig config = configSource.AddConfig("Groups"); 560 IConfig config = configSource.AddConfig("Groups");
561 config.Set("Enabled", true); 561 config.Set("Enabled", true);
562 config.Set("Module", "GroupsModule"); 562 config.Set("Module", "GroupsModule");
563 config.Set("DebugEnabled", true); 563 config.Set("DebugEnabled", true);
564 SceneHelpers.SetupSceneModules( 564 SceneHelpers.SetupSceneModules(
565 m_scene, configSource, new object[] { new GroupsModule(), groupsService, new LandManagementModule() }); 565 m_scene, configSource, new object[] { new GroupsModule(), groupsService, new LandManagementModule() });
566 566
567 // Create group in scene for loading 567 // Create group in scene for loading
568 // FIXME: For now we'll put up with the issue that we'll get a group ID that varies across tests. 568 // FIXME: For now we'll put up with the issue that we'll get a group ID that varies across tests.
569 UUID groupID 569 UUID groupID
570 = groupsService.CreateGroup(UUID.Zero, "group1", "", true, UUID.Zero, 3, true, true, true, UUID.Zero); 570 = groupsService.CreateGroup(UUID.Zero, "group1", "", true, UUID.Zero, 3, true, true, true, UUID.Zero);
571 571
572 // Construct OAR 572 // Construct OAR
@@ -591,11 +591,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
591 oarStream = new MemoryStream(oarStream.ToArray()); 591 oarStream = new MemoryStream(oarStream.ToArray());
592 592
593 // Load OAR 593 // Load OAR
594 lock (this) 594 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
595 { 595 m_oarEvent.Reset();
596 m_scene.EventManager.OnOarFileLoaded += LoadCompleted; 596 m_archiverModule.DearchiveRegion(oarStream);
597 m_archiverModule.DearchiveRegion(oarStream); 597
598 } 598 m_oarEvent.WaitOne(60000);
599 599
600 ILandObject rLo = m_scene.LandChannel.GetLandObject(16, 16); 600 ILandObject rLo = m_scene.LandChannel.GetLandObject(16, 16);
601 LandData rLd = rLo.LandData; 601 LandData rLd = rLo.LandData;
@@ -617,7 +617,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
617 617
618 MemoryStream archiveWriteStream = new MemoryStream(); 618 MemoryStream archiveWriteStream = new MemoryStream();
619 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); 619 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
620 620
621 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 621 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
622 tar.WriteFile( 622 tar.WriteFile(
623 ArchiveConstants.CONTROL_FILE_PATH, 623 ArchiveConstants.CONTROL_FILE_PATH,
@@ -658,17 +658,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
658 rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); 658 rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33"));
659 659
660 tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); 660 tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs));
661 661
662 tar.Close(); 662 tar.Close();
663 663
664 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 664 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
665 665
666 lock (this) 666 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
667 { 667 m_oarEvent.Reset();
668 m_scene.EventManager.OnOarFileLoaded += LoadCompleted; 668 m_archiverModule.DearchiveRegion(archiveReadStream);
669 m_archiverModule.DearchiveRegion(archiveReadStream); 669
670 } 670 m_oarEvent.WaitOne(60000);
671 671
672 Assert.That(m_lastErrorMessage, Is.Null); 672 Assert.That(m_lastErrorMessage, Is.Null);
673 RegionSettings loadedRs = m_scene.RegionInfo.RegionSettings; 673 RegionSettings loadedRs = m_scene.RegionInfo.RegionSettings;
674 674
@@ -705,7 +705,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
705 Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID 705 Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID
706 Assert.AreEqual(0, loadedRs.SpawnPoints().Count); 706 Assert.AreEqual(0, loadedRs.SpawnPoints().Count);
707 } 707 }
708 708
709 /// <summary> 709 /// <summary>
710 /// Test merging an OpenSim Region Archive into an existing scene 710 /// Test merging an OpenSim Region Archive into an existing scene
711 /// </summary> 711 /// </summary>
@@ -737,13 +737,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
737 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); 737 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
738 738
739 // Write out this scene 739 // Write out this scene
740
740 scene.EventManager.OnOarFileSaved += SaveCompleted; 741 scene.EventManager.OnOarFileSaved += SaveCompleted;
742 m_oarEvent.Reset();
743 m_archiverModule.ArchiveRegion(archiveWriteStream);
741 744
742 lock (this) 745 m_oarEvent.WaitOne(60000);
743 {
744 m_archiverModule.ArchiveRegion(archiveWriteStream);
745 Monitor.Wait(this, 60000);
746 }
747 } 746 }
748 747
749 { 748 {
@@ -754,10 +753,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
754 byte[] archive = archiveWriteStream.ToArray(); 753 byte[] archive = archiveWriteStream.ToArray();
755 MemoryStream archiveReadStream = new MemoryStream(archive); 754 MemoryStream archiveReadStream = new MemoryStream(archive);
756 755
756 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
757 Dictionary<string, object> archiveOptions = new Dictionary<string, object>(); 757 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
758 archiveOptions.Add("merge", null); 758 archiveOptions.Add("merge", null);
759 m_oarEvent.Reset();
759 m_archiverModule.DearchiveRegion(archiveReadStream, Guid.Empty, archiveOptions); 760 m_archiverModule.DearchiveRegion(archiveReadStream, Guid.Empty, archiveOptions);
760 761
762 m_oarEvent.WaitOne(60000);
763
761 SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name); 764 SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name);
762 Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge"); 765 Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
763 Assert.That(object1Existing.Name, Is.EqualTo(part1.Name), "object1 names not identical after merge"); 766 Assert.That(object1Existing.Name, Is.EqualTo(part1.Name), "object1 names not identical after merge");
@@ -816,7 +819,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
816 SceneObjectGroup sog1; 819 SceneObjectGroup sog1;
817 SceneObjectGroup sog2; 820 SceneObjectGroup sog2;
818 UUID ncAssetUuid; 821 UUID ncAssetUuid;
819 822
820 CreateTestObjects(scene, out sog1, out sog2, out ncAssetUuid); 823 CreateTestObjects(scene, out sog1, out sog2, out ncAssetUuid);
821 824
822 expectedPaths[scene.RegionInfo.RegionID] = new List<string>(); 825 expectedPaths[scene.RegionInfo.RegionID] = new List<string>();
@@ -829,18 +832,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
829 832
830 // Save OAR 833 // Save OAR
831 MemoryStream archiveWriteStream = new MemoryStream(); 834 MemoryStream archiveWriteStream = new MemoryStream();
832 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
833 835
834 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080"); 836 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
835 837
836 Dictionary<string, Object> options = new Dictionary<string, Object>(); 838 Dictionary<string, Object> options = new Dictionary<string, Object>();
837 options.Add("all", true); 839 options.Add("all", true);
838 840
839 lock (this) 841 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
840 { 842 m_oarEvent.Reset();
841 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options); 843 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
842 Monitor.Wait(this, 60000); 844
843 } 845 m_oarEvent.WaitOne(60000);
844 846
845 847
846 // Check that the OAR contains the expected data 848 // Check that the OAR contains the expected data
@@ -991,7 +993,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
991 993
992 tar.Close(); 994 tar.Close();
993 995
994 996
995 // Delete the current objects, to test that they're loaded from the OAR and didn't 997 // Delete the current objects, to test that they're loaded from the OAR and didn't
996 // just remain in the scene. 998 // just remain in the scene.
997 m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene) 999 m_sceneHelpers.SceneManager.ForEachScene(delegate(Scene scene)
@@ -1007,11 +1009,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
1007 1009
1008 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); 1010 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
1009 1011
1010 lock (this) 1012 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
1011 { 1013 m_oarEvent.Reset();
1012 m_scene.EventManager.OnOarFileLoaded += LoadCompleted; 1014 m_archiverModule.DearchiveRegion(archiveReadStream);
1013 m_archiverModule.DearchiveRegion(archiveReadStream); 1015
1014 } 1016 m_oarEvent.WaitOne(60000);
1015 1017
1016 Assert.That(m_lastErrorMessage, Is.Null); 1018 Assert.That(m_lastErrorMessage, Is.Null);
1017 1019
@@ -1027,8 +1029,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
1027 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); 1029 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
1028 Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical"); 1030 Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical");
1029 Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal"); 1031 Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
1030 Assert.That( 1032
1031 object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal"); 1033 Quaternion qtmp1 = new Quaternion (
1034 (float)Math.Round(object1PartLoaded.RotationOffset.X,5),
1035 (float)Math.Round(object1PartLoaded.RotationOffset.Y,5),
1036 (float)Math.Round(object1PartLoaded.RotationOffset.Z,5),
1037 (float)Math.Round(object1PartLoaded.RotationOffset.W,5));
1038 Quaternion qtmp2 = new Quaternion (
1039 (float)Math.Round(part1.RotationOffset.X,5),
1040 (float)Math.Round(part1.RotationOffset.Y,5),
1041 (float)Math.Round(part1.RotationOffset.Z,5),
1042 (float)Math.Round(part1.RotationOffset.W,5));
1043
1044 Assert.That(qtmp1, Is.EqualTo(qtmp2), "object1 rotation offset not equal");
1032 Assert.That( 1045 Assert.That(
1033 object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal"); 1046 object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
1034 Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation)); 1047 Assert.That(object1PartLoaded.SitTargetOrientation, Is.EqualTo(part1.SitTargetOrientation));
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wav b/OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wav
index b45ee54..b45ee54 100644..100755
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wav
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/Resources/test-sound.wav
Binary files differ