aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs314
1 files changed, 223 insertions, 91 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}