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/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index f4d541e922..87d04f8c1e 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -269,15 +269,19 @@ namespace OpenSim.Framework.Servers t.Priority, t.ThreadState); - sb.Append(Environment.NewLine); + sb.Append("\n"); } - int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; - ThreadPool.GetAvailableThreads(out workers, out ports); - ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts); + sb.Append("\n"); - sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine); - sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine); + // 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", totalThreads); + + sb.Append("Main threadpool (excluding script engine pools)\n"); + sb.Append(Util.GetThreadPoolReport()); return sb.ToString(); } 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 02da7f4231..a695542280 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. @@ -144,7 +147,6 @@ namespace OpenSim.Framework return lerp(y, lerp(x, a, b), lerp(x, c, d)); } - public static Encoding UTF8 = Encoding.UTF8; /// @@ -1683,6 +1685,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; diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index aad73a3283..9fcd99c1f6 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); 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; diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs new file mode 100644 index 0000000000..8077a7a53b --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs @@ -0,0 +1,123 @@ +/* + * 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.ToLower().Equals(words[0].ToLower()) || + d.LastName.ToLower().Equals(words[1].ToLower()))) + { + 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.ToLower().StartsWith(query.ToLower()) || + d.LastName.ToLower().StartsWith(query.ToLower()))) + 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 554af14071..23ef0fc98d 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -38,12 +38,13 @@ 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 { - class UserData + public class UserData { public UUID Id { get; set; } public string FirstName { get; set; } @@ -56,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 @@ -93,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 @@ -105,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) @@ -149,7 +143,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 +172,78 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } } + public void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query) + { + //EventManager.TriggerAvatarPickerRequest(); + + m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); + + 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[users.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 (UserData item in users) + { + 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 (users.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); + } + + protected virtual void AddAdditionalUsers(UUID avatarID, string query, List users) + { + } + #endregion Event Handlers private void CacheCreators(SceneObjectGroup sog) @@ -425,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/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/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 35f47d29ca..b95bda5c40 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 System.Timers; @@ -46,8 +48,6 @@ namespace OpenSim.Region.CoreModules.World.Estate { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private delegate void LookupUUIDS(List uuidLst); - private Timer m_regionChangeTimer = new Timer(); public Scene Scene { get; private set; } public IUserManagement UserManager { get; private set; } @@ -907,98 +907,77 @@ 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) + // 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; + + 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 = UserManager.GetUserName(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; } } 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 = 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 diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 0f83d82eab..02ac091d21 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1664,7 +1664,7 @@ namespace OpenSim.Region.CoreModules.World.Land { if (e.OwnerID == targetID) { - if (e.scriptScore >= 0.01) + if (e.ContainsScripts()) { returns.Add(e); } @@ -1681,7 +1681,7 @@ namespace OpenSim.Region.CoreModules.World.Land ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y); if (landobject.LandData.OwnerID != e.OwnerID) { - if (e.scriptScore >= 0.01) + if (e.ContainsScripts()) { returns.Add(e); } diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 4805ccbe1e..c51e140caf 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/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index f9384e9e27..3efb7ddbe3 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -92,7 +92,23 @@ 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 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); @@ -114,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); @@ -138,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) diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 2d6758b2f3..ce66100a65 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 @@ -76,5 +77,14 @@ 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 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/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/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index b006045732..35ac908b57 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -341,62 +341,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) - { - m_log.DebugFormat("[LLCIENT]: ProcessAvatarPickerRequest: returned null result"); - 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 de1517bfbd..753effcda0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1632,8 +1632,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); } @@ -2894,7 +2901,6 @@ namespace OpenSim.Region.Framework.Scenes { //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; - client.OnAvatarPickerRequest += ProcessAvatarPickerRequest; client.OnSetStartLocationRequest += SetHomeRezPoint; client.OnRegionHandleRequest += RegionHandleRequest; } @@ -3022,7 +3028,6 @@ namespace OpenSim.Region.Framework.Scenes { //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; - client.OnAvatarPickerRequest -= ProcessAvatarPickerRequest; client.OnSetStartLocationRequest -= SetHomeRezPoint; client.OnRegionHandleRequest -= RegionHandleRequest; } @@ -3693,9 +3698,9 @@ 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/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 4e9a8f876f..18069afc89 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -814,6 +814,7 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region Get Methods + /// /// Get the controlling client for the given avatar, if there is one. /// @@ -1155,36 +1156,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 5507aa0107..0d1adcbf28 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -293,8 +293,6 @@ namespace OpenSim.Region.Framework.Scenes get { return RootPart.VolumeDetectActive; } } - public float scriptScore; - private Vector3 lastPhysGroupPos; private Quaternion lastPhysGroupRot; @@ -1622,12 +1620,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/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/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/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 8762642903..b04f6b6624 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -78,12 +78,38 @@ 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; } 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/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/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 8dfc7d2695..d140c260ca 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -3003,5 +3003,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; + } } } 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/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index e59d3a8020..1f4c4b1393 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/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/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); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 65d3b9bbd8..b24f016a08 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,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { string retstr = String.Empty; - retstr += Generate(String.Format("{0}(", CheckName(fc.Id)), fc); - + string modinvoke = null; + if (m_comms != null) + 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. diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index f40da01b17..ff1f277fbb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -165,6 +165,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; } @@ -173,6 +177,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; @@ -191,6 +203,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; @@ -459,6 +473,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) @@ -712,8 +730,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; @@ -722,7 +748,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 ee5f519fa7..eb10975658 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -448,6 +448,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); @@ -475,7 +480,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) @@ -1154,7 +1159,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (!m_PrimObjects[localID].Contains(itemID)) m_PrimObjects[localID].Add(itemID); - } if (!m_Assemblies.ContainsKey(assetID)) @@ -1981,6 +1985,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.RootLocalID] = 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.RootLocalID] += adjustedExecutionTime; + } + } + + return topScripts; + } + public void SuspendScript(UUID itemID) { // m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID); 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 8671e31a3d..f4e3d9eb4f 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 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/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); - } -} 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..31a4059139 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" @@ -26,6 +27,7 @@ LandServices = "RemoteLandServicesConnector" FriendsModule = "HGFriendsModule" MapImageService = "MapImageServiceModule" + UserManagementModule = "HGUserManagementModule" LandServiceInConnector = true NeighbourServiceInConnector = true 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..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" @@ -231,3 +232,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..ee51067fed 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" @@ -22,6 +23,7 @@ EntityTransferModule = "HGEntityTransferModule" InventoryAccessModule = "HGInventoryAccessModule" FriendsModule = "HGFriendsModule" + UserManagementModule = "HGUserManagementModule" InventoryServiceInConnector = true AssetServiceInConnector = true @@ -68,9 +70,6 @@ LibraryName = "OpenSim Library" DefaultLibrary = "./inventory/Libraries.xml" -[AuthorizationService] - LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService" - [AuthenticationService] LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" diff --git a/bin/shutdown_commands.txt b/bin/shutdown_commands.txt index ec76ec276d..4397749d23 100644 --- a/bin/shutdown_commands.txt +++ b/bin/shutdown_commands.txt @@ -1 +1,3 @@ -backup +; 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 -