Merge branch 'master' into careminster

This commit is contained in:
Melanie
2012-05-16 12:40:45 +01:00
8 changed files with 288 additions and 225 deletions

View File

@@ -41,6 +41,7 @@ using OpenSim.Framework.Serialization.External;
using OpenSim.Region.CoreModules.World.Terrain;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.World.Archiver

View File

@@ -291,6 +291,59 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// TODO: Test presence of more files and contents of files.
}
/// <summary>
/// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g.
/// 2 can come after 3).
/// </summary>
[Test]
public void TestLoadOarUnorderedParts()
{
TestHelpers.InMethod();
UUID ownerId = TestHelpers.ParseTail(0xaaaa);
MemoryStream archiveWriteStream = new MemoryStream();
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
tar.WriteFile(
ArchiveConstants.CONTROL_FILE_PATH,
new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>()));
SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
SceneObjectPart sop2
= SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId);
SceneObjectPart sop3
= SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId);
// Add the parts so they will be written out in reverse order to the oar
sog1.AddPart(sop3);
sop3.LinkNum = 3;
sog1.AddPart(sop2);
sop2.LinkNum = 2;
tar.WriteFile(
ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition),
SceneObjectSerializer.ToXml2Format(sog1));
tar.Close();
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
lock (this)
{
m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
m_archiverModule.DearchiveRegion(archiveReadStream);
}
Assert.That(m_lastErrorMessage, Is.Null);
SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2");
Assert.That(part2.LinkNum, Is.EqualTo(2));
SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3");
Assert.That(part3.LinkNum, Is.EqualTo(3));
}
/// <summary>
/// Test loading an OpenSim Region Archive.
/// </summary>

View File

@@ -29,8 +29,10 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using log4net;
using Mono.Addins;
using NDesk.Options;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
@@ -78,25 +80,31 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_scene = scene;
m_console = MainConsole.Instance;
m_console.Commands.AddCommand("Objects", false, "delete object owner",
"delete object owner <UUID>",
"Delete a scene object by owner", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object owner",
"delete object owner <UUID>",
"Delete a scene object by owner", HandleDeleteObject);
m_console.Commands.AddCommand("Objects", false, "delete object creator",
"delete object creator <UUID>",
"Delete a scene object by creator", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object creator",
"delete object creator <UUID>",
"Delete a scene object by creator", HandleDeleteObject);
m_console.Commands.AddCommand("Objects", false, "delete object uuid",
"delete object uuid <UUID>",
"Delete a scene object by uuid", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object uuid",
"delete object uuid <UUID>",
"Delete a scene object by uuid", HandleDeleteObject);
m_console.Commands.AddCommand("Objects", false, "delete object name",
"delete object name <name>",
"Delete a scene object by name", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object name",
"delete object name [--regex] <name>",
"Delete a scene object by name.\nIf --regex is specified then the name is treatead as a regular expression",
HandleDeleteObject);
m_console.Commands.AddCommand("Objects", false, "delete object outside",
"delete object outside",
"Delete all scene objects outside region boundaries", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects", false, "delete object outside",
"delete object outside",
"Delete all scene objects outside region boundaries", HandleDeleteObject);
m_console.Commands.AddCommand(
"Objects",
@@ -109,8 +117,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"Objects",
false,
"show object name",
"show object name <name>",
"Show details of scene objects with the given name", HandleShowObjectByName);
"show object name [--regex] <name>",
"Show details of scene objects with the given name.\nIf --regex is specified then the name is treatead as a regular expression",
HandleShowObjectByName);
m_console.Commands.AddCommand(
"Objects",
@@ -123,8 +132,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
"Objects",
false,
"show part name",
"show part name <name>",
"Show details of scene object parts with the given name", HandleShowPartByName);
"show part name [--regex] <name>",
"Show details of scene object parts with the given name.\nIf --regex is specified then the name is treatead as a regular expression",
HandleShowPartByName);
}
public void RemoveRegion(Scene scene)
@@ -169,22 +179,38 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_console.OutputFormat(sb.ToString());
}
private void HandleShowObjectByName(string module, string[] cmd)
private void HandleShowObjectByName(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
if (cmd.Length < 4)
bool useRegex = false;
OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
{
m_console.OutputFormat("Usage: show object name <name>");
m_console.OutputFormat("Usage: show object name [--regex] <name>");
return;
}
string name = cmd[3];
string name = mainParams[3];
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
Action<SceneObjectGroup> searchAction;
m_scene.ForEachSOG(so => { if (so.Name == name) { sceneObjects.Add(so); }});
if (useRegex)
{
Regex nameRegex = new Regex(name);
searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }};
}
else
{
searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }};
}
m_scene.ForEachSOG(searchAction);
if (sceneObjects.Count == 0)
{
@@ -235,22 +261,39 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_console.OutputFormat(sb.ToString());
}
private void HandleShowPartByName(string module, string[] cmd)
private void HandleShowPartByName(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return;
if (cmd.Length < 4)
bool useRegex = false;
OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
{
m_console.OutputFormat("Usage: show part name <name>");
m_console.OutputFormat("Usage: show part name [--regex] <name>");
return;
}
string name = cmd[3];
string name = mainParams[3];
List<SceneObjectPart> parts = new List<SceneObjectPart>();
m_scene.ForEachSOG(so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }));
Action<SceneObjectGroup> searchAction;
if (useRegex)
{
Regex nameRegex = new Regex(name);
searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } });
}
else
{
searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } });
}
m_scene.ForEachSOG(searchAction);
if (parts.Count == 0)
{
@@ -312,96 +355,121 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
o = cmd[3];
}
List<SceneObjectGroup> deletes = new List<SceneObjectGroup>();
List<SceneObjectGroup> deletes = null;
UUID match;
bool requireConfirmation = true;
switch (mode)
{
case "owner":
if (!UUID.TryParse(o, out match))
return;
case "owner":
if (!UUID.TryParse(o, out match))
return;
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
if (g.OwnerID == match && !g.IsAttachment)
deletes.Add(g);
});
deletes = new List<SceneObjectGroup>();
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with owner {0}", match);
break;
case "creator":
if (!UUID.TryParse(o, out match))
return;
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
if (g.RootPart.CreatorID == match && !g.IsAttachment)
deletes.Add(g);
});
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with creator {0}", match);
break;
case "uuid":
if (!UUID.TryParse(o, out match))
return;
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
if (g.UUID == match && !g.IsAttachment)
deletes.Add(g);
});
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with uuid {0}", match);
break;
case "name":
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
if (g.RootPart.Name == o && !g.IsAttachment)
deletes.Add(g);
});
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with name {0}", o);
break;
case "outside":
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
SceneObjectPart rootPart = g.RootPart;
bool delete = false;
if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0)
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
delete = true;
}
else
{
ILandObject parcel
= m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
if (g.OwnerID == match && !g.IsAttachment)
deletes.Add(g);
});
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with owner {0}", match);
break;
case "creator":
if (!UUID.TryParse(o, out match))
return;
if (parcel == null || parcel.LandData.Name == "NO LAND")
deletes = new List<SceneObjectGroup>();
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
if (g.RootPart.CreatorID == match && !g.IsAttachment)
deletes.Add(g);
});
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with creator {0}", match);
break;
case "uuid":
if (!UUID.TryParse(o, out match))
return;
requireConfirmation = false;
deletes = new List<SceneObjectGroup>();
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
if (g.UUID == match && !g.IsAttachment)
deletes.Add(g);
});
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found with uuid {0}", match);
break;
case "name":
deletes = GetDeleteCandidatesByName(module, cmd);
break;
case "outside":
deletes = new List<SceneObjectGroup>();
m_scene.ForEachSOG(delegate (SceneObjectGroup g)
{
SceneObjectPart rootPart = g.RootPart;
bool delete = false;
if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0)
{
delete = true;
}
}
else
{
ILandObject parcel
= m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
if (parcel == null || parcel.LandData.Name == "NO LAND")
delete = true;
}
if (delete && !g.IsAttachment && !deletes.Contains(g))
deletes.Add(g);
});
if (deletes.Count == 0)
m_console.OutputFormat("No objects were found outside region bounds");
break;
if (delete && !g.IsAttachment && !deletes.Contains(g))
deletes.Add(g);
});
default:
m_console.OutputFormat("Unrecognized mode {0}", mode);
return;
}
// if (deletes.Count == 0)
// m_console.OutputFormat("No objects were found outside region bounds");
if (deletes == null || deletes.Count <= 0)
return;
break;
if (requireConfirmation)
{
string response = MainConsole.Instance.CmdPrompt(
string.Format(
"Are you sure that you want to delete {0} objects from {1}",
deletes.Count, m_scene.RegionInfo.RegionName),
"n");
if (response.ToLower() != "y")
{
MainConsole.Instance.OutputFormat(
"Aborting delete of {0} objects from {1}", deletes.Count, m_scene.RegionInfo.RegionName);
return;
}
}
m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName);
@@ -412,5 +480,44 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
m_scene.DeleteSceneObject(g, false);
}
}
private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams)
{
if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
return null;
bool useRegex = false;
OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
{
m_console.OutputFormat("Usage: delete object name [--regex] <name>");
return null;
}
string name = mainParams[3];
List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
Action<SceneObjectGroup> searchAction;
if (useRegex)
{
Regex nameRegex = new Regex(name);
searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }};
}
else
{
searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }};
}
m_scene.ForEachSOG(searchAction);
if (sceneObjects.Count == 0)
m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
return sceneObjects;
}
}
}