From 697ac7fd9de244cb3b25ff8576838fd323b257c3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Mar 2012 10:17:02 -0700 Subject: [PATCH 01/31] Hack around https://jira.secondlife.com/browse/VWR-28570 --- .../CoreModules/World/WorldMap/MapSearchModule.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 657975b86e..c8c80db0bd 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -92,7 +92,19 @@ namespace OpenSim.Region.CoreModules.World.WorldMap return; } -//m_log.DebugFormat("MAP NAME=({0})", mapName); + //m_log.DebugFormat("MAP NAME=({0})", mapName); + + // Hack to get around the fact that ll V3 now drops the port from the + // map name. See https://jira.secondlife.com/browse/VWR-28570 + // + // Caller, use this form instead: + // secondlife://mygrid.com|8002+Region+Name/128/128 + // the hacks we do with this viewer... + // + if (mapName.Contains("|")) + mapName = mapName.Replace('|', ':'); + if (mapName.Contains("+")) + mapName = mapName.Replace('+', ' '); // try to fetch from GridServer List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); From 10731732b4d40ec9d9e7a21f406a3d2b5dfc1075 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Mar 2012 11:04:56 -0700 Subject: [PATCH 02/31] More hacking around viewer bug --- OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index c8c80db0bd..2064ce3a1d 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -98,7 +98,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this form instead: - // secondlife://mygrid.com|8002+Region+Name/128/128 + // secondlife://mygrid.com|8002|Region+Name/128/128 // the hacks we do with this viewer... // if (mapName.Contains("|")) From 402ff75d781d6f4e38eee8884d7b4411bb756c9b Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Thu, 15 Mar 2012 13:16:02 -0700 Subject: [PATCH 03/31] Adds a new script command 'modInvoke' to invoke registered functions from region modules. The LSL translator is extended to generate the modInvoke format of commands for directly inlined function calls. A region module can register a function Test() with the name "Test". LSL code can call that function as "Test()". The compiler will translate that invocation into modInvoke("Test", ...) --- .../Interfaces/IScriptModuleComms.cs | 10 ++ .../ScriptModuleCommsModule.cs | 99 +++++++++++++++- .../Shared/Api/Implementation/MOD_Api.cs | 109 ++++++++++++++++++ .../Shared/Api/Interface/IMOD_Api.cs | 9 ++ .../Shared/Api/Runtime/MOD_Stub.cs | 15 +++ .../Shared/CodeTools/CSCodeGenerator.cs | 28 ++++- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 5 +- 7 files changed, 270 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs index d7fa316668..bb4c7885f5 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs @@ -31,6 +31,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { public delegate void ScriptCommand(UUID script, string id, string module, string command, string k); + public delegate object ScriptInvocation(UUID script, object[] parms); /// /// Interface for communication between OpenSim modules and in-world scripts @@ -45,6 +46,15 @@ namespace OpenSim.Region.Framework.Interfaces /// event ScriptCommand OnScriptCommand; + void RegisterScriptInvocation(string name, ScriptInvocation fn, Type[] csig, Type rsig); + + ScriptInvocation LookupScriptInvocation(string fname); + string LookupModInvocation(string fname); + Type[] LookupTypeSignature(string fname); + Type LookupReturnType(string fname); + + object InvokeOperation(UUID scriptId, string fname, params object[] parms); + /// /// Send a link_message event to an in-world script /// diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index 44c9ada221..a90362e974 100644 --- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -27,6 +27,7 @@ using System; using System.Reflection; +using System.Collections.Generic; using Nini.Config; using log4net; using OpenSim.Framework; @@ -35,7 +36,7 @@ using OpenSim.Region.Framework.Scenes; using Mono.Addins; using OpenMetaverse; -namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms +namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")] class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms @@ -43,10 +44,30 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private IScriptModule m_scriptModule = null; +#region ScriptInvocation + protected class ScriptInvocationData + { + public ScriptInvocation ScriptInvocationFn { get; private set; } + public string FunctionName { get; private set; } + public Type[] TypeSignature { get; private set; } + public Type ReturnType { get; private set; } + public ScriptInvocationData(string fname, ScriptInvocation fn, Type[] callsig, Type returnsig) + { + FunctionName = fname; + ScriptInvocationFn = fn; + TypeSignature = callsig; + ReturnType = returnsig; + } + } + + private Dictionary m_scriptInvocation = new Dictionary(); +#endregion + + private IScriptModule m_scriptModule = null; public event ScriptCommand OnScriptCommand; +#region RegionModuleInterface public void Initialise(IConfigSource config) { } @@ -81,6 +102,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms public void Close() { } +#endregion + +#region ScriptModuleComms public void RaiseEvent(UUID script, string id, string module, string command, string k) { @@ -101,5 +125,76 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms m_scriptModule.PostScriptEvent(script, "link_message", args); } + + public void RegisterScriptInvocation(string fname, ScriptInvocation fcall, Type[] csig, Type rsig) + { + lock (m_scriptInvocation) + { + m_scriptInvocation[fname] = new ScriptInvocationData(fname,fcall,csig,rsig); + } + } + + public string LookupModInvocation(string fname) + { + lock (m_scriptInvocation) + { + ScriptInvocationData sid; + if (m_scriptInvocation.TryGetValue(fname,out sid)) + { + if (sid.ReturnType == typeof(string)) + return "modInvokeS"; + else if (sid.ReturnType == typeof(int)) + return "modInvokeI"; + else if (sid.ReturnType == typeof(float)) + return "modInvokeF"; + } + } + + return null; + } + + public ScriptInvocation LookupScriptInvocation(string fname) + { + lock (m_scriptInvocation) + { + ScriptInvocationData sid; + if (m_scriptInvocation.TryGetValue(fname,out sid)) + return sid.ScriptInvocationFn; + } + + return null; + } + + public Type[] LookupTypeSignature(string fname) + { + lock (m_scriptInvocation) + { + ScriptInvocationData sid; + if (m_scriptInvocation.TryGetValue(fname,out sid)) + return sid.TypeSignature; + } + + return null; + } + + public Type LookupReturnType(string fname) + { + lock (m_scriptInvocation) + { + ScriptInvocationData sid; + if (m_scriptInvocation.TryGetValue(fname,out sid)) + return sid.ReturnType; + } + + return null; + } + + public object InvokeOperation(UUID scriptid, string fname, params object[] parms) + { + ScriptInvocation fn = LookupScriptInvocation(fname); + return fn(scriptid,parms); + } +#endregion + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index d4facdd657..294210419b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -116,6 +116,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); } + /// + /// + /// + /// The name of the function to invoke + /// List of parameters + /// string result of the invocation + public string modInvokeS(string fname, params object[] parms) + { + Type returntype = m_comms.LookupReturnType(fname); + if (returntype != typeof(string)) + MODError(String.Format("return type mismatch for {0}",fname)); + + return (string)modInvoke(fname,parms); + } + + public int modInvokeI(string fname, params object[] parms) + { + Type returntype = m_comms.LookupReturnType(fname); + if (returntype != typeof(int)) + MODError(String.Format("return type mismatch for {0}",fname)); + + return (int)modInvoke(fname,parms); + } + + public float modInvokeF(string fname, params object[] parms) + { + Type returntype = m_comms.LookupReturnType(fname); + if (returntype != typeof(float)) + MODError(String.Format("return type mismatch for {0}",fname)); + + return (float)modInvoke(fname,parms); + } + + /// + /// Invokes a preregistered function through the ScriptModuleComms class + /// + /// The name of the function to invoke + /// List of parameters + /// string result of the invocation + protected object modInvoke(string fname, params object[] parms) + { + if (!m_MODFunctionsEnabled) + { + MODShoutError("Module command functions not enabled"); + return ""; + } + + Type[] signature = m_comms.LookupTypeSignature(fname); + if (signature.Length != parms.Length) + MODError(String.Format("wrong number of parameters to function {0}",fname)); + + object[] convertedParms = new object[parms.Length]; + + for (int i = 0; i < parms.Length; i++) + { + if (parms[i] is LSL_String) + { + if (signature[i] != typeof(string)) + MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + + convertedParms[i] = (string)(LSL_String)parms[i]; + } + else if (parms[i] is LSL_Integer) + { + if (signature[i] != typeof(int)) + MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + + convertedParms[i] = (int)(LSL_Integer)parms[i]; + } + else if (parms[i] is LSL_Float) + { + if (signature[i] != typeof(float)) + MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + + convertedParms[i] = (float)(LSL_Float)parms[i]; + } + else if (parms[i] is LSL_Key) + { + if (signature[i] != typeof(string)) + MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + + convertedParms[i] = (string)(LSL_Key)parms[i]; + } + else if (parms[i] is LSL_Rotation) + { + if (signature[i] != typeof(string)) + MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + + convertedParms[i] = (string)(LSL_Rotation)parms[i]; + } + else if (parms[i] is LSL_Vector) + { + if (signature[i] != typeof(string)) + MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + + convertedParms[i] = (string)(LSL_Vector)parms[i]; + } + else + { + if (signature[i] != parms[i].GetType()) + MODError(String.Format("parameter type mismatch in {0}; expecting {1}",fname,signature[i].Name)); + + convertedParms[i] = parms[i]; + } + } + + return m_comms.InvokeOperation(m_itemID,fname,convertedParms); + } + public string modSendCommand(string module, string command, string k) { if (!m_MODFunctionsEnabled) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs index e08eca5b24..756a59f3e7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs @@ -40,6 +40,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces { public interface IMOD_Api { + // Invocation functions + string modInvokeS(string fname, params object[] parms); + int modInvokeI(string fname, params object[] parms); + float modInvokeF(string fname, params object[] parms); + // vector modInvokeV(string fname, params object[] parms); + // rotation modInvokeV(string fname, params object[] parms); + // key modInvokeK(string fname, params object[] parms); + // list modInvokeL(string fname, params object[] parms); + //Module functions string modSendCommand(string modules, string command, string k); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs index 6525c7690b..04b7f14b4e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs @@ -58,6 +58,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_MOD_Functions = (IMOD_Api)api; } + public string modInvokeS(string fname, params object[] parms) + { + return m_MOD_Functions.modInvokeS(fname, parms); + } + + public int modInvokeI(string fname, params object[] parms) + { + return m_MOD_Functions.modInvokeI(fname, parms); + } + + public float modInvokeF(string fname, params object[] parms) + { + return m_MOD_Functions.modInvokeF(fname, parms); + } + public string modSendCommand(string module, string command, string k) { return m_MOD_Functions.modSendCommand(module, command, k); diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 65d3b9bbd8..28c031f3e8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -32,6 +32,8 @@ using System.Reflection; using log4net; using Tools; +using OpenSim.Region.Framework.Interfaces; + namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { public class CSCodeGenerator : ICodeConverter @@ -45,12 +47,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private int m_CSharpLine; // the current line of generated C# code private int m_CSharpCol; // the current column of generated C# code private List m_warnings = new List(); + private IScriptModuleComms m_comms = null; /// /// Creates an 'empty' CSCodeGenerator instance. /// public CSCodeGenerator() { + m_comms = null; + ResetCounters(); + } + + public CSCodeGenerator(IScriptModuleComms comms) + { + m_comms = comms; ResetCounters(); } @@ -866,8 +876,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { string retstr = String.Empty; - retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); - + string modinvoke = m_comms.LookupModInvocation(fc.Id); + if (modinvoke != null) + { + if (fc.kids[0] is ArgumentList) + { + if ((fc.kids[0] as ArgumentList).kids.Count == 0) + retstr += Generate(String.Format("{0}(\"{1}\"",modinvoke,fc.Id), fc); + else + retstr += Generate(String.Format("{0}(\"{1}\",",modinvoke,fc.Id), fc); + } + } + else + { + retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); + } + foreach (SYMBOL kid in fc.kids) retstr += GenerateNode(kid); diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index c10143b9a1..8f2ec49cf4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -35,6 +35,7 @@ using Microsoft.CSharp; //using Microsoft.JScript; using Microsoft.VisualBasic; using log4net; + using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces; using OpenMetaverse; @@ -293,6 +294,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { // m_log.DebugFormat("[Compiler]: Compiling script\n{0}", Script); + IScriptModuleComms comms = m_scriptEngine.World.RequestModuleInterface(); + linemap = null; m_warnings.Clear(); @@ -382,7 +385,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools if (language == enumCompileType.lsl) { // Its LSL, convert it to C# - LSL_Converter = (ICodeConverter)new CSCodeGenerator(); + LSL_Converter = (ICodeConverter)new CSCodeGenerator(comms); compileScript = LSL_Converter.Convert(Script); // copy converter warnings into our warnings. From 8b5298a62eb6910ac228b3fe0ab328b6aea79794 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Thu, 15 Mar 2012 13:37:43 -0700 Subject: [PATCH 04/31] Protect the scriptmodulecomms interface. --- .../Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 28c031f3e8..b24f016a08 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -876,7 +876,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { string retstr = String.Empty; - string modinvoke = m_comms.LookupModInvocation(fc.Id); + string modinvoke = null; + if (m_comms != null) + modinvoke = m_comms.LookupModInvocation(fc.Id); + if (modinvoke != null) { if (fc.kids[0] is ArgumentList) From e5612553ce57b6e36cfa59db8450473099054da1 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Mar 2012 14:36:29 -0700 Subject: [PATCH 05/31] Revert "More hacking around viewer bug" This reverts commit 10731732b4d40ec9d9e7a21f406a3d2b5dfc1075. --- OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 2064ce3a1d..c8c80db0bd 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -98,7 +98,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this form instead: - // secondlife://mygrid.com|8002|Region+Name/128/128 + // secondlife://mygrid.com|8002+Region+Name/128/128 // the hacks we do with this viewer... // if (mapName.Contains("|")) From 5a9560db288a25799c93a3ecbd3544931149fa2a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Mar 2012 14:36:48 -0700 Subject: [PATCH 06/31] Revert "Hack around https://jira.secondlife.com/browse/VWR-28570" This reverts commit 697ac7fd9de244cb3b25ff8576838fd323b257c3. --- .../CoreModules/World/WorldMap/MapSearchModule.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index c8c80db0bd..657975b86e 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -92,19 +92,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap return; } - //m_log.DebugFormat("MAP NAME=({0})", mapName); - - // Hack to get around the fact that ll V3 now drops the port from the - // map name. See https://jira.secondlife.com/browse/VWR-28570 - // - // Caller, use this form instead: - // secondlife://mygrid.com|8002+Region+Name/128/128 - // the hacks we do with this viewer... - // - if (mapName.Contains("|")) - mapName = mapName.Replace('|', ':'); - if (mapName.Contains("+")) - mapName = mapName.Replace('+', ' '); +//m_log.DebugFormat("MAP NAME=({0})", mapName); // try to fetch from GridServer List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); From f52917288a04e922edcf28b3184b37d87c3c69ea Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Mar 2012 14:54:25 -0700 Subject: [PATCH 07/31] These SLURLs are very confusing! -- reverting the revert. Hack is, indeed, needed. Revert "Revert "Hack around https://jira.secondlife.com/browse/VWR-28570"" This reverts commit 5a9560db288a25799c93a3ecbd3544931149fa2a. --- .../CoreModules/World/WorldMap/MapSearchModule.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 657975b86e..c8c80db0bd 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -92,7 +92,19 @@ namespace OpenSim.Region.CoreModules.World.WorldMap return; } -//m_log.DebugFormat("MAP NAME=({0})", mapName); + //m_log.DebugFormat("MAP NAME=({0})", mapName); + + // Hack to get around the fact that ll V3 now drops the port from the + // map name. See https://jira.secondlife.com/browse/VWR-28570 + // + // Caller, use this form instead: + // secondlife://mygrid.com|8002+Region+Name/128/128 + // the hacks we do with this viewer... + // + if (mapName.Contains("|")) + mapName = mapName.Replace('|', ':'); + if (mapName.Contains("+")) + mapName = mapName.Replace('+', ' '); // try to fetch from GridServer List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); From df144eb9e23a1a170605b4045f0602f514efb519 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Mar 2012 14:55:25 -0700 Subject: [PATCH 08/31] Revert "Revert "More hacking around viewer bug"" This reverts commit e5612553ce57b6e36cfa59db8450473099054da1. --- OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index c8c80db0bd..2064ce3a1d 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -98,7 +98,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this form instead: - // secondlife://mygrid.com|8002+Region+Name/128/128 + // secondlife://mygrid.com|8002|Region+Name/128/128 // the hacks we do with this viewer... // if (mapName.Contains("|")) From 18d1d6d3b4658b2b00c738d54ff4230868c02c6c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Mar 2012 16:03:09 -0700 Subject: [PATCH 09/31] More on SLURLs and V3. This is hacky, but it works. Basically, we have to redefine the encoding of HG URLs because the viewer messes them up. Examples of what works and doesn't work: - secondlife://ucigrid00.nacs.uci.edu|8002/128/128 <-- works throughout the viewer - secondlife://http|!!ucigrid00.nacs.uci.edu|8002+Test+Zone+1/128/128 <-- works throughout the viewer - secondlife://http|!!grid.sciencesim.com!grid!hypergrid.php+Yellowstone01+74/128/128 <-- works throughout - secondlife://http%3A%2F%2Fucigrid00.nacs.uci.edu%3A8002%20UCI%20Central%201/128/128 <-- works in chat, but not as URLs in the webkit --- .../CoreModules/World/WorldMap/MapSearchModule.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 2064ce3a1d..83ec6c3e3f 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -97,14 +97,18 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // Hack to get around the fact that ll V3 now drops the port from the // map name. See https://jira.secondlife.com/browse/VWR-28570 // - // Caller, use this form instead: - // secondlife://mygrid.com|8002|Region+Name/128/128 + // Caller, use this magic form instead: + // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 + // or url encode if possible. // the hacks we do with this viewer... // + string mapNameOrig = mapName; if (mapName.Contains("|")) mapName = mapName.Replace('|', ':'); if (mapName.Contains("+")) mapName = mapName.Replace('+', ' '); + if (mapName.Contains("!")) + mapName = mapName.Replace('!', '/'); // try to fetch from GridServer List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); @@ -126,7 +130,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap data.MapImageId = UUID.Zero; else data.MapImageId = info.TerrainImage; - data.Name = info.RegionName; + // ugh! V2-3 is very sensitive about the result being + // exactly the same as the requested name + if (regionInfos.Count == 1) + data.Name = mapNameOrig; + else + data.Name = info.RegionName; data.RegionFlags = 0; // TODO not used? data.WaterHeight = 0; // not used data.X = (ushort)(info.RegionLocX / Constants.RegionSize); From a4b01ef38a735ffe70b402061871a9c99f2757ed Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 00:34:30 +0000 Subject: [PATCH 10/31] Replace script-lines-per-second with the script execution time scaled by its measurement period and an idealised frame time. The previous lines-per-second measurement used for top scripts report was inaccurate, since lines executed does not reflect time taken to execute. Also, every fetch of the report would reset all the numbers limiting its usefulness and we weren't even guaranteed to see the top 100. The actual measurement value should be script execution time per frame but XEngine does not work this way. Therefore, we use actual script execution time scaled by the measurement period and an idealised frame time. This is still not ideal but gives reasonable results and allows scripts to be compared. This commit moves script execution time calculations from SceneGraph into IScriptModule implementations. --- .../World/Estate/EstateManagementModule.cs | 77 +++++++++++-------- .../Framework/Interfaces/IScriptModule.cs | 9 ++- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 31 +------- .../Framework/Scenes/SceneObjectGroup.cs | 9 +-- .../Interfaces/IScriptInstance.cs | 15 ++++ .../Shared/Instance/ScriptInstance.cs | 21 ++++- .../Region/ScriptEngine/XEngine/XEngine.cs | 53 +++++++++++++ 7 files changed, 145 insertions(+), 70 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index c303d6db1c..d363b15c01 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -26,8 +26,10 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Security; using log4net; @@ -876,52 +878,67 @@ namespace OpenSim.Region.CoreModules.World.Estate if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false)) return; - Dictionary SceneData = new Dictionary(); + Dictionary sceneData = null; List uuidNameLookupList = new List(); if (reportType == 1) { - SceneData = Scene.PhysicsScene.GetTopColliders(); + sceneData = Scene.PhysicsScene.GetTopColliders(); } else if (reportType == 0) { - SceneData = Scene.SceneGraph.GetTopScripts(); + IScriptModule scriptModule = Scene.RequestModuleInterface(); + + if (scriptModule != null) + sceneData = scriptModule.GetObjectScriptsExecutionTimes(); } List SceneReport = new List(); - lock (SceneData) + if (sceneData != null) { - foreach (uint obj in SceneData.Keys) + var sortedSceneData + = sceneData.Select( + item => new { Measurement = item.Value, Part = Scene.GetSceneObjectPart(item.Key) }); + + sortedSceneData.OrderBy(item => item.Measurement); + + int items = 0; + + foreach (var entry in sortedSceneData) { - SceneObjectPart prt = Scene.GetSceneObjectPart(obj); - if (prt != null) + if (entry.Part == null) + continue; + + items++; + SceneObjectGroup so = entry.Part.ParentGroup; + + LandStatReportItem lsri = new LandStatReportItem(); + lsri.LocationX = so.AbsolutePosition.X; + lsri.LocationY = so.AbsolutePosition.Y; + lsri.LocationZ = so.AbsolutePosition.Z; + lsri.Score = entry.Measurement; + lsri.TaskID = so.UUID; + lsri.TaskLocalID = so.LocalId; + lsri.TaskName = entry.Part.Name; + lsri.OwnerName = "waiting"; + lock (uuidNameLookupList) + uuidNameLookupList.Add(so.OwnerID); + + if (filter.Length != 0) { - SceneObjectGroup sog = prt.ParentGroup; - LandStatReportItem lsri = new LandStatReportItem(); - lsri.LocationX = sog.AbsolutePosition.X; - lsri.LocationY = sog.AbsolutePosition.Y; - lsri.LocationZ = sog.AbsolutePosition.Z; - lsri.Score = SceneData[obj]; - lsri.TaskID = sog.UUID; - lsri.TaskLocalID = sog.LocalId; - lsri.TaskName = sog.GetPartName(obj); - lsri.OwnerName = "waiting"; - lock (uuidNameLookupList) - uuidNameLookupList.Add(sog.OwnerID); - - if (filter.Length != 0) + if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter))) { - if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter))) - { - } - else - { - continue; - } } - - SceneReport.Add(lsri); + else + { + continue; + } } + + SceneReport.Add(lsri); + + if (items >= 100) + break; } } diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 18c45dde6e..9fb4a25009 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections; +using System.Collections.Generic; using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces @@ -74,5 +75,11 @@ namespace OpenSim.Region.Framework.Interfaces /// Starts the processing threads. /// void StartProcessing(); + + /// + /// Get the execution times of all scripts in each object. + /// + /// A dictionary where the key is a local object ID and the value is an execution time in milliseconds. + Dictionary GetObjectScriptsExecutionTimes(); } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index bc3400a7a5..5c542d65a2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -733,6 +733,7 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region Get Methods + /// /// Get the controlling client for the given avatar, if there is one. /// @@ -1074,36 +1075,6 @@ namespace OpenSim.Region.Framework.Scenes return Entities.GetEntities(); } - public Dictionary GetTopScripts() - { - Dictionary topScripts = new Dictionary(); - - EntityBase[] EntityList = GetEntities(); - int limit = 0; - foreach (EntityBase ent in EntityList) - { - if (ent is SceneObjectGroup) - { - SceneObjectGroup grp = (SceneObjectGroup)ent; - if ((grp.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) - { - if (grp.scriptScore >= 0.01) - { - topScripts.Add(grp.LocalId, grp.scriptScore); - limit++; - if (limit >= 100) - { - break; - } - } - grp.scriptScore = 0; - } - } - } - - return topScripts; - } - #endregion #region Other Methods diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 878476e5c9..afb5ccfae5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -229,8 +229,6 @@ namespace OpenSim.Region.Framework.Scenes get { return RootPart.VolumeDetectActive; } } - public float scriptScore; - private Vector3 lastPhysGroupPos; private Quaternion lastPhysGroupRot; @@ -1184,12 +1182,7 @@ namespace OpenSim.Region.Framework.Scenes public void AddScriptLPS(int count) { - if (scriptScore + count >= float.MaxValue - count) - scriptScore = 0; - - scriptScore += (float)count; - SceneGraph d = m_scene.SceneGraph; - d.AddToScriptLPS(count); + m_scene.SceneGraph.AddToScriptLPS(count); } public void AddActiveScriptCount(int count) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 8762642903..11f54a267c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -78,6 +78,21 @@ namespace OpenSim.Region.ScriptEngine.Interfaces /// string State { get; set; } + /// + /// Time the script was last started + /// + DateTime TimeStarted { get; } + + /// + /// Tick the last measurement period was started. + /// + long MeasurementPeriodTickStart { get; } + + /// + /// Ticks spent executing in the last measurement period. + /// + long MeasurementPeriodExecutionTime { get; } + IScriptEngine Engine { get; } UUID AppDomain { get; set; } string PrimName { get; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 968351b450..b17728758a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -172,6 +172,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public TaskInventoryItem ScriptTask { get; private set; } + public DateTime TimeStarted { get; private set; } + + public long MeasurementPeriodTickStart { get; private set; } + + public long MeasurementPeriodExecutionTime { get; private set; } + + public static readonly long MaxMeasurementPeriod = 30 * TimeSpan.TicksPerMinute; + public void ClearQueue() { m_TimerQueued = false; @@ -458,6 +466,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance Running = true; + TimeStarted = DateTime.Now; + MeasurementPeriodTickStart = Util.EnvironmentTickCount(); + MeasurementPeriodExecutionTime = 0; + if (EventQueue.Count > 0) { if (m_CurrentWorkItem == null) @@ -710,8 +722,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_EventStart = DateTime.Now; m_InEvent = true; + int start = Util.EnvironmentTickCount(); + + // Reset the measurement period when we reach the end of the current one. + if (start - MeasurementPeriodTickStart > MaxMeasurementPeriod) + MeasurementPeriodTickStart = start; + m_Script.ExecuteEvent(State, data.EventName, data.Params); + MeasurementPeriodExecutionTime += Util.EnvironmentTickCount() - start; + m_InEvent = false; m_CurrentEvent = String.Empty; @@ -720,7 +740,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // This will be the very first event we deliver // (state_entry) in default state // - SaveState(m_Assembly); m_SaveState = false; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 105d97da47..bddb1b96fc 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1891,6 +1891,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } + public Dictionary GetObjectScriptsExecutionTimes() + { + long tickNow = Util.EnvironmentTickCount(); + Dictionary topScripts = new Dictionary(); + + lock (m_Scripts) + { + foreach (IScriptInstance si in m_Scripts.Values) + { + if (!topScripts.ContainsKey(si.LocalID)) + topScripts[si.LocalID] = 0; + +// long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; +// float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond); + + // Execution time of the script adjusted by it's measurement period to make scripts started at + // different times comparable. +// float adjustedExecutionTime +// = (float)si.MeasurementPeriodExecutionTime +// / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod) +// / TimeSpan.TicksPerMillisecond; + + long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; + + // Avoid divide by zerp + if (ticksElapsed == 0) + ticksElapsed = 1; + + // Scale execution time to the ideal 55 fps frame time for these reasons. + // + // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no + // 'script execution time per frame', which is the original purpose of this value. + // + // 2) Giving the raw execution times is misleading since scripts start at different times, making + // it impossible to compare scripts. + // + // 3) Scaling the raw execution time to the time that the script has been running is better but + // is still misleading since a script that has just been rezzed may appear to have been running + // for much longer. + // + // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect + // since the figure does not represent actual execution time and very hard running scripts will + // never exceed 18ms (though this is a very high number for script execution so is a warning sign). + float adjustedExecutionTime + = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f; + + topScripts[si.LocalID] += adjustedExecutionTime; + } + } + + return topScripts; + } + public void SuspendScript(UUID itemID) { // m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID); From 7df4a544fecb336d6f4b9cbc0faea98daf0b9edf Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 00:53:36 +0000 Subject: [PATCH 11/31] Fix owner name display in "Top Colliders" and "Top Script" region reports. --- .../World/Estate/EstateManagementModule.cs | 46 +------------------ 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index d363b15c01..1492861c11 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -47,8 +47,6 @@ namespace OpenSim.Region.CoreModules.World.Estate { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private delegate void LookupUUIDS(List uuidLst); - public Scene Scene { get; private set; } public IUserManagement UserManager { get; private set; } @@ -920,9 +918,7 @@ namespace OpenSim.Region.CoreModules.World.Estate lsri.TaskID = so.UUID; lsri.TaskLocalID = so.LocalId; lsri.TaskName = entry.Part.Name; - lsri.OwnerName = "waiting"; - lock (uuidNameLookupList) - uuidNameLookupList.Add(so.OwnerID); + lsri.OwnerName = UserManager.GetUserName(so.OwnerID); if (filter.Length != 0) { @@ -943,48 +939,8 @@ namespace OpenSim.Region.CoreModules.World.Estate } remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); - - if (uuidNameLookupList.Count > 0) - LookupUUID(uuidNameLookupList); } - private static void LookupUUIDSCompleted(IAsyncResult iar) - { - LookupUUIDS icon = (LookupUUIDS)iar.AsyncState; - icon.EndInvoke(iar); - } - - private void LookupUUID(List uuidLst) - { - LookupUUIDS d = LookupUUIDsAsync; - - d.BeginInvoke(uuidLst, - LookupUUIDSCompleted, - d); - } - - private void LookupUUIDsAsync(List uuidLst) - { - UUID[] uuidarr; - - lock (uuidLst) - { - uuidarr = uuidLst.ToArray(); - } - - for (int i = 0; i < uuidarr.Length; i++) - { - // string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]); - - IUserManagement userManager = Scene.RequestModuleInterface(); - if (userManager != null) - userManager.GetUserName(uuidarr[i]); - - // we drop it. It gets cached though... so we're ready for the next request. - // diva commnent 11/21/2010: uh?!? wft? - // justincc comment 21/01/2011: A side effect of userManager.GetUserName() I presume. - } - } #endregion #region Outgoing Packets From c386b68373d0f4c46811423a2ba9ffbb486a1d9f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 01:31:53 +0000 Subject: [PATCH 12/31] Aggregate script execution times by linksets rather than individual prims. This is for the top scripts report. --- OpenSim/Region/Framework/Interfaces/IScriptModule.cs | 5 ++++- .../Region/ScriptEngine/Interfaces/IScriptInstance.cs | 11 +++++++++++ .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 6 ++++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 5 ++--- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 9fb4a25009..9cab2e185b 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -79,7 +79,10 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Get the execution times of all scripts in each object. /// - /// A dictionary where the key is a local object ID and the value is an execution time in milliseconds. + /// + /// A dictionary where the key is the root object ID of a linkset + /// and the value is a representative execution time in milliseconds of all scripts in that linkset. + /// Dictionary GetObjectScriptsExecutionTimes(); } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 11f54a267c..b04f6b6624 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -99,6 +99,17 @@ namespace OpenSim.Region.ScriptEngine.Interfaces string ScriptName { get; } UUID ItemID { get; } UUID ObjectID { get; } + + /// + /// UUID of the root object for the linkset that the script is in. + /// + UUID RootObjectID { get; } + + /// + /// Local id of the root object for the linkset that the script is in. + /// + uint RootLocalID { get; } + uint LocalID { get; } UUID AssetID { get; } Queue EventQueue { get; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index b17728758a..6e367421c0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -164,6 +164,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance public uint LocalID { get; private set; } + public UUID RootObjectID { get; private set; } + + public uint RootLocalID { get; private set; } + public UUID AssetID { get; private set; } public Queue EventQueue { get; private set; } @@ -198,6 +202,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance Engine = engine; LocalID = part.LocalId; ObjectID = part.UUID; + RootLocalID = part.ParentGroup.LocalId; + RootObjectID = part.ParentGroup.UUID; ItemID = itemID; AssetID = assetID; PrimName = primName; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index bddb1b96fc..3697f78c83 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1083,7 +1083,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (!m_PrimObjects[localID].Contains(itemID)) m_PrimObjects[localID].Add(itemID); - } if (!m_Assemblies.ContainsKey(assetID)) @@ -1901,7 +1900,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine foreach (IScriptInstance si in m_Scripts.Values) { if (!topScripts.ContainsKey(si.LocalID)) - topScripts[si.LocalID] = 0; + topScripts[si.RootLocalID] = 0; // long ticksElapsed = tickNow - si.MeasurementPeriodTickStart; // float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond); @@ -1937,7 +1936,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine float adjustedExecutionTime = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f; - topScripts[si.LocalID] += adjustedExecutionTime; + topScripts[si.RootLocalID] += adjustedExecutionTime; } } From 8550a4a07eb581ada9a5dca08b558344d87eebfc Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 01:46:21 +0000 Subject: [PATCH 13/31] In Top Scripts report, don't show scripts with no or less than 1 microsecond of execution time. This is to make the report clearer and less confusing. --- .../CoreModules/World/Estate/EstateManagementModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 1492861c11..61d604ff3d 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -904,9 +904,15 @@ namespace OpenSim.Region.CoreModules.World.Estate foreach (var entry in sortedSceneData) { + // The object may have been deleted since we received the data. if (entry.Part == null) continue; + // Don't show scripts that haven't executed or where execution time is below one microsecond in + // order to produce a more readable report. + if (entry.Measurement < 0.001) + continue; + items++; SceneObjectGroup so = entry.Part.ParentGroup; From 34f6f87b6cbea176805b5802804af9be89284f99 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 01:51:16 +0000 Subject: [PATCH 14/31] Remove unused bin/ScriptEngines/Default.lsl It would certainly be nice to change the default script on disk, but this is currently unused and isn't a suitable default. At this location it would also stop an easy manual deletion of script engine compiles and state. --- bin/ScriptEngines/Default.lsl | 104 ---------------------------------- 1 file changed, 104 deletions(-) delete mode 100644 bin/ScriptEngines/Default.lsl diff --git a/bin/ScriptEngines/Default.lsl b/bin/ScriptEngines/Default.lsl deleted file mode 100644 index ade855d98f..0000000000 --- a/bin/ScriptEngines/Default.lsl +++ /dev/null @@ -1,104 +0,0 @@ -// autogenerated by generate_default_lsl.rb -integer touch_count = 0; - -default { - touch_start(integer total_number) { - float angle45 = PI/4.0; // 45 degrees - float angle30 = PI/6.0; // 30 degrees - float sqrt2 = llSqrt(2.0); - if((llFabs(-1.5) != 1.5) || (llFabs(10.4) != 10.4)) { - llShout(0, "Houston, we have a big problem! llFabs() does not work! Need it for other tests!"); - } - llSetText("This is a text by llSetText", <1,0,0>, 1); - llWhisper(0, "llWhispering a few random numbers between 0 and 100: " + llFrand(100) + "," + llFrand(100) + "," + llFrand(100) + "," + llFrand(100)); - llShout(0, "llShouting the unix time: " + llGetUnixTime() + ", and region corner: " + llGetRegionCorner()); - llShout(1, "Shouting a random number between 0 and 100 on the channel#1: " + llFrand(100)); - if (llAbs(-1) != 1) { - llSay(0, "Assert failed: llAbs(-1) != 1"); - } - if (llAbs(10) != 10) { - llSay(0, "Assert failed: llAbs(10) != 10"); - } - if (llFabs((llCos(angle45) - sqrt2/2.0) - 0) > 0.000001) { - llSay(0, "Assert failed: (llCos(angle45) - sqrt2/2.0) differs from 0 by more than 0.000001"); - llSay(0, " --> The actual result: " + (llCos(angle45) - sqrt2/2.0)); - } - if (llFabs((llSin(angle30) - 0.5) - 0) > 0.000001) { - llSay(0, "Assert failed: (llSin(angle30) - 0.5) differs from 0 by more than 0.000001"); - llSay(0, " --> The actual result: " + (llSin(angle30) - 0.5)); - } - if (llFabs((llAtan2(1, 1)*4 - PI) - 0) > 0.000001) { - llSay(0, "Assert failed: (llAtan2(1, 1)*4 - PI) differs from 0 by more than 0.000001"); - llSay(0, " --> The actual result: " + (llAtan2(1, 1)*4 - PI)); - } - if (llFabs((llTan(PI)) - 0) > 0.000001) { - llSay(0, "Assert failed: (llTan(PI)) differs from 0 by more than 0.000001"); - llSay(0, " --> The actual result: " + (llTan(PI))); - } - if (llFloor(2.4) != 2) { - llSay(0, "Assert failed: llFloor(2.4) != 2"); - } - if (llCeil(2.4) != 3) { - llSay(0, "Assert failed: llCeil(2.4) != 3"); - } - if (llRound(2.4) != 2) { - llSay(0, "Assert failed: llRound(2.4) != 2"); - } - if (llFloor(2.5) != 2) { - llSay(0, "Assert failed: llFloor(2.5) != 2"); - } - if (llCeil(2.5) != 3) { - llSay(0, "Assert failed: llCeil(2.5) != 3"); - } - if (llRound(2.5) != 3) { - llSay(0, "Assert failed: llRound(2.5) != 3"); - } - if (llFloor(2.51) != 2) { - llSay(0, "Assert failed: llFloor(2.51) != 2"); - } - if (llCeil(2.51) != 3) { - llSay(0, "Assert failed: llCeil(2.51) != 3"); - } - if (llRound(2.51) != 3) { - llSay(0, "Assert failed: llRound(2.51) != 3"); - } - if (llFloor(3.49) != 3) { - llSay(0, "Assert failed: llFloor(3.49) != 3"); - } - if (llCeil(3.49) != 4) { - llSay(0, "Assert failed: llCeil(3.49) != 4"); - } - if (llRound(3.49) != 3) { - llSay(0, "Assert failed: llRound(3.49) != 3"); - } - if (llFloor(3.5000001) != 3) { - llSay(0, "Assert failed: llFloor(3.5000001) != 3"); - } - if (llCeil(3.5000001) != 4) { - llSay(0, "Assert failed: llCeil(3.5000001) != 4"); - } - if (llRound(3.5000001) != 4) { - llSay(0, "Assert failed: llRound(3.5000001) != 4"); - } - if (llFloor(3.51) != 3) { - llSay(0, "Assert failed: llFloor(3.51) != 3"); - } - if (llCeil(3.51) != 4) { - llSay(0, "Assert failed: llCeil(3.51) != 4"); - } - if (llRound(3.51) != 4) { - llSay(0, "Assert failed: llRound(3.51) != 4"); - } - if ((llFabs(0-llPow(2, 16))) != 65536) { - llSay(0, "Assert failed: (llFabs(0-llPow(2, 16))) != 65536"); - } - if (llMD5String("Hello, Avatar!",0) != "112abd47ceaae1c05a826828650434a6") { - llSay(0, "Assert failed: llMD5String('Hello, Avatar!',0) != '112abd47ceaae1c05a826828650434a6'"); - } - if (llModPow(2, 16, 37) != 9) { - llSay(0, "Assert failed: llModPow(2, 16, 37) != 9"); - } - touch_count++; - llSay(0, "Object was touched. Touch count: " + touch_count); - } -} From aa881e80652aa9feebbb6a4c4783322be44b7574 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 02:07:26 +0000 Subject: [PATCH 15/31] Allow comments to appear in command scripts (e.g. shutdown_commands.txt). These can start with ; # or // --- OpenSim/Region/Application/OpenSim.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 6fba2493d4..e955a58527 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -503,7 +503,11 @@ namespace OpenSim string currentCommand; while ((currentCommand = readFile.ReadLine()) != null) { - if (currentCommand != String.Empty) + currentCommand = currentCommand.Trim(); + if (!(currentCommand == "" + || currentCommand.StartsWith(";") + || currentCommand.StartsWith("//") + || currentCommand.StartsWith("#"))) { m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'"); m_console.RunCommand(currentCommand); From b19be657b6e032321fe4b55b8751d609d9921384 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 02:10:59 +0000 Subject: [PATCH 16/31] Remove unnecessary "backup" command in shutdown_commands.txt The simulator is already doing this internally. --- bin/shutdown_commands.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/shutdown_commands.txt b/bin/shutdown_commands.txt index ec76ec276d..640c41a0bc 100644 --- a/bin/shutdown_commands.txt +++ b/bin/shutdown_commands.txt @@ -1 +1,2 @@ -backup +; You can place simulator console commands here to execute when the simulator is shut down +; e.g. show stats From 78e992dbd0bbc0b99dd01b1c6c303098d99aac55 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 02:13:45 +0000 Subject: [PATCH 17/31] Move startup_commands.txt.example to startup_commands.txt for consistency with the existing shutdown_commands.txt. Add comments to both files saying what they are (files that can contain console commands to execute on sim startup/shutdown) with an example. --- bin/shutdown_commands.txt | 1 + bin/startup_commands.txt | 3 +++ bin/startup_commands.txt.example | 4 ---- 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 bin/startup_commands.txt delete mode 100644 bin/startup_commands.txt.example diff --git a/bin/shutdown_commands.txt b/bin/shutdown_commands.txt index 640c41a0bc..4397749d23 100644 --- a/bin/shutdown_commands.txt +++ b/bin/shutdown_commands.txt @@ -1,2 +1,3 @@ ; You can place simulator console commands here to execute when the simulator is shut down ; e.g. show stats +; Lines starting with ; are comments diff --git a/bin/startup_commands.txt b/bin/startup_commands.txt new file mode 100644 index 0000000000..1abfa64c87 --- /dev/null +++ b/bin/startup_commands.txt @@ -0,0 +1,3 @@ +; You can place region console commands here to execute once the simulator has finished starting up +; e.g. show stats +; Lines start with ; are comments. diff --git a/bin/startup_commands.txt.example b/bin/startup_commands.txt.example deleted file mode 100644 index 3dba4b378d..0000000000 --- a/bin/startup_commands.txt.example +++ /dev/null @@ -1,4 +0,0 @@ -terrain load-tile f32 islandterrain_1024x512.raw 512 1024 1000 1000 -terrain multiply 0.1 -terrain add 5 - From 421b562a045c69c5d507ee33e0283613d133e376 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 02:43:33 +0000 Subject: [PATCH 18/31] Add process working memory to "show stats" memory statistics. This shows the actual amount of RAM being taken up by OpenSimulator (objects + vm overhead) --- OpenSim/Framework/Statistics/BaseStatsCollector.cs | 8 ++++++-- OpenSim/Framework/Util.cs | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/OpenSim/Framework/Statistics/BaseStatsCollector.cs b/OpenSim/Framework/Statistics/BaseStatsCollector.cs index a1841c568a..c9e57ce7b3 100644 --- a/OpenSim/Framework/Statistics/BaseStatsCollector.cs +++ b/OpenSim/Framework/Statistics/BaseStatsCollector.cs @@ -26,8 +26,8 @@ */ using System; +using System.Diagnostics; using System.Text; - using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -46,8 +46,12 @@ namespace OpenSim.Framework.Statistics sb.Append(Environment.NewLine); sb.Append( string.Format( - "Allocated to OpenSim : {0} MB" + Environment.NewLine, + "Allocated to OpenSim objects: {0} MB\n", Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); + sb.Append( + string.Format( + "Process memory : {0} MB\n", + Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0))); return sb.ToString(); } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index efa4a7ba87..31fa101e50 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -81,12 +81,15 @@ namespace OpenSim.Framework private static uint nextXferID = 5000; private static Random randomClass = new Random(); + // Get a list of invalid file characters (OS dependent) private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; private static object XferLock = new object(); - /// Thread pool used for Util.FireAndForget if - /// FireAndForgetMethod.SmartThreadPool is used + + /// + /// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used + /// private static SmartThreadPool m_ThreadPool; // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. From 05a1493fffcecb1296add194dbbf244c345c8b2f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 15 Mar 2012 20:22:26 -0700 Subject: [PATCH 19/31] More on map search: send extra messages to the user regarding the region being found or not, because the UI is horribly confusing -- places profile is always "loading..." whether the region exists or not. --- .../CoreModules/World/WorldMap/MapSearchModule.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 83ec6c3e3f..d60909c2f6 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -159,6 +159,17 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); + + // send extra user messages for V3 + // because the UI is very confusing + // while we don't fix the hard-coded urls + if (flags == 2) + { + if (regionInfos.Count == 0) + remoteClient.SendAgentAlertMessage("No regions found with that name.", true); + else if (regionInfos.Count == 1) + remoteClient.SendAgentAlertMessage("Region found!", false); + } } // private Scene GetClientScene(IClientAPI client) From 6e8f80f1ab933bbd00b892fa6d01f93f62a1bbbd Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 03:26:47 +0000 Subject: [PATCH 20/31] Improve threadpool reporting to "show threads" console command (also gets printed out periodically) --- .../Framework/Servers/BaseOpenSimServer.cs | 8 +-- OpenSim/Framework/Util.cs | 56 ++++++++++++++++++- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index d5c2515124..5c74ac905b 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -272,12 +272,8 @@ namespace OpenSim.Framework.Servers sb.Append(Environment.NewLine); } - int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; - ThreadPool.GetAvailableThreads(out workers, out ports); - ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts); - - sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine); - sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine); + sb.Append("\n*** Main threadpool (excluding script engine)***\n"); + sb.Append(Util.GetThreadPoolReport()); return sb.ToString(); } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 31fa101e50..9e0f1384f7 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -147,7 +147,6 @@ namespace OpenSim.Framework return lerp(y, lerp(x, a, b), lerp(x, c, d)); } - public static Encoding UTF8 = Encoding.UTF8; /// @@ -1674,6 +1673,61 @@ namespace OpenSim.Framework } } + /// + /// Get a thread pool report. + /// + /// + public static string GetThreadPoolReport() + { + string threadPoolUsed = null; + int maxThreads = 0; + int minThreads = 0; + int allocatedThreads = 0; + int inUseThreads = 0; + int waitingCallbacks = 0; + int completionPortThreads = 0; + + StringBuilder sb = new StringBuilder(); + if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) + { + threadPoolUsed = "SmartThreadPool"; + maxThreads = m_ThreadPool.MaxThreads; + minThreads = m_ThreadPool.MinThreads; + inUseThreads = m_ThreadPool.InUseThreads; + allocatedThreads = m_ThreadPool.ActiveThreads; + waitingCallbacks = m_ThreadPool.WaitingCallbacks; + } + else if ( + FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem + || FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) + { + threadPoolUsed = "BuiltInThreadPool"; + ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads); + ThreadPool.GetMinThreads(out minThreads, out completionPortThreads); + int availableThreads; + ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads); + inUseThreads = maxThreads - availableThreads; + allocatedThreads = -1; + waitingCallbacks = -1; + } + + if (threadPoolUsed != null) + { + sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); + sb.AppendFormat("Max threads : {0}\n", maxThreads); + sb.AppendFormat("Min threads : {0}\n", minThreads); + sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString()); + sb.AppendFormat("In use threads : {0}\n", inUseThreads); + sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString()); + } + else + { + sb.AppendFormat("Thread pool not used\n"); + } + + return sb.ToString(); + } + private static object SmartThreadPoolCallback(object o) { object[] array = (object[])o; From 9497a7c7bd901686999da7bc1cba0b587186570b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 03:32:14 +0000 Subject: [PATCH 21/31] refactor: separate out console and status report generation parts of XEngine --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 3697f78c83..d4108d72dc 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -380,6 +380,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) return; + MainConsole.Instance.OutputFormat(GetStatusReport()); + } + + public string GetStatusReport() + { StringBuilder sb = new StringBuilder(); sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); @@ -407,7 +412,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine Listener l = AsyncCommandManager.GetListenerPlugin(this); sb.AppendFormat("Listeners : {0}\n", l.ListenerCount); - MainConsole.Instance.OutputFormat(sb.ToString()); + return sb.ToString(); } public void HandleShowScripts(string module, string[] cmdparams) From bece2023e754d3d2c09753ad853f68c84243505c Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 03:52:13 +0000 Subject: [PATCH 22/31] Add total scripts count to "show threads" However, this returns 0 on Mono (at least on 2.6.7)! So not showing if it is zero. --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 5c74ac905b..6da1436267 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -269,10 +269,18 @@ namespace OpenSim.Framework.Servers t.Priority, t.ThreadState); - sb.Append(Environment.NewLine); + sb.Append("\n"); } - sb.Append("\n*** Main threadpool (excluding script engine)***\n"); + sb.Append("\n"); + + // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting + // zero active threads. + int totalThreads = Process.GetCurrentProcess().Threads.Count; + if (totalThreads > 0) + sb.AppendFormat("Total threads active: {0}\n\n", Process.GetCurrentProcess().Threads.Count); + + sb.Append("Main threadpool (excluding script engine pools)\n"); sb.Append(Util.GetThreadPoolReport()); return sb.ToString(); From 59b6f6a6e03417360d9ea94b8e9cabc8569ffe89 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 16 Mar 2012 03:56:56 +0000 Subject: [PATCH 23/31] minor: reuse threadpool count we just fetched instead of fetching it again --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 6da1436267..06a8021b5f 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -278,7 +278,7 @@ namespace OpenSim.Framework.Servers // zero active threads. int totalThreads = Process.GetCurrentProcess().Threads.Count; if (totalThreads > 0) - sb.AppendFormat("Total threads active: {0}\n\n", Process.GetCurrentProcess().Threads.Count); + sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); sb.Append("Main threadpool (excluding script engine pools)\n"); sb.Append(Util.GetThreadPoolReport()); From a2009ffe2e71afefad79471811418df8958870ab Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 16 Mar 2012 13:08:05 -0700 Subject: [PATCH 24/31] Terrain: added [Terrain] section with an option to load an initial flat terrain. Default is still pinhead island. I much rather have a flat land in the beginning. --- .../World/Terrain/TerrainModule.cs | 7 ++- OpenSim/Region/Framework/Scenes/Scene.cs | 11 +++- .../Region/Framework/Scenes/TerrainChannel.cs | 60 ++++++++++++++----- bin/OpenSim.ini.example | 4 +- bin/OpenSimDefaults.ini | 3 + 5 files changed, 65 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index cf000a44dd..ef9c95c990 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -86,6 +86,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain private volatile bool m_tainted; private readonly Stack m_undo = new Stack(5); + private String m_InitialTerrain = "pinhead-island"; + /// /// Human readable list of terrain file extensions that are supported. /// @@ -109,6 +111,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain /// Config for the region public void Initialise(IConfigSource config) { + IConfig terrainConfig = config.Configs["Terrain"]; + if (terrainConfig != null) + m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); } public void AddRegion(Scene scene) @@ -120,7 +125,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain { if (m_scene.Heightmap == null) { - m_channel = new TerrainChannel(); + m_channel = new TerrainChannel(m_InitialTerrain); m_scene.Heightmap = m_channel; m_revert = new TerrainChannel(); UpdateRevertMap(); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3a066d426e..5b1b165a17 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1576,8 +1576,15 @@ namespace OpenSim.Region.Framework.Scenes double[,] map = SimulationDataService.LoadTerrain(RegionInfo.RegionID); if (map == null) { - m_log.Info("[TERRAIN]: No default terrain. Generating a new terrain."); - Heightmap = new TerrainChannel(); + // This should be in the Terrain module, but it isn't because + // the heightmap is needed _way_ before the modules are initialized... + IConfig terrainConfig = m_config.Configs["Terrain"]; + String m_InitialTerrain = "pinhead-island"; + if (terrainConfig != null) + m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain); + + m_log.InfoFormat("[TERRAIN]: No default terrain. Generating a new terrain {0}.", m_InitialTerrain); + Heightmap = new TerrainChannel(m_InitialTerrain); SimulationDataService.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); } diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs index ca6210d029..c0ca48ef39 100644 --- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs +++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs @@ -46,23 +46,20 @@ namespace OpenSim.Region.Framework.Scenes public TerrainChannel() { map = new double[Constants.RegionSize, Constants.RegionSize]; - taint = new bool[Constants.RegionSize / 16,Constants.RegionSize / 16]; + taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; - int x; - for (x = 0; x < Constants.RegionSize; x++) - { - int y; - for (y = 0; y < Constants.RegionSize; y++) - { - map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; - double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01; - double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001; - if (map[x, y] < spherFacA) - map[x, y] = spherFacA; - if (map[x, y] < spherFacB) - map[x, y] = spherFacB; - } - } + PinHeadIsland(); + } + + public TerrainChannel(String type) + { + map = new double[Constants.RegionSize, Constants.RegionSize]; + taint = new bool[Constants.RegionSize / 16, Constants.RegionSize / 16]; + + if (type.Equals("flat")) + FlatLand(); + else + PinHeadIsland(); } public TerrainChannel(double[,] import) @@ -238,5 +235,36 @@ namespace OpenSim.Region.Framework.Scenes } } } + + private void PinHeadIsland() + { + int x; + for (x = 0; x < Constants.RegionSize; x++) + { + int y; + for (y = 0; y < Constants.RegionSize; y++) + { + map[x, y] = TerrainUtil.PerlinNoise2D(x, y, 2, 0.125) * 10; + double spherFacA = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 50) * 0.01; + double spherFacB = TerrainUtil.SphericalFactor(x, y, Constants.RegionSize / 2.0, Constants.RegionSize / 2.0, 100) * 0.001; + if (map[x, y] < spherFacA) + map[x, y] = spherFacA; + if (map[x, y] < spherFacB) + map[x, y] = spherFacB; + } + } + } + + private void FlatLand() + { + int x; + for (x = 0; x < Constants.RegionSize; x++) + { + int y; + for (y = 0; y < Constants.RegionSize; y++) + map[x, y] = 21; + } + } + } } diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 1f3cd0d554..2c85f9db18 100755 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -790,7 +790,9 @@ ;# {Enabled} {} {Enable Non Player Character (NPC) facilities} {true false} false ; Enabled = false - +[Terrain] + ;# {InitialTerrain} {} {Initial terrain type} {pinhead-island flat} pinhead-island + ; InitialTerrain = "pinhead-island" [Architecture] ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index fab2c476be..fd31131bb5 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1512,6 +1512,9 @@ ;; Enable Non Player Character (NPC) facilities Enabled = false +[Terrain] + InitialTerrain = "pinhead-island" + ;; ;; If you are using a simian grid frontend you can enable ;; this module to upload tile images for the mapping fn From 1e4180fc931b2d07756519403ed4ae18d136906b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Mar 2012 02:54:19 +0000 Subject: [PATCH 25/31] Clean up "save iar" help --- .../Archiver/InventoryArchiverModule.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 21548273a0..ac22c3f079 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -124,15 +124,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver "Archiving", this, "save iar", "save iar [-h|--home=] [--noassets] [] [-c|--creators] [-v|--verbose]", "Save user inventory archive (IAR).", - " is the user's first name." + Environment.NewLine - + " is the user's last name." + Environment.NewLine - + " is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine - + "-h|--home= adds the url of the profile service to the saved user information." + Environment.NewLine - + "-c|--creators preserves information about foreign creators." + Environment.NewLine - + "-v|--verbose extra debug messages." + Environment.NewLine - + "--noassets stops assets being saved to the IAR." + " is the user's first name.\n" + + " is the user's last name.\n" + + " is the path inside the user's inventory for the folder/item to be saved.\n" + " is the filesystem path at which to save the IAR." - + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), + + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) + + "-h|--home= adds the url of the profile service to the saved user information.\n" + + "-c|--creators preserves information about foreign creators.\n" + + "-v|--verbose extra debug messages.\n" + + "--noassets stops assets being saved to the IAR.", HandleSaveInvConsoleCommand); m_aScene = scene; From 4a57112f19c0e4eb3545fdc0cbbbd68ce46c6eaa Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 17 Mar 2012 04:02:23 +0000 Subject: [PATCH 26/31] Add osGetInventoryDesc() as per http://opensimulator.org/mantis/view.php?id=5927 This allows one to get description data for a given prim inventory item. Thanks MarcelEdward and GuduleLapointe! --- CONTRIBUTORS.txt | 1 + .../Shared/Api/Implementation/OSSL_Api.cs | 23 +++++++++++++++++++ .../Shared/Api/Interface/IOSSL_Api.cs | 2 ++ .../Shared/Api/Runtime/OSSL_Stub.cs | 5 ++++ 4 files changed, 31 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index de5a6fc04b..e6956bb729 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -107,6 +107,7 @@ what it is today. * M.Igarashi * maimedleech * Mana Janus +* MarcelEdward * Mic Bowman * Michelle Argus * Michael Cortez (The Flotsam Project, http://osflotsam.org/) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 3dbc31a10e..2ecd890e9c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2957,5 +2957,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); } + + /// + /// Get the description from an inventory item + /// + /// + /// Item description + public LSL_String osGetInventoryDesc(string item) + { + m_host.AddScriptLPS(1); + + lock (m_host.TaskInventory) + { + foreach (KeyValuePair inv in m_host.TaskInventory) + { + if (inv.Value.Name == item) + { + return inv.Value.Description.ToString(); + } + } + } + + return String.Empty; + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index a5b906f678..8f9efc04d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -229,5 +229,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_List osGetAvatarList(); LSL_String osUnixTimeToTimestamp(long time); + + LSL_String osGetInventoryDesc(string item); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index e048da2ce9..09e5992393 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -863,5 +863,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osUnixTimeToTimestamp(time); } + + public LSL_String osGetInventoryDesc(string item) + { + return m_OSSL_Functions.osGetInventoryDesc(item); + } } } From 33c14cb107ecb67a3e971d6adaab17d173d52747 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 17 Mar 2012 10:00:11 -0700 Subject: [PATCH 27/31] Region access control! Region operators can now specify things like DisallowForeigners (means what it says) and DisallowResidents (means that only admins and managers can get into the region). This puts the never-completed AuthorizationService to good use. Note that I didn't implement a grid-wide Authorization service; this service implementation is done entirely locally on the simulator. This can be changed as usual by pluging in a different AuthorizationServicesConnector. --- .../Authorization/AuthorizationService.cs | 124 ++++++++++++++++++ .../LocalAuthorizationServiceConnector.cs | 43 +++--- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- bin/config-include/Grid.ini | 1 + bin/config-include/GridCommon.ini.example | 10 ++ bin/config-include/GridHypergrid.ini | 1 + bin/config-include/Standalone.ini | 4 +- .../StandaloneCommon.ini.example | 10 ++ bin/config-include/StandaloneHypergrid.ini | 4 +- 9 files changed, 166 insertions(+), 35 deletions(-) create mode 100644 OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs new file mode 100644 index 0000000000..f0d21e67db --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs @@ -0,0 +1,124 @@ +/* + * 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; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Nini.Config; +using log4net; +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenMetaverse; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization +{ + public class AuthorizationService : IAuthorizationService + { + private enum AccessFlags + { + None = 0, /* No restrictions */ + DisallowResidents = 1, /* Only gods and managers*/ + DisallowForeigners = 2, /* Only local people */ + } + + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private IUserManagement m_UserManagement; + private IGridService m_GridService; + + private Scene m_Scene; + AccessFlags m_accessValue = AccessFlags.None; + + + public AuthorizationService(IConfig config, Scene scene) + { + m_Scene = scene; + m_UserManagement = scene.RequestModuleInterface(); + m_GridService = scene.GridService; + + if (config != null) + { + string accessStr = config.GetString("Region_" + scene.RegionInfo.RegionName.Replace(' ', '_'), String.Empty); + if (accessStr != string.Empty) + { + try + { + m_accessValue = (AccessFlags)Enum.Parse(typeof(AccessFlags), accessStr); + } + catch (ArgumentException) + { + m_log.WarnFormat("[AuthorizationService]: {0} is not a valid access flag", accessStr); + } + } + m_log.DebugFormat("[AuthorizationService]: Region {0} access restrictions: {1}", m_Scene.RegionInfo.RegionName, m_accessValue); + } + + } + + public bool IsAuthorizedForRegion( + string user, string firstName, string lastName, string regionID, out string message) + { + message = "authorized"; + + // This should not happen + if (m_Scene.RegionInfo.RegionID.ToString() != regionID) + { + m_log.WarnFormat("[AuthorizationService]: Service for region {0} received request to authorize for region {1}", + m_Scene.RegionInfo.RegionID, regionID); + return true; + } + + if (m_accessValue == AccessFlags.None) + return true; + + UUID userID = new UUID(user); + bool authorized = true; + if ((m_accessValue & AccessFlags.DisallowForeigners) == AccessFlags.DisallowForeigners) + { + authorized = m_UserManagement.IsLocalGridUser(userID); + if (!authorized) + message = "no foreigner users allowed in this region"; + } + if (authorized && (m_accessValue & AccessFlags.DisallowResidents) == AccessFlags.DisallowResidents) + { + authorized = m_Scene.Permissions.IsGod(userID) | m_Scene.Permissions.IsAdministrator(userID); + if (!authorized) + message = "only Admins and Managers allowed in this region"; + } + + return authorized; + } + + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs index 18a7177b6f..c982db61fc 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs @@ -39,13 +39,15 @@ using OpenMetaverse; namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization { - public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService + public class LocalAuthorizationServicesConnector : INonSharedRegionModule, IAuthorizationService { private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); private IAuthorizationService m_AuthorizationService; + private Scene m_Scene; + private IConfig m_AuthorizationConfig; private bool m_Enabled = false; @@ -69,33 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization string name = moduleConfig.GetString("AuthorizationServices", string.Empty); if (name == Name) { - IConfig authorizationConfig = source.Configs["AuthorizationService"]; - if (authorizationConfig == null) - { - m_log.Error("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); - return; - } - - string serviceDll = authorizationConfig.GetString("LocalServiceModule", - String.Empty); - - if (serviceDll == String.Empty) - { - m_log.Error("[AUTHORIZATION CONNECTOR]: No LocalServiceModule named in section AuthorizationService"); - return; - } - - Object[] args = new Object[] { source }; - m_AuthorizationService = - ServerUtils.LoadPlugin(serviceDll, - args); - - if (m_AuthorizationService == null) - { - m_log.Error("[AUTHORIZATION CONNECTOR]: Can't load authorization service"); - return; - } m_Enabled = true; + m_AuthorizationConfig = source.Configs["AuthorizationService"]; m_log.Info("[AUTHORIZATION CONNECTOR]: Local authorization connector enabled"); } } @@ -115,6 +92,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization return; scene.RegisterModuleInterface(this); + m_Scene = scene; + + scene.EventManager.OnLoginsEnabled += new EventManager.LoginsEnabled(OnLoginsEnabled); } public void RemoveRegion(Scene scene) @@ -131,9 +111,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization scene.RegionInfo.RegionName); } + private void OnLoginsEnabled(string regionName) + { + m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene); + } + public bool IsAuthorizedForRegion( string userID, string firstName, string lastName, string regionID, out string message) { + message = ""; + if (!m_Enabled) + return true; + return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5b1b165a17..0042f7bfbf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3533,8 +3533,8 @@ namespace OpenSim.Region.Framework.Scenes if (!AuthorizationService.IsAuthorizedForRegion( agent.AgentID.ToString(), agent.firstname, agent.lastname, RegionInfo.RegionID.ToString(), out reason)) { - m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the region", - agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); + m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because {4}", + agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName, reason); return false; } diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini index da860c6859..95d62649ca 100644 --- a/bin/config-include/Grid.ini +++ b/bin/config-include/Grid.ini @@ -14,6 +14,7 @@ AvatarServices = "RemoteAvatarServicesConnector" NeighbourServices = "RemoteNeighbourServicesConnector" AuthenticationServices = "RemoteAuthenticationServicesConnector" + AuthorizationServices = "LocalAuthorizationServicesConnector" PresenceServices = "RemotePresenceServicesConnector" UserAccountServices = "RemoteUserAccountServicesConnector" GridUserServices = "RemoteGridUserServicesConnector" diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 712481d299..fa6f5258c5 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -146,3 +146,13 @@ [MapImageService] MapImageServerURI = "http://mygridserver.com:8003" + +[AuthorizationService] + ; If you have regions with access restrictions + ; specify them here using the convention + ; Region_ = + ; Valid flags are: + ; DisallowForeigners -- HG visitors not allowed + ; DisallowResidents -- only Admins and Managers allowed + ; Example: + ; Region_Test_1 = "DisallowForeigners" diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index 5f0ba370e1..da447f1e12 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -17,6 +17,7 @@ AvatarServices = "RemoteAvatarServicesConnector" NeighbourServices = "RemoteNeighbourServicesConnector" AuthenticationServices = "RemoteAuthenticationServicesConnector" + AuthorizationServices = "LocalAuthorizationServicesConnector" PresenceServices = "RemotePresenceServicesConnector" UserAccountServices = "RemoteUserAccountServicesConnector" GridUserServices = "RemoteGridUserServicesConnector" diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index 6ad4ac9e68..d307387e85 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -9,6 +9,7 @@ InventoryServices = "LocalInventoryServicesConnector" NeighbourServices = "LocalNeighbourServicesConnector" AuthenticationServices = "LocalAuthenticationServicesConnector" + AuthorizationServices = "LocalAuthorizationServicesConnector" GridServices = "LocalGridServicesConnector" PresenceServices = "LocalPresenceServicesConnector" UserAccountServices = "LocalUserAccountServicesConnector" @@ -47,9 +48,6 @@ [AvatarService] LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService" -[AuthorizationService] - LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService" - [AuthenticationService] LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 2f39218b13..2a7e49e76f 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -231,3 +231,13 @@ [MapImageService] ; Set this if you want to change the default ; TilesStoragePath = "maptiles" + +[AuthorizationService] + ; If you have regions with access restrictions + ; specify them here using the convention + ; Region_ = + ; Valid flags are: + ; DisallowForeigners -- HG visitors not allowed + ; DisallowResidents -- only Admins and Managers allowed + ; Example: + ; Region_Test_1 = "DisallowForeigners" \ No newline at end of file diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 00beb31f10..286d0a1374 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -12,6 +12,7 @@ InventoryServices = "HGInventoryBroker" NeighbourServices = "LocalNeighbourServicesConnector" AuthenticationServices = "LocalAuthenticationServicesConnector" + AuthorizationServices = "LocalAuthorizationServicesConnector" GridServices = "LocalGridServicesConnector" PresenceServices = "LocalPresenceServicesConnector" UserAccountServices = "LocalUserAccountServicesConnector" @@ -68,9 +69,6 @@ LibraryName = "OpenSim Library" DefaultLibrary = "./inventory/Libraries.xml" -[AuthorizationService] - LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService" - [AuthenticationService] LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" From 1a4fdd26663fc6cfdcc76adb86d9babbd657a55d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 17 Mar 2012 10:48:22 -0700 Subject: [PATCH 28/31] Moved HandleAvatarPickerRequest from the generic Scene.PacketHandlers to the UserManagementModule where it belongs. No functional changes. --- .../UserManagement/UserManagementModule.cs | 62 +++++++++++++++++++ .../Framework/Scenes/Scene.PacketHandlers.cs | 53 ---------------- OpenSim/Region/Framework/Scenes/Scene.cs | 2 - 3 files changed, 62 insertions(+), 55 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 554af14071..39e06617c8 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -38,6 +38,7 @@ using OpenSim.Services.Interfaces; using OpenSim.Services.Connectors.Hypergrid; using OpenMetaverse; +using OpenMetaverse.Packets; using log4net; using Nini.Config; @@ -149,7 +150,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement void EventManager_OnNewClient(IClientAPI client) { + client.OnConnectionClosed += new Action(HandleConnectionClosed); client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); + client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest); + } + + void HandleConnectionClosed(IClientAPI client) + { + client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest); + client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); } void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) @@ -170,6 +179,59 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } } + public void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query) + { + //EventManager.TriggerAvatarPickerRequest(); + + List accounts = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); + + if (accounts == null) + return; + + AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); + // TODO: don't create new blocks if recycling an old packet + + AvatarPickerReplyPacket.DataBlock[] searchData = + new AvatarPickerReplyPacket.DataBlock[accounts.Count]; + AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock(); + + agentData.AgentID = avatarID; + agentData.QueryID = RequestID; + replyPacket.AgentData = agentData; + //byte[] bytes = new byte[AvatarResponses.Count*32]; + + int i = 0; + foreach (UserAccount item in accounts) + { + UUID translatedIDtem = item.PrincipalID; + searchData[i] = new AvatarPickerReplyPacket.DataBlock(); + searchData[i].AvatarID = translatedIDtem; + searchData[i].FirstName = Utils.StringToBytes((string)item.FirstName); + searchData[i].LastName = Utils.StringToBytes((string)item.LastName); + i++; + } + if (accounts.Count == 0) + { + searchData = new AvatarPickerReplyPacket.DataBlock[0]; + } + replyPacket.Data = searchData; + + AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs(); + agent_data.AgentID = replyPacket.AgentData.AgentID; + agent_data.QueryID = replyPacket.AgentData.QueryID; + + List data_args = new List(); + for (i = 0; i < replyPacket.Data.Length; i++) + { + AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs(); + data_arg.AvatarID = replyPacket.Data[i].AvatarID; + data_arg.FirstName = replyPacket.Data[i].FirstName; + data_arg.LastName = replyPacket.Data[i].LastName; + data_args.Add(data_arg); + } + client.SendAvatarPickerReply(agent_data, data_args); + } + #endregion Event Handlers private void CacheCreators(SceneObjectGroup sog) diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 3355ebe380..87ffc74acd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -339,59 +339,6 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient, surfaceArg); } - public void ProcessAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query) - { - //EventManager.TriggerAvatarPickerRequest(); - - List accounts = UserAccountService.GetUserAccounts(RegionInfo.ScopeID, query); - - if (accounts == null) - return; - - AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); - // TODO: don't create new blocks if recycling an old packet - - AvatarPickerReplyPacket.DataBlock[] searchData = - new AvatarPickerReplyPacket.DataBlock[accounts.Count]; - AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock(); - - agentData.AgentID = avatarID; - agentData.QueryID = RequestID; - replyPacket.AgentData = agentData; - //byte[] bytes = new byte[AvatarResponses.Count*32]; - - int i = 0; - foreach (UserAccount item in accounts) - { - UUID translatedIDtem = item.PrincipalID; - searchData[i] = new AvatarPickerReplyPacket.DataBlock(); - searchData[i].AvatarID = translatedIDtem; - searchData[i].FirstName = Utils.StringToBytes((string) item.FirstName); - searchData[i].LastName = Utils.StringToBytes((string) item.LastName); - i++; - } - if (accounts.Count == 0) - { - searchData = new AvatarPickerReplyPacket.DataBlock[0]; - } - replyPacket.Data = searchData; - - AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs(); - agent_data.AgentID = replyPacket.AgentData.AgentID; - agent_data.QueryID = replyPacket.AgentData.QueryID; - - List data_args = new List(); - for (i = 0; i < replyPacket.Data.Length; i++) - { - AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs(); - data_arg.AvatarID = replyPacket.Data[i].AvatarID; - data_arg.FirstName = replyPacket.Data[i].FirstName; - data_arg.LastName = replyPacket.Data[i].LastName; - data_args.Add(data_arg); - } - client.SendAvatarPickerReply(agent_data, data_args); - } - public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID, UUID itemID) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0042f7bfbf..0706905689 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2767,7 +2767,6 @@ namespace OpenSim.Region.Framework.Scenes { //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; - client.OnAvatarPickerRequest += ProcessAvatarPickerRequest; client.OnSetStartLocationRequest += SetHomeRezPoint; client.OnRegionHandleRequest += RegionHandleRequest; } @@ -2893,7 +2892,6 @@ namespace OpenSim.Region.Framework.Scenes { //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; - client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest; client.OnSetStartLocationRequest -= SetHomeRezPoint; client.OnRegionHandleRequest -= RegionHandleRequest; } From 92b1ade78ea51ca1499298476fe7cc7ce4e955cc Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 17 Mar 2012 15:01:10 -0700 Subject: [PATCH 29/31] BAD JUSTIN! People using standalone in master, please update your StandaloneCommon.ini according to this change. People using robust in master, please update your Robust.HG.ini.example[.HG].ini according to this change. --- bin/Robust.HG.ini.example | 1 + bin/Robust.ini.example | 1 + bin/config-include/StandaloneCommon.ini.example | 1 + 3 files changed, 3 insertions(+) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index db9f08b729..d98c826c5e 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -66,6 +66,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; * in turn, reads the asset loader and database connection information ; * [AssetService] + StorageProvider = "OpenSim.Data.MySQL.dll:MySQLAssetData" LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "./assets/AssetSets.xml" diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 326caeb86d..691bfdc1e9 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -58,6 +58,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ; * in turn, reads the asset loader and database connection information ; * [AssetService] + StorageProvider = "OpenSim.Data.MySQL.dll:MySQLAssetData" LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "./assets/AssetSets.xml" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index 2a7e49e76f..4c734a1ab4 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -44,6 +44,7 @@ ;AuthorizationServices = "LocalAuthorizationServicesConnector" [AssetService] + StorageProvider = "OpenSim.Data.MySQL.dll:MySQLAssetData" DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "assets/AssetSets.xml" From 7dfa0309c63263fb15dc9e3883f5717f28e21c0c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 17 Mar 2012 15:36:20 -0700 Subject: [PATCH 30/31] More on HG access control. This commit splits the UserManagementModule into the Basic one and the HG one, so that we can do everything that needs to be done for HG ACLs to work without interfering with the vanilla opensim. For the moment, it finds foreign users who have left a trace in the region, e.g. an object. This makes it possible to ban/IM/etc these users using the regular avatar picker. TODO: contact the UAS directly given a name of the form First.Last @foo.com. --- .../UserManagement/HGUserManagementModule.cs | 119 ++++++++++++++++++ .../UserManagement/UserManagementModule.cs | 102 +++++++++------ .../Resources/CoreModulePlugin.addin.xml | 1 + bin/config-include/GridHypergrid.ini | 1 + bin/config-include/StandaloneHypergrid.ini | 1 + 5 files changed, 184 insertions(+), 40 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs new file mode 100644 index 0000000000..6543bf294b --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs @@ -0,0 +1,119 @@ +/* + * 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; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.Hypergrid; + +using OpenMetaverse; +using OpenMetaverse.Packets; +using log4net; +using Nini.Config; + +namespace OpenSim.Region.CoreModules.Framework.UserManagement +{ + public class HGUserManagementModule : UserManagementModule, ISharedRegionModule, IUserManagement + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + + #region ISharedRegionModule + + public new void Initialise(IConfigSource config) + { + string umanmod = config.Configs["Modules"].GetString("UserManagementModule", base.Name); + if (umanmod == Name) + { + m_Enabled = true; + RegisterConsoleCmds(); + m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); + } + } + + public override string Name + { + get { return "HGUserManagementModule"; } + } + + #endregion ISharedRegionModule + + protected override void AddAdditionalUsers(UUID avatarID, string query, List users) + { + string[] words = query.Split(new char[] { ' ' }); + + for (int i = 0; i < words.Length; i++) + { + if (words[i].Length < 3) + { + if (i != words.Length - 1) + Array.Copy(words, i + 1, words, i, words.Length - i - 1); + Array.Resize(ref words, words.Length - 1); + } + } + + if (words.Length == 0 || words.Length > 2) + return; + + if (words.Length == 2) // First.Last @foo.com, maybe? + { + bool found = false; + foreach (UserData d in m_UserCache.Values) + { + if (d.LastName.StartsWith("@") && (d.FirstName.Equals(words[0]) || d.LastName.Equals(words[1]))) + { + users.Add(d); + found = true; + break; + } + } + if (!found) // This is it! Let's ask the other world + { + // TODO + //UserAgentServiceConnector uasConn = new UserAgentServiceConnector(words[0]); + //uasConn.GetUserInfo(...); + } + } + else + { + foreach (UserData d in m_UserCache.Values) + { + if (d.LastName.StartsWith("@") && (d.FirstName.StartsWith(query) || d.LastName.StartsWith(query))) + users.Add(d); + } + } + } + + } +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 39e06617c8..23ef0fc98d 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -44,7 +44,7 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.UserManagement { - class UserData + public class UserData { public UUID Id { get; set; } public string FirstName { get; set; } @@ -57,36 +57,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private List m_Scenes = new List(); + protected bool m_Enabled; + protected List m_Scenes = new List(); // The cache - Dictionary m_UserCache = new Dictionary(); + protected Dictionary m_UserCache = new Dictionary(); #region ISharedRegionModule public void Initialise(IConfigSource config) { - //m_Enabled = config.Configs["Modules"].GetBoolean("LibraryModule", m_Enabled); - //if (m_Enabled) - //{ - // IConfig libConfig = config.Configs["LibraryService"]; - // if (libConfig != null) - // { - // string dllName = libConfig.GetString("LocalServiceModule", string.Empty); - // m_log.Debug("[LIBRARY MODULE]: Library service dll is " + dllName); - // if (dllName != string.Empty) - // { - // Object[] args = new Object[] { config }; - // m_Library = ServerUtils.LoadPlugin(dllName, args); - // } - // } - //} - MainConsole.Instance.Commands.AddCommand("Users", true, - "show names", - "show names", - "Show the bindings between user UUIDs and user names", - String.Empty, - HandleShowUsers); + string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name); + if (umanmod == Name) + { + m_Enabled = true; + RegisterConsoleCmds(); + m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); + } } public bool IsSharedModule @@ -94,9 +81,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement get { return true; } } - public string Name + public virtual string Name { - get { return "UserManagement Module"; } + get { return "BasicUserManagementModule"; } } public Type ReplaceableInterface @@ -106,17 +93,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public void AddRegion(Scene scene) { - m_Scenes.Add(scene); + if (m_Enabled) + { + m_Scenes.Add(scene); - scene.RegisterModuleInterface(this); - scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); - scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); + scene.RegisterModuleInterface(this); + scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); + scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); + } } public void RemoveRegion(Scene scene) { - scene.UnregisterModuleInterface(this); - m_Scenes.Remove(scene); + if (m_Enabled) + { + scene.UnregisterModuleInterface(this); + m_Scenes.Remove(scene); + } } public void RegionLoaded(Scene s) @@ -183,16 +176,31 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement { //EventManager.TriggerAvatarPickerRequest(); - List accounts = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); + m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); - if (accounts == null) - return; + List accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); + + List users = new List(); + if (accs != null) + { + m_log.DebugFormat("[USER MANAGEMENT MODULE]: Found {0} users", accs.Count); + foreach (UserAccount acc in accs) + { + UserData ud = new UserData(); + ud.FirstName = acc.FirstName; + ud.LastName = acc.LastName; + ud.Id = acc.PrincipalID; + users.Add(ud); + } + } + + AddAdditionalUsers(avatarID, query, users); AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); // TODO: don't create new blocks if recycling an old packet AvatarPickerReplyPacket.DataBlock[] searchData = - new AvatarPickerReplyPacket.DataBlock[accounts.Count]; + new AvatarPickerReplyPacket.DataBlock[users.Count]; AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock(); agentData.AgentID = avatarID; @@ -201,16 +209,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement //byte[] bytes = new byte[AvatarResponses.Count*32]; int i = 0; - foreach (UserAccount item in accounts) + foreach (UserData item in users) { - UUID translatedIDtem = item.PrincipalID; + UUID translatedIDtem = item.Id; searchData[i] = new AvatarPickerReplyPacket.DataBlock(); searchData[i].AvatarID = translatedIDtem; searchData[i].FirstName = Utils.StringToBytes((string)item.FirstName); searchData[i].LastName = Utils.StringToBytes((string)item.LastName); i++; } - if (accounts.Count == 0) + if (users.Count == 0) { searchData = new AvatarPickerReplyPacket.DataBlock[0]; } @@ -232,6 +240,10 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement client.SendAvatarPickerReply(agent_data, data_args); } + protected virtual void AddAdditionalUsers(UUID avatarID, string query, List users) + { + } + #endregion Event Handlers private void CacheCreators(SceneObjectGroup sog) @@ -487,13 +499,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement #endregion IUserManagement + protected void RegisterConsoleCmds() + { + MainConsole.Instance.Commands.AddCommand("Users", true, + "show names", + "show names", + "Show the bindings between user UUIDs and user names", + String.Empty, + HandleShowUsers); + } + private void HandleShowUsers(string module, string[] cmd) { lock (m_UserCache) { if (m_UserCache.Count == 0) { - MainConsole.Instance.Output("No users not found"); + MainConsole.Instance.Output("No users found"); return; } diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index e22fd38107..dc6efed1e1 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml @@ -9,6 +9,7 @@ + diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index da447f1e12..31a4059139 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -27,6 +27,7 @@ LandServices = "RemoteLandServicesConnector" FriendsModule = "HGFriendsModule" MapImageService = "MapImageServiceModule" + UserManagementModule = "HGUserManagementModule" LandServiceInConnector = true NeighbourServiceInConnector = true diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index 286d0a1374..ee51067fed 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -23,6 +23,7 @@ EntityTransferModule = "HGEntityTransferModule" InventoryAccessModule = "HGInventoryAccessModule" FriendsModule = "HGFriendsModule" + UserManagementModule = "HGUserManagementModule" InventoryServiceInConnector = true AssetServiceInConnector = true From 441ef301a34ab1968e74038e19066b37e7a74a66 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 17 Mar 2012 19:41:47 -0700 Subject: [PATCH 31/31] Amend to previous commit: normalize strings ToLower. --- .../Framework/UserManagement/HGUserManagementModule.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs index 6543bf294b..8077a7a53b 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs @@ -91,7 +91,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement bool found = false; foreach (UserData d in m_UserCache.Values) { - if (d.LastName.StartsWith("@") && (d.FirstName.Equals(words[0]) || d.LastName.Equals(words[1]))) + if (d.LastName.StartsWith("@") && + (d.FirstName.ToLower().Equals(words[0].ToLower()) || + d.LastName.ToLower().Equals(words[1].ToLower()))) { users.Add(d); found = true; @@ -109,7 +111,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement { foreach (UserData d in m_UserCache.Values) { - if (d.LastName.StartsWith("@") && (d.FirstName.StartsWith(query) || d.LastName.StartsWith(query))) + if (d.LastName.StartsWith("@") && + (d.FirstName.ToLower().StartsWith(query.ToLower()) || + d.LastName.ToLower().StartsWith(query.ToLower()))) users.Add(d); } }