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.cs314
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs84
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs109
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs36
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs23
6 files changed, 406 insertions, 169 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index c810242..9c6706f 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -36,6 +36,7 @@ using System.Xml;
36using log4net; 36using log4net;
37using OpenMetaverse; 37using OpenMetaverse;
38using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Framework.Monitoring;
39using OpenSim.Framework.Serialization; 40using OpenSim.Framework.Serialization;
40using OpenSim.Framework.Serialization.External; 41using OpenSim.Framework.Serialization.External;
41using OpenSim.Region.CoreModules.World.Terrain; 42using OpenSim.Region.CoreModules.World.Terrain;
@@ -96,14 +97,42 @@ namespace OpenSim.Region.CoreModules.World.Archiver
96 97
97 /// <value> 98 /// <value>
98 /// Should the archive being loaded be merged with what is already on the region? 99 /// Should the archive being loaded be merged with what is already on the region?
100 /// Merging usually suppresses terrain and parcel loading
99 /// </value> 101 /// </value>
100 protected bool m_merge; 102 protected bool m_merge;
101 103
102 /// <value> 104 /// <value>
105 /// If true, force the loading of terrain from the oar file
106 /// </value>
107 protected bool m_forceTerrain;
108
109 /// <value>
110 /// If true, force the loading of parcels from the oar file
111 /// </value>
112 protected bool m_forceParcels;
113
114 /// <value>
103 /// Should we ignore any assets when reloading the archive? 115 /// Should we ignore any assets when reloading the archive?
104 /// </value> 116 /// </value>
105 protected bool m_skipAssets; 117 protected bool m_skipAssets;
106 118
119 /// <value>
120 /// Displacement added to each object as it is added to the world
121 /// </value>
122 protected Vector3 m_displacement = Vector3.Zero;
123
124 /// <value>
125 /// Rotation (in radians) to apply to the objects as they are loaded.
126 /// </value>
127 protected float m_rotation = 0f;
128
129 /// <value>
130 /// Center around which to apply the rotation relative to the origional oar position
131 /// </value>
132 protected Vector3 m_rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0f);
133
134 protected bool m_noObjects = false;
135
107 /// <summary> 136 /// <summary>
108 /// Used to cache lookups for valid uuids. 137 /// Used to cache lookups for valid uuids.
109 /// </summary> 138 /// </summary>
@@ -132,10 +161,22 @@ namespace OpenSim.Region.CoreModules.World.Archiver
132 private IAssetService m_assetService = null; 161 private IAssetService m_assetService = null;
133 162
134 163
135 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) 164 private UUID m_defaultUser;
165
166 public ArchiveReadRequest(Scene scene, string loadPath, Guid requestId, Dictionary<string,object>options)
136 { 167 {
137 m_rootScene = scene; 168 m_rootScene = scene;
138 169
170 if (options.ContainsKey("default-user"))
171 {
172 m_defaultUser = (UUID)options["default-user"];
173 m_log.InfoFormat("Using User {0} as default user", m_defaultUser.ToString());
174 }
175 else
176 {
177 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner;
178 }
179
139 m_loadPath = loadPath; 180 m_loadPath = loadPath;
140 try 181 try
141 { 182 {
@@ -150,26 +191,36 @@ namespace OpenSim.Region.CoreModules.World.Archiver
150 } 191 }
151 192
152 m_errorMessage = String.Empty; 193 m_errorMessage = String.Empty;
153 m_merge = merge; 194 m_merge = options.ContainsKey("merge");
154 m_skipAssets = skipAssets; 195 m_forceTerrain = options.ContainsKey("force-terrain");
196 m_forceParcels = options.ContainsKey("force-parcels");
197 m_noObjects = options.ContainsKey("no-objects");
198 m_skipAssets = options.ContainsKey("skipAssets");
155 m_requestId = requestId; 199 m_requestId = requestId;
200 m_displacement = options.ContainsKey("displacement") ? (Vector3)options["displacement"] : Vector3.Zero;
201 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);
156 204
157 // Zero can never be a valid user id 205 // Zero can never be a valid user or group id
158 m_validUserUuids[UUID.Zero] = false; 206 m_validUserUuids[UUID.Zero] = false;
207 m_validGroupUuids[UUID.Zero] = false;
159 208
160 m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>(); 209 m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>();
161 m_assetService = m_rootScene.AssetService; 210 m_assetService = m_rootScene.AssetService;
162 } 211 }
163 212
164 public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) 213 public ArchiveReadRequest(Scene scene, Stream loadStream, Guid requestId, Dictionary<string, object>options)
165 { 214 {
166 m_rootScene = scene; 215 m_rootScene = scene;
167 m_loadPath = null; 216 m_loadPath = null;
168 m_loadStream = loadStream; 217 m_loadStream = loadStream;
169 m_merge = merge; 218 m_skipAssets = options.ContainsKey("skipAssets");
170 m_skipAssets = skipAssets; 219 m_merge = options.ContainsKey("merge");
171 m_requestId = requestId; 220 m_requestId = requestId;
172 221
222 m_defaultUser = scene.RegionInfo.EstateSettings.EstateOwner;
223
173 // Zero can never be a valid user id 224 // Zero can never be a valid user id
174 m_validUserUuids[UUID.Zero] = false; 225 m_validUserUuids[UUID.Zero] = false;
175 226
@@ -229,7 +280,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
229 280
230 // Process the file 281 // Process the file
231 282
232 if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) 283 if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH) && !m_noObjects)
233 { 284 {
234 sceneContext.SerialisedSceneObjects.Add(Encoding.UTF8.GetString(data)); 285 sceneContext.SerialisedSceneObjects.Add(Encoding.UTF8.GetString(data));
235 } 286 }
@@ -243,7 +294,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
243 if ((successfulAssetRestores + failedAssetRestores) % 250 == 0) 294 if ((successfulAssetRestores + failedAssetRestores) % 250 == 0)
244 m_log.Debug("[ARCHIVER]: Loaded " + successfulAssetRestores + " assets and failed to load " + failedAssetRestores + " assets..."); 295 m_log.Debug("[ARCHIVER]: Loaded " + successfulAssetRestores + " assets and failed to load " + failedAssetRestores + " assets...");
245 } 296 }
246 else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) 297 else if (filePath.StartsWith(ArchiveConstants.TERRAINS_PATH) && (!m_merge || m_forceTerrain))
247 { 298 {
248 LoadTerrain(scene, filePath, data); 299 LoadTerrain(scene, filePath, data);
249 } 300 }
@@ -251,7 +302,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
251 { 302 {
252 LoadRegionSettings(scene, filePath, data, dearchivedScenes); 303 LoadRegionSettings(scene, filePath, data, dearchivedScenes);
253 } 304 }
254 else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) 305 else if (filePath.StartsWith(ArchiveConstants.LANDDATA_PATH) && (!m_merge || m_forceParcels))
255 { 306 {
256 sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data)); 307 sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data));
257 } 308 }
@@ -321,7 +372,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
321 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so 372 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so
322 // that users can enter the scene. If we allow the scripts to start in the loop above 373 // that users can enter the scene. If we allow the scripts to start in the loop above
323 // then they significantly increase the time until the OAR finishes loading. 374 // then they significantly increase the time until the OAR finishes loading.
324 Util.FireAndForget(delegate(object o) 375 WorkManager.RunInThread(o =>
325 { 376 {
326 Thread.Sleep(15000); 377 Thread.Sleep(15000);
327 m_log.Info("[ARCHIVER]: Starting scripts in scene objects"); 378 m_log.Info("[ARCHIVER]: Starting scripts in scene objects");
@@ -336,7 +387,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
336 387
337 sceneContext.SceneObjects.Clear(); 388 sceneContext.SceneObjects.Clear();
338 } 389 }
339 }); 390 }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId));
340 391
341 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); 392 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive");
342 393
@@ -422,6 +473,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
422 // Reload serialized prims 473 // Reload serialized prims
423 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); 474 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
424 475
476 OpenMetaverse.Quaternion rot = OpenMetaverse.Quaternion.CreateFromAxisAngle(0, 0, 1, m_rotation);
477
425 UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; 478 UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject;
426 479
427 IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>(); 480 IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>();
@@ -445,6 +498,32 @@ namespace OpenSim.Region.CoreModules.World.Archiver
445 498
446 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); 499 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject);
447 500
501 // Happily this does not do much to the object since it hasn't been added to the scene yet
502 if (!sceneObject.IsAttachment)
503 {
504 if (m_displacement != Vector3.Zero || m_rotation != 0f)
505 {
506 Vector3 pos = sceneObject.AbsolutePosition;
507 if (m_rotation != 0f)
508 {
509 // Rotate the object
510 sceneObject.RootPart.RotationOffset = rot * sceneObject.GroupRotation;
511 // Get object position relative to rotation axis
512 Vector3 offset = pos - m_rotationCenter;
513 // Rotate the object position
514 offset *= rot;
515 // Restore the object position back to relative to the region
516 pos = m_rotationCenter + offset;
517 }
518 if (m_displacement != Vector3.Zero)
519 {
520 pos += m_displacement;
521 }
522 sceneObject.AbsolutePosition = pos;
523 }
524 }
525
526
448 bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero); 527 bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero);
449 528
450 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned 529 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned
@@ -460,58 +539,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
460 oldTelehubUUID = UUID.Zero; 539 oldTelehubUUID = UUID.Zero;
461 } 540 }
462 541
463 // Try to retain the original creator/owner/lastowner if their uuid is present on this grid 542 ModifySceneObject(scene, sceneObject);
464 // or creator data is present. Otherwise, use the estate owner instead.
465 foreach (SceneObjectPart part in sceneObject.Parts)
466 {
467 if (part.CreatorData == null || part.CreatorData == string.Empty)
468 {
469 if (!ResolveUserUuid(scene, part.CreatorID))
470 part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
471 }
472 if (UserManager != null)
473 UserManager.AddUser(part.CreatorID, part.CreatorData);
474
475 if (!ResolveUserUuid(scene, part.OwnerID))
476 part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
477
478 if (!ResolveUserUuid(scene, part.LastOwnerID))
479 part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
480
481 if (!ResolveGroupUuid(part.GroupID))
482 part.GroupID = UUID.Zero;
483
484 // And zap any troublesome sit target information
485// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
486// part.SitTargetPosition = new Vector3(0, 0, 0);
487
488 // Fix ownership/creator of inventory items
489 // Not doing so results in inventory items
490 // being no copy/no mod for everyone
491 lock (part.TaskInventory)
492 {
493 TaskInventoryDictionary inv = part.TaskInventory;
494 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
495 {
496 if (!ResolveUserUuid(scene, kvp.Value.OwnerID))
497 {
498 kvp.Value.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
499 }
500
501 if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
502 {
503 if (!ResolveUserUuid(scene, kvp.Value.CreatorID))
504 kvp.Value.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
505 }
506
507 if (UserManager != null)
508 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
509
510 if (!ResolveGroupUuid(kvp.Value.GroupID))
511 kvp.Value.GroupID = UUID.Zero;
512 }
513 }
514 }
515 543
516 if (scene.AddRestoredSceneObject(sceneObject, true, false)) 544 if (scene.AddRestoredSceneObject(sceneObject, true, false))
517 { 545 {
@@ -535,6 +563,67 @@ namespace OpenSim.Region.CoreModules.World.Archiver
535 scene.RegionInfo.RegionSettings.ClearSpawnPoints(); 563 scene.RegionInfo.RegionSettings.ClearSpawnPoints();
536 } 564 }
537 } 565 }
566
567 /// <summary>
568 /// Optionally modify a loaded SceneObjectGroup. Currently this just ensures that the
569 /// User IDs and Group IDs are valid, but other manipulations could be done as well.
570 /// </summary>
571 private void ModifySceneObject(Scene scene, SceneObjectGroup sceneObject)
572 {
573 // Try to retain the original creator/owner/lastowner if their uuid is present on this grid
574 // or creator data is present. Otherwise, use the estate owner instead.
575 foreach (SceneObjectPart part in sceneObject.Parts)
576 {
577 if (string.IsNullOrEmpty(part.CreatorData))
578 {
579 if (!ResolveUserUuid(scene, part.CreatorID))
580 part.CreatorID = m_defaultUser;
581 }
582 if (UserManager != null)
583 UserManager.AddUser(part.CreatorID, part.CreatorData);
584
585 if (!(ResolveUserUuid(scene, part.OwnerID) || ResolveGroupUuid(part.OwnerID)))
586 part.OwnerID = m_defaultUser;
587
588 if (!(ResolveUserUuid(scene, part.LastOwnerID) || ResolveGroupUuid(part.LastOwnerID)))
589 part.LastOwnerID = m_defaultUser;
590
591 if (!ResolveGroupUuid(part.GroupID))
592 part.GroupID = UUID.Zero;
593
594 // And zap any troublesome sit target information
595 // part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
596 // part.SitTargetPosition = new Vector3(0, 0, 0);
597
598 // Fix ownership/creator of inventory items
599 // Not doing so results in inventory items
600 // being no copy/no mod for everyone
601 lock (part.TaskInventory)
602 {
603 TaskInventoryDictionary inv = part.TaskInventory;
604 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
605 {
606 if (!(ResolveUserUuid(scene, kvp.Value.OwnerID) || ResolveGroupUuid(kvp.Value.OwnerID)))
607 {
608 kvp.Value.OwnerID = m_defaultUser;
609 }
610
611 if (string.IsNullOrEmpty(kvp.Value.CreatorData))
612 {
613 if (!ResolveUserUuid(scene, kvp.Value.CreatorID))
614 kvp.Value.CreatorID = m_defaultUser;
615 }
616
617 if (UserManager != null)
618 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
619
620 if (!ResolveGroupUuid(kvp.Value.GroupID))
621 kvp.Value.GroupID = UUID.Zero;
622 }
623 }
624 }
625 }
626
538 627
539 /// <summary> 628 /// <summary>
540 /// Load serialized parcels. 629 /// Load serialized parcels.
@@ -549,15 +638,29 @@ namespace OpenSim.Region.CoreModules.World.Archiver
549 foreach (string serialisedParcel in serialisedParcels) 638 foreach (string serialisedParcel in serialisedParcels)
550 { 639 {
551 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); 640 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
641
642 if (m_displacement != Vector3.Zero)
643 {
644 Vector3 parcelDisp = new Vector3(m_displacement.X, m_displacement.Y, 0f);
645 parcel.AABBMin += parcelDisp;
646 parcel.AABBMax += parcelDisp;
647 }
552 648
553 // Validate User and Group UUID's 649 // Validate User and Group UUID's
554 650
651 if (!ResolveGroupUuid(parcel.GroupID))
652 parcel.GroupID = UUID.Zero;
653
555 if (parcel.IsGroupOwned) 654 if (parcel.IsGroupOwned)
556 { 655 {
557 if (!ResolveGroupUuid(parcel.GroupID)) 656 if (parcel.GroupID != UUID.Zero)
657 {
658 // In group-owned parcels, OwnerID=GroupID. This should already be the case, but let's make sure.
659 parcel.OwnerID = parcel.GroupID;
660 }
661 else
558 { 662 {
559 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; 663 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
560 parcel.GroupID = UUID.Zero;
561 parcel.IsGroupOwned = false; 664 parcel.IsGroupOwned = false;
562 } 665 }
563 } 666 }
@@ -565,9 +668,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
565 { 668 {
566 if (!ResolveUserUuid(scene, parcel.OwnerID)) 669 if (!ResolveUserUuid(scene, parcel.OwnerID))
567 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; 670 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
568
569 if (!ResolveGroupUuid(parcel.GroupID))
570 parcel.GroupID = UUID.Zero;
571 } 671 }
572 672
573 List<LandAccessEntry> accessList = new List<LandAccessEntry>(); 673 List<LandAccessEntry> accessList = new List<LandAccessEntry>();
@@ -604,13 +704,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
604 /// <returns></returns> 704 /// <returns></returns>
605 private bool ResolveUserUuid(Scene scene, UUID uuid) 705 private bool ResolveUserUuid(Scene scene, UUID uuid)
606 { 706 {
607 if (!m_validUserUuids.ContainsKey(uuid)) 707 lock (m_validUserUuids)
608 { 708 {
609 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid); 709 if (!m_validUserUuids.ContainsKey(uuid))
610 m_validUserUuids.Add(uuid, account != null); 710 {
611 } 711 // Note: we call GetUserAccount() inside the lock because this UserID is likely
712 // to occur many times, and we only want to query the users service once.
713 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid);
714 m_validUserUuids.Add(uuid, account != null);
715 }
612 716
613 return m_validUserUuids[uuid]; 717 return m_validUserUuids[uuid];
718 }
614 } 719 }
615 720
616 /// <summary> 721 /// <summary>
@@ -620,22 +725,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver
620 /// <returns></returns> 725 /// <returns></returns>
621 private bool ResolveGroupUuid(UUID uuid) 726 private bool ResolveGroupUuid(UUID uuid)
622 { 727 {
623 if (uuid == UUID.Zero) 728 lock (m_validGroupUuids)
624 return true; // this means the object has no group
625
626 if (!m_validGroupUuids.ContainsKey(uuid))
627 { 729 {
628 bool exists; 730 if (!m_validGroupUuids.ContainsKey(uuid))
629 731 {
630 if (m_groupsModule == null) 732 bool exists;
631 exists = false; 733 if (m_groupsModule == null)
632 else 734 {
633 exists = (m_groupsModule.GetGroupRecord(uuid) != null); 735 exists = false;
736 }
737 else
738 {
739 // Note: we call GetGroupRecord() inside the lock because this GroupID is likely
740 // to occur many times, and we only want to query the groups service once.
741 exists = (m_groupsModule.GetGroupRecord(uuid) != null);
742 }
743 m_validGroupUuids.Add(uuid, exists);
744 }
634 745
635 m_validGroupUuids.Add(uuid, exists); 746 return m_validGroupUuids[uuid];
636 } 747 }
637
638 return m_validGroupUuids[uuid];
639 } 748 }
640 749
641 /// Load an asset 750 /// Load an asset
@@ -672,7 +781,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver
672 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; 781 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
673 782
674 if (assetType == (sbyte)AssetType.Unknown) 783 if (assetType == (sbyte)AssetType.Unknown)
784 {
675 m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); 785 m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid);
786 }
787 else if (assetType == (sbyte)AssetType.Object)
788 {
789 data = SceneObjectSerializer.ModifySerializedObject(UUID.Parse(uuid), data,
790 sog =>
791 {
792 ModifySceneObject(m_rootScene, sog);
793 return true;
794 });
795
796 if (data == null)
797 return false;
798 }
676 799
677 //m_log.DebugFormat("[ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); 800 //m_log.DebugFormat("[ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType);
678 801
@@ -796,9 +919,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
796 { 919 {
797 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); 920 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
798 921
799 MemoryStream ms = new MemoryStream(data); 922 using (MemoryStream ms = new MemoryStream(data))
800 terrainModule.LoadFromStream(terrainPath, ms); 923 {
801 ms.Close(); 924 if (m_displacement != Vector3.Zero || m_rotation != 0f)
925 {
926 Vector2 rotationCenter = new Vector2(m_rotationCenter.X, m_rotationCenter.Y);
927 terrainModule.LoadFromStream(terrainPath, m_displacement, m_rotation, rotationCenter, ms);
928 }
929 else
930 {
931 terrainModule.LoadFromStream(terrainPath, ms);
932 }
933 }
802 934
803 m_log.DebugFormat("[ARCHIVER]: Restored terrain {0}", terrainPath); 935 m_log.DebugFormat("[ARCHIVER]: Restored terrain {0}", terrainPath);
804 936
@@ -887,4 +1019,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver
887 return dearchivedScenes; 1019 return dearchivedScenes;
888 } 1020 }
889 } 1021 }
890} \ No newline at end of file 1022}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
index 7bdd65c..cb2c7f1 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -36,6 +36,7 @@ using System.Xml;
36using log4net; 36using log4net;
37using OpenMetaverse; 37using OpenMetaverse;
38using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Framework.Monitoring;
39using OpenSim.Framework.Serialization; 40using OpenSim.Framework.Serialization;
40using OpenSim.Region.CoreModules.World.Terrain; 41using OpenSim.Region.CoreModules.World.Terrain;
41using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
@@ -43,7 +44,9 @@ using OpenSim.Region.Framework.Scenes;
43using Ionic.Zlib; 44using Ionic.Zlib;
44using GZipStream = Ionic.Zlib.GZipStream; 45using GZipStream = Ionic.Zlib.GZipStream;
45using CompressionMode = Ionic.Zlib.CompressionMode; 46using CompressionMode = Ionic.Zlib.CompressionMode;
47using CompressionLevel = Ionic.Zlib.CompressionLevel;
46using OpenSim.Framework.Serialization.External; 48using OpenSim.Framework.Serialization.External;
49using PermissionMask = OpenSim.Framework.PermissionMask;
47 50
48namespace OpenSim.Region.CoreModules.World.Archiver 51namespace OpenSim.Region.CoreModules.World.Archiver
49{ 52{
@@ -78,7 +81,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
78 /// Determines which objects will be included in the archive, according to their permissions. 81 /// Determines which objects will be included in the archive, according to their permissions.
79 /// Default is null, meaning no permission checks. 82 /// Default is null, meaning no permission checks.
80 /// </summary> 83 /// </summary>
81 public string CheckPermissions { get; set; } 84 public string FilterContent { get; set; }
82 85
83 protected Scene m_rootScene; 86 protected Scene m_rootScene;
84 protected Stream m_saveStream; 87 protected Stream m_saveStream;
@@ -129,7 +132,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
129 132
130 MultiRegionFormat = false; 133 MultiRegionFormat = false;
131 SaveAssets = true; 134 SaveAssets = true;
132 CheckPermissions = null; 135 FilterContent = null;
133 } 136 }
134 137
135 /// <summary> 138 /// <summary>
@@ -148,7 +151,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
148 151
149 Object temp; 152 Object temp;
150 if (options.TryGetValue("checkPermissions", out temp)) 153 if (options.TryGetValue("checkPermissions", out temp))
151 CheckPermissions = (string)temp; 154 FilterContent = (string)temp;
152 155
153 156
154 // Find the regions to archive 157 // Find the regions to archive
@@ -177,7 +180,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
177 180
178 // Archive the regions 181 // Archive the regions
179 182
180 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); 183 Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>();
181 184
182 scenesGroup.ForEachScene(delegate(Scene scene) 185 scenesGroup.ForEachScene(delegate(Scene scene)
183 { 186 {
@@ -198,7 +201,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
198 m_rootScene.AssetService, m_rootScene.UserAccountService, 201 m_rootScene.AssetService, m_rootScene.UserAccountService,
199 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); 202 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets);
200 203
201 Util.FireAndForget(o => ar.Execute()); 204 WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request");
202 205
203 // CloseArchive() will be called from ReceivedAllAssets() 206 // CloseArchive() will be called from ReceivedAllAssets()
204 } 207 }
@@ -215,9 +218,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
215 } 218 }
216 } 219 }
217 220
218 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids) 221 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids)
219 { 222 {
220 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); 223 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name);
221 224
222 EntityBase[] entities = scene.GetEntities(); 225 EntityBase[] entities = scene.GetEntities();
223 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 226 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
@@ -236,7 +239,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
236 239
237 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) 240 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
238 { 241 {
239 if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, CheckPermissions, permissionsModule)) 242 if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, FilterContent, permissionsModule))
240 { 243 {
241 // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR. 244 // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
242 ++numObjectsSkippedPermissions; 245 ++numObjectsSkippedPermissions;
@@ -251,13 +254,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
251 254
252 if (SaveAssets) 255 if (SaveAssets)
253 { 256 {
254 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService); 257 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids);
255 int prevAssets = assetUuids.Count; 258 int prevAssets = assetUuids.Count;
256 259
257 foreach (SceneObjectGroup sceneObject in sceneObjects) 260 foreach (SceneObjectGroup sceneObject in sceneObjects)
258 { 261 assetGatherer.AddForInspection(sceneObject);
259 assetGatherer.GatherAssetUuids(sceneObject, assetUuids); 262
260 } 263 assetGatherer.GatherAll();
261 264
262 m_log.DebugFormat( 265 m_log.DebugFormat(
263 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", 266 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
@@ -275,16 +278,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
275 RegionSettings regionSettings = scene.RegionInfo.RegionSettings; 278 RegionSettings regionSettings = scene.RegionInfo.RegionSettings;
276 279
277 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) 280 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
278 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture; 281 assetUuids[regionSettings.TerrainTexture1] = (sbyte)AssetType.Texture;
279 282
280 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) 283 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
281 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture; 284 assetUuids[regionSettings.TerrainTexture2] = (sbyte)AssetType.Texture;
282 285
283 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) 286 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
284 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture; 287 assetUuids[regionSettings.TerrainTexture3] = (sbyte)AssetType.Texture;
285 288
286 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) 289 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
287 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture; 290 assetUuids[regionSettings.TerrainTexture4] = (sbyte)AssetType.Texture;
288 291
289 Save(scene, sceneObjects, regionDir); 292 Save(scene, sceneObjects, regionDir);
290 } 293 }
@@ -294,12 +297,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
294 /// </summary> 297 /// </summary>
295 /// <param name="user">The user</param> 298 /// <param name="user">The user</param>
296 /// <param name="objGroup">The object group</param> 299 /// <param name="objGroup">The object group</param>
297 /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param> 300 /// <param name="filterContent">Which permissions to check: "C" = Copy, "T" = Transfer</param>
298 /// <param name="permissionsModule">The scene's permissions module</param> 301 /// <param name="permissionsModule">The scene's permissions module</param>
299 /// <returns>Whether the user is allowed to export the object to an OAR</returns> 302 /// <returns>Whether the user is allowed to export the object to an OAR</returns>
300 private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions, IPermissionsModule permissionsModule) 303 private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string filterContent, IPermissionsModule permissionsModule)
301 { 304 {
302 if (checkPermissions == null) 305 if (filterContent == null)
303 return true; 306 return true;
304 307
305 if (permissionsModule == null) 308 if (permissionsModule == null)
@@ -341,9 +344,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
341 canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0; 344 canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0;
342 345
343 bool partPermitted = true; 346 bool partPermitted = true;
344 if (checkPermissions.Contains("C") && !canCopy) 347 if (filterContent.Contains("C") && !canCopy)
345 partPermitted = false; 348 partPermitted = false;
346 if (checkPermissions.Contains("T") && !canTransfer) 349 if (filterContent.Contains("T") && !canTransfer)
347 partPermitted = false; 350 partPermitted = false;
348 351
349 // If the user is the Creator of the object then it can always be included in the OAR 352 // If the user is the Creator of the object then it can always be included in the OAR
@@ -532,7 +535,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
532 if (isMegaregion) 535 if (isMegaregion)
533 size = rcMod.GetSizeOfMegaregion(scene.RegionInfo.RegionID); 536 size = rcMod.GetSizeOfMegaregion(scene.RegionInfo.RegionID);
534 else 537 else
535 size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize); 538 size = new Vector2((float)scene.RegionInfo.RegionSizeX, (float)scene.RegionInfo.RegionSizeY);
536 539
537 xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); 540 xtw.WriteElementString("is_megaregion", isMegaregion.ToString());
538 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); 541 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
@@ -568,10 +571,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
568 string terrainPath = String.Format("{0}{1}{2}.r32", 571 string terrainPath = String.Format("{0}{1}{2}.r32",
569 regionDir, ArchiveConstants.TERRAINS_PATH, scene.RegionInfo.RegionName); 572 regionDir, ArchiveConstants.TERRAINS_PATH, scene.RegionInfo.RegionName);
570 573
571 MemoryStream ms = new MemoryStream(); 574 using (MemoryStream ms = new MemoryStream())
572 scene.RequestModuleInterface<ITerrainModule>().SaveToStream(terrainPath, ms); 575 {
573 m_archiveWriter.WriteFile(terrainPath, ms.ToArray()); 576 scene.RequestModuleInterface<ITerrainModule>().SaveToStream(terrainPath, ms);
574 ms.Close(); 577 m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
578 }
575 579
576 m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive."); 580 m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
577 581
@@ -587,19 +591,29 @@ namespace OpenSim.Region.CoreModules.World.Archiver
587 } 591 }
588 } 592 }
589 593
590 protected void ReceivedAllAssets( 594 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut)
591 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
592 { 595 {
593 foreach (UUID uuid in assetsNotFoundUuids) 596 string errorMessage;
597
598 if (timedOut)
594 { 599 {
595 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid); 600 errorMessage = "Loading assets timed out";
596 } 601 }
602 else
603 {
604 foreach (UUID uuid in assetsNotFoundUuids)
605 {
606 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid);
607 }
597 608
598 // m_log.InfoFormat( 609 // m_log.InfoFormat(
599 // "[ARCHIVER]: Received {0} of {1} assets requested", 610 // "[ARCHIVER]: Received {0} of {1} assets requested",
600 // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count); 611 // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
601 612
602 CloseArchive(String.Empty); 613 errorMessage = String.Empty;
614 }
615
616 CloseArchive(errorMessage);
603 } 617 }
604 618
605 /// <summary> 619 /// <summary>
@@ -626,4 +640,4 @@ namespace OpenSim.Region.CoreModules.World.Archiver
626 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage); 640 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage);
627 } 641 }
628 } 642 }
629} \ No newline at end of file 643}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index 1be6386..6a09caf 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -33,11 +33,14 @@ using log4net;
33using NDesk.Options; 33using NDesk.Options;
34using Nini.Config; 34using Nini.Config;
35using Mono.Addins; 35using Mono.Addins;
36
36using OpenSim.Framework; 37using OpenSim.Framework;
37using OpenSim.Framework.Console; 38using OpenSim.Framework.Console;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
40 41
42using OpenMetaverse;
43
41namespace OpenSim.Region.CoreModules.World.Archiver 44namespace OpenSim.Region.CoreModules.World.Archiver
42{ 45{
43 /// <summary> 46 /// <summary>
@@ -101,9 +104,62 @@ namespace OpenSim.Region.CoreModules.World.Archiver
101 { 104 {
102 bool mergeOar = false; 105 bool mergeOar = false;
103 bool skipAssets = false; 106 bool skipAssets = false;
107 bool forceTerrain = false;
108 bool forceParcels = false;
109 bool noObjects = false;
110 Vector3 displacement = new Vector3(0f, 0f, 0f);
111 String defaultUser = "";
112 float rotation = 0f;
113 Vector3 rotationCenter = new Vector3(Constants.RegionSize / 2f, Constants.RegionSize / 2f, 0);
104 114
105 OptionSet options = new OptionSet().Add("m|merge", delegate (string v) { mergeOar = v != null; }); 115 OptionSet options = new OptionSet();
106 options.Add("s|skip-assets", delegate (string v) { skipAssets = v != null; }); 116 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("force-terrain", delegate (string v) { forceTerrain = (v != null); });
119 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("forceparcels", delegate (string v) { forceParcels = (v != null); }); // downward compatibility
122 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("displacement=", delegate (string v) {
125 try
126 {
127 displacement = v == null ? Vector3.Zero : Vector3.Parse(v);
128 }
129 catch
130 {
131 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing displacement");
132 m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as vector3: --displacement \"<128,128,0>\"");
133 return;
134 }
135 });
136 options.Add("rotation=", delegate(string v)
137 {
138 try
139 {
140 rotation = v == null ? 0f : float.Parse(v);
141 }
142 catch
143 {
144 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing rotation");
145 m_log.ErrorFormat("[ARCHIVER MODULE] Must be an angle in degrees between -360 and +360: --rotation 45");
146 return;
147 }
148 // Convert to radians for internals
149 rotation = Util.Clamp<float>(rotation, -359f, 359f) / 180f * (float)Math.PI;
150 });
151 options.Add("rotation-center=", delegate (string v) {
152 try
153 {
154 rotationCenter = v == null ? Vector3.Zero : Vector3.Parse(v);
155 }
156 catch
157 {
158 m_log.ErrorFormat("[ARCHIVER MODULE] failure parsing rotation displacement");
159 m_log.ErrorFormat("[ARCHIVER MODULE] Must be represented as vector3: --rotation-center \"<128,128,0>\"");
160 return;
161 }
162 });
107 163
108 // Send a message to the region ready module 164 // Send a message to the region ready module
109 /* bluewall* Disable this for the time being 165 /* bluewall* Disable this for the time being
@@ -122,13 +178,44 @@ namespace OpenSim.Region.CoreModules.World.Archiver
122// foreach (string param in mainParams) 178// foreach (string param in mainParams)
123// m_log.DebugFormat("GOT PARAM [{0}]", param); 179// m_log.DebugFormat("GOT PARAM [{0}]", param);
124 180
181 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
182 if (mergeOar) archiveOptions.Add("merge", null);
183 if (skipAssets) archiveOptions.Add("skipAssets", null);
184 if (forceTerrain) archiveOptions.Add("force-terrain", null);
185 if (forceParcels) archiveOptions.Add("force-parcels", null);
186 if (noObjects) archiveOptions.Add("no-objects", null);
187 if (defaultUser != "")
188 {
189 UUID defaultUserUUID = UUID.Zero;
190 try
191 {
192 defaultUserUUID = Scene.UserManagementModule.GetUserIdByName(defaultUser);
193 }
194 catch
195 {
196 m_log.ErrorFormat("[ARCHIVER MODULE] default user must be in format \"First Last\"", defaultUser);
197 }
198 if (defaultUserUUID == UUID.Zero)
199 {
200 m_log.ErrorFormat("[ARCHIVER MODULE] cannot find specified default user {0}", defaultUser);
201 return;
202 }
203 else
204 {
205 archiveOptions.Add("default-user", defaultUserUUID);
206 }
207 }
208 archiveOptions.Add("displacement", displacement);
209 archiveOptions.Add("rotation", rotation);
210 archiveOptions.Add("rotation-center", rotationCenter);
211
125 if (mainParams.Count > 2) 212 if (mainParams.Count > 2)
126 { 213 {
127 DearchiveRegion(mainParams[2], mergeOar, skipAssets, Guid.Empty); 214 DearchiveRegion(mainParams[2], Guid.Empty, archiveOptions);
128 } 215 }
129 else 216 else
130 { 217 {
131 DearchiveRegion(DEFAULT_OAR_BACKUP_FILENAME, mergeOar, skipAssets, Guid.Empty); 218 DearchiveRegion(DEFAULT_OAR_BACKUP_FILENAME, Guid.Empty, archiveOptions);
132 } 219 }
133 } 220 }
134 221
@@ -198,25 +285,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
198 285
199 public void DearchiveRegion(string loadPath) 286 public void DearchiveRegion(string loadPath)
200 { 287 {
201 DearchiveRegion(loadPath, false, false, Guid.Empty); 288 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
289 DearchiveRegion(loadPath, Guid.Empty, archiveOptions);
202 } 290 }
203 291
204 public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) 292 public void DearchiveRegion(string loadPath, Guid requestId, Dictionary<string,object> options)
205 { 293 {
206 m_log.InfoFormat( 294 m_log.InfoFormat(
207 "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath); 295 "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath);
208 296
209 new ArchiveReadRequest(Scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); 297 new ArchiveReadRequest(Scene, loadPath, requestId, options).DearchiveRegion();
210 } 298 }
211 299
212 public void DearchiveRegion(Stream loadStream) 300 public void DearchiveRegion(Stream loadStream)
213 { 301 {
214 DearchiveRegion(loadStream, false, false, Guid.Empty); 302 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
303 DearchiveRegion(loadStream, Guid.Empty, archiveOptions);
215 } 304 }
216 305
217 public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) 306 public void DearchiveRegion(Stream loadStream, Guid requestId, Dictionary<string, object> options)
218 { 307 {
219 new ArchiveReadRequest(Scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); 308 new ArchiveReadRequest(Scene, loadStream, requestId, options).DearchiveRegion();
220 } 309 }
221 } 310 }
222} 311}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
index 95d109c..a8eae56 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs
@@ -145,17 +145,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
145 m_assetsWritten++; 145 m_assetsWritten++;
146 146
147 //m_log.DebugFormat("[ARCHIVER]: Added asset {0}", m_assetsWritten); 147 //m_log.DebugFormat("[ARCHIVER]: Added asset {0}", m_assetsWritten);
148 148
149 if (m_assetsWritten % LOG_ASSET_LOAD_NOTIFICATION_INTERVAL == 0) 149 if (m_assetsWritten % LOG_ASSET_LOAD_NOTIFICATION_INTERVAL == 0)
150 m_log.InfoFormat("[ARCHIVER]: Added {0} assets to archive", m_assetsWritten); 150 m_log.InfoFormat("[ARCHIVER]: Added {0} assets to archive", m_assetsWritten);
151 } 151 }
152 152
153 /// <summary>
154 /// Only call this if you need to force a close on the underlying writer.
155 /// </summary>
156 public void ForceClose()
157 {
158 m_archiveWriter.Close();
159 }
160 } 153 }
161} 154}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 103eb47..db66c83 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -33,6 +33,7 @@ using System.Timers;
33using log4net; 33using log4net;
34using OpenMetaverse; 34using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Monitoring;
36using OpenSim.Framework.Serialization; 37using OpenSim.Framework.Serialization;
37using OpenSim.Framework.Serialization.External; 38using OpenSim.Framework.Serialization.External;
38using OpenSim.Services.Interfaces; 39using OpenSim.Services.Interfaces;
@@ -50,7 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
50 /// Method called when all the necessary assets for an archive request have been received. 51 /// Method called when all the necessary assets for an archive request have been received.
51 /// </summary> 52 /// </summary>
52 public delegate void AssetsRequestCallback( 53 public delegate void AssetsRequestCallback(
53 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids); 54 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids, bool timedOut);
54 55
55 enum RequestState 56 enum RequestState
56 { 57 {
@@ -81,7 +82,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
81 /// <value> 82 /// <value>
82 /// uuids to request 83 /// uuids to request
83 /// </value> 84 /// </value>
84 protected IDictionary<UUID, AssetType> m_uuids; 85 protected IDictionary<UUID, sbyte> m_uuids;
85 86
86 /// <value> 87 /// <value>
87 /// Callback used when all the assets requested have been received. 88 /// Callback used when all the assets requested have been received.
@@ -115,7 +116,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
115 protected Dictionary<string, object> m_options; 116 protected Dictionary<string, object> m_options;
116 117
117 protected internal AssetsRequest( 118 protected internal AssetsRequest(
118 AssetsArchiver assetsArchiver, IDictionary<UUID, AssetType> uuids, 119 AssetsArchiver assetsArchiver, IDictionary<UUID, sbyte> uuids,
119 IAssetService assetService, IUserAccountService userService, 120 IAssetService assetService, IUserAccountService userService,
120 UUID scope, Dictionary<string, object> options, 121 UUID scope, Dictionary<string, object> options,
121 AssetsRequestCallback assetsRequestCallback) 122 AssetsRequestCallback assetsRequestCallback)
@@ -143,19 +144,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver
143 m_requestState = RequestState.Running; 144 m_requestState = RequestState.Running;
144 145
145 m_log.DebugFormat("[ARCHIVER]: AssetsRequest executed looking for {0} possible assets", m_repliesRequired); 146 m_log.DebugFormat("[ARCHIVER]: AssetsRequest executed looking for {0} possible assets", m_repliesRequired);
146 147
147 // We can stop here if there are no assets to fetch 148 // We can stop here if there are no assets to fetch
148 if (m_repliesRequired == 0) 149 if (m_repliesRequired == 0)
149 { 150 {
150 m_requestState = RequestState.Completed; 151 m_requestState = RequestState.Completed;
151 PerformAssetsRequestCallback(null); 152 PerformAssetsRequestCallback(false);
152 return; 153 return;
153 } 154 }
154 155
155 m_requestCallbackTimer.Enabled = true; 156 m_requestCallbackTimer.Enabled = true;
156 157
157 foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids) 158 foreach (KeyValuePair<UUID, sbyte> kvp in m_uuids)
158 { 159 {
160// m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key);
161
159// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); 162// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
160 AssetBase asset = m_assetService.Get(kvp.Key.ToString()); 163 AssetBase asset = m_assetService.Get(kvp.Key.ToString());
161 PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset); 164 PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
@@ -164,7 +167,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
164 167
165 protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) 168 protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
166 { 169 {
167 bool close = true; 170 bool timedOut = true;
168 171
169 try 172 try
170 { 173 {
@@ -174,7 +177,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
174 // the final request came in (assuming that such a thing is possible) 177 // the final request came in (assuming that such a thing is possible)
175 if (m_requestState == RequestState.Completed) 178 if (m_requestState == RequestState.Completed)
176 { 179 {
177 close = false; 180 timedOut = false;
178 return; 181 return;
179 } 182 }
180 183
@@ -223,8 +226,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
223 } 226 }
224 finally 227 finally
225 { 228 {
226 if (close) 229 if (timedOut)
227 m_assetsArchiver.ForceClose(); 230 WorkManager.RunInThread(PerformAssetsRequestCallback, true, "Archive Assets Request Callback");
228 } 231 }
229 } 232 }
230 233
@@ -233,9 +236,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
233 // Check for broken asset types and fix them with the AssetType gleaned by UuidGatherer 236 // Check for broken asset types and fix them with the AssetType gleaned by UuidGatherer
234 if (fetchedAsset != null && fetchedAsset.Type == (sbyte)AssetType.Unknown) 237 if (fetchedAsset != null && fetchedAsset.Type == (sbyte)AssetType.Unknown)
235 { 238 {
236 AssetType type = (AssetType)assetType; 239 m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", fetchedAsset.ID, SLUtil.AssetTypeFromCode((sbyte)assetType));
237 m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", fetchedAsset.ID, type); 240 fetchedAsset.Type = (sbyte)assetType;
238 fetchedAsset.Type = (sbyte)type;
239 } 241 }
240 242
241 AssetRequestCallback(fetchedAssetID, this, fetchedAsset); 243 AssetRequestCallback(fetchedAssetID, this, fetchedAsset);
@@ -294,7 +296,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
294 296
295 // We want to stop using the asset cache thread asap 297 // We want to stop using the asset cache thread asap
296 // as we now need to do the work of producing the rest of the archive 298 // as we now need to do the work of producing the rest of the archive
297 Util.FireAndForget(PerformAssetsRequestCallback); 299 WorkManager.RunInThread(PerformAssetsRequestCallback, false, "Archive Assets Request Callback");
298 } 300 }
299 else 301 else
300 { 302 {
@@ -315,9 +317,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
315 { 317 {
316 Culture.SetCurrentCulture(); 318 Culture.SetCurrentCulture();
317 319
320 Boolean timedOut = (Boolean)o;
321
318 try 322 try
319 { 323 {
320 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids); 324 m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids, timedOut);
321 } 325 }
322 catch (Exception e) 326 catch (Exception e)
323 { 327 {
@@ -331,7 +335,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
331 if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home")) 335 if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home"))
332 { 336 {
333 //m_log.DebugFormat("[ARCHIVER]: Rewriting object data for {0}", asset.ID); 337 //m_log.DebugFormat("[ARCHIVER]: Rewriting object data for {0}", asset.ID);
334 string xml = ExternalRepresentationUtils.RewriteSOP(Utils.BytesToString(asset.Data), m_options["home"].ToString(), m_userAccountService, m_scopeID); 338 string xml = ExternalRepresentationUtils.RewriteSOP(Utils.BytesToString(asset.Data), string.Empty, m_options["home"].ToString(), m_userAccountService, m_scopeID);
335 asset.Data = Utils.StringToBytes(xml); 339 asset.Data = Utils.StringToBytes(xml);
336 } 340 }
337 return asset; 341 return asset;
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index eec1cec..9f197f5 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -45,7 +45,6 @@ using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.Framework.Scenes.Serialization; 45using OpenSim.Region.Framework.Scenes.Serialization;
46using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; 46using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock;
49using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants; 48using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants;
50using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; 49using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader;
51using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; 50using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter;
@@ -224,8 +223,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
224 223
225 byte[] data = tar.ReadEntry(out filePath, out tarEntryType); 224 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
226 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 225 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
227 226
228 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); 227 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
228 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions);
229 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo()); 229 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
230 230
231 Assert.That(arr.ControlFileLoaded, Is.True); 231 Assert.That(arr.ControlFileLoaded, Is.True);
@@ -308,8 +308,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
308 308
309 byte[] data = tar.ReadEntry(out filePath, out tarEntryType); 309 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
310 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 310 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
311 311
312 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); 312 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
313 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions);
313 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo()); 314 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
314 315
315 Assert.That(arr.ControlFileLoaded, Is.True); 316 Assert.That(arr.ControlFileLoaded, Is.True);
@@ -577,13 +578,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
577 ArchiveConstants.CONTROL_FILE_PATH, 578 ArchiveConstants.CONTROL_FILE_PATH,
578 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup())); 579 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
579 580
580 LandObject lo = new LandObject(groupID, true, null); 581 LandObject lo = new LandObject(groupID, true, m_scene);
581 lo.SetLandBitmap(lo.BasicFullRegionLandBitmap()); 582 lo.SetLandBitmap(lo.BasicFullRegionLandBitmap());
582 LandData ld = lo.LandData; 583 LandData ld = lo.LandData;
583 ld.GlobalID = landID; 584 ld.GlobalID = landID;
584 585
585 string ldPath = ArchiveConstants.CreateOarLandDataPath(ld); 586 string ldPath = ArchiveConstants.CreateOarLandDataPath(ld);
586 tar.WriteFile(ldPath, LandDataSerializer.Serialize(ld, null)); 587 Dictionary<string, object> options = new Dictionary<string, object>();
588 tar.WriteFile(ldPath, LandDataSerializer.Serialize(ld, options));
587 tar.Close(); 589 tar.Close();
588 590
589 oarStream = new MemoryStream(oarStream.ToArray()); 591 oarStream = new MemoryStream(oarStream.ToArray());
@@ -752,7 +754,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
752 byte[] archive = archiveWriteStream.ToArray(); 754 byte[] archive = archiveWriteStream.ToArray();
753 MemoryStream archiveReadStream = new MemoryStream(archive); 755 MemoryStream archiveReadStream = new MemoryStream(archive);
754 756
755 m_archiverModule.DearchiveRegion(archiveReadStream, true, false, Guid.Empty); 757 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
758 archiveOptions.Add("merge", null);
759 m_archiverModule.DearchiveRegion(archiveReadStream, Guid.Empty, archiveOptions);
756 760
757 SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name); 761 SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name);
758 Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge"); 762 Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
@@ -860,7 +864,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
860 byte[] data = tar.ReadEntry(out filePath, out tarEntryType); 864 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
861 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 865 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
862 866
863 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); 867 Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
868 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, Guid.Empty, archiveOptions);
864 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo()); 869 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
865 870
866 Assert.That(arr.ControlFileLoaded, Is.True); 871 Assert.That(arr.ControlFileLoaded, Is.True);