From 8c10cb5ffe783d457184923d32e8baea5321ed1d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 14 Jul 2010 20:43:35 +0100 Subject: [PATCH 01/21] improve closing of load/save iar streams in the event of a problem --- .../Archiver/InventoryArchiveReadRequest.cs | 80 +++++----- .../Archiver/InventoryArchiveWriteRequest.cs | 141 +++++++++--------- .../Archiver/InventoryArchiverException.cs | 40 +++++ .../Archiver/InventoryArchiverModule.cs | 113 ++++++++------ 4 files changed, 215 insertions(+), 159 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index c8697fe614..31dfe145f5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -93,37 +93,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// public List Execute() { - string filePath = "ERROR"; - int successfulAssetRestores = 0; - int failedAssetRestores = 0; - int successfulItemRestores = 0; - - List loadedNodes = new List(); - - List folderCandidates - = InventoryArchiveUtils.FindFolderByPath( - m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); - - if (folderCandidates.Count == 0) - { - // Possibly provide an option later on to automatically create this folder if it does not exist - m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); - - return loadedNodes; - } - - InventoryFolderBase rootDestinationFolder = folderCandidates[0]; - archive = new TarArchiveReader(m_loadStream); - - // In order to load identically named folders, we need to keep track of the folders that we have already - // resolved - Dictionary resolvedFolders = new Dictionary(); - - byte[] data; - TarArchiveReader.TarEntryType entryType; - try { + string filePath = "ERROR"; + int successfulAssetRestores = 0; + int failedAssetRestores = 0; + int successfulItemRestores = 0; + + List loadedNodes = new List(); + + List folderCandidates + = InventoryArchiveUtils.FindFolderByPath( + m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); + + if (folderCandidates.Count == 0) + { + // Possibly provide an option later on to automatically create this folder if it does not exist + m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); + + return loadedNodes; + } + + InventoryFolderBase rootDestinationFolder = folderCandidates[0]; + archive = new TarArchiveReader(m_loadStream); + + // In order to load identically named folders, we need to keep track of the folders that we have already + // resolved + Dictionary resolvedFolders = new Dictionary(); + + byte[] data; + TarArchiveReader.TarEntryType entryType; + while ((data = archive.ReadEntry(out filePath, out entryType)) != null) { if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) @@ -166,18 +166,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } } } + + archive.Close(); + + m_log.DebugFormat( + "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", + successfulAssetRestores, failedAssetRestores); + m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); + + return loadedNodes; } finally { - archive.Close(); - } - - m_log.DebugFormat( - "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", - successfulAssetRestores, failedAssetRestores); - m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); - - return loadedNodes; + m_loadStream.Close(); + } } public void Close() @@ -247,7 +249,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver ref string archivePath, Dictionary resolvedFolders) { - string originalArchivePath = archivePath; +// string originalArchivePath = archivePath; InventoryFolderBase destFolder = null; diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 2c2724e74c..25a78ff618 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -119,22 +119,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver protected void ReceivedAllAssets(ICollection assetsFoundUuids, ICollection assetsNotFoundUuids) { Exception reportedException = null; - bool succeeded = true; - + bool succeeded = true; + try { // We're almost done. Just need to write out the control file now m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, Create0p1ControlFile()); m_log.InfoFormat("[ARCHIVER]: Added control file to archive."); - m_archiveWriter.Close(); } catch (Exception e) { - m_saveStream.Close(); reportedException = e; succeeded = false; } + finally + { + m_saveStream.Close(); + } m_module.TriggerInventoryArchiveSaved( m_id, succeeded, m_userInfo, m_invPath, m_saveStream, reportedException); @@ -213,70 +215,68 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// public void Execute() { - InventoryFolderBase inventoryFolder = null; - InventoryItemBase inventoryItem = null; - InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); - - bool foundStar = false; - - // Eliminate double slashes and any leading / on the path. - string[] components - = m_invPath.Split( - new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); - - int maxComponentIndex = components.Length - 1; - - // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the - // folder itself. This may get more sophisicated later on - if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) - { - foundStar = true; - maxComponentIndex--; - } - - m_invPath = String.Empty; - for (int i = 0; i <= maxComponentIndex; i++) - { - m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; - } - - // Annoyingly Split actually returns the original string if the input string consists only of delimiters - // Therefore if we still start with a / after the split, then we need the root folder - if (m_invPath.Length == 0) - { - inventoryFolder = rootFolder; - } - else - { - m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); - List candidateFolders - = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); - if (candidateFolders.Count > 0) - inventoryFolder = candidateFolders[0]; - } - - // The path may point to an item instead - if (inventoryFolder == null) - { - inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); - //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath); - } - - if (null == inventoryFolder && null == inventoryItem) - { - // We couldn't find the path indicated - string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); - m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", errorMessage); - m_module.TriggerInventoryArchiveSaved( - m_id, false, m_userInfo, m_invPath, m_saveStream, - new Exception(errorMessage)); - return; - } - - m_archiveWriter = new TarArchiveWriter(m_saveStream); - try { + InventoryFolderBase inventoryFolder = null; + InventoryItemBase inventoryItem = null; + InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); + + bool foundStar = false; + + // Eliminate double slashes and any leading / on the path. + string[] components + = m_invPath.Split( + new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); + + int maxComponentIndex = components.Length - 1; + + // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the + // folder itself. This may get more sophisicated later on + if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) + { + foundStar = true; + maxComponentIndex--; + } + + m_invPath = String.Empty; + for (int i = 0; i <= maxComponentIndex; i++) + { + m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; + } + + // Annoyingly Split actually returns the original string if the input string consists only of delimiters + // Therefore if we still start with a / after the split, then we need the root folder + if (m_invPath.Length == 0) + { + inventoryFolder = rootFolder; + } + else + { + m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); + List candidateFolders + = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); + if (candidateFolders.Count > 0) + inventoryFolder = candidateFolders[0]; + } + + // The path may point to an item instead + if (inventoryFolder == null) + { + inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); + //inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath); + } + + if (null == inventoryFolder && null == inventoryItem) + { + // We couldn't find the path indicated + string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); + Exception e = new InventoryArchiverException(errorMessage); + m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); + throw e; + } + + m_archiveWriter = new TarArchiveWriter(m_saveStream); + if (inventoryFolder != null) { m_log.DebugFormat( @@ -297,16 +297,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // Don't put all this profile information into the archive right now. //SaveUsers(); + + new AssetsRequest( + new AssetsArchiver(m_archiveWriter), m_assetUuids, m_scene.AssetService, ReceivedAllAssets).Execute(); } catch (Exception) { - m_archiveWriter.Close(); + m_saveStream.Close(); throw; } - - new AssetsRequest( - new AssetsArchiver(m_archiveWriter), m_assetUuids, - m_scene.AssetService, ReceivedAllAssets).Execute(); } /// diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs new file mode 100644 index 0000000000..e07e2ca689 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverException.cs @@ -0,0 +1,40 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; + +namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver +{ + /// + /// Signals an inventory archiving problem + /// + public class InventoryArchiverException : Exception + { + public InventoryArchiverException(string message) : base(message) {} + public InventoryArchiverException(string message, Exception e) : base(message, e) {} + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index cfefbe9d3b..f7a2b098f5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -322,34 +322,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// protected void HandleLoadInvConsoleCommand(string module, string[] cmdparams) { - m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); - - Dictionary options = new Dictionary(); - OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); - - List mainParams = optionSet.Parse(cmdparams); - - if (mainParams.Count < 6) - { - m_log.Error( - "[INVENTORY ARCHIVER]: usage is load iar []"); - return; - } - - string firstName = mainParams[2]; - string lastName = mainParams[3]; - string invPath = mainParams[4]; - string pass = mainParams[5]; - string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); - - m_log.InfoFormat( - "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", - loadPath, invPath, firstName, lastName); - - if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) + try + { + m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); + + Dictionary options = new Dictionary(); + OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); + + List mainParams = optionSet.Parse(cmdparams); + + if (mainParams.Count < 6) + { + m_log.Error( + "[INVENTORY ARCHIVER]: usage is load iar []"); + return; + } + + string firstName = mainParams[2]; + string lastName = mainParams[3]; + string invPath = mainParams[4]; + string pass = mainParams[5]; + string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); + m_log.InfoFormat( - "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", - loadPath, firstName, lastName); + "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", + loadPath, invPath, firstName, lastName); + + if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) + m_log.InfoFormat( + "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", + loadPath, firstName, lastName); + } + catch (InventoryArchiverException e) + { + m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); + } } /// @@ -358,30 +365,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// protected void HandleSaveInvConsoleCommand(string module, string[] cmdparams) { - if (cmdparams.Length < 6) - { - m_log.Error( - "[INVENTORY ARCHIVER]: usage is save iar []"); - return; - } - - m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); - - string firstName = cmdparams[2]; - string lastName = cmdparams[3]; - string invPath = cmdparams[4]; - string pass = cmdparams[5]; - string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME); - - m_log.InfoFormat( - "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", - savePath, invPath, firstName, lastName); - Guid id = Guid.NewGuid(); - ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary()); - + + try + { + if (cmdparams.Length < 6) + { + m_log.Error( + "[INVENTORY ARCHIVER]: usage is save iar []"); + return; + } + + m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME."); + + string firstName = cmdparams[2]; + string lastName = cmdparams[3]; + string invPath = cmdparams[4]; + string pass = cmdparams[5]; + string savePath = (cmdparams.Length > 6 ? cmdparams[6] : DEFAULT_INV_BACKUP_FILENAME); + + m_log.InfoFormat( + "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", + savePath, invPath, firstName, lastName); + + ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, new Dictionary()); + } + catch (InventoryArchiverException e) + { + m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); + } + lock (m_pendingConsoleSaves) - m_pendingConsoleSaves.Add(id); + m_pendingConsoleSaves.Add(id); } private void SaveInvConsoleCommandCompleted( From 6afa55d446860250812e78c92f6a7f6c5843a5fa Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 14 Jul 2010 14:47:01 -0700 Subject: [PATCH 02/21] Removed a few obsolete mono addin references. Mantis #4854 --- OpenSim/Data/Resources/OpenSim.Data.addin.xml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/OpenSim/Data/Resources/OpenSim.Data.addin.xml b/OpenSim/Data/Resources/OpenSim.Data.addin.xml index 65774ffc4f..10c9c3cb28 100644 --- a/OpenSim/Data/Resources/OpenSim.Data.addin.xml +++ b/OpenSim/Data/Resources/OpenSim.Data.addin.xml @@ -3,19 +3,10 @@ - - - - - - - - - From 264f4f07cde42d2df7c6f7c2b3cec429f0595a5c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 14 Jul 2010 20:46:26 +0200 Subject: [PATCH 03/21] Detach attachments displaced by other attachments --- .../Avatar/Attachments/AttachmentsModule.cs | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 527934d729..ff3036aca8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -140,19 +140,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments group.SetAttachmentPoint((byte)AttachmentPt); group.AbsolutePosition = attachPos; - // Saves and gets itemID - UUID itemId; + // Remove any previous attachments + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + UUID itemID = UUID.Zero; + if (sp != null) + { + foreach(SceneObjectGroup grp in sp.Attachments) + { + if (grp.GetAttachmentPoint() == (byte)AttachmentPt) + { + itemID = grp.GetFromItemID(); + break; + } + } + if (itemID != UUID.Zero) + DetachSingleAttachmentToInv(itemID, remoteClient); + } if (group.GetFromItemID() == UUID.Zero) { - m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); + m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID); } else { - itemId = group.GetFromItemID(); + itemID = group.GetFromItemID(); } - SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group); + SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemID, group); group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); From b75fc97865bfc9f48cc310ec375a39dcad7fba5a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Jul 2010 03:34:03 -0700 Subject: [PATCH 04/21] Fixes mantis #4872. Port for GridInfo was wrong in Robust.HG.ini.example --- bin/Robust.HG.ini.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 6b0029f0f7..0cf9ab1431 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -11,7 +11,7 @@ ;; [Startup] -ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8003/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:AssetServiceConnector" +ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8002/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector,8002/OpenSim.Server.Handlers.dll:UserAgentServerConnector,HGInventoryService@8002/OpenSim.Server.Handlers.dll:XInventoryInConnector,8002/OpenSim.Server.Handlers.dll:AssetServiceConnector" ; * This is common for all services, it's the network setup for the entire ; * server instance, if none if specified above From f5bdf0d9b9538b9f2ac612fcb8bce4442794fb4d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Jul 2010 00:26:26 +0100 Subject: [PATCH 05/21] Fix bugs in llRot2Euler() Applies patch in http://opensimulator.org/mantis/view.php?id=4482. Thanks Micheil Merlin! --- .../Shared/Api/Implementation/LSL_Api.cs | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index dbea6eff3b..789bbb2bfe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -465,22 +465,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke - // Utility function for llRot2Euler - - // normalize an angle between -PI and PI (-180 to +180 degrees) - protected double NormalizeAngle(double angle) - { - if (angle > -Math.PI && angle < Math.PI) - return angle; - - int numPis = (int)(Math.PI / angle); - double remainder = angle - Math.PI * numPis; - if (numPis % 2 == 1) - return Math.PI - angle; - return remainder; - } - - // Old implementation of llRot2Euler, now normalized + // Old implementation of llRot2Euler. Normalization not required as Atan2 function will + // only return values >= -PI (-180 degrees) and <= PI (180 degrees). public LSL_Vector llRot2Euler(LSL_Rotation r) { @@ -492,13 +478,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api double n = 2 * (r.y * r.s + r.x * r.z); double p = m * m - n * n; if (p > 0) - return new LSL_Vector(NormalizeAngle(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s))), - NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))), - NormalizeAngle(Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s)))); + return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), + Math.Atan2(n, Math.Sqrt(p)), + Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); else if (n > 0) - return new LSL_Vector(0.0, Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); + return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); else - return new LSL_Vector(0.0, -Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); + return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); } /* From wiki: From 9cfa71d1bf77bcc3305bbfcd12d964496b2ce39d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Jul 2010 00:35:51 +0100 Subject: [PATCH 06/21] Allow use of old angle rules PSYS_SRC_INNERANGLE and PSYS_SRC_OUTERANGLE in llParticleSystem() This is a patch from http://opensimulator.org/mantis/view.php?id=3201 Thanks Micheil Martin! --- .../Shared/Api/Implementation/LSL_Api.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 789bbb2bfe..417cef4e64 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5859,6 +5859,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api PSYS_PART_MAX_AGE = 7, PSYS_SRC_ACCEL = 8, PSYS_SRC_PATTERN = 9, + PSYS_SRC_INNERANGLE = 10, + PSYS_SRC_OUTERANGLE = 11, PSYS_SRC_TEXTURE = 12, PSYS_SRC_BURST_RATE = 13, PSYS_SRC_BURST_PART_COUNT = 15, @@ -5991,6 +5993,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api prules.Pattern = (Primitive.ParticleSystem.SourcePattern)tmpi; break; + // PSYS_SRC_INNERANGLE and PSYS_SRC_ANGLE_BEGIN use the same variables. The + // PSYS_SRC_OUTERANGLE and PSYS_SRC_ANGLE_END also use the same variable. The + // client tells the difference between the two by looking at the 0x02 bit in + // the PartFlags variable. + case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE: + tempf = (float)rules.GetLSLFloatItem(i + 1); + prules.InnerAngle = (float)tempf; + prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. + break; + + case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE: + tempf = (float)rules.GetLSLFloatItem(i + 1); + prules.OuterAngle = (float)tempf; + prules.PartFlags &= 0xFFFFFFFD; // Make sure new angle format is off. + break; + case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1)); break; @@ -6047,11 +6065,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case (int)ScriptBaseClass.PSYS_SRC_ANGLE_BEGIN: tempf = (float)rules.GetLSLFloatItem(i + 1); prules.InnerAngle = (float)tempf; + prules.PartFlags |= 0x02; // Set new angle format. break; case (int)ScriptBaseClass.PSYS_SRC_ANGLE_END: tempf = (float)rules.GetLSLFloatItem(i + 1); prules.OuterAngle = (float)tempf; + prules.PartFlags |= 0x02; // Set new angle format. break; } From e157dd630e53f95f505a3edffc14e5544d9b04b6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 17 Jul 2010 16:32:55 +0200 Subject: [PATCH 07/21] Allow communicating with blue box dialogs across a region border via a child agent --- .../CoreModules/Avatar/Dialog/DialogModule.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index b5c3176d8e..72fff948ed 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -81,14 +81,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { ScenePresence sp = m_scene.GetScenePresence(agentID); - if (sp != null && !sp.IsChildAgent) + if (sp != null) sp.ControllingClient.SendAgentAlertMessage(message, modal); } public void SendAlertToUser(string firstName, string lastName, string message, bool modal) { ScenePresence presence = m_scene.GetScenePresence(firstName, lastName); - if (presence != null && !presence.IsChildAgent) + if (presence != null) presence.ControllingClient.SendAgentAlertMessage(message, modal); } @@ -96,8 +96,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { m_scene.ForEachScenePresence(delegate(ScenePresence presence) { - if (!presence.IsChildAgent) - presence.ControllingClient.SendAlertMessage(message); + presence.ControllingClient.SendAlertMessage(message); }); } @@ -119,7 +118,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog } ScenePresence sp = m_scene.GetScenePresence(avatarID); - if (sp != null && !sp.IsChildAgent) + if (sp != null) sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); } @@ -128,7 +127,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { ScenePresence sp = m_scene.GetScenePresence(avatarID); - if (sp != null && !sp.IsChildAgent) + if (sp != null) sp.ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, message, url); } @@ -149,7 +148,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog ScenePresence sp = m_scene.GetScenePresence(avatarid); - if (sp != null && !sp.IsChildAgent) + if (sp != null) sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid); } @@ -205,4 +204,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog return result; } } -} \ No newline at end of file +} From f798679b8005e532f933553007cca989112f4a1d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 19 Jul 2010 00:06:23 +0100 Subject: [PATCH 08/21] A stab in the dark. Revert the compile lockout temporarily. If you know what this is, you should test it. If you don't, don't use it. --- .../Region/ScriptEngine/XEngine/XEngine.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 02993856fd..bf7fed8698 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); IWorkItemResult m_CurrentCompile = null; - private Dictionary m_CompileDict = new Dictionary(); +// private Dictionary m_CompileDict = new Dictionary(); public string ScriptEngineName { @@ -488,20 +488,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (stateSource == (int)StateSource.ScriptedRez) { - lock (m_CompileDict) - { - m_CompileDict[itemID] = 0; - } +// lock (m_CompileDict) +// { +// m_CompileDict[itemID] = 0; +// } DoOnRezScript(parms); } else { m_CompileQueue.Enqueue(parms); - lock (m_CompileDict) - { - m_CompileDict[itemID] = 0; - } +// lock (m_CompileDict) +// { +// m_CompileDict[itemID] = 0; +// } if (m_CurrentCompile == null) { @@ -564,12 +564,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine bool postOnRez = (bool)p[4]; StateSource stateSource = (StateSource)p[5]; - lock(m_CompileDict) - { - if (!m_CompileDict.ContainsKey(itemID)) - return false; - m_CompileDict.Remove(itemID); - } +// lock(m_CompileDict) +// { +// if (!m_CompileDict.ContainsKey(itemID)) +// return false; +// m_CompileDict.Remove(itemID); +// } // Get the asset ID of the script, so we can check if we // already have it. @@ -814,11 +814,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void OnRemoveScript(uint localID, UUID itemID) { // If it's not yet been compiled, make sure we don't try - lock (m_CompileDict) - { - if (m_CompileDict.ContainsKey(itemID)) - m_CompileDict.Remove(itemID); - } +// lock (m_CompileDict) +// { +// if (m_CompileDict.ContainsKey(itemID)) +// m_CompileDict.Remove(itemID); +// } lock (m_Scripts) { From fa45d5b5faf222a8a8e976e2827dad5b65d42583 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 19 Jul 2010 01:10:57 +0100 Subject: [PATCH 09/21] Revert "A stab in the dark. Revert the compile lockout temporarily. If you know what" This reverts commit f798679b8005e532f933553007cca989112f4a1d. --- .../Region/ScriptEngine/XEngine/XEngine.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index bf7fed8698..02993856fd 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); IWorkItemResult m_CurrentCompile = null; -// private Dictionary m_CompileDict = new Dictionary(); + private Dictionary m_CompileDict = new Dictionary(); public string ScriptEngineName { @@ -488,20 +488,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (stateSource == (int)StateSource.ScriptedRez) { -// lock (m_CompileDict) -// { -// m_CompileDict[itemID] = 0; -// } + lock (m_CompileDict) + { + m_CompileDict[itemID] = 0; + } DoOnRezScript(parms); } else { m_CompileQueue.Enqueue(parms); -// lock (m_CompileDict) -// { -// m_CompileDict[itemID] = 0; -// } + lock (m_CompileDict) + { + m_CompileDict[itemID] = 0; + } if (m_CurrentCompile == null) { @@ -564,12 +564,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine bool postOnRez = (bool)p[4]; StateSource stateSource = (StateSource)p[5]; -// lock(m_CompileDict) -// { -// if (!m_CompileDict.ContainsKey(itemID)) -// return false; -// m_CompileDict.Remove(itemID); -// } + lock(m_CompileDict) + { + if (!m_CompileDict.ContainsKey(itemID)) + return false; + m_CompileDict.Remove(itemID); + } // Get the asset ID of the script, so we can check if we // already have it. @@ -814,11 +814,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void OnRemoveScript(uint localID, UUID itemID) { // If it's not yet been compiled, make sure we don't try -// lock (m_CompileDict) -// { -// if (m_CompileDict.ContainsKey(itemID)) -// m_CompileDict.Remove(itemID); -// } + lock (m_CompileDict) + { + if (m_CompileDict.ContainsKey(itemID)) + m_CompileDict.Remove(itemID); + } lock (m_Scripts) { From 575f7d3366552562d0a5c0d8c481e96f8805f973 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 19 Jul 2010 14:36:53 +0100 Subject: [PATCH 10/21] Revert "Thank you, Snoopy, for a patch to reduce sim script startup CPU usage" This reverts commit c404c5fb5405eac24cc8b7cd402eb8d8fb0ff0cf. --- .../Scenes/SceneObjectPartInventory.cs | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index cabcf37b6f..46febe3754 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -31,7 +31,6 @@ using System.IO; using System.Collections.Generic; using System.Collections; using System.Reflection; -using System.Threading; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -201,7 +200,6 @@ namespace OpenSim.Region.Framework.Scenes if ((int)InventoryType.LSL == item.InvType) { CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); - Thread.Sleep(10); // workaround for Mono cpu utilization > 100% bug } } } @@ -259,7 +257,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.InfoFormat( // "[PRIM INVENTORY]: " + // "Starting script {0}, {1} in prim {2}, {3}", - // item.Name, item.ItemID, m_part.Name, m_part.UUID); + // item.Name, item.ItemID, Name, UUID); if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) return; @@ -295,20 +293,20 @@ namespace OpenSim.Region.Framework.Scenes } else { + if (m_part.ParentGroup.m_savedScriptState != null) + RestoreSavedScriptState(item.OldItemID, item.ItemID); + lock (m_items) { - if (m_part.ParentGroup.m_savedScriptState != null) - RestoreSavedScriptState(item.OldItemID, item.ItemID); - m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; - - string script = Utils.BytesToString(asset.Data); - m_part.ParentGroup.Scene.EventManager.TriggerRezScript( - m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); - m_part.ParentGroup.AddActiveScriptCount(1); - m_part.ScheduleFullUpdate(); } + + string script = Utils.BytesToString(asset.Data); + m_part.ParentGroup.Scene.EventManager.TriggerRezScript( + m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); + m_part.ParentGroup.AddActiveScriptCount(1); + m_part.ScheduleFullUpdate(); } } } From a974704a3e5a625fcb1fd6b286a02afa9d1b5206 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 19 Jul 2010 14:37:27 +0100 Subject: [PATCH 11/21] re-add the sleep lost in the revert. --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 46febe3754..a6d2f76c9c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -31,6 +31,7 @@ using System.IO; using System.Collections.Generic; using System.Collections; using System.Reflection; +using System.Threading; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -200,6 +201,7 @@ namespace OpenSim.Region.Framework.Scenes if ((int)InventoryType.LSL == item.InvType) { CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); + Thread.Sleep(10); // workaround for Mono cpu utilization > 100% bug } } } From cd2bb7daf33ef57dfb2057a67663428a36adec0a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 19 Jul 2010 08:07:37 -0700 Subject: [PATCH 12/21] Deleted Snoopy's patch completely, including Thread.Sleep. Preliminary tests indicate that this is what causes deadlock. More tests needed. --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index a6d2f76c9c..b27dc59a1c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -201,7 +201,6 @@ namespace OpenSim.Region.Framework.Scenes if ((int)InventoryType.LSL == item.InvType) { CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); - Thread.Sleep(10); // workaround for Mono cpu utilization > 100% bug } } } From 5c0c7fda6c323cfbbe76562eda3fe0b767561dd1 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 19 Jul 2010 13:59:11 -0700 Subject: [PATCH 13/21] One more stab at http://opensimulator.org/mantis/view.php?id=4858. Eliminated the nested locks of m_Scripts and m_PrimObjects. --- .../Region/ScriptEngine/XEngine/XEngine.cs | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 02993856fd..c436582702 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -820,60 +820,60 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_CompileDict.Remove(itemID); } + IScriptInstance instance = null; + lock (m_Scripts) { // Do we even have it? if (!m_Scripts.ContainsKey(itemID)) return; - IScriptInstance instance=m_Scripts[itemID]; + instance=m_Scripts[itemID]; m_Scripts.Remove(itemID); + } - instance.ClearQueue(); - instance.Stop(0); - + instance.ClearQueue(); + instance.Stop(0); // bool objectRemoved = false; - lock (m_PrimObjects) + lock (m_PrimObjects) + { + // Remove the script from it's prim + if (m_PrimObjects.ContainsKey(localID)) { - // Remove the script from it's prim - if (m_PrimObjects.ContainsKey(localID)) - { - // Remove inventory item record - if (m_PrimObjects[localID].Contains(itemID)) - m_PrimObjects[localID].Remove(itemID); + // Remove inventory item record + if (m_PrimObjects[localID].Contains(itemID)) + m_PrimObjects[localID].Remove(itemID); - // If there are no more scripts, remove prim - if (m_PrimObjects[localID].Count == 0) - { - m_PrimObjects.Remove(localID); + // If there are no more scripts, remove prim + if (m_PrimObjects[localID].Count == 0) + { + m_PrimObjects.Remove(localID); // objectRemoved = true; - } } } - - instance.RemoveState(); - instance.DestroyScriptInstance(); - - m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); - if (m_DomainScripts[instance.AppDomain].Count == 0) - { - m_DomainScripts.Remove(instance.AppDomain); - UnloadAppDomain(instance.AppDomain); - } - - instance = null; - - ObjectRemoved handlerObjectRemoved = OnObjectRemoved; - if (handlerObjectRemoved != null) - { - SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); - handlerObjectRemoved(part.UUID); - } - - CleanAssemblies(); } + instance.RemoveState(); + instance.DestroyScriptInstance(); + + m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); + if (m_DomainScripts[instance.AppDomain].Count == 0) + { + m_DomainScripts.Remove(instance.AppDomain); + UnloadAppDomain(instance.AppDomain); + } + + instance = null; + + ObjectRemoved handlerObjectRemoved = OnObjectRemoved; + if (handlerObjectRemoved != null) + { + SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); + handlerObjectRemoved(part.UUID); + } + + ScriptRemoved handlerScriptRemoved = OnScriptRemoved; if (handlerScriptRemoved != null) handlerScriptRemoved(itemID); From ffbae52a130376ecaa04d7d475709985c62c06ed Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 19 Jul 2010 15:20:34 -0700 Subject: [PATCH 14/21] Another stab at http://opensimulator.org/mantis/view.php?id=4858. Eliminated more nested locks. --- .../Region/ScriptEngine/XEngine/XEngine.cs | 74 ++++++++++--------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index c436582702..b0503499f2 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -701,9 +701,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } + ScriptInstance instance = null; lock (m_Scripts) { - ScriptInstance instance = null; // Create the object record if ((!m_Scripts.ContainsKey(itemID)) || @@ -786,28 +786,29 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_Scripts[itemID] = instance; } - - lock (m_PrimObjects) - { - if (!m_PrimObjects.ContainsKey(localID)) - m_PrimObjects[localID] = new List(); - - if (!m_PrimObjects[localID].Contains(itemID)) - m_PrimObjects[localID].Add(itemID); - - } - - if (!m_Assemblies.ContainsKey(assetID)) - m_Assemblies[assetID] = assembly; - - lock (m_AddingAssemblies) - { - m_AddingAssemblies[assembly]--; - } - - if (instance!=null) - instance.Init(); } + + lock (m_PrimObjects) + { + if (!m_PrimObjects.ContainsKey(localID)) + m_PrimObjects[localID] = new List(); + + if (!m_PrimObjects[localID].Contains(itemID)) + m_PrimObjects[localID].Add(itemID); + + } + + if (!m_Assemblies.ContainsKey(assetID)) + m_Assemblies[assetID] = assembly; + + lock (m_AddingAssemblies) + { + m_AddingAssemblies[assembly]--; + } + + if (instance != null) + instance.Init(); + return true; } @@ -1007,26 +1008,33 @@ namespace OpenSim.Region.ScriptEngine.XEngine public bool PostObjectEvent(uint localID, EventParams p) { bool result = false; - + List uuids = null; + lock (m_PrimObjects) { if (!m_PrimObjects.ContainsKey(localID)) return false; - - foreach (UUID itemID in m_PrimObjects[localID]) + uuids = m_PrimObjects[localID]; + } + + foreach (UUID itemID in uuids) + { + IScriptInstance instance = null; + try { if (m_Scripts.ContainsKey(itemID)) - { - IScriptInstance instance = m_Scripts[itemID]; - if (instance != null) - { - instance.PostEvent(p); - result = true; - } - } + instance = m_Scripts[itemID]; + } + catch { /* ignore race conditions */ } + + if (instance != null) + { + instance.PostEvent(p); + result = true; } } + return result; } From c0d9ab941dd1ab88f00f6d4f2a53a4fe5c605e57 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 19 Jul 2010 16:22:29 -0700 Subject: [PATCH 15/21] Reverting this for now, but this needs to go in again. Revert "Another stab at http://opensimulator.org/mantis/view.php?id=4858. Eliminated more nested locks." This reverts commit ffbae52a130376ecaa04d7d475709985c62c06ed. --- .../Region/ScriptEngine/XEngine/XEngine.cs | 74 +++++++++---------- 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index b0503499f2..c436582702 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -701,9 +701,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - ScriptInstance instance = null; lock (m_Scripts) { + ScriptInstance instance = null; // Create the object record if ((!m_Scripts.ContainsKey(itemID)) || @@ -786,29 +786,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_Scripts[itemID] = instance; } + + lock (m_PrimObjects) + { + if (!m_PrimObjects.ContainsKey(localID)) + m_PrimObjects[localID] = new List(); + + if (!m_PrimObjects[localID].Contains(itemID)) + m_PrimObjects[localID].Add(itemID); + + } + + if (!m_Assemblies.ContainsKey(assetID)) + m_Assemblies[assetID] = assembly; + + lock (m_AddingAssemblies) + { + m_AddingAssemblies[assembly]--; + } + + if (instance!=null) + instance.Init(); } - - lock (m_PrimObjects) - { - if (!m_PrimObjects.ContainsKey(localID)) - m_PrimObjects[localID] = new List(); - - if (!m_PrimObjects[localID].Contains(itemID)) - m_PrimObjects[localID].Add(itemID); - - } - - if (!m_Assemblies.ContainsKey(assetID)) - m_Assemblies[assetID] = assembly; - - lock (m_AddingAssemblies) - { - m_AddingAssemblies[assembly]--; - } - - if (instance != null) - instance.Init(); - return true; } @@ -1008,33 +1007,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine public bool PostObjectEvent(uint localID, EventParams p) { bool result = false; - List uuids = null; - + lock (m_PrimObjects) { if (!m_PrimObjects.ContainsKey(localID)) return false; - uuids = m_PrimObjects[localID]; - } - - foreach (UUID itemID in uuids) - { - IScriptInstance instance = null; - try + + foreach (UUID itemID in m_PrimObjects[localID]) { if (m_Scripts.ContainsKey(itemID)) - instance = m_Scripts[itemID]; - } - catch { /* ignore race conditions */ } - - if (instance != null) - { - instance.PostEvent(p); - result = true; + { + IScriptInstance instance = m_Scripts[itemID]; + if (instance != null) + { + instance.PostEvent(p); + result = true; + } + } } } - return result; } From b7f12883614ddfd253fd7020b1f9fec54023d58f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 20 Jul 2010 04:23:39 -0700 Subject: [PATCH 16/21] Adding it again. Revert "Reverting this for now, but this needs to go in again." This reverts commit c0d9ab941dd1ab88f00f6d4f2a53a4fe5c605e57. --- .../Region/ScriptEngine/XEngine/XEngine.cs | 74 ++++++++++--------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index c436582702..b0503499f2 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -701,9 +701,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } + ScriptInstance instance = null; lock (m_Scripts) { - ScriptInstance instance = null; // Create the object record if ((!m_Scripts.ContainsKey(itemID)) || @@ -786,28 +786,29 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_Scripts[itemID] = instance; } - - lock (m_PrimObjects) - { - if (!m_PrimObjects.ContainsKey(localID)) - m_PrimObjects[localID] = new List(); - - if (!m_PrimObjects[localID].Contains(itemID)) - m_PrimObjects[localID].Add(itemID); - - } - - if (!m_Assemblies.ContainsKey(assetID)) - m_Assemblies[assetID] = assembly; - - lock (m_AddingAssemblies) - { - m_AddingAssemblies[assembly]--; - } - - if (instance!=null) - instance.Init(); } + + lock (m_PrimObjects) + { + if (!m_PrimObjects.ContainsKey(localID)) + m_PrimObjects[localID] = new List(); + + if (!m_PrimObjects[localID].Contains(itemID)) + m_PrimObjects[localID].Add(itemID); + + } + + if (!m_Assemblies.ContainsKey(assetID)) + m_Assemblies[assetID] = assembly; + + lock (m_AddingAssemblies) + { + m_AddingAssemblies[assembly]--; + } + + if (instance != null) + instance.Init(); + return true; } @@ -1007,26 +1008,33 @@ namespace OpenSim.Region.ScriptEngine.XEngine public bool PostObjectEvent(uint localID, EventParams p) { bool result = false; - + List uuids = null; + lock (m_PrimObjects) { if (!m_PrimObjects.ContainsKey(localID)) return false; - - foreach (UUID itemID in m_PrimObjects[localID]) + uuids = m_PrimObjects[localID]; + } + + foreach (UUID itemID in uuids) + { + IScriptInstance instance = null; + try { if (m_Scripts.ContainsKey(itemID)) - { - IScriptInstance instance = m_Scripts[itemID]; - if (instance != null) - { - instance.PostEvent(p); - result = true; - } - } + instance = m_Scripts[itemID]; + } + catch { /* ignore race conditions */ } + + if (instance != null) + { + instance.PostEvent(p); + result = true; } } + return result; } From 7c124a5543534dde332d90e07dd72d9b52108836 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 20 Jul 2010 05:59:18 -0700 Subject: [PATCH 17/21] Relaxed the ultra-conservative lock on m_items. Needs testing under linux and stress. --- .../Scenes/SceneObjectPartInventory.cs | 411 ++++++++---------- 1 file changed, 190 insertions(+), 221 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index b27dc59a1c..517b387098 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -118,20 +118,20 @@ namespace OpenSim.Region.Framework.Scenes /// Link number for the part public void ResetInventoryIDs() { - lock (Items) + lock (m_items) { - if (0 == Items.Count) + if (0 == m_items.Count) return; HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - Items.Clear(); + IList items = GetInventoryItems(); + m_items.Clear(); foreach (TaskInventoryItem item in items) { item.ResetIDs(m_part.UUID); - Items.Add(item.ItemID, item); + m_items.Add(item.ItemID, item); } } } @@ -148,17 +148,17 @@ namespace OpenSim.Region.Framework.Scenes { return; } + } - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - foreach (TaskInventoryItem item in items) + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + List items = GetInventoryItems(); + foreach (TaskInventoryItem item in items) + { + if (ownerId != item.OwnerID) { - if (ownerId != item.OwnerID) - { - item.LastOwnerID = item.OwnerID; - item.OwnerID = ownerId; - } + item.LastOwnerID = item.OwnerID; + item.OwnerID = ownerId; } } } @@ -175,17 +175,15 @@ namespace OpenSim.Region.Framework.Scenes { return; } + } - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - foreach (TaskInventoryItem item in items) - { - if (groupID != item.GroupID) - { - item.GroupID = groupID; - } - } + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + List items = GetInventoryItems(); + foreach (TaskInventoryItem item in items) + { + if (groupID != item.GroupID) + item.GroupID = groupID; } } @@ -194,16 +192,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) { - lock (m_items) - { - foreach (TaskInventoryItem item in Items.Values) - { - if ((int)InventoryType.LSL == item.InvType) - { - CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); - } - } - } + List scripts = GetInventoryScripts(); + foreach (TaskInventoryItem item in scripts) + CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); } public ArrayList GetScriptErrors(UUID itemID) @@ -236,16 +227,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void RemoveScriptInstances(bool sceneObjectBeingDeleted) { - lock (Items) - { - foreach (TaskInventoryItem item in Items.Values) - { - if ((int)InventoryType.LSL == item.InvType) - { - RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); - } - } - } + List scripts = GetInventoryScripts(); + foreach (TaskInventoryItem item in scripts) + RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); } /// @@ -375,21 +359,15 @@ namespace OpenSim.Region.Framework.Scenes /// public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) { - lock (m_items) - { - if (m_items.ContainsKey(itemId)) - { - CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", - itemId, m_part.Name, m_part.UUID, - m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); - } - } + TaskInventoryItem item = GetInventoryItem(itemId); + if (item != null) + CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); + else + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", + itemId, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } /// @@ -430,16 +408,18 @@ namespace OpenSim.Region.Framework.Scenes /// /// Check if the inventory holds an item with a given name. - /// This method assumes that the task inventory is already locked. /// /// /// private bool InventoryContainsName(string name) { - foreach (TaskInventoryItem item in Items.Values) + lock (m_items) { - if (item.Name == name) - return true; + foreach (TaskInventoryItem item in m_items.Values) + { + if (item.Name == name) + return true; + } } return false; } @@ -482,12 +462,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) { - List il; - - lock (m_items) - { - il = new List(m_items.Values); - } + List il = GetInventoryItems(); foreach (TaskInventoryItem i in il) { @@ -527,14 +502,12 @@ namespace OpenSim.Region.Framework.Scenes item.GroupID = m_part.GroupID; lock (m_items) - { m_items.Add(item.ItemID, item); - if (allowedDrop) - m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); - else - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - } + if (allowedDrop) + m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); + else + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); m_inventorySerial++; //m_inventorySerial += 2; @@ -558,9 +531,8 @@ namespace OpenSim.Region.Framework.Scenes m_items.Add(item.ItemID, item); // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); } + m_inventorySerial++; } - - m_inventorySerial++; } /// @@ -615,45 +587,44 @@ namespace OpenSim.Region.Framework.Scenes public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) { - lock(m_items) + TaskInventoryItem it = GetInventoryItem(item.ItemID); + if (it != null) { - if (m_items.ContainsKey(item.ItemID)) - { - if (m_items.ContainsKey(item.ItemID)) - { - item.ParentID = m_part.UUID; - item.ParentPartID = m_part.UUID; - item.Flags = m_items[item.ItemID].Flags; + item.ParentID = m_part.UUID; + item.ParentPartID = m_part.UUID; + item.Flags = m_items[item.ItemID].Flags; - // If group permissions have been set on, check that the groupID is up to date in case it has - // changed since permissions were last set. - if (item.GroupPermissions != (uint)PermissionMask.None) - item.GroupID = m_part.GroupID; + // If group permissions have been set on, check that the groupID is up to date in case it has + // changed since permissions were last set. + if (item.GroupPermissions != (uint)PermissionMask.None) + item.GroupID = m_part.GroupID; - if (item.AssetID == UUID.Zero) - { - item.AssetID = m_items[item.ItemID].AssetID; - } - m_items[item.ItemID] = item; - m_inventorySerial++; - if (fireScriptEvents) - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - return true; - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", - item.ItemID, m_part.Name, m_part.UUID, - m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); - } + if (item.AssetID == UUID.Zero) + item.AssetID = it.AssetID; + lock (m_items) + { + m_items[item.ItemID] = item; + m_inventorySerial++; } - return false; + + if (fireScriptEvents) + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + return true; } + else + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", + item.ItemID, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); + } + return false; + } /// @@ -664,52 +635,37 @@ namespace OpenSim.Region.Framework.Scenes /// in this prim's inventory. public int RemoveInventoryItem(UUID itemID) { - lock (m_items) + TaskInventoryItem item = GetInventoryItem(itemID); + if (item != null) { - if (m_items.ContainsKey(itemID)) + int type = m_items[itemID].InvType; + if (type == 10) // Script { - int type = m_items[itemID].InvType; - if (type == 10) // Script - { - m_part.RemoveScriptEvents(itemID); - m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); - } - m_items.Remove(itemID); - m_inventorySerial++; - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - - int scriptcount = 0; - lock (m_items) - { - foreach (TaskInventoryItem item in m_items.Values) - { - if (item.Type == 10) - { - scriptcount++; - } - } - } - - if (scriptcount <= 0) - { - m_part.RemFlag(PrimFlags.Scripted); - } - - m_part.ScheduleFullUpdate(); - - return type; - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", - itemID, m_part.Name, m_part.UUID, - m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); + m_part.RemoveScriptEvents(itemID); + m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); } + m_items.Remove(itemID); + m_inventorySerial++; + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + + if (!ContainsScripts()) + m_part.RemFlag(PrimFlags.Scripted); + + m_part.ScheduleFullUpdate(); + + return type; + + } + else + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", + itemID, m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } return -1; @@ -763,52 +719,50 @@ namespace OpenSim.Region.Framework.Scenes // isn't available (such as drag from prim inventory to agent inventory) InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); - lock (m_items) + List items = GetInventoryItems(); + foreach (TaskInventoryItem item in items) { - foreach (TaskInventoryItem item in m_items.Values) - { - UUID ownerID = item.OwnerID; - uint everyoneMask = 0; - uint baseMask = item.BasePermissions; - uint ownerMask = item.CurrentPermissions; - uint groupMask = item.GroupPermissions; + UUID ownerID = item.OwnerID; + uint everyoneMask = 0; + uint baseMask = item.BasePermissions; + uint ownerMask = item.CurrentPermissions; + uint groupMask = item.GroupPermissions; - invString.AddItemStart(); - invString.AddNameValueLine("item_id", item.ItemID.ToString()); - invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); + invString.AddItemStart(); + invString.AddNameValueLine("item_id", item.ItemID.ToString()); + invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); - invString.AddPermissionsStart(); + invString.AddPermissionsStart(); - invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); - invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); - invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); - invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); - invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); + invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); + invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); + invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); + invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); + invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); - invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); - invString.AddNameValueLine("owner_id", ownerID.ToString()); + invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); + invString.AddNameValueLine("owner_id", ownerID.ToString()); - invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); + invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); - invString.AddNameValueLine("group_id", item.GroupID.ToString()); - invString.AddSectionEnd(); + invString.AddNameValueLine("group_id", item.GroupID.ToString()); + invString.AddSectionEnd(); - invString.AddNameValueLine("asset_id", item.AssetID.ToString()); - invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); - invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); - invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); + invString.AddNameValueLine("asset_id", item.AssetID.ToString()); + invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); + invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); + invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); - invString.AddSaleStart(); - invString.AddNameValueLine("sale_type", "not"); - invString.AddNameValueLine("sale_price", "0"); - invString.AddSectionEnd(); + invString.AddSaleStart(); + invString.AddNameValueLine("sale_type", "not"); + invString.AddNameValueLine("sale_price", "0"); + invString.AddSectionEnd(); - invString.AddNameValueLine("name", item.Name + "|"); - invString.AddNameValueLine("desc", item.Description + "|"); + invString.AddNameValueLine("name", item.Name + "|"); + invString.AddNameValueLine("desc", item.Description + "|"); - invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); - invString.AddSectionEnd(); - } + invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); + invString.AddSectionEnd(); } fileData = Utils.StringToBytes(invString.BuildString); @@ -830,12 +784,10 @@ namespace OpenSim.Region.Framework.Scenes { if (HasInventoryChanged) { - lock (Items) - { - datastore.StorePrimInventory(m_part.UUID, Items.Values); - } - HasInventoryChanged = false; + List items = GetInventoryItems(); + datastore.StorePrimInventory(m_part.UUID, items); + } } @@ -1000,6 +952,30 @@ namespace OpenSim.Region.Framework.Scenes return ret; } + + public List GetInventoryItems() + { + List ret = new List(); + + lock (m_items) + ret = new List(m_items.Values); + + return ret; + } + + public List GetInventoryScripts() + { + List ret = new List(); + + lock (m_items) + { + foreach (TaskInventoryItem item in m_items.Values) + if (item.InvType == (int)InventoryType.LSL) + ret.Add(item); + } + + return ret; + } public Dictionary GetScriptStates() { @@ -1009,24 +985,20 @@ namespace OpenSim.Region.Framework.Scenes if (engines == null) // No engine at all return ret; - lock (m_items) + List scripts = GetInventoryScripts(); + + foreach (TaskInventoryItem item in scripts) { - foreach (TaskInventoryItem item in m_items.Values) + foreach (IScriptModule e in engines) { - if (item.InvType == (int)InventoryType.LSL) + if (e != null) { - foreach (IScriptModule e in engines) + string n = e.GetXMLState(item.ItemID); + if (n != String.Empty) { - if (e != null) - { - string n = e.GetXMLState(item.ItemID); - if (n != String.Empty) - { - if (!ret.ContainsKey(item.ItemID)) - ret[item.ItemID] = n; - break; - } - } + if (!ret.ContainsKey(item.ItemID)) + ret[item.ItemID] = n; + break; } } } @@ -1041,25 +1013,22 @@ namespace OpenSim.Region.Framework.Scenes if (engines == null) return; - lock (m_items) + List scripts = GetInventoryScripts(); + + foreach (TaskInventoryItem item in scripts) { - foreach (TaskInventoryItem item in m_items.Values) + foreach (IScriptModule engine in engines) { - if (item.InvType == (int)InventoryType.LSL) + if (engine != null) { - foreach (IScriptModule engine in engines) - { - if (engine != null) - { - if (item.OwnerChanged) - engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); - item.OwnerChanged = false; - engine.ResumeScript(item.ItemID); - } - } + if (item.OwnerChanged) + engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); + item.OwnerChanged = false; + engine.ResumeScript(item.ItemID); } - } + } } } + } } From e46c0a0fc9c5053bf242e3b5a957cf00c7c792e8 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 20 Jul 2010 21:32:13 +0100 Subject: [PATCH 18/21] adjust DialogModule to only send broadcast alerts to root agents --- OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index 72fff948ed..2105f3c44b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -96,7 +96,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { m_scene.ForEachScenePresence(delegate(ScenePresence presence) { - presence.ControllingClient.SendAlertMessage(message); + if (!presence.IsChildAgent) + presence.ControllingClient.SendAlertMessage(message); }); } @@ -204,4 +205,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog return result; } } -} +} \ No newline at end of file From 78605baab330f850f1b47d205b4041d59080a00c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 15 Jul 2010 20:03:08 +0200 Subject: [PATCH 19/21] Fix a few permissions vulnerability. Owners could cause permissions escalation on items contained in prims using a hacked viewer --- .../Framework/Scenes/Scene.Inventory.cs | 35 +++++++++++++++++-- .../Framework/Scenes/SceneObjectPart.cs | 3 ++ .../Scenes/SceneObjectPartInventory.cs | 10 +++--- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6e73fe920f..1bb7075c17 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1340,16 +1340,45 @@ namespace OpenSim.Region.Framework.Scenes { agentTransactions.HandleTaskItemUpdateFromTransaction( remoteClient, part, transactionID, currentItem); - } - if (part.Inventory.UpdateInventoryItem(itemInfo)) - { + 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); + } + // Check if we're allowed to mess with permissions + if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god + { + if (remoteClient.AgentId != part.OwnerID) // Not owner + { + // Friends and group members can't change any perms + itemInfo.BasePermissions = currentItem.BasePermissions; + itemInfo.EveryonePermissions = currentItem.EveryonePermissions; + itemInfo.GroupPermissions = currentItem.GroupPermissions; + itemInfo.NextPermissions = currentItem.NextPermissions; + itemInfo.CurrentPermissions = currentItem.CurrentPermissions; + } + else + { + // Owner can't change base, and can change other + // only up to base + // Base ALWAYS has move + currentItem.BasePermissions |= (uint)PermissionMask.Move; + itemInfo.BasePermissions = currentItem.BasePermissions; + itemInfo.EveryonePermissions &= currentItem.BasePermissions; + itemInfo.GroupPermissions &= currentItem.BasePermissions; + itemInfo.CurrentPermissions &= currentItem.BasePermissions; + itemInfo.NextPermissions &= currentItem.BasePermissions; + // Next ALWAYS has move + itemInfo.NextPermissions |= (uint)PermissionMask.Move; + } + + } + if (part.Inventory.UpdateInventoryItem(itemInfo)) + { part.GetProperties(remoteClient); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 13e4b564f7..e331bb05ec 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4144,6 +4144,9 @@ namespace OpenSim.Region.Framework.Scenes // objects if ((_nextOwnerMask & (uint)PermissionMask.Copy) == 0) _nextOwnerMask |= (uint)PermissionMask.Transfer; + + _nextOwnerMask |= (uint)PermissionMask.Move; + break; } SendFullUpdateToAllClients(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 517b387098..91d9be3f27 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -600,12 +600,12 @@ namespace OpenSim.Region.Framework.Scenes item.GroupID = m_part.GroupID; if (item.AssetID == UUID.Zero) - item.AssetID = it.AssetID; - - lock (m_items) { - m_items[item.ItemID] = item; - m_inventorySerial++; + item.AssetID = m_items[item.ItemID].AssetID; + } + else if ((InventoryType)item.Type == InventoryType.Notecard) + { + ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID); } if (fireScriptEvents) From ea51bea508a966420bab82dfc2af3c240095e427 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 15 Jul 2010 20:28:18 +0200 Subject: [PATCH 20/21] prevent hacked viewers from being able to delete arbitrary items from any prim. Allow friends with perms and shared group members to move or copy things out of prims --- .../Framework/Scenes/Scene.Inventory.cs | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 1bb7075c17..953dd56483 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -916,6 +916,9 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = part.ParentGroup; if (group != null) { + if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) + return; + TaskInventoryItem item = group.GetInventoryItem(localID, itemID); if (item == null) return; @@ -1055,9 +1058,21 @@ namespace OpenSim.Region.Framework.Scenes return; } - // Only owner can copy - if (remoteClient.AgentId != taskItem.OwnerID) - return; + TaskInventoryItem item = part.Inventory.GetInventoryItem(itemId); + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + { + // If the item to be moved is no copy, we need to be able to + // edit the prim. + if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) + return; + } + else + { + // If the item is copiable, then we just need to have perms + // on it. The delete check is a pure rights check + if (!Permissions.CanDeleteObject(part.UUID, remoteClient.AgentId)) + return; + } MoveTaskInventoryItem(remoteClient, folderId, part, itemId); } From 120d7014fdd021f57a5849e8f9941a6ce1180e54 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 20 Jul 2010 14:45:46 +0200 Subject: [PATCH 21/21] When a god uses mass permission setting, the V bit is cleared from next perms, rendering the item unmoveable for the next owenr. Make god mods conform to the rules, too. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 953dd56483..01edf51a3b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1364,6 +1364,9 @@ namespace OpenSim.Region.Framework.Scenes remoteClient.SendAgentAlertMessage("Item saved", false); } + // Base ALWAYS has move + currentItem.BasePermissions |= (uint)PermissionMask.Move; + // Check if we're allowed to mess with permissions if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god { @@ -1380,18 +1383,18 @@ namespace OpenSim.Region.Framework.Scenes { // Owner can't change base, and can change other // only up to base - // Base ALWAYS has move - currentItem.BasePermissions |= (uint)PermissionMask.Move; itemInfo.BasePermissions = currentItem.BasePermissions; itemInfo.EveryonePermissions &= currentItem.BasePermissions; itemInfo.GroupPermissions &= currentItem.BasePermissions; itemInfo.CurrentPermissions &= currentItem.BasePermissions; itemInfo.NextPermissions &= currentItem.BasePermissions; - // Next ALWAYS has move - itemInfo.NextPermissions |= (uint)PermissionMask.Move; } } + + // Next ALWAYS has move + itemInfo.NextPermissions |= (uint)PermissionMask.Move; + if (part.Inventory.UpdateInventoryItem(itemInfo)) { part.GetProperties(remoteClient);