aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs9
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs45
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs14
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs104
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs85
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs91
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs25
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs5
9 files changed, 317 insertions, 69 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 14f670d..86975c9 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -267,12 +267,13 @@ namespace OpenSim
267 267
268 m_console.Commands.AddCommand("region", false, "save oar", 268 m_console.Commands.AddCommand("region", false, "save oar",
269 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", 269 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
270 "save oar [-p|--profile=<url>] [<OAR path>]", 270 "save oar [-p|--profile=<url>] [--noassets] [<OAR path>]",
271 "Save a region's data to an OAR archive.", 271 "Save a region's data to an OAR archive.",
272// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine 272// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
273 "-p|--profile=<url> adds the url of the profile service to the saved user information" + Environment.NewLine 273 "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
274 + "The OAR path must be a filesystem path." 274 + " The OAR path must be a filesystem path."
275 + " If this is not given then the oar is saved to region.oar in the current directory.", 275 + " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine
276 + "--noassets stops assets being saved to the OAR.",
276 SaveOar); 277 SaveOar);
277 278
278 m_console.Commands.AddCommand("region", false, "edit scale", 279 m_console.Commands.AddCommand("region", false, "edit scale",
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index dd16bfe..e043caa 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -46,6 +46,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
46 { 46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 /// <summary>
50 /// Determine whether this archive will save assets. Default is true.
51 /// </summary>
52 public bool SaveAssets { get; set; }
53
49 /// <value> 54 /// <value>
50 /// Used to select all inventory nodes in a folder but not the folder itself 55 /// Used to select all inventory nodes in a folder but not the folder itself
51 /// </value> 56 /// </value>
@@ -112,6 +117,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
112 m_invPath = invPath; 117 m_invPath = invPath;
113 m_saveStream = saveStream; 118 m_saveStream = saveStream;
114 m_assetGatherer = new UuidGatherer(m_scene.AssetService); 119 m_assetGatherer = new UuidGatherer(m_scene.AssetService);
120
121 SaveAssets = true;
115 } 122 }
116 123
117 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids) 124 protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
@@ -147,7 +154,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
147 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService); 154 string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
148 m_archiveWriter.WriteFile(filename, serialization); 155 m_archiveWriter.WriteFile(filename, serialization);
149 156
150 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); 157 if (SaveAssets)
158 m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
151 } 159 }
152 160
153 /// <summary> 161 /// <summary>
@@ -189,6 +197,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
189 /// </summary> 197 /// </summary>
190 public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService) 198 public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
191 { 199 {
200 if (options.ContainsKey("noassets") && (bool)options["noassets"])
201 SaveAssets = false;
202
192 try 203 try
193 { 204 {
194 InventoryFolderBase inventoryFolder = null; 205 InventoryFolderBase inventoryFolder = null;
@@ -279,12 +290,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
279 290
280 // Don't put all this profile information into the archive right now. 291 // Don't put all this profile information into the archive right now.
281 //SaveUsers(); 292 //SaveUsers();
282 293
283 new AssetsRequest( 294 if (SaveAssets)
284 new AssetsArchiver(m_archiveWriter), 295 {
285 m_assetUuids, m_scene.AssetService, 296 m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count);
286 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, 297
287 options, ReceivedAllAssets).Execute(); 298 new AssetsRequest(
299 new AssetsArchiver(m_archiveWriter),
300 m_assetUuids, m_scene.AssetService,
301 m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
302 options, ReceivedAllAssets).Execute();
303 }
304 else
305 {
306 m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified");
307
308 ReceivedAllAssets(new List<UUID>(), new List<UUID>());
309 }
288 } 310 }
289 catch (Exception) 311 catch (Exception)
290 { 312 {
@@ -381,19 +403,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
381 /// </summary> 403 /// </summary>
382 /// <param name="options"></param> 404 /// <param name="options"></param>
383 /// <returns></returns> 405 /// <returns></returns>
384 public static string CreateControlFile(Dictionary<string, object> options) 406 public string CreateControlFile(Dictionary<string, object> options)
385 { 407 {
386 int majorVersion, minorVersion; 408 int majorVersion, minorVersion;
387 409
388 if (options.ContainsKey("profile")) 410 if (options.ContainsKey("profile"))
389 { 411 {
390 majorVersion = 1; 412 majorVersion = 1;
391 minorVersion = 1; 413 minorVersion = 2;
392 } 414 }
393 else 415 else
394 { 416 {
395 majorVersion = 0; 417 majorVersion = 0;
396 minorVersion = 2; 418 minorVersion = 3;
397 } 419 }
398 420
399 m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); 421 m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion);
@@ -405,6 +427,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
405 xtw.WriteStartElement("archive"); 427 xtw.WriteStartElement("archive");
406 xtw.WriteAttributeString("major_version", majorVersion.ToString()); 428 xtw.WriteAttributeString("major_version", majorVersion.ToString());
407 xtw.WriteAttributeString("minor_version", minorVersion.ToString()); 429 xtw.WriteAttributeString("minor_version", minorVersion.ToString());
430
431 xtw.WriteElementString("assets_included", SaveAssets.ToString());
432
408 xtw.WriteEndElement(); 433 xtw.WriteEndElement();
409 434
410 xtw.Flush(); 435 xtw.Flush();
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 613f0ed..e0b02aa 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -122,7 +122,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
122 122
123 scene.AddCommand( 123 scene.AddCommand(
124 this, "save iar", 124 this, "save iar",
125 "save iar [--p|-profile=<url>] <first> <last> <inventory path> <password> [<IAR path>]", 125 "save iar [--p|-profile=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]",
126 "Save user inventory archive (IAR).", 126 "Save user inventory archive (IAR).",
127 "<first> is the user's first name." + Environment.NewLine 127 "<first> is the user's first name." + Environment.NewLine
128 + "<last> is the user's last name." + Environment.NewLine 128 + "<last> is the user's last name." + Environment.NewLine
@@ -130,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
130 + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine 130 + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
131 + "-c|--creators preserves information about foreign creators." + Environment.NewLine 131 + "-c|--creators preserves information about foreign creators." + Environment.NewLine
132 + "-v|--verbose extra debug messages." + Environment.NewLine 132 + "-v|--verbose extra debug messages." + Environment.NewLine
133 + "--noassets stops assets being saved to the IAR."
133 + "<IAR path> is the filesystem path at which to save the IAR." 134 + "<IAR path> is the filesystem path at which to save the IAR."
134 + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), 135 + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
135 HandleSaveInvConsoleCommand); 136 HandleSaveInvConsoleCommand);
@@ -398,6 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
398 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); 399 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
399 ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); 400 ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
400 ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); 401 ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
402 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
401 403
402 List<string> mainParams = ops.Parse(cmdparams); 404 List<string> mainParams = ops.Parse(cmdparams);
403 405
@@ -406,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
406 if (mainParams.Count < 6) 408 if (mainParams.Count < 6)
407 { 409 {
408 m_log.Error( 410 m_log.Error(
409 "[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] <first name> <last name> <inventory path> <user password> [<save file path>]"); 411 "[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>]");
410 return; 412 return;
411 } 413 }
412 414
@@ -423,16 +425,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
423 m_log.InfoFormat( 425 m_log.InfoFormat(
424 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", 426 "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
425 savePath, invPath, firstName, lastName); 427 savePath, invPath, firstName, lastName);
426 428
429 lock (m_pendingConsoleSaves)
430 m_pendingConsoleSaves.Add(id);
431
427 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options); 432 ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
428 } 433 }
429 catch (InventoryArchiverException e) 434 catch (InventoryArchiverException e)
430 { 435 {
431 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); 436 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
432 } 437 }
433
434 lock (m_pendingConsoleSaves)
435 m_pendingConsoleSaves.Add(id);
436 } 438 }
437 439
438 private void SaveInvConsoleCommandCompleted( 440 private void SaveInvConsoleCommandCompleted(
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index d97311a..ae3ab21 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -123,11 +123,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
123 } 123 }
124 124
125 /// <summary> 125 /// <summary>
126 /// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive 126 /// Test saving a single inventory item to an IAR
127 /// (subject to change since there is no fixed format yet). 127 /// (subject to change since there is no fixed format yet).
128 /// </summary> 128 /// </summary>
129 [Test] 129 [Test]
130 public void TestSaveItemToIarV0_1() 130 public void TestSaveItemToIar()
131 { 131 {
132 TestHelper.InMethod(); 132 TestHelper.InMethod();
133// log4net.Config.XmlConfigurator.Configure(); 133// log4net.Config.XmlConfigurator.Configure();
@@ -217,6 +217,106 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
217 217
218 // TODO: Test presence of more files and contents of files. 218 // TODO: Test presence of more files and contents of files.
219 } 219 }
220
221 /// <summary>
222 /// Test saving a single inventory item to an IAR without its asset
223 /// </summary>
224 [Test]
225 public void TestSaveItemToIarNoAssets()
226 {
227 TestHelper.InMethod();
228// log4net.Config.XmlConfigurator.Configure();
229
230 // Create user
231 string userFirstName = "Jock";
232 string userLastName = "Stirrup";
233 string userPassword = "troll";
234 UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
235 UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
236
237 // Create asset
238 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
239 SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
240
241 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
242 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
243 m_scene.AssetService.Store(asset1);
244
245 // Create item
246 UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
247 string item1Name = "My Little Dog";
248 InventoryItemBase item1 = new InventoryItemBase();
249 item1.Name = item1Name;
250 item1.AssetID = asset1.FullID;
251 item1.ID = item1Id;
252 InventoryFolderBase objsFolder
253 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0];
254 item1.Folder = objsFolder.ID;
255 m_scene.AddInventoryItem(item1);
256
257 MemoryStream archiveWriteStream = new MemoryStream();
258
259 Dictionary<string, Object> options = new Dictionary<string, Object>();
260 options.Add("noassets", true);
261
262 // When we're not saving assets, archiving is being done synchronously.
263 m_archiverModule.ArchiveInventory(
264 Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
265
266 byte[] archive = archiveWriteStream.ToArray();
267 MemoryStream archiveReadStream = new MemoryStream(archive);
268 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
269
270 //bool gotControlFile = false;
271 bool gotObject1File = false;
272 //bool gotObject2File = false;
273 string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1);
274 string expectedObject1FilePath = string.Format(
275 "{0}{1}",
276 ArchiveConstants.INVENTORY_PATH,
277 expectedObject1FileName);
278
279 string filePath;
280 TarArchiveReader.TarEntryType tarEntryType;
281
282// Console.WriteLine("Reading archive");
283
284 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
285 {
286 Console.WriteLine("Got {0}", filePath);
287
288// if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
289// {
290// gotControlFile = true;
291// }
292
293 if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
294 {
295// string fileName = filePath.Remove(0, "Objects/".Length);
296//
297// if (fileName.StartsWith(part1.Name))
298// {
299 Assert.That(expectedObject1FilePath, Is.EqualTo(filePath));
300 gotObject1File = true;
301// }
302// else if (fileName.StartsWith(part2.Name))
303// {
304// Assert.That(fileName, Is.EqualTo(expectedObject2FileName));
305// gotObject2File = true;
306// }
307 }
308 else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
309 {
310 Assert.Fail("Found asset path in TestSaveItemToIarNoAssets()");
311 }
312 }
313
314// Assert.That(gotControlFile, Is.True, "No control file in archive");
315 Assert.That(gotObject1File, Is.True, "No item1 file in archive");
316// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
317
318 // TODO: Test presence of more files and contents of files.
319 }
220 320
221 /// <summary> 321 /// <summary>
222 /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized 322 /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
index 597b780..10a83ee 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
49 public class ArchiveWriteRequestPreparation 49 public class ArchiveWriteRequestPreparation
50 { 50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 /// <summary> 53 /// <summary>
54 /// The minimum major version of OAR that we can write. 54 /// The minimum major version of OAR that we can write.
55 /// </summary> 55 /// </summary>
@@ -58,7 +58,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
58 /// <summary> 58 /// <summary>
59 /// The maximum major version of OAR that we can write. 59 /// The maximum major version of OAR that we can write.
60 /// </summary> 60 /// </summary>
61 public static int MAX_MAJOR_VERSION = 0; 61 public static int MAX_MAJOR_VERSION = 0;
62
63 /// <summary>
64 /// Determine whether this archive will save assets. Default is true.
65 /// </summary>
66 public bool SaveAssets { get; set; }
62 67
63 protected Scene m_scene; 68 protected Scene m_scene;
64 protected Stream m_saveStream; 69 protected Stream m_saveStream;
@@ -73,10 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
73 /// <exception cref="System.IO.IOException"> 78 /// <exception cref="System.IO.IOException">
74 /// If there was a problem opening a stream for the file specified by the savePath 79 /// If there was a problem opening a stream for the file specified by the savePath
75 /// </exception> 80 /// </exception>
76 public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) 81 public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId)
77 { 82 {
78 m_scene = scene;
79
80 try 83 try
81 { 84 {
82 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress); 85 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress);
@@ -86,10 +89,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
86 m_log.ErrorFormat( 89 m_log.ErrorFormat(
87 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream." 90 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
88 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?"); 91 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
89 m_log.Error(e); 92 m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
90 } 93 }
91
92 m_requestId = requestId;
93 } 94 }
94 95
95 /// <summary> 96 /// <summary>
@@ -98,11 +99,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
98 /// <param name="scene"></param> 99 /// <param name="scene"></param>
99 /// <param name="saveStream">The stream to which to save data.</param> 100 /// <param name="saveStream">The stream to which to save data.</param>
100 /// <param name="requestId">The id associated with this request</param> 101 /// <param name="requestId">The id associated with this request</param>
101 public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) 102 public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId)
102 { 103 {
103 m_scene = scene;
104 m_saveStream = saveStream; 104 m_saveStream = saveStream;
105 }
106
107 protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId)
108 {
109 m_scene = scene;
105 m_requestId = requestId; 110 m_requestId = requestId;
111
112 SaveAssets = true;
106 } 113 }
107 114
108 /// <summary> 115 /// <summary>
@@ -111,22 +118,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
111 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception> 118 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
112 public void ArchiveRegion(Dictionary<string, object> options) 119 public void ArchiveRegion(Dictionary<string, object> options)
113 { 120 {
121 if (options.ContainsKey("noassets") && (bool)options["noassets"])
122 SaveAssets = false;
123
114 try 124 try
115 { 125 {
116 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); 126 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
117 127
118 EntityBase[] entities = m_scene.GetEntities(); 128 EntityBase[] entities = m_scene.GetEntities();
119 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); 129 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
120
121 /*
122 foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
123 {
124 if (name == lo.LandData.Name)
125 {
126 // This is the parcel we want
127 }
128 }
129 */
130 130
131 // Filter entities so that we only have scene objects. 131 // Filter entities so that we only have scene objects.
132 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods 132 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
@@ -141,17 +141,24 @@ namespace OpenSim.Region.CoreModules.World.Archiver
141 sceneObjects.Add((SceneObjectGroup)entity); 141 sceneObjects.Add((SceneObjectGroup)entity);
142 } 142 }
143 } 143 }
144 144
145 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService); 145 if (SaveAssets)
146 146 {
147 foreach (SceneObjectGroup sceneObject in sceneObjects) 147 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
148
149 foreach (SceneObjectGroup sceneObject in sceneObjects)
150 {
151 assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
152 }
153
154 m_log.DebugFormat(
155 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
156 sceneObjects.Count, assetUuids.Count);
157 }
158 else
148 { 159 {
149 assetGatherer.GatherAssetUuids(sceneObject, assetUuids); 160 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
150 } 161 }
151
152 m_log.DebugFormat(
153 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
154 sceneObjects.Count, assetUuids.Count);
155 162
156 // Make sure that we also request terrain texture assets 163 // Make sure that we also request terrain texture assets
157 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings; 164 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
@@ -187,11 +194,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
187 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this 194 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
188 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options)); 195 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
189 m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); 196 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
190 197
191 new AssetsRequest( 198 if (SaveAssets)
192 new AssetsArchiver(archiveWriter), assetUuids, 199 new AssetsRequest(
193 m_scene.AssetService, m_scene.UserAccountService, 200 new AssetsArchiver(archiveWriter), assetUuids,
194 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute(); 201 m_scene.AssetService, m_scene.UserAccountService,
202 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
203 else
204 awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
195 } 205 }
196 catch (Exception) 206 catch (Exception)
197 { 207 {
@@ -204,9 +214,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
204 /// Create the control file for the most up to date archive 214 /// Create the control file for the most up to date archive
205 /// </summary> 215 /// </summary>
206 /// <returns></returns> 216 /// <returns></returns>
207 public static string CreateControlFile(Dictionary<string, object> options) 217 public string CreateControlFile(Dictionary<string, object> options)
208 { 218 {
209 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 6; 219 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7;
210// 220//
211// if (options.ContainsKey("version")) 221// if (options.ContainsKey("version"))
212// { 222// {
@@ -258,6 +268,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
258 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); 268 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
259 xtw.WriteElementString("id", UUID.Random().ToString()); 269 xtw.WriteElementString("id", UUID.Random().ToString());
260 xtw.WriteEndElement(); 270 xtw.WriteEndElement();
271
272 xtw.WriteElementString("assets_included", SaveAssets.ToString());
273
261 xtw.WriteEndElement(); 274 xtw.WriteEndElement();
262 275
263 xtw.Flush(); 276 xtw.Flush();
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index 9277c59..08eb80c 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -127,6 +127,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
127 OptionSet ops = new OptionSet(); 127 OptionSet ops = new OptionSet();
128// ops.Add("v|version=", delegate(string v) { options["version"] = v; }); 128// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
129 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); 129 ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
130 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
130 131
131 List<string> mainParams = ops.Parse(cmdparams); 132 List<string> mainParams = ops.Parse(cmdparams);
132 133
@@ -160,7 +161,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
160 161
161 public void ArchiveRegion(Stream saveStream, Guid requestId) 162 public void ArchiveRegion(Stream saveStream, Guid requestId)
162 { 163 {
163 new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(new Dictionary<string, object>()); 164 ArchiveRegion(saveStream, requestId, new Dictionary<string, object>());
165 }
166
167 public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options)
168 {
169 new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options);
164 } 170 }
165 171
166 public void DearchiveRegion(string loadPath) 172 public void DearchiveRegion(string loadPath)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 2eb2861..34e2e23 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -212,6 +212,89 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
212 } 212 }
213 213
214 /// <summary> 214 /// <summary>
215 /// Test saving an OpenSim Region Archive with the no assets option
216 /// </summary>
217 [Test]
218 public void TestSaveOarNoAssets()
219 {
220 TestHelper.InMethod();
221// log4net.Config.XmlConfigurator.Configure();
222
223 SceneObjectPart part1 = CreateSceneObjectPart1();
224 SceneObjectGroup sog1 = new SceneObjectGroup(part1);
225 m_scene.AddNewSceneObject(sog1, false);
226
227 SceneObjectPart part2 = CreateSceneObjectPart2();
228
229 AssetNotecard nc = new AssetNotecard();
230 nc.BodyText = "Hello World!";
231 nc.Encode();
232 UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
233 UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
234 AssetBase ncAsset
235 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
236 m_scene.AssetService.Store(ncAsset);
237 SceneObjectGroup sog2 = new SceneObjectGroup(part2);
238 TaskInventoryItem ncItem
239 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
240 part2.Inventory.AddInventoryItem(ncItem, true);
241
242 m_scene.AddNewSceneObject(sog2, false);
243
244 MemoryStream archiveWriteStream = new MemoryStream();
245
246 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
247
248 Dictionary<string, Object> options = new Dictionary<string, Object>();
249 options.Add("noassets", true);
250 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
251 //AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
252 //while (assetServer.HasWaitingRequests())
253 // assetServer.ProcessNextRequest();
254
255 // Don't wait for completion - with --noassets save oar happens synchronously
256// Monitor.Wait(this, 60000);
257
258 Assert.That(m_lastRequestId, Is.EqualTo(requestId));
259
260 byte[] archive = archiveWriteStream.ToArray();
261 MemoryStream archiveReadStream = new MemoryStream(archive);
262 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
263
264 List<string> foundPaths = new List<string>();
265 List<string> expectedPaths = new List<string>();
266 expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog1));
267 expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2));
268
269 string filePath;
270 TarArchiveReader.TarEntryType tarEntryType;
271
272 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
273 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
274
275 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
276 arr.LoadControlFile(filePath, data);
277
278 Assert.That(arr.ControlFileLoaded, Is.True);
279
280 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
281 {
282 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
283 {
284 Assert.Fail("Asset was found in saved oar of TestSaveOarNoAssets()");
285 }
286 else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
287 {
288 foundPaths.Add(filePath);
289 }
290 }
291
292 Assert.That(foundPaths, Is.EquivalentTo(expectedPaths));
293
294 // TODO: Test presence of more files and contents of files.
295 }
296
297 /// <summary>
215 /// Test loading an OpenSim Region Archive. 298 /// Test loading an OpenSim Region Archive.
216 /// </summary> 299 /// </summary>
217 [Test] 300 [Test]
@@ -230,7 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
230 // upset load 313 // upset load
231 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 314 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
232 315
233 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>())); 316 tar.WriteFile(
317 ArchiveConstants.CONTROL_FILE_PATH,
318 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
234 319
235 SceneObjectPart part1 = CreateSceneObjectPart1(); 320 SceneObjectPart part1 = CreateSceneObjectPart1();
236 SceneObjectGroup object1 = new SceneObjectGroup(part1); 321 SceneObjectGroup object1 = new SceneObjectGroup(part1);
@@ -331,7 +416,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
331 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); 416 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
332 417
333 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 418 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
334 tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>())); 419 tar.WriteFile(
420 ArchiveConstants.CONTROL_FILE_PATH,
421 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
335 422
336 RegionSettings rs = new RegionSettings(); 423 RegionSettings rs = new RegionSettings();
337 rs.AgentLimit = 17; 424 rs.AgentLimit = 17;
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
index d8229de..3fafc47 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionArchiverModule.cs
@@ -52,31 +52,44 @@ namespace OpenSim.Region.Framework.Interfaces
52 /// <summary> 52 /// <summary>
53 /// Archive the region to the given path 53 /// Archive the region to the given path
54 /// </summary> 54 /// </summary>
55 /// 55 /// <remarks>
56 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to 56 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
57 /// the EventManager.OnOarFileSaved event. 57 /// the EventManager.OnOarFileSaved event.
58 /// 58 /// </remarks>
59 /// <param name="savePath"></param> 59 /// <param name="savePath"></param>
60 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param> 60 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
61 /// <param name="options">Options for the save</param>
61 void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options); 62 void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options);
62 63
63 /// <summary> 64 /// <summary>
64 /// Archive the region to a stream. 65 /// Archive the region to a stream.
65 /// </summary> 66 /// </summary>
66 /// 67 /// <remarks>
67 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to 68 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
68 /// the EventManager.OnOarFileSaved event. 69 /// the EventManager.OnOarFileSaved event.
69 /// 70 /// </remarks>
70 /// <param name="saveStream"></param> 71 /// <param name="saveStream"></param>
71 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param> 72 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
72 void ArchiveRegion(Stream saveStream, Guid requestId); 73 void ArchiveRegion(Stream saveStream, Guid requestId);
73 74
74 /// <summary> 75 /// <summary>
76 /// Archive the region to a stream.
77 /// </summary>
78 /// <remarks>
79 /// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
80 /// the EventManager.OnOarFileSaved event.
81 /// </remarks>
82 /// <param name="saveStream"></param>
83 /// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
84 /// <param name="options">Options for the save</param>
85 void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options);
86
87 /// <summary>
75 /// Dearchive the given region archive. This replaces the existing scene. 88 /// Dearchive the given region archive. This replaces the existing scene.
76 /// </summary> 89 /// </summary>
77 /// 90 /// <remarks>
78 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event. 91 /// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
79 /// 92 /// </remarks>
80 /// <param name="loadPath"></param> 93 /// <param name="loadPath"></param>
81 void DearchiveRegion(string loadPath); 94 void DearchiveRegion(string loadPath);
82 95
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index 8589901..7304145 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -95,8 +95,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
95 scene.AddCommand( 95 scene.AddCommand(
96 this, "appearance show", 96 this, "appearance show",
97 "appearance show", 97 "appearance show",
98 "Show appearance information for each avatar in the simulator. At the moment, ", 98 "Show appearance information for each avatar in the simulator.",
99 ShowAppearanceInfo); 99 "At the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.",
100 ShowAppearanceInfo);
100 } 101 }
101 102
102 protected void ShowAppearanceInfo(string module, string[] cmd) 103 protected void ShowAppearanceInfo(string module, string[] cmd)