From deeb7287a204af34caa24e7b221222de2fb3583b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 28 Jan 2012 00:39:53 +0000 Subject: [PATCH 1/4] Comment out xfer section in Scene.UpdateTaskInventory() which was causing spurious errors and "script saved" messages when script properties were changed. Viewers since at least Linden Lab 1.23 use the script upload capability to save script changes. It's unknown whether the commented out code was working for very old viewers or not. Code is commented out to reduce complexity and so that useful error messages don't need to be removed. If there is a substantial population using extremely old viewers that can't upgrade to a newer version 1 viewer (e.g. 1.23) or similar TPV then this can be revisited. --- .../Framework/Scenes/Scene.Inventory.cs | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index f344dcc64f..dd3208acb1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1472,20 +1472,27 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()", // currentItem.Name, part.Name); - - IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); - if (agentTransactions != null) - { - agentTransactions.HandleTaskItemUpdateFromTransaction( - remoteClient, part, transactionID, currentItem); - if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) - remoteClient.SendAgentAlertMessage("Notecard saved", false); - else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) - remoteClient.SendAgentAlertMessage("Script saved", false); - else - remoteClient.SendAgentAlertMessage("Item saved", false); - } + // Viewers from at least Linden Lab 1.23 onwards use a capability to update script contents rather + // than UDP. With viewers from at least 1.23 onwards, changing properties on scripts (e.g. renaming) causes + // this to spew spurious errors and "thing saved" messages. + // Rather than retaining complexity in the code and removing useful error messages, I'm going to + // comment this section out. If this was still working for very old viewers and there is + // a large population using them which cannot upgrade to 1.23 or derivatives then we can revisit + // this - justincc +// IAgentAssetTransactions agentTransactions = this.RequestModuleInterface(); +// if (agentTransactions != null) +// { +// agentTransactions.HandleTaskItemUpdateFromTransaction( +// remoteClient, part, transactionID, currentItem); +// +// if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) +// remoteClient.SendAgentAlertMessage("Notecard saved", false); +// else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) +// remoteClient.SendAgentAlertMessage("Script saved", false); +// else +// remoteClient.SendAgentAlertMessage("Item saved", false); +// } // Base ALWAYS has move currentItem.BasePermissions |= (uint)PermissionMask.Move; From 088f1213b423204f6c8ae70d90e8f2bea58162c6 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 28 Jan 2012 01:01:19 +0000 Subject: [PATCH 2/4] Remove accidental /user postfix from HomeURI in [HGInventoryAccessModule] in GridCommon.ini.example and from SRV_ProfileServerURI in [LoginService] in Robust.HG.ini.example As per http://opensimulator.org/mantis/view.php?id=5852, confirmed by diva via aiaustin --- bin/Robust.HG.ini.example | 2 +- bin/config-include/GridCommon.ini.example | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 668fabc448..ab5880d741 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -251,7 +251,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 SRV_HomeURI = "http://127.0.0.1:8002" SRV_InventoryServerURI = "http://127.0.0.1:8002" SRV_AssetServerURI = "http://127.0.0.1:8002" - SRV_ProfileServerURI = "http://127.0.0.1:8002/user" + SRV_ProfileServerURI = "http://127.0.0.1:8002" SRV_FriendsServerURI = "http://127.0.0.1:8002" SRV_IMServerURI = "http://127.0.0.1:8002" diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index d70c8e47c1..4195bcee50 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -129,7 +129,7 @@ ; Change this to your server ; accessible from other grids ; - HomeURI = "http://mygridserver.com:8002/user" + HomeURI = "http://mygridserver.com:8002" Gatekeeper = "http://mygridserver.com:8002" ;; If you want to protect your assets from being copied by foreign visitors ;; uncomment the next line. You may want to do this on sims that have licensed content. From 154ba0124aaf0836ee50bce81a3441be6d11f06a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 28 Jan 2012 02:21:41 +0000 Subject: [PATCH 3/4] Add experimental --publish option to "save oar" so that OARs reloaded to the same grid don't have the publisher as owner. --- OpenSim/Region/Application/OpenSim.cs | 8 +- .../World/Archiver/ArchiveReadRequest.cs | 16 ++-- .../ArchiveWriteRequestPreparation.cs | 3 - .../World/Archiver/ArchiverModule.cs | 1 + .../World/Archiver/Tests/ArchiverTests.cs | 83 ++++++++++++++++++- .../Framework/Scenes/SceneObjectGroup.cs | 6 ++ .../Serialization/SceneObjectSerializer.cs | 20 +++-- 7 files changed, 116 insertions(+), 21 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 8683476599..145875b601 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -291,12 +291,16 @@ namespace OpenSim m_console.Commands.AddCommand("region", false, "save oar", //"save oar [-v|--version=] [-p|--profile=] []", - "save oar [-h|--home=] [--noassets] [--perm=] []", + "save oar [-h|--home=] [--noassets] [--publish] [--perm=] []", "Save a region's data to an OAR archive.", // "-v|--version= generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine "-h|--home= adds the url of the profile service to the saved user information." + Environment.NewLine + "--noassets stops assets being saved to the OAR." + Environment.NewLine - + "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine + + "--publish saves an OAR stripped of owner and last owner information." + Environment.NewLine + + " on reload, the estate owner will be the owner of all objects" + Environment.NewLine + + " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published" + Environment.NewLine + + " this option is EXPERIMENTAL" + Environment.NewLine + + "--perm= stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine + " can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine + "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.", diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index edc5ba432a..a6dbaba7d7 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -116,6 +116,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_merge = merge; m_skipAssets = skipAssets; m_requestId = requestId; + + // Zero can never be a valid user id + m_validUserUuids[UUID.Zero] = false; } public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) @@ -125,6 +128,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver m_merge = merge; m_skipAssets = skipAssets; m_requestId = requestId; + + // Zero can never be a valid user id + m_validUserUuids[UUID.Zero] = false; } /// @@ -368,16 +374,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (!m_validUserUuids.ContainsKey(uuid)) { UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); - if (account != null) - m_validUserUuids.Add(uuid, true); - else - m_validUserUuids.Add(uuid, false); + m_validUserUuids.Add(uuid, account != null); } - if (m_validUserUuids[uuid]) - return true; - else - return false; + return m_validUserUuids[uuid]; } /// diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index b895afe85d..ffcf063121 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -282,10 +282,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied. if (permissionClass != PermissionClass.Owner) - { canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0; - } - bool partPermitted = true; if (checkPermissions.Contains("C") && !canCopy) diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index 0b22598834..f5a5a8d1be 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs @@ -142,6 +142,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver ops.Add("h|home=", delegate(string v) { options["home"] = v; }); ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); + ops.Add("publish", v => options["wipe-owners"] = v != null); ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); List mainParams = ops.Parse(cmdparams); diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index eec3c1be64..63f1363729 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs @@ -248,9 +248,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Dictionary options = new Dictionary(); 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); @@ -409,6 +406,86 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod()); } + /// + /// Test loading an OpenSim Region Archive saved with the --publish option. + /// + [Test] + public void TestLoadPublishedOar() + { + TestHelpers.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(); + m_scene.EventManager.OnOarFileSaved += SaveCompleted; + + Guid requestId = new Guid("00000000-0000-0000-0000-808080808080"); + + lock (this) + { + m_archiverModule.ArchiveRegion( + archiveWriteStream, requestId, new Dictionary() { { "wipe-owners", Boolean.TrueString } }); + + Monitor.Wait(this, 60000); + } + + Assert.That(m_lastRequestId, Is.EqualTo(requestId)); + + byte[] archive = archiveWriteStream.ToArray(); + MemoryStream archiveReadStream = new MemoryStream(archive); + + { + UUID estateOwner = TestHelpers.ParseTail(0x4747); + UUID objectOwner = TestHelpers.ParseTail(0x15); + + // Reload to new scene + ArchiverModule archiverModule = new ArchiverModule(); + SerialiserModule serialiserModule = new SerialiserModule(); + TerrainModule terrainModule = new TerrainModule(); + + TestScene scene2 = SceneHelpers.SetupScene(); + SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); + + // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is + // behaving correctly + UserAccountHelpers.CreateUserWithInventory(scene2, objectOwner); + + scene2.RegionInfo.EstateSettings.EstateOwner = estateOwner; + + lock (this) + { + scene2.EventManager.OnOarFileLoaded += LoadCompleted; + archiverModule.DearchiveRegion(archiveReadStream); + } + + Assert.That(m_lastErrorMessage, Is.Null); + + SceneObjectGroup loadedSog = scene2.GetSceneObjectGroup(part1.Name); + Assert.That(loadedSog.OwnerID, Is.EqualTo(estateOwner)); + Assert.That(loadedSog.LastOwnerID, Is.EqualTo(estateOwner)); + } + } + /// /// Test loading the region settings of an OpenSim Region Archive. /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index cad09b8c5f..739c5fa12c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -441,6 +441,12 @@ namespace OpenSim.Region.Framework.Scenes } } + public UUID LastOwnerID + { + get { return m_rootPart.LastOwnerID; } + set { m_rootPart.LastOwnerID = value; } + } + public UUID OwnerID { get { return m_rootPart.OwnerID; } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 7c60ddd8a3..3a08271c4f 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1192,8 +1192,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("ObjectSaleType", sop.ObjectSaleType.ToString()); writer.WriteElementString("OwnershipCost", sop.OwnershipCost.ToString()); WriteUUID(writer, "GroupID", sop.GroupID, options); - WriteUUID(writer, "OwnerID", sop.OwnerID, options); - WriteUUID(writer, "LastOwnerID", sop.LastOwnerID, options); + + UUID ownerID = options.ContainsKey("wipe-owners") ? UUID.Zero : sop.OwnerID; + WriteUUID(writer, "OwnerID", ownerID, options); + + UUID lastOwnerID = options.ContainsKey("wipe-owners") ? UUID.Zero : sop.LastOwnerID; + WriteUUID(writer, "LastOwnerID", lastOwnerID, options); + writer.WriteElementString("BaseMask", sop.BaseMask.ToString()); writer.WriteElementString("OwnerMask", sop.OwnerMask.ToString()); writer.WriteElementString("GroupMask", sop.GroupMask.ToString()); @@ -1277,7 +1282,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("BasePermissions", item.BasePermissions.ToString()); writer.WriteElementString("CreationDate", item.CreationDate.ToString()); - WriteUUID(writer, "CreatorID", item.CreatorID, options); if (item.CreatorData != null && item.CreatorData != string.Empty) @@ -1298,10 +1302,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("InvType", item.InvType.ToString()); WriteUUID(writer, "ItemID", item.ItemID, options); WriteUUID(writer, "OldItemID", item.OldItemID, options); - WriteUUID(writer, "LastOwnerID", item.LastOwnerID, options); + + UUID lastOwnerID = options.ContainsKey("wipe-owners") ? UUID.Zero : item.LastOwnerID; + WriteUUID(writer, "LastOwnerID", lastOwnerID, options); + writer.WriteElementString("Name", item.Name); writer.WriteElementString("NextPermissions", item.NextPermissions.ToString()); - WriteUUID(writer, "OwnerID", item.OwnerID, options); + + UUID ownerID = options.ContainsKey("wipe-owners") ? UUID.Zero : item.OwnerID; + WriteUUID(writer, "OwnerID", ownerID, options); + writer.WriteElementString("CurrentPermissions", item.CurrentPermissions.ToString()); WriteUUID(writer, "ParentID", item.ParentID, options); WriteUUID(writer, "ParentPartID", item.ParentPartID, options); From 2ef9fd05fa7abaf06f971f0e0945cbcbe828f318 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 28 Jan 2012 02:45:13 +0000 Subject: [PATCH 4/4] Add an overloaded SceneObjectPart.UpdateTextureEntry(Primitive.TextureEntry texEntry) for region modules --- .../Region/Framework/Scenes/SceneObjectPart.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ad3bcd5246..36d3588e44 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4520,10 +4520,18 @@ namespace OpenSim.Region.Framework.Scenes /// /// Update the texture entry for this part. /// - /// - public void UpdateTextureEntry(byte[] textureEntry) + /// + public void UpdateTextureEntry(byte[] serializedTextureEntry) + { + UpdateTextureEntry(new Primitive.TextureEntry(serializedTextureEntry, 0, serializedTextureEntry.Length)); + } + + /// + /// Update the texture entry for this part. + /// + /// + public void UpdateTextureEntry(Primitive.TextureEntry newTex) { - Primitive.TextureEntry newTex = new Primitive.TextureEntry(textureEntry, 0, textureEntry.Length); Primitive.TextureEntry oldTex = Shape.Textures; Changed changeFlags = 0; @@ -4555,7 +4563,7 @@ namespace OpenSim.Region.Framework.Scenes break; } - m_shape.TextureEntry = textureEntry; + m_shape.TextureEntry = newTex.GetBytes(); if (changeFlags != 0) TriggerScriptChangedEvent(changeFlags); UpdateFlag = UpdateRequired.FULL;