diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 0c4069fe54..619550c1c5 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -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
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 394ca27123..5deaf5264b 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -291,6 +291,59 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
// TODO: Test presence of more files and contents of files.
}
+ ///
+ /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g.
+ /// 2 can come after 3).
+ ///
+ [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()));
+
+ 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));
+ }
+
///
/// Test loading an OpenSim Region Archive.
///
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index 5e928f3e8f..830d9cbc1b 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -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 ",
- "Delete a scene object by owner", HandleDeleteObject);
+ m_console.Commands.AddCommand(
+ "Objects", false, "delete object owner",
+ "delete object owner ",
+ "Delete a scene object by owner", HandleDeleteObject);
- m_console.Commands.AddCommand("Objects", false, "delete object creator",
- "delete object creator ",
- "Delete a scene object by creator", HandleDeleteObject);
+ m_console.Commands.AddCommand(
+ "Objects", false, "delete object creator",
+ "delete object creator ",
+ "Delete a scene object by creator", HandleDeleteObject);
- m_console.Commands.AddCommand("Objects", false, "delete object uuid",
- "delete object uuid ",
- "Delete a scene object by uuid", HandleDeleteObject);
+ m_console.Commands.AddCommand(
+ "Objects", false, "delete object uuid",
+ "delete object uuid ",
+ "Delete a scene object by uuid", HandleDeleteObject);
- m_console.Commands.AddCommand("Objects", false, "delete object name",
- "delete object name ",
- "Delete a scene object by name", HandleDeleteObject);
+ m_console.Commands.AddCommand(
+ "Objects", false, "delete object name",
+ "delete object name [--regex] ",
+ "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 ",
- "Show details of scene objects with the given name", HandleShowObjectByName);
+ "show object name [--regex] ",
+ "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 ",
- "Show details of scene object parts with the given name", HandleShowPartByName);
+ "show part name [--regex] ",
+ "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 mainParams = options.Parse(cmdparams);
+
+ if (mainParams.Count < 4)
{
- m_console.OutputFormat("Usage: show object name ");
+ m_console.OutputFormat("Usage: show object name [--regex] ");
return;
}
- string name = cmd[3];
+ string name = mainParams[3];
List sceneObjects = new List();
+ Action 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 mainParams = options.Parse(cmdparams);
+
+ if (mainParams.Count < 4)
{
- m_console.OutputFormat("Usage: show part name ");
+ m_console.OutputFormat("Usage: show part name [--regex] ");
return;
}
- string name = cmd[3];
+ string name = mainParams[3];
List parts = new List();
- m_scene.ForEachSOG(so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }));
+ Action 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 deletes = new List();
-
+ List 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();
-// 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();
+
+ 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();
+
+ 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();
+
+ 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 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 mainParams = options.Parse(cmdparams);
+
+ if (mainParams.Count < 4)
+ {
+ m_console.OutputFormat("Usage: delete object name [--regex] ");
+ return null;
+ }
+
+ string name = mainParams[3];
+
+ List sceneObjects = new List();
+ Action 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;
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index f62eef3dfc..a1f434e567 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1010,7 +1010,18 @@ namespace OpenSim.Region.Framework.Scenes
public int LinkNum
{
get { return m_linkNum; }
- set { m_linkNum = value; }
+ set
+ {
+// if (ParentGroup != null)
+// {
+// m_log.DebugFormat(
+// "[SCENE OBJECT PART]: Setting linknum of {0}@{1} to {2} from {3}",
+// Name, AbsolutePosition, value, m_linkNum);
+// Util.PrintCallStack();
+// }
+
+ m_linkNum = value;
+ }
}
public byte ClickAction
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 151eba26bc..e223f4716f 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -1538,51 +1538,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
}
}
- //////// Read /////////
- public static bool Xml2ToSOG(XmlTextReader reader, SceneObjectGroup sog)
- {
- reader.Read();
- reader.ReadStartElement("SceneObjectGroup");
- SceneObjectPart root = Xml2ToSOP(reader);
- if (root != null)
- sog.SetRootPart(root);
- else
- {
- return false;
- }
-
- if (sog.UUID == UUID.Zero)
- sog.UUID = sog.RootPart.UUID;
-
- reader.Read(); // OtherParts
-
- while (!reader.EOF)
- {
- switch (reader.NodeType)
- {
- case XmlNodeType.Element:
- if (reader.Name == "SceneObjectPart")
- {
- SceneObjectPart child = Xml2ToSOP(reader);
- if (child != null)
- sog.AddPart(child);
- }
- else
- {
- //Logger.Log("Found unexpected prim XML element " + reader.Name, Helpers.LogLevel.Debug);
- reader.Read();
- }
- break;
- case XmlNodeType.EndElement:
- default:
- reader.Read();
- break;
- }
-
- }
- return true;
- }
-
public static SceneObjectPart Xml2ToSOP(XmlTextReader reader)
{
SceneObjectPart obj = new SceneObjectPart();
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
index d214eba1fc..a3485d29e6 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs
@@ -223,50 +223,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
public static SceneObjectGroup DeserializeGroupFromXml2(string xmlString)
{
- XmlDocument doc = new XmlDocument();
- XmlNode rootNode;
-
- XmlTextReader reader = new XmlTextReader(new StringReader(xmlString));
- reader.WhitespaceHandling = WhitespaceHandling.None;
- doc.Load(reader);
- reader.Close();
- rootNode = doc.FirstChild;
-
- // This is to deal with neighbouring regions that are still surrounding the group xml with the
- // tag. It should be possible to remove the first part of this if statement once we go past 0.5.9 (or
- // when some other changes forces all regions to upgrade).
- // This might seem rather pointless since prim crossing from this revision to an earlier revision remains
- // broken. But it isn't much work to accomodate the old format here.
- if (rootNode.LocalName.Equals("scene"))
- {
- foreach (XmlNode aPrimNode in rootNode.ChildNodes)
- {
- // There is only ever one prim. This oddity should be removeable post 0.5.9
- //return SceneObjectSerializer.FromXml2Format(aPrimNode.OuterXml);
- using (reader = new XmlTextReader(new StringReader(aPrimNode.OuterXml)))
- {
- SceneObjectGroup obj = new SceneObjectGroup();
- if (SceneObjectSerializer.Xml2ToSOG(reader, obj))
- return obj;
-
- return null;
- }
- }
-
- return null;
- }
- else
- {
- //return SceneObjectSerializer.FromXml2Format(rootNode.OuterXml);
- using (reader = new XmlTextReader(new StringReader(rootNode.OuterXml)))
- {
- SceneObjectGroup obj = new SceneObjectGroup();
- if (SceneObjectSerializer.Xml2ToSOG(reader, obj))
- return obj;
-
- return null;
- }
- }
+ return SceneObjectSerializer.FromXml2Format(xmlString);
}
///
@@ -307,8 +264,8 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
ICollection sceneObjects = new List();
foreach (XmlNode aPrimNode in rootNode.ChildNodes)
{
- SceneObjectGroup obj = CreatePrimFromXml2(scene, aPrimNode.OuterXml);
- if (obj != null && startScripts)
+ SceneObjectGroup obj = DeserializeGroupFromXml2(aPrimNode.OuterXml);
+ if (startScripts)
sceneObjects.Add(obj);
}
@@ -319,27 +276,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
}
}
- ///
- /// Create a prim from the xml2 representation.
- ///
- ///
- ///
- /// The scene object created. null if the scene object already existed
- protected static SceneObjectGroup CreatePrimFromXml2(Scene scene, string xmlData)
- {
- //SceneObjectGroup obj = SceneObjectSerializer.FromXml2Format(xmlData);
- using (XmlTextReader reader = new XmlTextReader(new StringReader(xmlData)))
- {
- SceneObjectGroup obj = new SceneObjectGroup();
- SceneObjectSerializer.Xml2ToSOG(reader, obj);
-
- if (scene.AddRestoredSceneObject(obj, true, false))
- return obj;
- else
- return null;
- }
- }
-
#endregion
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
index 78f94347bd..59829d994f 100644
--- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
@@ -624,7 +624,7 @@ namespace OpenSim.Tests.Common
///
///
/// The prefix to be given to part names. This will be suffixed with "Part"
- /// (e.g. mynamePart0 for the root part)
+ /// (e.g. mynamePart1 for the root part)
///
///
/// The hexadecimal last part of the UUID for parts created. A UUID of the form "00000000-0000-0000-0000-{0:XD12}"
@@ -637,14 +637,14 @@ namespace OpenSim.Tests.Common
SceneObjectGroup sog
= new SceneObjectGroup(
- CreateSceneObjectPart(string.Format("{0}Part0", partNamePrefix), new UUID(rawSogId), ownerId));
+ CreateSceneObjectPart(string.Format("{0}Part1", partNamePrefix), new UUID(rawSogId), ownerId));
if (parts > 1)
- for (int i = 1; i < parts; i++)
+ for (int i = 2; i <= parts; i++)
sog.AddPart(
CreateSceneObjectPart(
string.Format("{0}Part{1}", partNamePrefix, i),
- new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail + i)),
+ new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", uuidTail + i - 1)),
ownerId));
return sog;
diff --git a/bin/Ionic.Zip.dll b/bin/Ionic.Zip.dll
old mode 100755
new mode 100644