diff options
author | Oren Hurvitz | 2012-07-24 19:48:08 +0300 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-09-14 20:25:03 +0100 |
commit | ce468215d576cc301a261d85bee9baa68a246ce6 (patch) | |
tree | ad2c6d7e3156bf8dab596f2772cc712d4f96c698 /OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |
parent | Don't store the unnecessary VERSIONMIN. VERSIONMAX, METHOD or UserID (present... (diff) | |
download | opensim-SC_OLD-ce468215d576cc301a261d85bee9baa68a246ce6.zip opensim-SC_OLD-ce468215d576cc301a261d85bee9baa68a246ce6.tar.gz opensim-SC_OLD-ce468215d576cc301a261d85bee9baa68a246ce6.tar.bz2 opensim-SC_OLD-ce468215d576cc301a261d85bee9baa68a246ce6.tar.xz |
Support multi-region OAR files
Merged ArchiveWriteRequestPreparation.cs and ArchiveWriteRequestExecution.cs. This simplifies the code, and it's faster to write each scene to the archive as it's found rather than all at once at the end.
Diffstat (limited to 'OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | 365 |
1 files changed, 282 insertions, 83 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 433166d..a6923ef 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Interfaces; | |||
43 | using OpenSim.Region.Framework.Scenes; | 43 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Region.Framework.Scenes.Serialization; | 44 | using OpenSim.Region.Framework.Scenes.Serialization; |
45 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
46 | using System.Threading; | ||
46 | 47 | ||
47 | namespace OpenSim.Region.CoreModules.World.Archiver | 48 | namespace OpenSim.Region.CoreModules.World.Archiver |
48 | { | 49 | { |
@@ -52,7 +53,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
52 | public class ArchiveReadRequest | 53 | public class ArchiveReadRequest |
53 | { | 54 | { |
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 55 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
56 | |||
57 | /// <summary> | ||
58 | /// Contains data used while dearchiving a single scene. | ||
59 | /// </summary> | ||
60 | private class DearchiveContext | ||
61 | { | ||
62 | public Scene Scene { get; set; } | ||
63 | |||
64 | public List<string> SerialisedSceneObjects { get; set; } | ||
65 | |||
66 | public List<string> SerialisedParcels { get; set; } | ||
67 | |||
68 | public List<SceneObjectGroup> SceneObjects { get; set; } | ||
69 | |||
70 | public DearchiveContext(Scene scene) | ||
71 | { | ||
72 | Scene = scene; | ||
73 | SerialisedSceneObjects = new List<string>(); | ||
74 | SerialisedParcels = new List<string>(); | ||
75 | SceneObjects = new List<SceneObjectGroup>(); | ||
76 | } | ||
77 | } | ||
55 | 78 | ||
79 | |||
56 | /// <summary> | 80 | /// <summary> |
57 | /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version | 81 | /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version |
58 | /// bumps here should be compatible. | 82 | /// bumps here should be compatible. |
@@ -62,9 +86,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
62 | /// <summary> | 86 | /// <summary> |
63 | /// Has the control file been loaded for this archive? | 87 | /// Has the control file been loaded for this archive? |
64 | /// </summary> | 88 | /// </summary> |
65 | public bool ControlFileLoaded { get; private set; } | 89 | public bool ControlFileLoaded { get; private set; } |
66 | 90 | ||
67 | protected Scene m_scene; | 91 | protected string m_loadPath; |
92 | protected Scene m_rootScene; | ||
68 | protected Stream m_loadStream; | 93 | protected Stream m_loadStream; |
69 | protected Guid m_requestId; | 94 | protected Guid m_requestId; |
70 | protected string m_errorMessage; | 95 | protected string m_errorMessage; |
@@ -91,7 +116,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
91 | { | 116 | { |
92 | if (m_UserMan == null) | 117 | if (m_UserMan == null) |
93 | { | 118 | { |
94 | m_UserMan = m_scene.RequestModuleInterface<IUserManagement>(); | 119 | m_UserMan = m_rootScene.RequestModuleInterface<IUserManagement>(); |
95 | } | 120 | } |
96 | return m_UserMan; | 121 | return m_UserMan; |
97 | } | 122 | } |
@@ -104,10 +129,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
104 | 129 | ||
105 | private IGroupsModule m_groupsModule; | 130 | private IGroupsModule m_groupsModule; |
106 | 131 | ||
132 | private IAssetService m_assetService = null; | ||
133 | |||
134 | |||
107 | public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) | 135 | public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) |
108 | { | 136 | { |
109 | m_scene = scene; | 137 | m_rootScene = scene; |
110 | 138 | ||
139 | m_loadPath = loadPath; | ||
111 | try | 140 | try |
112 | { | 141 | { |
113 | m_loadStream = new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress); | 142 | m_loadStream = new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress); |
@@ -128,12 +157,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
128 | // Zero can never be a valid user id | 157 | // Zero can never be a valid user id |
129 | m_validUserUuids[UUID.Zero] = false; | 158 | m_validUserUuids[UUID.Zero] = false; |
130 | 159 | ||
131 | m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | 160 | m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>(); |
161 | m_assetService = m_rootScene.AssetService; | ||
132 | } | 162 | } |
133 | 163 | ||
134 | public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) | 164 | public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) |
135 | { | 165 | { |
136 | m_scene = scene; | 166 | m_rootScene = scene; |
167 | m_loadPath = null; | ||
137 | m_loadStream = loadStream; | 168 | m_loadStream = loadStream; |
138 | m_merge = merge; | 169 | m_merge = merge; |
139 | m_skipAssets = skipAssets; | 170 | m_skipAssets = skipAssets; |
@@ -142,7 +173,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
142 | // Zero can never be a valid user id | 173 | // Zero can never be a valid user id |
143 | m_validUserUuids[UUID.Zero] = false; | 174 | m_validUserUuids[UUID.Zero] = false; |
144 | 175 | ||
145 | m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | 176 | m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>(); |
177 | m_assetService = m_rootScene.AssetService; | ||
146 | } | 178 | } |
147 | 179 | ||
148 | /// <summary> | 180 | /// <summary> |
@@ -150,25 +182,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
150 | /// </summary> | 182 | /// </summary> |
151 | public void DearchiveRegion() | 183 | public void DearchiveRegion() |
152 | { | 184 | { |
153 | // The same code can handle dearchiving 0.1 and 0.2 OpenSim Archive versions | ||
154 | DearchiveRegion0DotStar(); | ||
155 | } | ||
156 | |||
157 | private void DearchiveRegion0DotStar() | ||
158 | { | ||
159 | int successfulAssetRestores = 0; | 185 | int successfulAssetRestores = 0; |
160 | int failedAssetRestores = 0; | 186 | int failedAssetRestores = 0; |
161 | List<string> serialisedSceneObjects = new List<string>(); | ||
162 | List<string> serialisedParcels = new List<string>(); | ||
163 | string filePath = "NONE"; | ||
164 | 187 | ||
165 | TarArchiveReader archive = new TarArchiveReader(m_loadStream); | 188 | DearchiveScenesInfo dearchivedScenes; |
189 | |||
190 | // We dearchive all the scenes at once, because the files in the TAR archive might be mixed. | ||
191 | // Therefore, we have to keep track of the dearchive context of all the scenes. | ||
192 | Dictionary<UUID, DearchiveContext> sceneContexts = new Dictionary<UUID, DearchiveContext>(); | ||
193 | |||
194 | string fullPath = "NONE"; | ||
195 | TarArchiveReader archive = null; | ||
166 | byte[] data; | 196 | byte[] data; |
167 | TarArchiveReader.TarEntryType entryType; | 197 | TarArchiveReader.TarEntryType entryType; |
168 | 198 | ||
169 | try | 199 | try |
170 | { | 200 | { |
171 | while ((data = archive.ReadEntry(out filePath, out entryType)) != null) | 201 | FindAndLoadControlFile(out archive, out dearchivedScenes); |
202 | |||
203 | while ((data = archive.ReadEntry(out fullPath, out entryType)) != null) | ||
172 | { | 204 | { |
173 | //m_log.DebugFormat( | 205 | //m_log.DebugFormat( |
174 | // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length); | 206 | // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length); |
@@ -176,9 +208,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
176 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) | 208 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) |
177 | continue; | 209 | continue; |
178 | 210 | ||
211 | |||
212 | // Find the scene that this file belongs to | ||
213 | |||
214 | Scene scene; | ||
215 | string filePath; | ||
216 | if (!dearchivedScenes.GetRegionFromPath(fullPath, out scene, out filePath)) | ||
217 | continue; // this file belongs to a region that we're not loading | ||
218 | |||
219 | DearchiveContext sceneContext = null; | ||
220 | if (scene != null) | ||
221 | { | ||
222 | if (!sceneContexts.TryGetValue(scene.RegionInfo.RegionID, out sceneContext)) | ||
223 | { | ||
224 | sceneContext = new DearchiveContext(scene); | ||
225 | sceneContexts.Add(scene.RegionInfo.RegionID, sceneContext); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | |||
230 | // Process the file | ||
231 | |||
179 | if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) | 232 | if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) |
180 | { | 233 | { |
181 | serialisedSceneObjects.Add(Encoding.UTF8.GetString(data)); | 234 | sceneContext.SerialisedSceneObjects.Add(Encoding.UTF8.GetString(data)); |
182 | } | 235 | } |
183 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH) && !m_skipAssets) | 236 | else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH) && !m_skipAssets) |
184 | { | 237 | { |
@@ -192,19 +245,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
192 | } | 245 | } |
193 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) | 246 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) |
194 | { | 247 | { |
195 | LoadTerrain(filePath, data); | 248 | LoadTerrain(scene, filePath, data); |
196 | } | 249 | } |
197 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) | 250 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) |
198 | { | 251 | { |
199 | LoadRegionSettings(filePath, data); | 252 | LoadRegionSettings(scene, filePath, data, dearchivedScenes); |
200 | } | 253 | } |
201 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) | 254 | else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) |
202 | { | 255 | { |
203 | serialisedParcels.Add(Encoding.UTF8.GetString(data)); | 256 | sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data)); |
204 | } | 257 | } |
205 | else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) | 258 | else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) |
206 | { | 259 | { |
207 | LoadControlFile(filePath, data); | 260 | // Ignore, because we already read the control file |
208 | } | 261 | } |
209 | } | 262 | } |
210 | 263 | ||
@@ -212,15 +265,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
212 | } | 265 | } |
213 | catch (Exception e) | 266 | catch (Exception e) |
214 | { | 267 | { |
215 | m_log.ErrorFormat( | 268 | m_log.Error( |
216 | "[ARCHIVER]: Aborting load with error in archive file {0}. {1}", filePath, e); | 269 | String.Format("[ARCHIVER]: Aborting load with error in archive file {0} ", fullPath), e); |
217 | m_errorMessage += e.ToString(); | 270 | m_errorMessage += e.ToString(); |
218 | m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); | 271 | m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, new List<UUID>(), m_errorMessage); |
219 | return; | 272 | return; |
220 | } | 273 | } |
221 | finally | 274 | finally |
222 | { | 275 | { |
223 | archive.Close(); | 276 | if (archive != null) |
277 | archive.Close(); | ||
224 | } | 278 | } |
225 | 279 | ||
226 | if (!m_skipAssets) | 280 | if (!m_skipAssets) |
@@ -234,32 +288,143 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
234 | } | 288 | } |
235 | } | 289 | } |
236 | 290 | ||
237 | if (!m_merge) | 291 | foreach (DearchiveContext sceneContext in sceneContexts.Values) |
238 | { | 292 | { |
239 | m_log.Info("[ARCHIVER]: Clearing all existing scene objects"); | 293 | m_log.InfoFormat("[ARCHIVER:] Loading region {0}", sceneContext.Scene.RegionInfo.RegionName); |
240 | m_scene.DeleteAllSceneObjects(); | 294 | |
295 | if (!m_merge) | ||
296 | { | ||
297 | m_log.Info("[ARCHIVER]: Clearing all existing scene objects"); | ||
298 | sceneContext.Scene.DeleteAllSceneObjects(); | ||
299 | } | ||
300 | |||
301 | try | ||
302 | { | ||
303 | LoadParcels(sceneContext.Scene, sceneContext.SerialisedParcels); | ||
304 | LoadObjects(sceneContext.Scene, sceneContext.SerialisedSceneObjects, sceneContext.SceneObjects); | ||
305 | |||
306 | // Inform any interested parties that the region has changed. We waited until now so that all | ||
307 | // of the region's objects will be loaded when we send this notification. | ||
308 | IEstateModule estateModule = sceneContext.Scene.RequestModuleInterface<IEstateModule>(); | ||
309 | if (estateModule != null) | ||
310 | estateModule.TriggerRegionInfoChange(); | ||
311 | } | ||
312 | catch (Exception e) | ||
313 | { | ||
314 | m_log.Error("[ARCHIVER]: Error loading parcels or objects ", e); | ||
315 | m_errorMessage += e.ToString(); | ||
316 | m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, new List<UUID>(), m_errorMessage); | ||
317 | return; | ||
318 | } | ||
241 | } | 319 | } |
242 | 320 | ||
243 | LoadParcels(serialisedParcels); | 321 | // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so |
244 | LoadObjects(serialisedSceneObjects); | 322 | // 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. | ||
324 | Util.FireAndForget(delegate(object o) | ||
325 | { | ||
326 | Thread.Sleep(15000); | ||
327 | m_log.Info("Starting scripts in scene objects"); | ||
328 | |||
329 | foreach (DearchiveContext sceneContext in sceneContexts.Values) | ||
330 | { | ||
331 | foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects) | ||
332 | { | ||
333 | sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart | ||
334 | sceneObject.ResumeScripts(); | ||
335 | } | ||
336 | |||
337 | sceneContext.SceneObjects.Clear(); | ||
338 | } | ||
339 | }); | ||
245 | 340 | ||
246 | m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); | 341 | m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); |
247 | 342 | ||
248 | m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); | 343 | m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, dearchivedScenes.GetLoadedScenes(), m_errorMessage); |
344 | } | ||
345 | |||
346 | /// <summary> | ||
347 | /// Searches through the files in the archive for the control file, and reads it. | ||
348 | /// We must read the control file first, in order to know which regions are available. | ||
349 | /// </summary> | ||
350 | /// <remarks> | ||
351 | /// In most cases the control file *is* first, since that's how we create archives. However, | ||
352 | /// it's possible that someone rewrote the archive externally so we can't rely on this fact. | ||
353 | /// </remarks> | ||
354 | /// <param name="archive"></param> | ||
355 | /// <param name="dearchivedScenes"></param> | ||
356 | private void FindAndLoadControlFile(out TarArchiveReader archive, out DearchiveScenesInfo dearchivedScenes) | ||
357 | { | ||
358 | archive = new TarArchiveReader(m_loadStream); | ||
359 | dearchivedScenes = new DearchiveScenesInfo(); | ||
360 | |||
361 | string filePath; | ||
362 | byte[] data; | ||
363 | TarArchiveReader.TarEntryType entryType; | ||
364 | bool firstFile = true; | ||
365 | |||
366 | while ((data = archive.ReadEntry(out filePath, out entryType)) != null) | ||
367 | { | ||
368 | if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) | ||
369 | continue; | ||
370 | |||
371 | if (filePath == ArchiveConstants.CONTROL_FILE_PATH) | ||
372 | { | ||
373 | LoadControlFile(filePath, data, dearchivedScenes); | ||
374 | |||
375 | // Find which scenes are available in the simulator | ||
376 | ArchiveScenesGroup simulatorScenes = new ArchiveScenesGroup(); | ||
377 | SceneManager.Instance.ForEachScene(delegate(Scene scene2) | ||
378 | { | ||
379 | simulatorScenes.AddScene(scene2); | ||
380 | }); | ||
381 | simulatorScenes.CalcSceneLocations(); | ||
382 | dearchivedScenes.SetSimulatorScenes(m_rootScene, simulatorScenes); | ||
383 | |||
384 | // If the control file wasn't the first file then reset the read pointer | ||
385 | if (!firstFile) | ||
386 | { | ||
387 | m_log.Warn("Control file wasn't the first file in the archive"); | ||
388 | if (m_loadStream.CanSeek) | ||
389 | { | ||
390 | m_loadStream.Seek(0, SeekOrigin.Begin); | ||
391 | } | ||
392 | else if (m_loadPath != null) | ||
393 | { | ||
394 | archive.Close(); | ||
395 | archive = null; | ||
396 | m_loadStream.Close(); | ||
397 | m_loadStream = null; | ||
398 | m_loadStream = new GZipStream(ArchiveHelpers.GetStream(m_loadPath), CompressionMode.Decompress); | ||
399 | archive = new TarArchiveReader(m_loadStream); | ||
400 | } | ||
401 | else | ||
402 | { | ||
403 | // There isn't currently a scenario where this happens, but it's best to add a check just in case | ||
404 | throw new Exception("Error reading archive: control file wasn't the first file, and the input stream doesn't allow seeking"); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | return; | ||
409 | } | ||
410 | |||
411 | firstFile = false; | ||
412 | } | ||
413 | |||
414 | throw new Exception("Control file not found"); | ||
249 | } | 415 | } |
250 | 416 | ||
251 | /// <summary> | 417 | /// <summary> |
252 | /// Load serialized scene objects. | 418 | /// Load serialized scene objects. |
253 | /// </summary> | 419 | /// </summary> |
254 | /// <param name="serialisedSceneObjects"></param> | 420 | protected void LoadObjects(Scene scene, List<string> serialisedSceneObjects, List<SceneObjectGroup> sceneObjects) |
255 | protected void LoadObjects(List<string> serialisedSceneObjects) | ||
256 | { | 421 | { |
257 | // Reload serialized prims | 422 | // Reload serialized prims |
258 | m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); | 423 | m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); |
259 | 424 | ||
260 | UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; | 425 | UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject; |
261 | 426 | ||
262 | IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface<IRegionSerialiserModule>(); | 427 | IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>(); |
263 | int sceneObjectsLoadedCount = 0; | 428 | int sceneObjectsLoadedCount = 0; |
264 | 429 | ||
265 | foreach (string serialisedSceneObject in serialisedSceneObjects) | 430 | foreach (string serialisedSceneObject in serialisedSceneObjects) |
@@ -280,7 +445,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
280 | 445 | ||
281 | SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); | 446 | SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); |
282 | 447 | ||
283 | bool isTelehub = (sceneObject.UUID == oldTelehubUUID); | 448 | bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero); |
284 | 449 | ||
285 | // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned | 450 | // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned |
286 | // on the same region server and multiple examples a single object archive to be imported | 451 | // on the same region server and multiple examples a single object archive to be imported |
@@ -290,8 +455,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
290 | if (isTelehub) | 455 | if (isTelehub) |
291 | { | 456 | { |
292 | // Change the Telehub Object to the new UUID | 457 | // Change the Telehub Object to the new UUID |
293 | m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; | 458 | scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; |
294 | m_scene.RegionInfo.RegionSettings.Save(); | 459 | scene.RegionInfo.RegionSettings.Save(); |
295 | oldTelehubUUID = UUID.Zero; | 460 | oldTelehubUUID = UUID.Zero; |
296 | } | 461 | } |
297 | 462 | ||
@@ -301,17 +466,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
301 | { | 466 | { |
302 | if (part.CreatorData == null || part.CreatorData == string.Empty) | 467 | if (part.CreatorData == null || part.CreatorData == string.Empty) |
303 | { | 468 | { |
304 | if (!ResolveUserUuid(part.CreatorID)) | 469 | if (!ResolveUserUuid(scene, part.CreatorID)) |
305 | part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 470 | part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; |
306 | } | 471 | } |
307 | if (UserManager != null) | 472 | if (UserManager != null) |
308 | UserManager.AddUser(part.CreatorID, part.CreatorData); | 473 | UserManager.AddUser(part.CreatorID, part.CreatorData); |
309 | 474 | ||
310 | if (!ResolveUserUuid(part.OwnerID)) | 475 | if (!ResolveUserUuid(scene, part.OwnerID)) |
311 | part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 476 | part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner; |
312 | 477 | ||
313 | if (!ResolveUserUuid(part.LastOwnerID)) | 478 | if (!ResolveUserUuid(scene, part.LastOwnerID)) |
314 | part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 479 | part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner; |
315 | 480 | ||
316 | if (!ResolveGroupUuid(part.GroupID)) | 481 | if (!ResolveGroupUuid(part.GroupID)) |
317 | part.GroupID = UUID.Zero; | 482 | part.GroupID = UUID.Zero; |
@@ -328,15 +493,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
328 | TaskInventoryDictionary inv = part.TaskInventory; | 493 | TaskInventoryDictionary inv = part.TaskInventory; |
329 | foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) | 494 | foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) |
330 | { | 495 | { |
331 | if (!ResolveUserUuid(kvp.Value.OwnerID)) | 496 | if (!ResolveUserUuid(scene, kvp.Value.OwnerID)) |
332 | { | 497 | { |
333 | kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 498 | kvp.Value.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner; |
334 | } | 499 | } |
335 | 500 | ||
336 | if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) | 501 | if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) |
337 | { | 502 | { |
338 | if (!ResolveUserUuid(kvp.Value.CreatorID)) | 503 | if (!ResolveUserUuid(scene, kvp.Value.CreatorID)) |
339 | kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 504 | kvp.Value.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; |
340 | } | 505 | } |
341 | 506 | ||
342 | if (UserManager != null) | 507 | if (UserManager != null) |
@@ -348,10 +513,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
348 | } | 513 | } |
349 | } | 514 | } |
350 | 515 | ||
351 | if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) | 516 | if (scene.AddRestoredSceneObject(sceneObject, true, false)) |
352 | { | 517 | { |
353 | sceneObjectsLoadedCount++; | 518 | sceneObjectsLoadedCount++; |
354 | sceneObject.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, 0); | 519 | sceneObject.CreateScriptInstances(0, false, scene.DefaultScriptEngine, 0); |
355 | sceneObject.ResumeScripts(); | 520 | sceneObject.ResumeScripts(); |
356 | } | 521 | } |
357 | } | 522 | } |
@@ -366,16 +531,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
366 | if (oldTelehubUUID != UUID.Zero) | 531 | if (oldTelehubUUID != UUID.Zero) |
367 | { | 532 | { |
368 | m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); | 533 | m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); |
369 | m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; | 534 | scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; |
370 | m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); | 535 | scene.RegionInfo.RegionSettings.ClearSpawnPoints(); |
371 | } | 536 | } |
372 | } | 537 | } |
373 | 538 | ||
374 | /// <summary> | 539 | /// <summary> |
375 | /// Load serialized parcels. | 540 | /// Load serialized parcels. |
376 | /// </summary> | 541 | /// </summary> |
542 | /// <param name="scene"></param> | ||
377 | /// <param name="serialisedParcels"></param> | 543 | /// <param name="serialisedParcels"></param> |
378 | protected void LoadParcels(List<string> serialisedParcels) | 544 | protected void LoadParcels(Scene scene, List<string> serialisedParcels) |
379 | { | 545 | { |
380 | // Reload serialized parcels | 546 | // Reload serialized parcels |
381 | m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); | 547 | m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); |
@@ -386,8 +552,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
386 | 552 | ||
387 | // Validate User and Group UUID's | 553 | // Validate User and Group UUID's |
388 | 554 | ||
389 | if (!ResolveUserUuid(parcel.OwnerID)) | 555 | if (!ResolveUserUuid(scene, parcel.OwnerID)) |
390 | parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 556 | parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner; |
391 | 557 | ||
392 | if (!ResolveGroupUuid(parcel.GroupID)) | 558 | if (!ResolveGroupUuid(parcel.GroupID)) |
393 | { | 559 | { |
@@ -398,7 +564,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
398 | List<LandAccessEntry> accessList = new List<LandAccessEntry>(); | 564 | List<LandAccessEntry> accessList = new List<LandAccessEntry>(); |
399 | foreach (LandAccessEntry entry in parcel.ParcelAccessList) | 565 | foreach (LandAccessEntry entry in parcel.ParcelAccessList) |
400 | { | 566 | { |
401 | if (ResolveUserUuid(entry.AgentID)) | 567 | if (ResolveUserUuid(scene, entry.AgentID)) |
402 | accessList.Add(entry); | 568 | accessList.Add(entry); |
403 | // else, drop this access rule | 569 | // else, drop this access rule |
404 | } | 570 | } |
@@ -414,23 +580,24 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
414 | if (!m_merge) | 580 | if (!m_merge) |
415 | { | 581 | { |
416 | bool setupDefaultParcel = (landData.Count == 0); | 582 | bool setupDefaultParcel = (landData.Count == 0); |
417 | m_scene.LandChannel.Clear(setupDefaultParcel); | 583 | scene.LandChannel.Clear(setupDefaultParcel); |
418 | } | 584 | } |
419 | 585 | ||
420 | m_scene.EventManager.TriggerIncomingLandDataFromStorage(landData); | 586 | scene.EventManager.TriggerIncomingLandDataFromStorage(landData); |
421 | m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); | 587 | m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); |
422 | } | 588 | } |
423 | 589 | ||
424 | /// <summary> | 590 | /// <summary> |
425 | /// Look up the given user id to check whether it's one that is valid for this grid. | 591 | /// Look up the given user id to check whether it's one that is valid for this grid. |
426 | /// </summary> | 592 | /// </summary> |
593 | /// <param name="scene"></param> | ||
427 | /// <param name="uuid"></param> | 594 | /// <param name="uuid"></param> |
428 | /// <returns></returns> | 595 | /// <returns></returns> |
429 | private bool ResolveUserUuid(UUID uuid) | 596 | private bool ResolveUserUuid(Scene scene, UUID uuid) |
430 | { | 597 | { |
431 | if (!m_validUserUuids.ContainsKey(uuid)) | 598 | if (!m_validUserUuids.ContainsKey(uuid)) |
432 | { | 599 | { |
433 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); | 600 | UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid); |
434 | m_validUserUuids.Add(uuid, account != null); | 601 | m_validUserUuids.Add(uuid, account != null); |
435 | } | 602 | } |
436 | 603 | ||
@@ -485,7 +652,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
485 | string extension = filename.Substring(i); | 652 | string extension = filename.Substring(i); |
486 | string uuid = filename.Remove(filename.Length - extension.Length); | 653 | string uuid = filename.Remove(filename.Length - extension.Length); |
487 | 654 | ||
488 | if (m_scene.AssetService.GetMetadata(uuid) != null) | 655 | if (m_assetService.GetMetadata(uuid) != null) |
489 | { | 656 | { |
490 | // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); | 657 | // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); |
491 | return true; | 658 | return true; |
@@ -505,7 +672,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
505 | 672 | ||
506 | // We're relying on the asset service to do the sensible thing and not store the asset if it already | 673 | // We're relying on the asset service to do the sensible thing and not store the asset if it already |
507 | // exists. | 674 | // exists. |
508 | m_scene.AssetService.Store(asset); | 675 | m_assetService.Store(asset); |
509 | 676 | ||
510 | /** | 677 | /** |
511 | * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so | 678 | * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so |
@@ -533,12 +700,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
533 | /// <summary> | 700 | /// <summary> |
534 | /// Load region settings data | 701 | /// Load region settings data |
535 | /// </summary> | 702 | /// </summary> |
703 | /// <param name="scene"></param> | ||
536 | /// <param name="settingsPath"></param> | 704 | /// <param name="settingsPath"></param> |
537 | /// <param name="data"></param> | 705 | /// <param name="data"></param> |
706 | /// <param name="dearchivedScenes"></param> | ||
538 | /// <returns> | 707 | /// <returns> |
539 | /// true if settings were loaded successfully, false otherwise | 708 | /// true if settings were loaded successfully, false otherwise |
540 | /// </returns> | 709 | /// </returns> |
541 | private bool LoadRegionSettings(string settingsPath, byte[] data) | 710 | private bool LoadRegionSettings(Scene scene, string settingsPath, byte[] data, DearchiveScenesInfo dearchivedScenes) |
542 | { | 711 | { |
543 | RegionSettings loadedRegionSettings; | 712 | RegionSettings loadedRegionSettings; |
544 | 713 | ||
@@ -554,7 +723,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
554 | return false; | 723 | return false; |
555 | } | 724 | } |
556 | 725 | ||
557 | RegionSettings currentRegionSettings = m_scene.RegionInfo.RegionSettings; | 726 | RegionSettings currentRegionSettings = scene.RegionInfo.RegionSettings; |
558 | 727 | ||
559 | currentRegionSettings.AgentLimit = loadedRegionSettings.AgentLimit; | 728 | currentRegionSettings.AgentLimit = loadedRegionSettings.AgentLimit; |
560 | currentRegionSettings.AllowDamage = loadedRegionSettings.AllowDamage; | 729 | currentRegionSettings.AllowDamage = loadedRegionSettings.AllowDamage; |
@@ -591,12 +760,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
591 | foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) | 760 | foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) |
592 | currentRegionSettings.AddSpawnPoint(sp); | 761 | currentRegionSettings.AddSpawnPoint(sp); |
593 | 762 | ||
763 | currentRegionSettings.LoadedCreationDateTime = dearchivedScenes.LoadedCreationDateTime; | ||
764 | currentRegionSettings.LoadedCreationID = dearchivedScenes.GetOriginalRegionID(scene.RegionInfo.RegionID).ToString(); | ||
765 | |||
594 | currentRegionSettings.Save(); | 766 | currentRegionSettings.Save(); |
595 | 767 | ||
596 | m_scene.TriggerEstateSunUpdate(); | 768 | scene.TriggerEstateSunUpdate(); |
597 | 769 | ||
598 | IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); | 770 | IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>(); |
599 | |||
600 | if (estateModule != null) | 771 | if (estateModule != null) |
601 | estateModule.sendRegionHandshakeToAll(); | 772 | estateModule.sendRegionHandshakeToAll(); |
602 | 773 | ||
@@ -606,14 +777,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
606 | /// <summary> | 777 | /// <summary> |
607 | /// Load terrain data | 778 | /// Load terrain data |
608 | /// </summary> | 779 | /// </summary> |
780 | /// <param name="scene"></param> | ||
609 | /// <param name="terrainPath"></param> | 781 | /// <param name="terrainPath"></param> |
610 | /// <param name="data"></param> | 782 | /// <param name="data"></param> |
611 | /// <returns> | 783 | /// <returns> |
612 | /// true if terrain was resolved successfully, false otherwise. | 784 | /// true if terrain was resolved successfully, false otherwise. |
613 | /// </returns> | 785 | /// </returns> |
614 | private bool LoadTerrain(string terrainPath, byte[] data) | 786 | private bool LoadTerrain(Scene scene, string terrainPath, byte[] data) |
615 | { | 787 | { |
616 | ITerrainModule terrainModule = m_scene.RequestModuleInterface<ITerrainModule>(); | 788 | ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>(); |
617 | 789 | ||
618 | MemoryStream ms = new MemoryStream(data); | 790 | MemoryStream ms = new MemoryStream(data); |
619 | terrainModule.LoadFromStream(terrainPath, ms); | 791 | terrainModule.LoadFromStream(terrainPath, ms); |
@@ -629,17 +801,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
629 | /// </summary> | 801 | /// </summary> |
630 | /// <param name="path"></param> | 802 | /// <param name="path"></param> |
631 | /// <param name="data"></param> | 803 | /// <param name="data"></param> |
632 | public void LoadControlFile(string path, byte[] data) | 804 | /// <param name="dearchivedScenes"></param> |
805 | public DearchiveScenesInfo LoadControlFile(string path, byte[] data, DearchiveScenesInfo dearchivedScenes) | ||
633 | { | 806 | { |
634 | XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); | 807 | XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); |
635 | XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); | 808 | XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); |
636 | XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context); | 809 | XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context); |
637 | 810 | ||
638 | RegionSettings currentRegionSettings = m_scene.RegionInfo.RegionSettings; | 811 | // Loaded metadata will be empty if no information exists in the archive |
812 | dearchivedScenes.LoadedCreationDateTime = 0; | ||
813 | dearchivedScenes.DefaultOriginalID = ""; | ||
639 | 814 | ||
640 | // Loaded metadata will empty if no information exists in the archive | 815 | bool multiRegion = false; |
641 | currentRegionSettings.LoadedCreationDateTime = 0; | ||
642 | currentRegionSettings.LoadedCreationID = ""; | ||
643 | 816 | ||
644 | while (xtr.Read()) | 817 | while (xtr.Read()) |
645 | { | 818 | { |
@@ -665,18 +838,44 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
665 | { | 838 | { |
666 | int value; | 839 | int value; |
667 | if (Int32.TryParse(xtr.ReadElementContentAsString(), out value)) | 840 | if (Int32.TryParse(xtr.ReadElementContentAsString(), out value)) |
668 | currentRegionSettings.LoadedCreationDateTime = value; | 841 | dearchivedScenes.LoadedCreationDateTime = value; |
669 | } | 842 | } |
670 | else if (xtr.Name.ToString() == "id") | 843 | else if (xtr.Name.ToString() == "row") |
844 | { | ||
845 | multiRegion = true; | ||
846 | dearchivedScenes.StartRow(); | ||
847 | } | ||
848 | else if (xtr.Name.ToString() == "region") | ||
671 | { | 849 | { |
672 | currentRegionSettings.LoadedCreationID = xtr.ReadElementContentAsString(); | 850 | dearchivedScenes.StartRegion(); |
851 | } | ||
852 | else if (xtr.Name.ToString() == "id") | ||
853 | { | ||
854 | string id = xtr.ReadElementContentAsString(); | ||
855 | dearchivedScenes.DefaultOriginalID = id; | ||
856 | if (multiRegion) | ||
857 | dearchivedScenes.SetRegionOriginalID(id); | ||
858 | } | ||
859 | else if (xtr.Name.ToString() == "dir") | ||
860 | { | ||
861 | dearchivedScenes.SetRegionDirectory(xtr.ReadElementContentAsString()); | ||
673 | } | 862 | } |
674 | } | 863 | } |
675 | } | 864 | } |
676 | 865 | ||
677 | currentRegionSettings.Save(); | 866 | dearchivedScenes.MultiRegionFormat = multiRegion; |
678 | 867 | if (!multiRegion) | |
868 | { | ||
869 | // Add the single scene | ||
870 | dearchivedScenes.StartRow(); | ||
871 | dearchivedScenes.StartRegion(); | ||
872 | dearchivedScenes.SetRegionOriginalID(dearchivedScenes.DefaultOriginalID); | ||
873 | dearchivedScenes.SetRegionDirectory(""); | ||
874 | } | ||
875 | |||
679 | ControlFileLoaded = true; | 876 | ControlFileLoaded = true; |
877 | |||
878 | return dearchivedScenes; | ||
680 | } | 879 | } |
681 | } | 880 | } |
682 | } \ No newline at end of file | 881 | } \ No newline at end of file |