Merge branch 'master' into careminster-presence-refactor
commit
f02fbdbc68
|
@ -267,12 +267,13 @@ namespace OpenSim
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "save oar",
|
m_console.Commands.AddCommand("region", false, "save oar",
|
||||||
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
||||||
"save oar [-p|--profile=<url>] [<OAR path>]",
|
"save oar [-p|--profile=<url>] [--noassets] [<OAR path>]",
|
||||||
"Save a region's data to an OAR archive.",
|
"Save a region's data to an OAR archive.",
|
||||||
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
|
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
|
||||||
"-p|--profile=<url> adds the url of the profile service to the saved user information" + Environment.NewLine
|
"-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
||||||
+ " The OAR path must be a filesystem path."
|
+ " The OAR path must be a filesystem path."
|
||||||
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
+ " If this is not given then the oar is saved to region.oar in the current directory." + Environment.NewLine
|
||||||
|
+ "--noassets stops assets being saved to the OAR.",
|
||||||
SaveOar);
|
SaveOar);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "edit scale",
|
m_console.Commands.AddCommand("region", false, "edit scale",
|
||||||
|
|
|
@ -46,6 +46,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determine whether this archive will save assets. Default is true.
|
||||||
|
/// </summary>
|
||||||
|
public bool SaveAssets { get; set; }
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Used to select all inventory nodes in a folder but not the folder itself
|
/// Used to select all inventory nodes in a folder but not the folder itself
|
||||||
/// </value>
|
/// </value>
|
||||||
|
@ -112,6 +117,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
m_invPath = invPath;
|
m_invPath = invPath;
|
||||||
m_saveStream = saveStream;
|
m_saveStream = saveStream;
|
||||||
m_assetGatherer = new UuidGatherer(m_scene.AssetService);
|
m_assetGatherer = new UuidGatherer(m_scene.AssetService);
|
||||||
|
|
||||||
|
SaveAssets = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
|
protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
|
||||||
|
@ -147,6 +154,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
|
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
|
||||||
m_archiveWriter.WriteFile(filename, serialization);
|
m_archiveWriter.WriteFile(filename, serialization);
|
||||||
|
|
||||||
|
if (SaveAssets)
|
||||||
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
|
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,6 +197,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
|
public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
|
||||||
{
|
{
|
||||||
|
if (options.ContainsKey("noassets") && (bool)options["noassets"])
|
||||||
|
SaveAssets = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
InventoryFolderBase inventoryFolder = null;
|
InventoryFolderBase inventoryFolder = null;
|
||||||
|
@ -280,12 +291,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
// Don't put all this profile information into the archive right now.
|
// Don't put all this profile information into the archive right now.
|
||||||
//SaveUsers();
|
//SaveUsers();
|
||||||
|
|
||||||
|
if (SaveAssets)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count);
|
||||||
|
|
||||||
new AssetsRequest(
|
new AssetsRequest(
|
||||||
new AssetsArchiver(m_archiveWriter),
|
new AssetsArchiver(m_archiveWriter),
|
||||||
m_assetUuids, m_scene.AssetService,
|
m_assetUuids, m_scene.AssetService,
|
||||||
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
|
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
|
||||||
options, ReceivedAllAssets).Execute();
|
options, ReceivedAllAssets).Execute();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified");
|
||||||
|
|
||||||
|
ReceivedAllAssets(new List<UUID>(), new List<UUID>());
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
m_saveStream.Close();
|
m_saveStream.Close();
|
||||||
|
@ -381,19 +403,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options"></param>
|
/// <param name="options"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string CreateControlFile(Dictionary<string, object> options)
|
public string CreateControlFile(Dictionary<string, object> options)
|
||||||
{
|
{
|
||||||
int majorVersion, minorVersion;
|
int majorVersion, minorVersion;
|
||||||
|
|
||||||
if (options.ContainsKey("profile"))
|
if (options.ContainsKey("profile"))
|
||||||
{
|
{
|
||||||
majorVersion = 1;
|
majorVersion = 1;
|
||||||
minorVersion = 1;
|
minorVersion = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
majorVersion = 0;
|
majorVersion = 0;
|
||||||
minorVersion = 2;
|
minorVersion = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion);
|
m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion);
|
||||||
|
@ -405,6 +427,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
xtw.WriteStartElement("archive");
|
xtw.WriteStartElement("archive");
|
||||||
xtw.WriteAttributeString("major_version", majorVersion.ToString());
|
xtw.WriteAttributeString("major_version", majorVersion.ToString());
|
||||||
xtw.WriteAttributeString("minor_version", minorVersion.ToString());
|
xtw.WriteAttributeString("minor_version", minorVersion.ToString());
|
||||||
|
|
||||||
|
xtw.WriteElementString("assets_included", SaveAssets.ToString());
|
||||||
|
|
||||||
xtw.WriteEndElement();
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
xtw.Flush();
|
xtw.Flush();
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
|
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
this, "save iar",
|
this, "save iar",
|
||||||
"save iar [--p|-profile=<url>] <first> <last> <inventory path> <password> [<IAR path>]",
|
"save iar [--p|-profile=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]",
|
||||||
"Save user inventory archive (IAR).",
|
"Save user inventory archive (IAR).",
|
||||||
"<first> is the user's first name." + Environment.NewLine
|
"<first> is the user's first name." + Environment.NewLine
|
||||||
+ "<last> is the user's last name." + Environment.NewLine
|
+ "<last> is the user's last name." + Environment.NewLine
|
||||||
|
@ -130,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
+ "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
+ "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
||||||
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
|
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
|
||||||
+ "-v|--verbose extra debug messages." + Environment.NewLine
|
+ "-v|--verbose extra debug messages." + Environment.NewLine
|
||||||
|
+ "--noassets stops assets being saved to the IAR."
|
||||||
+ "<IAR path> is the filesystem path at which to save the IAR."
|
+ "<IAR path> is the filesystem path at which to save the IAR."
|
||||||
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
|
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
|
||||||
HandleSaveInvConsoleCommand);
|
HandleSaveInvConsoleCommand);
|
||||||
|
@ -398,6 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
|
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
|
||||||
ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
|
ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
|
||||||
ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
|
ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
|
||||||
|
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
|
||||||
|
|
||||||
List<string> mainParams = ops.Parse(cmdparams);
|
List<string> mainParams = ops.Parse(cmdparams);
|
||||||
|
|
||||||
|
@ -406,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
if (mainParams.Count < 6)
|
if (mainParams.Count < 6)
|
||||||
{
|
{
|
||||||
m_log.Error(
|
m_log.Error(
|
||||||
"[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] <first name> <last name> <inventory path> <user password> [<save file path>]");
|
"[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,15 +426,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||||
"[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
|
"[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
|
||||||
savePath, invPath, firstName, lastName);
|
savePath, invPath, firstName, lastName);
|
||||||
|
|
||||||
|
lock (m_pendingConsoleSaves)
|
||||||
|
m_pendingConsoleSaves.Add(id);
|
||||||
|
|
||||||
ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
|
ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
|
||||||
}
|
}
|
||||||
catch (InventoryArchiverException e)
|
catch (InventoryArchiverException e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
|
m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_pendingConsoleSaves)
|
|
||||||
m_pendingConsoleSaves.Add(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveInvConsoleCommandCompleted(
|
private void SaveInvConsoleCommandCompleted(
|
||||||
|
|
|
@ -123,11 +123,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive
|
/// Test saving a single inventory item to an IAR
|
||||||
/// (subject to change since there is no fixed format yet).
|
/// (subject to change since there is no fixed format yet).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSaveItemToIarV0_1()
|
public void TestSaveItemToIar()
|
||||||
{
|
{
|
||||||
TestHelper.InMethod();
|
TestHelper.InMethod();
|
||||||
// log4net.Config.XmlConfigurator.Configure();
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
@ -211,6 +211,106 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assert.That(gotControlFile, Is.True, "No control file in archive");
|
||||||
|
Assert.That(gotObject1File, Is.True, "No item1 file in archive");
|
||||||
|
// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
|
||||||
|
|
||||||
|
// TODO: Test presence of more files and contents of files.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test saving a single inventory item to an IAR without its asset
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSaveItemToIarNoAssets()
|
||||||
|
{
|
||||||
|
TestHelper.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
// Create user
|
||||||
|
string userFirstName = "Jock";
|
||||||
|
string userLastName = "Stirrup";
|
||||||
|
string userPassword = "troll";
|
||||||
|
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
|
||||||
|
UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
|
||||||
|
|
||||||
|
// Create asset
|
||||||
|
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
|
||||||
|
SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
|
||||||
|
|
||||||
|
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
|
||||||
|
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
|
||||||
|
m_scene.AssetService.Store(asset1);
|
||||||
|
|
||||||
|
// Create item
|
||||||
|
UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
|
||||||
|
string item1Name = "My Little Dog";
|
||||||
|
InventoryItemBase item1 = new InventoryItemBase();
|
||||||
|
item1.Name = item1Name;
|
||||||
|
item1.AssetID = asset1.FullID;
|
||||||
|
item1.ID = item1Id;
|
||||||
|
InventoryFolderBase objsFolder
|
||||||
|
= InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0];
|
||||||
|
item1.Folder = objsFolder.ID;
|
||||||
|
m_scene.AddInventoryItem(item1);
|
||||||
|
|
||||||
|
MemoryStream archiveWriteStream = new MemoryStream();
|
||||||
|
|
||||||
|
Dictionary<string, Object> options = new Dictionary<string, Object>();
|
||||||
|
options.Add("noassets", true);
|
||||||
|
|
||||||
|
// When we're not saving assets, archiving is being done synchronously.
|
||||||
|
m_archiverModule.ArchiveInventory(
|
||||||
|
Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
|
||||||
|
|
||||||
|
byte[] archive = archiveWriteStream.ToArray();
|
||||||
|
MemoryStream archiveReadStream = new MemoryStream(archive);
|
||||||
|
TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
|
||||||
|
|
||||||
|
//bool gotControlFile = false;
|
||||||
|
bool gotObject1File = false;
|
||||||
|
//bool gotObject2File = false;
|
||||||
|
string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1);
|
||||||
|
string expectedObject1FilePath = string.Format(
|
||||||
|
"{0}{1}",
|
||||||
|
ArchiveConstants.INVENTORY_PATH,
|
||||||
|
expectedObject1FileName);
|
||||||
|
|
||||||
|
string filePath;
|
||||||
|
TarArchiveReader.TarEntryType tarEntryType;
|
||||||
|
|
||||||
|
// Console.WriteLine("Reading archive");
|
||||||
|
|
||||||
|
while (tar.ReadEntry(out filePath, out tarEntryType) != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Got {0}", filePath);
|
||||||
|
|
||||||
|
// if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
|
||||||
|
// {
|
||||||
|
// gotControlFile = true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
|
||||||
|
{
|
||||||
|
// string fileName = filePath.Remove(0, "Objects/".Length);
|
||||||
|
//
|
||||||
|
// if (fileName.StartsWith(part1.Name))
|
||||||
|
// {
|
||||||
|
Assert.That(expectedObject1FilePath, Is.EqualTo(filePath));
|
||||||
|
gotObject1File = true;
|
||||||
|
// }
|
||||||
|
// else if (fileName.StartsWith(part2.Name))
|
||||||
|
// {
|
||||||
|
// Assert.That(fileName, Is.EqualTo(expectedObject2FileName));
|
||||||
|
// gotObject2File = true;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
|
||||||
|
{
|
||||||
|
Assert.Fail("Found asset path in TestSaveItemToIarNoAssets()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Assert.That(gotControlFile, Is.True, "No control file in archive");
|
// Assert.That(gotControlFile, Is.True, "No control file in archive");
|
||||||
Assert.That(gotObject1File, Is.True, "No item1 file in archive");
|
Assert.That(gotObject1File, Is.True, "No item1 file in archive");
|
||||||
// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
|
// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
|
||||||
|
|
|
@ -60,6 +60,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static int MAX_MAJOR_VERSION = 0;
|
public static int MAX_MAJOR_VERSION = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determine whether this archive will save assets. Default is true.
|
||||||
|
/// </summary>
|
||||||
|
public bool SaveAssets { get; set; }
|
||||||
|
|
||||||
protected Scene m_scene;
|
protected Scene m_scene;
|
||||||
protected Stream m_saveStream;
|
protected Stream m_saveStream;
|
||||||
protected Guid m_requestId;
|
protected Guid m_requestId;
|
||||||
|
@ -73,10 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
/// <exception cref="System.IO.IOException">
|
/// <exception cref="System.IO.IOException">
|
||||||
/// If there was a problem opening a stream for the file specified by the savePath
|
/// If there was a problem opening a stream for the file specified by the savePath
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId)
|
public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress);
|
m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress);
|
||||||
|
@ -86,10 +89,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
|
"[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
|
||||||
+ "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
|
+ "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
|
||||||
m_log.Error(e);
|
m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_requestId = requestId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -98,11 +99,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
/// <param name="scene"></param>
|
/// <param name="scene"></param>
|
||||||
/// <param name="saveStream">The stream to which to save data.</param>
|
/// <param name="saveStream">The stream to which to save data.</param>
|
||||||
/// <param name="requestId">The id associated with this request</param>
|
/// <param name="requestId">The id associated with this request</param>
|
||||||
public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId)
|
public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId)
|
||||||
|
{
|
||||||
|
m_saveStream = saveStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_saveStream = saveStream;
|
|
||||||
m_requestId = requestId;
|
m_requestId = requestId;
|
||||||
|
|
||||||
|
SaveAssets = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -111,6 +118,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
/// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
|
/// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
|
||||||
public void ArchiveRegion(Dictionary<string, object> options)
|
public void ArchiveRegion(Dictionary<string, object> options)
|
||||||
{
|
{
|
||||||
|
if (options.ContainsKey("noassets") && (bool)options["noassets"])
|
||||||
|
SaveAssets = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
|
Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
|
||||||
|
@ -118,16 +128,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
EntityBase[] entities = m_scene.GetEntities();
|
EntityBase[] entities = m_scene.GetEntities();
|
||||||
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
|
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
|
||||||
|
|
||||||
/*
|
|
||||||
foreach (ILandObject lo in m_scene.LandChannel.AllParcels())
|
|
||||||
{
|
|
||||||
if (name == lo.LandData.Name)
|
|
||||||
{
|
|
||||||
// This is the parcel we want
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Filter entities so that we only have scene objects.
|
// Filter entities so that we only have scene objects.
|
||||||
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
|
// FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
|
||||||
// end up having to do this
|
// end up having to do this
|
||||||
|
@ -142,6 +142,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SaveAssets)
|
||||||
|
{
|
||||||
UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
|
UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
|
||||||
|
|
||||||
foreach (SceneObjectGroup sceneObject in sceneObjects)
|
foreach (SceneObjectGroup sceneObject in sceneObjects)
|
||||||
|
@ -152,6 +154,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
|
"[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
|
||||||
sceneObjects.Count, assetUuids.Count);
|
sceneObjects.Count, assetUuids.Count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure that we also request terrain texture assets
|
// Make sure that we also request terrain texture assets
|
||||||
RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
|
RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
|
||||||
|
@ -188,10 +195,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
|
archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
|
||||||
m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
|
m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
|
||||||
|
|
||||||
|
if (SaveAssets)
|
||||||
new AssetsRequest(
|
new AssetsRequest(
|
||||||
new AssetsArchiver(archiveWriter), assetUuids,
|
new AssetsArchiver(archiveWriter), assetUuids,
|
||||||
m_scene.AssetService, m_scene.UserAccountService,
|
m_scene.AssetService, m_scene.UserAccountService,
|
||||||
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
|
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
|
||||||
|
else
|
||||||
|
awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
@ -204,9 +214,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
/// Create the control file for the most up to date archive
|
/// Create the control file for the most up to date archive
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string CreateControlFile(Dictionary<string, object> options)
|
public string CreateControlFile(Dictionary<string, object> options)
|
||||||
{
|
{
|
||||||
int majorVersion = MAX_MAJOR_VERSION, minorVersion = 6;
|
int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7;
|
||||||
//
|
//
|
||||||
// if (options.ContainsKey("version"))
|
// if (options.ContainsKey("version"))
|
||||||
// {
|
// {
|
||||||
|
@ -258,6 +268,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
|
xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
|
||||||
xtw.WriteElementString("id", UUID.Random().ToString());
|
xtw.WriteElementString("id", UUID.Random().ToString());
|
||||||
xtw.WriteEndElement();
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
|
xtw.WriteElementString("assets_included", SaveAssets.ToString());
|
||||||
|
|
||||||
xtw.WriteEndElement();
|
xtw.WriteEndElement();
|
||||||
|
|
||||||
xtw.Flush();
|
xtw.Flush();
|
||||||
|
|
|
@ -127,6 +127,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
OptionSet ops = new OptionSet();
|
OptionSet ops = new OptionSet();
|
||||||
// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
|
// ops.Add("v|version=", delegate(string v) { options["version"] = v; });
|
||||||
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
|
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
|
||||||
|
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
|
||||||
|
|
||||||
List<string> mainParams = ops.Parse(cmdparams);
|
List<string> mainParams = ops.Parse(cmdparams);
|
||||||
|
|
||||||
|
@ -160,7 +161,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
|
|
||||||
public void ArchiveRegion(Stream saveStream, Guid requestId)
|
public void ArchiveRegion(Stream saveStream, Guid requestId)
|
||||||
{
|
{
|
||||||
new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(new Dictionary<string, object>());
|
ArchiveRegion(saveStream, requestId, new Dictionary<string, object>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options)
|
||||||
|
{
|
||||||
|
new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DearchiveRegion(string loadPath)
|
public void DearchiveRegion(string loadPath)
|
||||||
|
|
|
@ -211,6 +211,89 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
// TODO: Test presence of more files and contents of files.
|
// TODO: Test presence of more files and contents of files.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test saving an OpenSim Region Archive with the no assets option
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestSaveOarNoAssets()
|
||||||
|
{
|
||||||
|
TestHelper.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
SceneObjectPart part1 = CreateSceneObjectPart1();
|
||||||
|
SceneObjectGroup sog1 = new SceneObjectGroup(part1);
|
||||||
|
m_scene.AddNewSceneObject(sog1, false);
|
||||||
|
|
||||||
|
SceneObjectPart part2 = CreateSceneObjectPart2();
|
||||||
|
|
||||||
|
AssetNotecard nc = new AssetNotecard();
|
||||||
|
nc.BodyText = "Hello World!";
|
||||||
|
nc.Encode();
|
||||||
|
UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
|
||||||
|
UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
|
||||||
|
AssetBase ncAsset
|
||||||
|
= AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
|
||||||
|
m_scene.AssetService.Store(ncAsset);
|
||||||
|
SceneObjectGroup sog2 = new SceneObjectGroup(part2);
|
||||||
|
TaskInventoryItem ncItem
|
||||||
|
= new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
|
||||||
|
part2.Inventory.AddInventoryItem(ncItem, true);
|
||||||
|
|
||||||
|
m_scene.AddNewSceneObject(sog2, false);
|
||||||
|
|
||||||
|
MemoryStream archiveWriteStream = new MemoryStream();
|
||||||
|
|
||||||
|
Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
|
||||||
|
|
||||||
|
Dictionary<string, Object> options = new Dictionary<string, Object>();
|
||||||
|
options.Add("noassets", true);
|
||||||
|
m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
|
||||||
|
//AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
|
||||||
|
//while (assetServer.HasWaitingRequests())
|
||||||
|
// assetServer.ProcessNextRequest();
|
||||||
|
|
||||||
|
// Don't wait for completion - with --noassets save oar happens synchronously
|
||||||
|
// Monitor.Wait(this, 60000);
|
||||||
|
|
||||||
|
Assert.That(m_lastRequestId, Is.EqualTo(requestId));
|
||||||
|
|
||||||
|
byte[] archive = archiveWriteStream.ToArray();
|
||||||
|
MemoryStream archiveReadStream = new MemoryStream(archive);
|
||||||
|
TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
|
||||||
|
|
||||||
|
List<string> foundPaths = new List<string>();
|
||||||
|
List<string> expectedPaths = new List<string>();
|
||||||
|
expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog1));
|
||||||
|
expectedPaths.Add(ArchiveHelpers.CreateObjectPath(sog2));
|
||||||
|
|
||||||
|
string filePath;
|
||||||
|
TarArchiveReader.TarEntryType tarEntryType;
|
||||||
|
|
||||||
|
byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
|
||||||
|
Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
|
||||||
|
|
||||||
|
ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
|
||||||
|
arr.LoadControlFile(filePath, data);
|
||||||
|
|
||||||
|
Assert.That(arr.ControlFileLoaded, Is.True);
|
||||||
|
|
||||||
|
while (tar.ReadEntry(out filePath, out tarEntryType) != null)
|
||||||
|
{
|
||||||
|
if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
|
||||||
|
{
|
||||||
|
Assert.Fail("Asset was found in saved oar of TestSaveOarNoAssets()");
|
||||||
|
}
|
||||||
|
else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
|
||||||
|
{
|
||||||
|
foundPaths.Add(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.That(foundPaths, Is.EquivalentTo(expectedPaths));
|
||||||
|
|
||||||
|
// TODO: Test presence of more files and contents of files.
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test loading an OpenSim Region Archive.
|
/// Test loading an OpenSim Region Archive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -230,7 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
// upset load
|
// upset load
|
||||||
tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
|
tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
|
||||||
|
|
||||||
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>()));
|
tar.WriteFile(
|
||||||
|
ArchiveConstants.CONTROL_FILE_PATH,
|
||||||
|
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
|
||||||
|
|
||||||
SceneObjectPart part1 = CreateSceneObjectPart1();
|
SceneObjectPart part1 = CreateSceneObjectPart1();
|
||||||
SceneObjectGroup object1 = new SceneObjectGroup(part1);
|
SceneObjectGroup object1 = new SceneObjectGroup(part1);
|
||||||
|
@ -331,7 +416,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
|
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
|
||||||
|
|
||||||
tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
|
tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
|
||||||
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestPreparation.CreateControlFile(new Dictionary<string, Object>()));
|
tar.WriteFile(
|
||||||
|
ArchiveConstants.CONTROL_FILE_PATH,
|
||||||
|
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
|
||||||
|
|
||||||
RegionSettings rs = new RegionSettings();
|
RegionSettings rs = new RegionSettings();
|
||||||
rs.AgentLimit = 17;
|
rs.AgentLimit = 17;
|
||||||
|
|
|
@ -52,31 +52,44 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Archive the region to the given path
|
/// Archive the region to the given path
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
/// <remarks>
|
||||||
/// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
|
/// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
|
||||||
/// the EventManager.OnOarFileSaved event.
|
/// the EventManager.OnOarFileSaved event.
|
||||||
///
|
/// </remarks>
|
||||||
/// <param name="savePath"></param>
|
/// <param name="savePath"></param>
|
||||||
/// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
|
/// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
|
||||||
|
/// <param name="options">Options for the save</param>
|
||||||
void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options);
|
void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Archive the region to a stream.
|
/// Archive the region to a stream.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
/// <remarks>
|
||||||
/// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
|
/// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
|
||||||
/// the EventManager.OnOarFileSaved event.
|
/// the EventManager.OnOarFileSaved event.
|
||||||
///
|
/// </remarks>
|
||||||
/// <param name="saveStream"></param>
|
/// <param name="saveStream"></param>
|
||||||
/// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
|
/// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
|
||||||
void ArchiveRegion(Stream saveStream, Guid requestId);
|
void ArchiveRegion(Stream saveStream, Guid requestId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Archive the region to a stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method occurs asynchronously. If you want notification of when it has completed then subscribe to
|
||||||
|
/// the EventManager.OnOarFileSaved event.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="saveStream"></param>
|
||||||
|
/// <param name="requestId">If supplied, this request Id is later returned in the saved event</param>
|
||||||
|
/// <param name="options">Options for the save</param>
|
||||||
|
void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dearchive the given region archive. This replaces the existing scene.
|
/// Dearchive the given region archive. This replaces the existing scene.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
/// <remarks>
|
||||||
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
|
/// If you want notification of when it has completed then subscribe to the EventManager.OnOarFileLoaded event.
|
||||||
///
|
/// </remarks>
|
||||||
/// <param name="loadPath"></param>
|
/// <param name="loadPath"></param>
|
||||||
void DearchiveRegion(string loadPath);
|
void DearchiveRegion(string loadPath);
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
|
||||||
scene.AddCommand(
|
scene.AddCommand(
|
||||||
this, "appearance show",
|
this, "appearance show",
|
||||||
"appearance show",
|
"appearance show",
|
||||||
"Show appearance information for each avatar in the simulator. At the moment, ",
|
"Show appearance information for each avatar in the simulator.",
|
||||||
|
"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.",
|
||||||
ShowAppearanceInfo);
|
ShowAppearanceInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,9 @@ namespace OpenSim.Services.InventoryService
|
||||||
{
|
{
|
||||||
public class XInventoryService : ServiceBase, IInventoryService
|
public class XInventoryService : ServiceBase, IInventoryService
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
// private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(
|
// LogManager.GetLogger(
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected IXInventoryData m_Database;
|
protected IXInventoryData m_Database;
|
||||||
protected bool m_AllowDelete = true;
|
protected bool m_AllowDelete = true;
|
||||||
|
@ -424,7 +424,7 @@ namespace OpenSim.Services.InventoryService
|
||||||
{
|
{
|
||||||
if (!m_Database.DeleteItems(
|
if (!m_Database.DeleteItems(
|
||||||
new string[] { "inventoryID", "assetType" },
|
new string[] { "inventoryID", "assetType" },
|
||||||
new string[] { id.ToString(), ((sbyte)AssetType.Link).ToString() }));
|
new string[] { id.ToString(), ((sbyte)AssetType.Link).ToString() }))
|
||||||
{
|
{
|
||||||
m_Database.DeleteItems(
|
m_Database.DeleteItems(
|
||||||
new string[] { "inventoryID", "assetType" },
|
new string[] { "inventoryID", "assetType" },
|
||||||
|
|
Loading…
Reference in New Issue