aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs44
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs16
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs82
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs30
4 files changed, 145 insertions, 27 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 3218abc..0cc1f86 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -51,26 +51,33 @@ namespace OpenSim.Region.CoreModules.World.Archiver
51 51
52 private static System.Text.ASCIIEncoding m_asciiEncoding = new System.Text.ASCIIEncoding(); 52 private static System.Text.ASCIIEncoding m_asciiEncoding = new System.Text.ASCIIEncoding();
53 53
54 private Scene m_scene; 54 private Scene m_scene;
55 private Stream m_loadStream; 55 private Stream m_loadStream;
56 private string m_errorMessage; 56 private string m_errorMessage;
57
58 /// <value>
59 /// Should the archive being loaded be merged with what is already on the region?
60 /// </value>
61 private bool m_merge;
57 62
58 /// <summary> 63 /// <summary>
59 /// Used to cache lookups for valid uuids. 64 /// Used to cache lookups for valid uuids.
60 /// </summary> 65 /// </summary>
61 private IDictionary<UUID, bool> m_validUserUuids = new Dictionary<UUID, bool>(); 66 private IDictionary<UUID, bool> m_validUserUuids = new Dictionary<UUID, bool>();
62 67
63 public ArchiveReadRequest(Scene scene, string loadPath) 68 public ArchiveReadRequest(Scene scene, string loadPath, bool merge)
64 { 69 {
65 m_scene = scene; 70 m_scene = scene;
66 m_loadStream = new GZipStream(GetStream(loadPath), CompressionMode.Decompress); 71 m_loadStream = new GZipStream(GetStream(loadPath), CompressionMode.Decompress);
67 m_errorMessage = String.Empty; 72 m_errorMessage = String.Empty;
73 m_merge = merge;
68 } 74 }
69 75
70 public ArchiveReadRequest(Scene scene, Stream loadStream) 76 public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge)
71 { 77 {
72 m_scene = scene; 78 m_scene = scene;
73 m_loadStream = loadStream; 79 m_loadStream = loadStream;
80 m_merge = merge;
74 } 81 }
75 82
76 /// <summary> 83 /// <summary>
@@ -92,8 +99,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
92 { 99 {
93 TarArchiveReader archive = new TarArchiveReader(m_loadStream); 100 TarArchiveReader archive = new TarArchiveReader(m_loadStream);
94 101
95 //AssetsDearchiver dearchiver = new AssetsDearchiver(m_scene.AssetCache);
96
97 string filePath = "ERROR"; 102 string filePath = "ERROR";
98 103
99 byte[] data; 104 byte[] data;
@@ -103,6 +108,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
103 { 108 {
104 //m_log.DebugFormat( 109 //m_log.DebugFormat(
105 // "[ARCHIVER]: Successfully read {0} ({1} bytes)}", filePath, data.Length); 110 // "[ARCHIVER]: Successfully read {0} ({1} bytes)}", filePath, data.Length);
111
106 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) 112 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
107 { 113 {
108 m_log.WarnFormat("[ARCHIVER]: Ignoring directory entry {0}", 114 m_log.WarnFormat("[ARCHIVER]: Ignoring directory entry {0}",
@@ -112,11 +118,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
112 { 118 {
113 serialisedSceneObjects.Add(m_asciiEncoding.GetString(data)); 119 serialisedSceneObjects.Add(m_asciiEncoding.GetString(data));
114 } 120 }
115// else if (filePath.Equals(ArchiveConstants.ASSETS_METADATA_PATH))
116// {
117// string xml = m_asciiEncoding.GetString(data);
118// dearchiver.AddAssetMetadata(xml);
119// }
120 else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) 121 else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
121 { 122 {
122 if (LoadAsset(filePath, data)) 123 if (LoadAsset(filePath, data))
@@ -124,11 +125,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
124 else 125 else
125 failedAssetRestores++; 126 failedAssetRestores++;
126 } 127 }
127 else if (filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) 128 else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH))
128 { 129 {
129 LoadTerrain(filePath, data); 130 LoadTerrain(filePath, data);
130 } 131 }
131 else if (filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) 132 else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH))
132 { 133 {
133 LoadRegionSettings(filePath, data); 134 LoadRegionSettings(filePath, data);
134 } 135 }
@@ -155,8 +156,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
155 m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores); 156 m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores);
156 } 157 }
157 158
158 m_log.Info("[ARCHIVER]: Clearing all existing scene objects"); 159 if (!m_merge)
159 m_scene.DeleteAllSceneObjects(); 160 {
161 m_log.Info("[ARCHIVER]: Clearing all existing scene objects");
162 m_scene.DeleteAllSceneObjects();
163 }
160 164
161 // Reload serialized prims 165 // Reload serialized prims
162 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); 166 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
@@ -182,13 +186,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
182 186
183 foreach (SceneObjectPart part in sceneObject.Children.Values) 187 foreach (SceneObjectPart part in sceneObject.Children.Values)
184 { 188 {
185 if (!resolveUserUuid(part.CreatorID)) 189 if (!ResolveUserUuid(part.CreatorID))
186 part.CreatorID = masterAvatarId; 190 part.CreatorID = masterAvatarId;
187 191
188 if (!resolveUserUuid(part.OwnerID)) 192 if (!ResolveUserUuid(part.OwnerID))
189 part.OwnerID = masterAvatarId; 193 part.OwnerID = masterAvatarId;
190 194
191 if (!resolveUserUuid(part.LastOwnerID)) 195 if (!ResolveUserUuid(part.LastOwnerID))
192 part.LastOwnerID = masterAvatarId; 196 part.LastOwnerID = masterAvatarId;
193 197
194 // And zap any troublesome sit target information 198 // And zap any troublesome sit target information
@@ -201,11 +205,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
201 TaskInventoryDictionary inv = part.TaskInventory; 205 TaskInventoryDictionary inv = part.TaskInventory;
202 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) 206 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
203 { 207 {
204 if (!resolveUserUuid(kvp.Value.OwnerID)) 208 if (!ResolveUserUuid(kvp.Value.OwnerID))
205 { 209 {
206 kvp.Value.OwnerID = masterAvatarId; 210 kvp.Value.OwnerID = masterAvatarId;
207 } 211 }
208 if (!resolveUserUuid(kvp.Value.CreatorID)) 212 if (!ResolveUserUuid(kvp.Value.CreatorID))
209 { 213 {
210 kvp.Value.CreatorID = masterAvatarId; 214 kvp.Value.CreatorID = masterAvatarId;
211 } 215 }
@@ -242,7 +246,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
242 /// </summary> 246 /// </summary>
243 /// <param name="uuid"></param> 247 /// <param name="uuid"></param>
244 /// <returns></returns> 248 /// <returns></returns>
245 private bool resolveUserUuid(UUID uuid) 249 private bool ResolveUserUuid(UUID uuid)
246 { 250 {
247 if (!m_validUserUuids.ContainsKey(uuid)) 251 if (!m_validUserUuids.ContainsKey(uuid))
248 { 252 {
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index c1f5b18..6259662 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -81,15 +81,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver
81 81
82 public void DearchiveRegion(string loadPath) 82 public void DearchiveRegion(string loadPath)
83 { 83 {
84 DearchiveRegion(loadPath, false);
85 }
86
87 public void DearchiveRegion(string loadPath, bool merge)
88 {
84 m_log.InfoFormat( 89 m_log.InfoFormat(
85 "[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath); 90 "[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath);
86 91
87 new ArchiveReadRequest(m_scene, loadPath).DearchiveRegion(); 92 new ArchiveReadRequest(m_scene, loadPath, merge).DearchiveRegion();
88 } 93 }
89 94
90 public void DearchiveRegion(Stream loadStream) 95 public void DearchiveRegion(Stream loadStream)
91 { 96 {
92 new ArchiveReadRequest(m_scene, loadStream).DearchiveRegion(); 97 DearchiveRegion(loadStream, false);
93 } 98 }
99
100 public void DearchiveRegion(Stream loadStream, bool merge)
101 {
102 new ArchiveReadRequest(m_scene, loadStream, merge).DearchiveRegion();
103 }
94 } 104 }
95} 105}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 77a3044..f201e74 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -167,14 +167,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
167 [Test] 167 [Test]
168 public void TestLoadOarV0p2() 168 public void TestLoadOarV0p2()
169 { 169 {
170 log4net.Config.XmlConfigurator.Configure(); 170 //log4net.Config.XmlConfigurator.Configure();
171 171
172 MemoryStream archiveWriteStream = new MemoryStream(); 172 MemoryStream archiveWriteStream = new MemoryStream();
173 TarArchiveWriter tar = new TarArchiveWriter(); 173 TarArchiveWriter tar = new TarArchiveWriter();
174 174
175 tar.AddFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile()); 175 tar.AddFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
176 176
177 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000020");
178 string part1Name = "object1"; 177 string part1Name = "object1";
179 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder(); 178 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
180 Vector3 groupPosition = new Vector3(90, 80, 70); 179 Vector3 groupPosition = new Vector3(90, 80, 70);
@@ -216,5 +215,84 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
216 Assert.That( 215 Assert.That(
217 object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal"); 216 object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal");
218 } 217 }
218
219 /// <summary>
220 /// Test merging a V0.2 OpenSim Region Archive into an existing scene
221 /// </summary>
222 [Test]
223 public void TestMergeOarV0p2()
224 {
225 log4net.Config.XmlConfigurator.Configure();
226
227 MemoryStream archiveWriteStream = new MemoryStream();
228
229 string part2Name = "objectMerge";
230 PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
231 Vector3 part2GroupPosition = new Vector3(90, 80, 70);
232 Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
233 Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
234
235 // Create an oar file that we can use for the merge
236 {
237 ArchiverModule archiverModule = new ArchiverModule();
238 SerialiserModule serialiserModule = new SerialiserModule();
239 TerrainModule terrainModule = new TerrainModule();
240
241 Scene scene = SceneSetupHelpers.SetupScene();
242 SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
243
244 SceneObjectPart part2
245 = new SceneObjectPart(
246 UUID.Zero, part2Shape, part2GroupPosition, part2RotationOffset, part2OffsetPosition);
247 part2.Name = part2Name;
248 SceneObjectGroup object2 = new SceneObjectGroup(part2);
249
250 scene.AddNewSceneObject(object2, false);
251
252 // Write out this scene
253 scene.EventManager.OnOarFileSaved += SaveCompleted;
254 archiverModule.ArchiveRegion(archiveWriteStream);
255 m_waitHandle.WaitOne(60000, true);
256 }
257
258 {
259 ArchiverModule archiverModule = new ArchiverModule();
260 SerialiserModule serialiserModule = new SerialiserModule();
261 TerrainModule terrainModule = new TerrainModule();
262
263 Scene scene = SceneSetupHelpers.SetupScene();
264 SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
265
266 string part1Name = "objectExisting";
267 PrimitiveBaseShape part1Shape = PrimitiveBaseShape.CreateCylinder();
268 Vector3 part1GroupPosition = new Vector3(80, 70, 60);
269 Quaternion part1RotationOffset = new Quaternion(50, 60, 70, 80);
270 Vector3 part1OffsetPosition = new Vector3(15, 20, 25);
271
272 SceneObjectPart part1
273 = new SceneObjectPart(
274 UUID.Zero, part1Shape, part1GroupPosition, part1RotationOffset, part1OffsetPosition);
275 part1.Name = part1Name;
276 SceneObjectGroup object1 = new SceneObjectGroup(part1);
277
278 scene.AddNewSceneObject(object1, false);
279
280 // Merge in the archive we created earlier
281 byte[] archive = archiveWriteStream.ToArray();
282 MemoryStream archiveReadStream = new MemoryStream(archive);
283
284 archiverModule.DearchiveRegion(archiveReadStream, true);
285
286 SceneObjectPart object1Existing = scene.GetSceneObjectPart(part1Name);
287 Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
288 Assert.That(object1Existing.Name, Is.EqualTo(part1Name), "object1 names not identical after merge");
289 Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1GroupPosition), "object1 group position not equal after merge");
290
291 SceneObjectPart object2PartMerged = scene.GetSceneObjectPart(part2Name);
292 Assert.That(object2PartMerged, Is.Not.Null, "object2 was not present after merge");
293 Assert.That(object2PartMerged.Name, Is.EqualTo(part2Name), "object2 names not identical after merge");
294 Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2GroupPosition), "object2 group position not equal after merge");
295 }
296 }
219 } 297 }
220} \ No newline at end of file 298} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
index 97afe8d..601b83e 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.Framework.Interfaces
55 void ArchiveRegion(Stream saveStream); 55 void ArchiveRegion(Stream saveStream);
56 56
57 /// <summary> 57 /// <summary>
58 /// Dearchive the given region archive into the scene 58 /// Dearchive the given region archive. This replaces the existing scene.
59 /// </summary> 59 /// </summary>
60 /// 60 ///
61 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event. 61 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
@@ -64,12 +64,38 @@ namespace OpenSim.Region.Framework.Interfaces
64 void DearchiveRegion(string loadPath); 64 void DearchiveRegion(string loadPath);
65 65
66 /// <summary> 66 /// <summary>
67 /// Dearchive a region from a stream. 67 /// Dearchive the given region archive. This replaces the existing scene.
68 /// </summary>
69 ///
70 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
71 ///
72 /// <param name="loadPath"></param>
73 /// <param name="merge">
74 /// If true, the loaded region merges with the existing one rather than replacing it. Any terrain or region
75 /// settings in the archive will be ignored.
76 /// </param>
77 void DearchiveRegion(string loadPath, bool merge);
78
79 /// <summary>
80 /// Dearchive a region from a stream. This replaces the existing scene.
68 /// </summary> 81 /// </summary>
69 /// 82 ///
70 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event. 83 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
71 /// 84 ///
72 /// <param name="loadStream"></param> 85 /// <param name="loadStream"></param>
73 void DearchiveRegion(Stream loadStream); 86 void DearchiveRegion(Stream loadStream);
87
88 /// <summary>
89 /// Dearchive a region from a stream. This replaces the existing scene.
90 /// </summary>
91 ///
92 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
93 ///
94 /// <param name="loadStream"></param>
95 /// <param name="merge">
96 /// If true, the loaded region merges with the existing one rather than replacing it. Any terrain or region
97 /// settings in the archive will be ignored.
98 /// </param>
99 void DearchiveRegion(Stream loadStream, bool merge);
74 } 100 }
75} 101}