From e717398f6c72bdb30e59468462f3a5f589c1bb35 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 4 Oct 2012 00:32:42 +0100 Subject: [PATCH 01/25] Add experimental "slow frames" stat, available in "show stats" and via the monitoring module. This increments a SlowFrames counter if a frame takes over 120% of maximum time. This commit also introduces a generic OpenSim.Framework.Monitoring.Stat which is available to any code that wants to register a statistic. This is more granualar than asking objects to create their own reports. At some point this will supersede earlier IMonitor and IAlert facilities in MonitoringModule which are only available to scene code. --- .../Monitoring/SimExtraStatsCollector.cs | 13 +- OpenSim/Framework/Monitoring/StatsManager.cs | 114 ++++++++++++++++++ .../Framework/Scenes/SimStatsReporter.cs | 33 +++++ 3 files changed, 158 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs index cdd7cc711e..8ac9090b06 100644 --- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs @@ -355,10 +355,19 @@ Asset service request failures: {3}" + Environment.NewLine, sb.Append(Environment.NewLine); sb.Append( string.Format( - "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}", + "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}\n\n", inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime, netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime)); - sb.Append(Environment.NewLine); + + foreach (KeyValuePair kvp in StatsManager.RegisteredStats) + { + Stat stat = kvp.Value; + + if (stat.Category == "scene" && stat.Verbosity == StatVerbosity.Info) + { + sb.AppendFormat("Slow frames ({0}): {1}\n", stat.Container, stat.Value); + } + } /* sb.Append(Environment.NewLine); diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index d78fa6a1f0..02df0ac106 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -25,6 +25,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; +using System.Collections.Generic; + namespace OpenSim.Framework.Monitoring { /// @@ -32,6 +35,14 @@ namespace OpenSim.Framework.Monitoring /// public class StatsManager { + /// + /// Registered stats. + /// + /// + /// Do not add or remove from this dictionary. + /// + public static Dictionary RegisteredStats = new Dictionary(); + private static AssetStatsCollector assetStats; private static UserStatsCollector userStats; private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); @@ -61,5 +72,108 @@ namespace OpenSim.Framework.Monitoring return userStats; } + + public static bool RegisterStat(Stat stat) + { + lock (RegisteredStats) + { + if (RegisteredStats.ContainsKey(stat.UniqueName)) + { + // XXX: For now just return false. This is to avoid problems in regression tests where all tests + // in a class are run in the same instance of the VM. + return false; + +// throw new Exception( +// "StatsManager already contains stat with ShortName {0} in Category {1}", stat.ShortName, stat.Category); + } + + // We take a replace-on-write approach here so that we don't need to generate a new Dictionary + Dictionary newRegisteredStats = new Dictionary(RegisteredStats); + newRegisteredStats[stat.UniqueName] = stat; + RegisteredStats = newRegisteredStats; + } + + return true; + } + + public static bool DeregisterStat(Stat stat) + { + lock (RegisteredStats) + { + if (!RegisteredStats.ContainsKey(stat.UniqueName)) + return false; + + Dictionary newRegisteredStats = new Dictionary(RegisteredStats); + newRegisteredStats.Remove(stat.UniqueName); + RegisteredStats = newRegisteredStats; + + return true; + } + } + } + + /// + /// Verbosity of stat. + /// + /// + /// Info will always be displayed. + /// + public enum StatVerbosity + { + Debug, + Info + } + + /// + /// Holds individual static details + /// + public class Stat + { + /// + /// Unique stat name used for indexing. Each ShortName in a Category must be unique. + /// + public string UniqueName { get; private set; } + + /// + /// Category of this stat (e.g. cache, scene, etc). + /// + public string Category { get; private set; } + + /// + /// Containing name for this stat. + /// FIXME: In the case of a scene, this is currently the scene name (though this leaves + /// us with a to-be-resolved problem of non-unique region names). + /// + /// + /// The container. + /// + public string Container { get; private set; } + + public StatVerbosity Verbosity { get; private set; } + public string ShortName { get; private set; } + public string Name { get; private set; } + public string Description { get; private set; } + public string UnitName { get; private set; } + + public double Value { get; set; } + + public Stat( + string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description) + { + ShortName = shortName; + Name = name; + UnitName = unitName; + Category = category; + Container = container; + Verbosity = verbosity; + Description = description; + + UniqueName = GenUniqueName(Container, Category, ShortName); + } + + public static string GenUniqueName(string container, string category, string shortName) + { + return string.Format("{0}+{1}+{2}", container, category, shortName); + } } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 96317c3de3..b7b5ea21d8 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -47,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates"; + public const string SlowFramesStatName = "SlowFrames"; public delegate void SendStatResult(SimStats stats); @@ -128,6 +129,16 @@ namespace OpenSim.Region.Framework.Scenes get { return lastReportedSimStats; } } + /// + /// Number of frames that have taken longer to process than Scene.MIN_FRAME_TIME + /// + public Stat SlowFramesStat { get; private set; } + + /// + /// The threshold at which we log a slow frame. + /// + public int SlowFramesStatReportThreshold { get; private set; } + /// /// Extra sim statistics that are used by monitors but not sent to the client. /// @@ -225,6 +236,22 @@ namespace OpenSim.Region.Framework.Scenes if (StatsManager.SimExtraStats != null) OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket; + + /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit + /// longer than ideal (which in itself is a concern). + SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.MinFrameTime * 1000 * 1.2); + + SlowFramesStat + = new Stat( + "SlowFrames", + "Slow Frames", + "frames", + "scene", + m_scene.Name, + StatVerbosity.Info, + "Number of frames where frame time has been significantly longer than the desired frame time."); + + StatsManager.RegisterStat(SlowFramesStat); } public void Close() @@ -418,6 +445,7 @@ namespace OpenSim.Region.Framework.Scenes lock (m_lastReportedExtraSimStats) { m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; + m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value; Dictionary physicsStats = m_scene.PhysicsScene.GetStats(); @@ -535,6 +563,11 @@ namespace OpenSim.Region.Framework.Scenes public void addFrameMS(int ms) { m_frameMS += ms; + + // At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit + // longer than ideal due to the inaccuracy of the Sleep in Scene.Update() (which in itself is a concern). + if (ms > SlowFramesStatReportThreshold) + SlowFramesStat.Value++; } public void AddSpareMS(int ms) From 3d36a6d55cb0bba408f5447d4596c12564366030 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 4 Oct 2012 01:27:40 +0100 Subject: [PATCH 02/25] Add generic PercentageStat. Not yet used. --- OpenSim/Framework/Monitoring/StatsManager.cs | 35 +++++++++++++++++-- .../Framework/Scenes/SimStatsReporter.cs | 2 +- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 02df0ac106..b5dc24f4ae 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -153,9 +153,9 @@ namespace OpenSim.Framework.Monitoring public string ShortName { get; private set; } public string Name { get; private set; } public string Description { get; private set; } - public string UnitName { get; private set; } + public virtual string UnitName { get; private set; } - public double Value { get; set; } + public virtual double Value { get; set; } public Stat( string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description) @@ -176,4 +176,35 @@ namespace OpenSim.Framework.Monitoring return string.Format("{0}+{1}+{2}", container, category, shortName); } } + + public class PercentageStat : Stat + { + public int Antecedent { get; set; } + public int Consequent { get; set; } + + public override double Value + { + get + { + int c = Consequent; + + // Avoid any chance of a multi-threaded divide-by-zero + if (c == 0) + return 0; + + return (double)Antecedent / c; + } + + set + { + throw new Exception("Cannot set value on a PercentageStat"); + } + } + + public PercentageStat( + string shortName, string name, string category, string container, StatVerbosity verbosity, string description) + : base(shortName, name, " %", category, container, verbosity, description) + { + } + } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index b7b5ea21d8..2addb5bab8 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -245,7 +245,7 @@ namespace OpenSim.Region.Framework.Scenes = new Stat( "SlowFrames", "Slow Frames", - "frames", + " frames", "scene", m_scene.Name, StatVerbosity.Info, From aa52c8b20fc041ee505301301a14192ecb8776de Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 4 Oct 2012 02:17:57 +0100 Subject: [PATCH 03/25] Output monitor data in response to console command on MainConsole.Instance rather than m_log This should really be happening for all console commands (though many don't). However, things might get difficult if both a console command and other code invoke the same paths. --- .../Region/CoreModules/Framework/Monitoring/MonitorModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index e135c21b79..e4115851af 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -95,14 +95,14 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring { foreach (IMonitor monitor in m_staticMonitors) { - m_log.InfoFormat( + MainConsole.Instance.OutputFormat( "[MONITOR MODULE]: {0} reports {1} = {2}", m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue()); } foreach (KeyValuePair tuple in m_scene.StatsReporter.GetExtraSimStats()) { - m_log.InfoFormat( + MainConsole.Instance.OutputFormat( "[MONITOR MODULE]: {0} reports {1} = {2}", m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value); } From b977f962fab9be0c823b0b3ae9b4777241c9f22c Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 4 Oct 2012 15:20:04 +0200 Subject: [PATCH 04/25] Allow default animation to be stopped to be replaced with another one. Fixes Mantis #6327 --- .../Scenes/Animation/AnimationSet.cs | 27 ++++++++++++------- .../Scenes/Animation/ScenePresenceAnimator.cs | 18 ++++++++----- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs index 33041e9ac7..ad421eeedb 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs @@ -87,7 +87,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation { if (m_defaultAnimation.AnimID == animID) { - ResetDefaultAnimation(); + m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero); } else if (HasAnimation(animID)) { @@ -149,19 +149,26 @@ namespace OpenSim.Region.Framework.Scenes.Animation { lock (m_animations) { - animIDs = new UUID[m_animations.Count + 1]; - sequenceNums = new int[m_animations.Count + 1]; - objectIDs = new UUID[m_animations.Count + 1]; + int defaultSize = 0; + if (m_defaultAnimation.AnimID != UUID.Zero) + defaultSize++; - animIDs[0] = m_defaultAnimation.AnimID; - sequenceNums[0] = m_defaultAnimation.SequenceNum; - objectIDs[0] = m_defaultAnimation.ObjectID; + animIDs = new UUID[m_animations.Count + defaultSize]; + sequenceNums = new int[m_animations.Count + defaultSize]; + objectIDs = new UUID[m_animations.Count + defaultSize]; + + if (m_defaultAnimation.AnimID != UUID.Zero) + { + animIDs[0] = m_defaultAnimation.AnimID; + sequenceNums[0] = m_defaultAnimation.SequenceNum; + objectIDs[0] = m_defaultAnimation.ObjectID; + } for (int i = 0; i < m_animations.Count; ++i) { - animIDs[i + 1] = m_animations[i].AnimID; - sequenceNums[i + 1] = m_animations[i].SequenceNum; - objectIDs[i + 1] = m_animations[i].ObjectID; + animIDs[i + defaultSize] = m_animations[i].AnimID; + sequenceNums[i + defaultSize] = m_animations[i].SequenceNum; + objectIDs[i + defaultSize] = m_animations[i].ObjectID; } } } diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index ff53f45f71..bb33f07b77 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -408,13 +408,19 @@ namespace OpenSim.Region.Framework.Scenes.Animation { lock (m_animations) { - CurrentMovementAnimation = DetermineMovementAnimation(); + string newMovementAnimation = DetermineMovementAnimation(); + if (CurrentMovementAnimation != newMovementAnimation) + { + CurrentMovementAnimation = DetermineMovementAnimation(); -// m_log.DebugFormat( -// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", -// CurrentMovementAnimation, m_scenePresence.Name); +// m_log.DebugFormat( +// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", +// CurrentMovementAnimation, m_scenePresence.Name); - TrySetMovementAnimation(CurrentMovementAnimation); + // Only set it if it's actually changed, give a script + // a chance to stop a default animation + TrySetMovementAnimation(CurrentMovementAnimation); + } } } @@ -536,4 +542,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation SendAnimPack(animIDs, sequenceNums, objectIDs); } } -} \ No newline at end of file +} From d98af79f7727fd5d3cd94537b5b4d514f54f5250 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Thu, 4 Oct 2012 08:41:06 -0700 Subject: [PATCH 05/25] Make the asset retrieval concurrency a config switch. The current value of 30 is still hanging badly on some mono versions. The switch defaults to 30 to preserve current behavior. --- .../Connectors/Asset/AssetServicesConnector.cs | 11 ++++++++--- bin/OpenSimDefaults.ini | 4 ++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index 086b5adc90..2b2f11f94b 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs @@ -47,7 +47,8 @@ namespace OpenSim.Services.Connectors private string m_ServerURI = String.Empty; private IImprovedAssetCache m_Cache = null; - + private int m_maxAssetRequestConcurrency = 30; + private delegate void AssetRetrievedEx(AssetBase asset); // Keeps track of concurrent requests for the same asset, so that it's only loaded once. @@ -71,6 +72,10 @@ namespace OpenSim.Services.Connectors public virtual void Initialise(IConfigSource source) { + IConfig netconfig = source.Configs["Network"]; + if (netconfig != null) + m_maxAssetRequestConcurrency = netconfig.GetInt("MaxRequestConcurrency",m_maxAssetRequestConcurrency); + IConfig assetConfig = source.Configs["AssetService"]; if (assetConfig == null) { @@ -108,7 +113,7 @@ namespace OpenSim.Services.Connectors if (asset == null) { asset = SynchronousRestObjectRequester. - MakeRequest("GET", uri, 0, 30); + MakeRequest("GET", uri, 0, m_maxAssetRequestConcurrency); if (m_Cache != null) m_Cache.Cache(asset); @@ -221,7 +226,7 @@ namespace OpenSim.Services.Connectors m_AssetHandlers.Remove(id); } handlers.Invoke(a); - }, 30); + }, m_maxAssetRequestConcurrency); success = true; } diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 6e6a089d7f..677ac746ce 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -427,6 +427,10 @@ ; " (Mozilla Compatible)" to the text where there are problems with a web server ;user_agent = "OpenSim LSL (Mozilla Compatible)" + ; OpenSim can send multiple simultaneous requests for services such as asset + ; retrieval. However, some versions of mono appear to hang when there are too + ; many simultaneous requests, default is 30 and is currently applied only to assets + ;MaxRequestConcurrency = 30 [XMLRPC] ; ## From 5b90f5bb17b1bb73f670e6c2f90cca8395a2e9bc Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 4 Oct 2012 15:32:49 -0700 Subject: [PATCH 06/25] One more abstraction for GridUser so that it can be overridden in a sub-class. --- .../Connectors/GridUser/GridUserServicesConnector.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs index 20d7eaf301..94bda82d14 100644 --- a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs +++ b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs @@ -207,7 +207,7 @@ namespace OpenSim.Services.Connectors if ((replyData != null) && replyData.ContainsKey("result") && (replyData["result"] != null)) { if (replyData["result"] is Dictionary) - guinfo = new GridUserInfo((Dictionary)replyData["result"]); + guinfo = Create((Dictionary)replyData["result"]); } return guinfo; @@ -273,7 +273,7 @@ namespace OpenSim.Services.Connectors { if (griduser is Dictionary) { - GridUserInfo pinfo = new GridUserInfo((Dictionary)griduser); + GridUserInfo pinfo = Create((Dictionary)griduser); rinfos.Add(pinfo); } else @@ -286,5 +286,10 @@ namespace OpenSim.Services.Connectors return rinfos.ToArray(); } + + protected virtual GridUserInfo Create(Dictionary griduser) + { + return new GridUserInfo(griduser); + } } } From f0178a6a413e35a45efcb0f7f0eeffc0daed15fe Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 01:12:56 +0100 Subject: [PATCH 07/25] refactor: Move OpenSim.Framework.PacketPool to OpenSim.Region.Clientstack.Linden.UDP This is to allow it to use OpenSim.Framework.Monitoring in the future. This is also a better location since the packet pool is linden udp specific --- .../ClientStack/Linden/UDP}/PacketPool.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) rename OpenSim/{Framework => Region/ClientStack/Linden/UDP}/PacketPool.cs (98%) diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs similarity index 98% rename from OpenSim/Framework/PacketPool.cs rename to OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs index 41d17c54f2..fc9406b88d 100644 --- a/OpenSim/Framework/PacketPool.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs @@ -32,9 +32,8 @@ using OpenMetaverse; using OpenMetaverse.Packets; using log4net; -namespace OpenSim.Framework +namespace OpenSim.Region.ClientStack.LindenUDP { - public sealed class PacketPool { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -44,6 +43,9 @@ namespace OpenSim.Framework private bool packetPoolEnabled = true; private bool dataBlockPoolEnabled = true; + /// + /// Pool of packets available for reuse. + /// private readonly Dictionary> pool = new Dictionary>(); private static Dictionary> DataBlocks = @@ -244,4 +246,4 @@ namespace OpenSim.Framework } } } -} +} \ No newline at end of file From 7c7cdf3431c1c8ee1575779f96980ac1d0de6be8 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 01:43:29 +0100 Subject: [PATCH 08/25] Read PacketPool config in LLUDPServer with other config params rather than in Scene. This is to resolve previous build break. This unnecessarily but harmlessly reads and sets the parameter multiple times - scene was doing the same thing. --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 55780d641c..d11fcbf7e0 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -222,6 +222,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_pausedAckTimeout = 1000 * 300; // 5 minutes } + // FIXME: This actually only needs to be done once since the PacketPool is shared across all servers. + // However, there is no harm in temporarily doing it multiple times. + IConfig packetConfig = configSource.Configs["PacketPool"]; + if (packetConfig != null) + { + PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); + PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); + } + #region BinaryStats config = configSource.Configs["Statistics.Binary"]; m_shouldCollectStats = false; From 03136df1a7f858482ef755d342a33e5b6cfa6ae7 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 01:45:49 +0100 Subject: [PATCH 09/25] Forgot to actually remove the packetpool set code from scene. --- OpenSim/Region/Framework/Scenes/Scene.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0a4aa4aa38..e6b8c16275 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -801,13 +801,6 @@ namespace OpenSim.Region.Framework.Scenes SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); - IConfig packetConfig = m_config.Configs["PacketPool"]; - if (packetConfig != null) - { - PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); - PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); - } - m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); From 046113c137db67f1ded44e0093762c4805283b12 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 01:46:28 +0100 Subject: [PATCH 10/25] Print number of objects found with "show object name" and "show part name" simulator console commands --- .../Objects/Commands/ObjectCommandsModule.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 09f6758ba4..e96dc3e87d 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -215,12 +215,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_scene.ForEachSOG(searchAction); - if (sceneObjects.Count == 0) - { - m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); - return; - } - StringBuilder sb = new StringBuilder(); foreach (SceneObjectGroup so in sceneObjects) @@ -229,6 +223,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands sb.Append("\n"); } + sb.AppendFormat("{0} objects found in {1}\n", sceneObjects.Count, m_scene.Name); + m_console.OutputFormat(sb.ToString()); } @@ -298,12 +294,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_scene.ForEachSOG(searchAction); - if (parts.Count == 0) - { - m_console.OutputFormat("No parts with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); - return; - } - StringBuilder sb = new StringBuilder(); foreach (SceneObjectPart part in parts) @@ -312,6 +302,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands sb.Append("\n"); } + sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name); + m_console.OutputFormat(sb.ToString()); } From d87813a194359b648dc62965d29ae3a10b91c2bb Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 02:02:19 +0100 Subject: [PATCH 11/25] Finally fix build break by allowing UserManagementModule (which constructs a packet directly) to reference OpenSim.Region.ClientStack.LindenUDP. This time I actually properly did a clean build --- .../UserManagement/UserManagementModule.cs | 1 + prebuild.xml | 209 +++++++++--------- 2 files changed, 106 insertions(+), 104 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 36c84c7bc6..b4811dadce 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -31,6 +31,7 @@ using System.Reflection; using OpenSim.Framework; using OpenSim.Framework.Console; +using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; diff --git a/prebuild.xml b/prebuild.xml index d3af8922b2..b8d37c5459 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1376,110 +1376,6 @@ - - - - ../../../bin/ - true - - - - - ../../../bin/ - true - - - - ../../../bin/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1600,6 +1496,111 @@ + + + + ../../../bin/ + true + + + + + ../../../bin/ + true + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + From 8cd1dc8d6097d4a5fd1965f9dc2f9f98489f8220 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 02:07:28 +0100 Subject: [PATCH 12/25] minor: Add missing license information from the top of IUserManagement --- .../Framework/Interfaces/IUserManagement.cs | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs index 24cd06978e..f8088c3d3c 100644 --- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs +++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs @@ -1,4 +1,31 @@ -using System; +/* + * 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 OpenMetaverse; From 130768b16a35e307389e88d902f6e3a785dfb8ee Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 03:52:42 +0100 Subject: [PATCH 13/25] Add "show object pos to " command to simulator console. This allows you to display details of all objects in a given bounding box. Values parts of the co-ord can be left out as appropriate (e.g. to get all objects between the ground and z=30. See "help show object pos" for more details. --- OpenSim/Framework/Util.cs | 13 ++++ .../Objects/Commands/ObjectCommandsModule.cs | 67 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 1b9777f10b..5c7797a95e 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -533,6 +533,19 @@ namespace OpenSim.Framework return (x + y - (min >> 1) - (min >> 2) + (min >> 4)); } + /// + /// Determines whether a point is inside a bounding box. + /// + /// /param> + /// + /// + /// + public static bool IsInsideBox(Vector3 v, Vector3 min, Vector3 max) + { + return v.X >= min.X & v.Y >= min.Y && v.Z >= min.Z + && v.X <= max.X && v.Y <= max.Y && v.Z <= max.Z; + } + /// /// Are the co-ordinates of the new region visible from the old region? /// diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index e96dc3e87d..5ecf5a1e27 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -123,6 +123,25 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands "If --regex is specified then the name is treatead as a regular expression", HandleShowObjectByName); + m_console.Commands.AddCommand( + "Objects", + false, + "show object pos", + "show object pos to ", + "Show details of scene objects within the given area.", + "Each component of the coord is comma separated. There must be no spaces between the commas.\n" + + "If you don't care about the z component you can simply omit it.\n" + + "If you don't care about the x or y components then you can leave them blank (though a comma is still required)\n" + + "If you want to specify the maxmimum value of a component then you can use ~ instead of a number\n" + + "If you want to specify the minimum value of a component then you can use -~ instead of a number\n" + + "e.g.\n" + + "show object pos 20,20,20 to 40,40,40\n" + + "show object pos 20,20 to 40,40\n" + + "show object pos ,20,20 to ,40,40\n" + + "show object pos ,,30 to ,,~\n" + + "show object pos ,,-~ to ,,30\n", + HandleShowObjectByPos); + m_console.Commands.AddCommand( "Objects", false, @@ -228,6 +247,54 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_console.OutputFormat(sb.ToString()); } + private void HandleShowObjectByPos(string module, string[] cmdparams) + { + if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) + return; + + if (cmdparams.Length < 5) + { + m_console.OutputFormat("Usage: show object pos to "); + return; + } + + string rawConsoleStartVector = cmdparams[3]; + Vector3 startVector; + + if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) + { + m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); + return; + } + + string rawConsoleEndVector = cmdparams[5]; + Vector3 endVector; + + if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) + { + m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); + return; + } + + List sceneObjects = new List(); + Action searchAction + = so => { if (Util.IsInsideBox(so.AbsolutePosition, startVector, endVector)) { sceneObjects.Add(so); }}; + + m_scene.ForEachSOG(searchAction); + + StringBuilder sb = new StringBuilder(); + + foreach (SceneObjectGroup so in sceneObjects) + { + AddSceneObjectReport(sb, so); + sb.Append("\n"); + } + + sb.AppendFormat("{0} objects found in {1}\n", sceneObjects.Count, m_scene.Name); + + m_console.OutputFormat(sb.ToString()); + } + private void HandleShowPartByUuid(string module, string[] cmd) { if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) From 633e1ed62cadbdc06592e19bbb1cfaa6fbae72b2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 03:57:35 +0100 Subject: [PATCH 14/25] Add missing ConsoleUtil from last commit --- OpenSim/Framework/Console/ConsoleUtil.cs | 111 +++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 OpenSim/Framework/Console/ConsoleUtil.cs diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs new file mode 100644 index 0000000000..a254be05b8 --- /dev/null +++ b/OpenSim/Framework/Console/ConsoleUtil.cs @@ -0,0 +1,111 @@ +/* + * 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 log4net; +using OpenMetaverse; + +public class ConsoleUtil +{ + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public const string MinRawConsoleVectorValue = "-~"; + public const string MaxRawConsoleVectorValue = "~"; + + public const string VectorSeparator = ","; + public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray(); + + /// + /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3 + /// + /// /param> + /// + /// + public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector) + { + return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector); + } + + /// + /// Convert a maximum vector input from the console to an OpenMetaverse.Vector3 + /// + /// /param> + /// + /// + public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector) + { + return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector); + } + + /// + /// Convert a vector input from the console to an OpenMetaverse.Vector3 + /// + /// + /// A string in the form ,, where there is no space between values. + /// Any component can be missing (e.g. ,,40). blankComponentFunc is invoked to replace the blank with a suitable value + /// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40,30 or 40) + /// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue + /// Other than that, component values must be numeric. + /// + /// + /// + /// + public static bool TryParseConsoleVector( + string rawConsoleVector, Func blankComponentFunc, out Vector3 vector) + { + List components = rawConsoleVector.Split(VectorSeparatorChars).ToList(); + + if (components.Count < 1 || components.Count > 3) + return false; + + for (int i = components.Count; i < 3; i++) + components.Add(""); + + List semiDigestedComponents + = components.ConvertAll( + c => + { + if (c == "") + return blankComponentFunc.Invoke(c); + else if (c == MaxRawConsoleVectorValue) + return float.MaxValue.ToString(); + else if (c == MinRawConsoleVectorValue) + return float.MinValue.ToString(); + else + return c; + }); + + string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray()); + + m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector); + + return Vector3.TryParse(semiDigestedConsoleVector, out vector); + } +} \ No newline at end of file From 68859af3f8c610e562351a328a78a987ab7f229d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 03:58:52 +0100 Subject: [PATCH 15/25] Add Vector3.Zero return on TryParseConsoleVector() which fails on mono 2.4.3 but not mono 2.10.9 --- OpenSim/Framework/Console/ConsoleUtil.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs index a254be05b8..2612a50425 100644 --- a/OpenSim/Framework/Console/ConsoleUtil.cs +++ b/OpenSim/Framework/Console/ConsoleUtil.cs @@ -83,7 +83,10 @@ public class ConsoleUtil List components = rawConsoleVector.Split(VectorSeparatorChars).ToList(); if (components.Count < 1 || components.Count > 3) + { + vector = Vector3.Zero; return false; + } for (int i = components.Count; i < 3; i++) components.Add(""); From 16feed456adbcf43a9ec797d1a499599aadda6b9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 04:16:38 +0100 Subject: [PATCH 16/25] refactor: eliminate some now duplicate code in ObjectCommandsModule --- .../Objects/Commands/ObjectCommandsModule.cs | 59 ++++++++----------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 5ecf5a1e27..fbc64e31ad 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -139,7 +139,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands + "show object pos 20,20 to 40,40\n" + "show object pos ,20,20 to ,40,40\n" + "show object pos ,,30 to ,,~\n" - + "show object pos ,,-~ to ,,30\n", + + "show object pos ,,-~ to ,,30", HandleShowObjectByPos); m_console.Commands.AddCommand( @@ -169,6 +169,23 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); } + private void OutputSogsToConsole(Predicate searchPredicate) + { + List sceneObjects = m_scene.GetSceneObjectGroups().FindAll(searchPredicate); + + StringBuilder sb = new StringBuilder(); + + foreach (SceneObjectGroup so in sceneObjects) + { + AddSceneObjectReport(sb, so); + sb.Append("\n"); + } + + sb.AppendFormat("{0} object(s) found in {1}\n", sceneObjects.Count, m_scene.Name); + + m_console.OutputFormat(sb.ToString()); + } + private void HandleShowObjectByUuid(string module, string[] cmd) { if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) @@ -219,32 +236,19 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands string name = mainParams[3]; - List sceneObjects = new List(); - Action searchAction; + Predicate searchPredicate; if (useRegex) { Regex nameRegex = new Regex(name); - searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; + searchPredicate = so => nameRegex.IsMatch(so.Name); } else { - searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; + searchPredicate = so => so.Name == name; } - m_scene.ForEachSOG(searchAction); - - StringBuilder sb = new StringBuilder(); - - foreach (SceneObjectGroup so in sceneObjects) - { - AddSceneObjectReport(sb, so); - sb.Append("\n"); - } - - sb.AppendFormat("{0} objects found in {1}\n", sceneObjects.Count, m_scene.Name); - - m_console.OutputFormat(sb.ToString()); + OutputSogsToConsole(searchPredicate); } private void HandleShowObjectByPos(string module, string[] cmdparams) @@ -276,23 +280,10 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands return; } - List sceneObjects = new List(); - Action searchAction - = so => { if (Util.IsInsideBox(so.AbsolutePosition, startVector, endVector)) { sceneObjects.Add(so); }}; + Predicate searchPredicate + = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector); - m_scene.ForEachSOG(searchAction); - - StringBuilder sb = new StringBuilder(); - - foreach (SceneObjectGroup so in sceneObjects) - { - AddSceneObjectReport(sb, so); - sb.Append("\n"); - } - - sb.AppendFormat("{0} objects found in {1}\n", sceneObjects.Count, m_scene.Name); - - m_console.OutputFormat(sb.ToString()); + OutputSogsToConsole(searchPredicate); } private void HandleShowPartByUuid(string module, string[] cmd) From 22f6fa49e3751ce0bf80167e7d4467681faacf89 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 04:22:08 +0100 Subject: [PATCH 17/25] Add "show part pos" console command to match "show object pos" --- .../Objects/Commands/ObjectCommandsModule.cs | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index fbc64e31ad..0c9295bd22 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -157,6 +157,25 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands "Show details of scene object parts with the given name.", "If --regex is specified then the name is treatead as a regular expression", HandleShowPartByName); + + m_console.Commands.AddCommand( + "Objects", + false, + "show part pos", + "show part pos to ", + "Show details of scene object parts within the given area.", + "Each component of the coord is comma separated. There must be no spaces between the commas.\n" + + "If you don't care about the z component you can simply omit it.\n" + + "If you don't care about the x or y components then you can leave them blank (though a comma is still required)\n" + + "If you want to specify the maxmimum value of a component then you can use ~ instead of a number\n" + + "If you want to specify the minimum value of a component then you can use -~ instead of a number\n" + + "e.g.\n" + + "show object pos 20,20,20 to 40,40,40\n" + + "show object pos 20,20 to 40,40\n" + + "show object pos ,20,20 to ,40,40\n" + + "show object pos ,,30 to ,,~\n" + + "show object pos ,,-~ to ,,30", + HandleShowPartByPos); } public void RemoveRegion(Scene scene) @@ -318,6 +337,59 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_console.OutputFormat(sb.ToString()); } + private void HandleShowPartByPos(string module, string[] cmdparams) + { + if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) + return; + + if (cmdparams.Length < 5) + { + m_console.OutputFormat("Usage: show part pos to "); + return; + } + + string rawConsoleStartVector = cmdparams[3]; + Vector3 startVector; + + if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector)) + { + m_console.OutputFormat("Error: Start vector {0} does not have a valid format", rawConsoleStartVector); + return; + } + + string rawConsoleEndVector = cmdparams[5]; + Vector3 endVector; + + if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector)) + { + m_console.OutputFormat("Error: End vector {0} does not have a valid format", rawConsoleEndVector); + return; + } + + Predicate searchPredicate + = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector); + + List parts = new List(); + + Action searchAction + = so + => so.ForEachPart(sop => { if (Util.IsInsideBox(so.AbsolutePosition, startVector, endVector)) { parts.Add(sop); }}); + + m_scene.ForEachSOG(searchAction); + + StringBuilder sb = new StringBuilder(); + + foreach (SceneObjectPart part in parts) + { + AddScenePartReport(sb, part); + sb.Append("\n"); + } + + sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name); + + m_console.OutputFormat(sb.ToString()); + } + private void HandleShowPartByName(string module, string[] cmdparams) { if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) From 1fb53e7103fccba7a2ee440e7e7055c379d93803 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Oct 2012 04:31:43 +0100 Subject: [PATCH 18/25] Fix bug in implementation of "show part pos" that would not filter probably. Also refactors more of ObjectCommandsModule to remove duplicate code --- .../Objects/Commands/ObjectCommandsModule.cs | 65 +++++++------------ 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 0c9295bd22..6e39e9acc9 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -205,6 +205,26 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands m_console.OutputFormat(sb.ToString()); } + private void OutputSopsToConsole(Predicate searchPredicate) + { + List sceneObjects = m_scene.GetSceneObjectGroups(); + List parts = new List(); + + sceneObjects.ForEach(so => parts.AddRange(Array.FindAll(so.Parts, searchPredicate))); + + StringBuilder sb = new StringBuilder(); + + foreach (SceneObjectPart part in parts) + { + AddScenePartReport(sb, part); + sb.Append("\n"); + } + + sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name); + + m_console.OutputFormat(sb.ToString()); + } + private void HandleShowObjectByUuid(string module, string[] cmd) { if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) @@ -366,28 +386,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands return; } - Predicate searchPredicate - = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector); - - List parts = new List(); - - Action searchAction - = so - => so.ForEachPart(sop => { if (Util.IsInsideBox(so.AbsolutePosition, startVector, endVector)) { parts.Add(sop); }}); - - m_scene.ForEachSOG(searchAction); - - StringBuilder sb = new StringBuilder(); - - foreach (SceneObjectPart part in parts) - { - AddScenePartReport(sb, part); - sb.Append("\n"); - } - - sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name); - - m_console.OutputFormat(sb.ToString()); + OutputSopsToConsole(sop => Util.IsInsideBox(sop.AbsolutePosition, startVector, endVector)); } private void HandleShowPartByName(string module, string[] cmdparams) @@ -408,33 +407,19 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands string name = mainParams[3]; - List parts = new List(); - - Action searchAction; + Predicate searchPredicate; if (useRegex) { Regex nameRegex = new Regex(name); - searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } }); + searchPredicate = sop => nameRegex.IsMatch(sop.Name); } else { - searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }); + searchPredicate = sop => sop.Name == name; } - m_scene.ForEachSOG(searchAction); - - StringBuilder sb = new StringBuilder(); - - foreach (SceneObjectPart part in parts) - { - AddScenePartReport(sb, part); - sb.Append("\n"); - } - - sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name); - - m_console.OutputFormat(sb.ToString()); + OutputSopsToConsole(searchPredicate); } private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so) From 16c9c1dff7bbf299efddd44e4f9aeeb7db38fff6 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 6 Oct 2012 02:34:49 +0100 Subject: [PATCH 19/25] On receiving TaskInventoryAccepted with a destination folder in the binary bucket slot for RLV, notify the viewer about inventory folder updates. The viewer would not see the folder move without this, either on accept or decline. This commit also updates the TaskInventoryOffered message to better conform with the data LL uses Changes are, agentID is prim owner rather than prim id, agent name is now simply object name rather than name with owner detail, message is just folder name in single quotes, message is not timestamped. However, folder is not renamed "still #RLV/~". Long term solution is probably not to do these operations server-side. Notes will be added to http://opensimulator.org/mantis/view.php?id=6311 --- OpenSim/Framework/GridInstantMessage.cs | 9 ++-- .../ClientStack/Linden/UDP/LLClientView.cs | 3 +- .../Avatar/Friends/CallingCardModule.cs | 2 +- .../Transfer/InventoryTransferModule.cs | 42 +++++++++++++++++++ .../CoreModules/Avatar/Lure/HGLureModule.cs | 2 +- .../CoreModules/Avatar/Lure/LureModule.cs | 2 +- .../EntityTransfer/EntityTransferModule.cs | 22 +++++++--- .../Framework/Scenes/Scene.Inventory.cs | 2 +- .../OptionalModules/World/NPC/NPCAvatar.cs | 2 +- .../Shared/Api/Implementation/LSL_Api.cs | 19 +++++---- 10 files changed, 81 insertions(+), 24 deletions(-) diff --git a/OpenSim/Framework/GridInstantMessage.cs b/OpenSim/Framework/GridInstantMessage.cs index a6bf6e3c32..6ae0488fc2 100644 --- a/OpenSim/Framework/GridInstantMessage.cs +++ b/OpenSim/Framework/GridInstantMessage.cs @@ -44,7 +44,6 @@ namespace OpenSim.Framework public Vector3 Position; public byte[] binaryBucket; - public uint ParentEstateID; public Guid RegionID; public uint timestamp; @@ -58,7 +57,7 @@ namespace OpenSim.Framework string _fromAgentName, UUID _toAgentID, byte _dialog, bool _fromGroup, string _message, UUID _imSessionID, bool _offline, Vector3 _position, - byte[] _binaryBucket) + byte[] _binaryBucket, bool addTimestamp) { fromAgentID = _fromAgentID.Guid; fromAgentName = _fromAgentName; @@ -79,7 +78,9 @@ namespace OpenSim.Framework ParentEstateID = scene.RegionInfo.EstateSettings.ParentEstateID; RegionID = scene.RegionInfo.RegionSettings.RegionUUID.Guid; } - timestamp = (uint)Util.UnixTimeSinceEpoch(); + + if (addTimestamp) + timestamp = (uint)Util.UnixTimeSinceEpoch(); } public GridInstantMessage(IScene scene, UUID _fromAgentID, @@ -87,7 +88,7 @@ namespace OpenSim.Framework string _message, bool _offline, Vector3 _position) : this(scene, _fromAgentID, _fromAgentName, _toAgentID, _dialog, false, _message, - _fromAgentID ^ _toAgentID, _offline, _position, new byte[0]) + _fromAgentID ^ _toAgentID, _offline, _position, new byte[0], true) { } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index d05ffea1bd..0869bd527a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5862,7 +5862,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP msgpack.MessageBlock.ID, msgpack.MessageBlock.Offline != 0 ? true : false, msgpack.MessageBlock.Position, - msgpack.MessageBlock.BinaryBucket); + msgpack.MessageBlock.BinaryBucket, + true); handlerInstantMessage(this, im); } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs index d942e8742a..5ec0ea94b4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs @@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends client.FirstName+" "+client.LastName, destID, (byte)211, false, String.Empty, - transactionID, false, new Vector3(), new byte[0]), + transactionID, false, new Vector3(), new byte[0], true), delegate(bool success) {} ); } } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 91eda19f41..33b48393fb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -297,6 +297,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer }); } } + + // XXX: This code was placed here to try and accomdate RLV which moves given folders named #RLV/~ + // to a folder called name in #RLV. However, this approach may not be ultimately correct - from analysis + // of Firestorm 4.2.2 on sending an InventoryOffered instead of TaskInventoryOffered (as was previously + // done), the viewer itself would appear to move and rename the folder, rather than the simulator doing it here. else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) { UUID destinationFolderID = UUID.Zero; @@ -308,6 +313,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer if (destinationFolderID != UUID.Zero) { + InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); + if (destinationFolder == null) + { + m_log.WarnFormat( + "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", + client.Name, scene.Name, destinationFolderID); + + return; + } + IInventoryService invService = scene.InventoryService; UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip @@ -315,9 +330,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); item = invService.GetItem(item); InventoryFolderBase folder = null; + UUID? previousParentFolderID = null; if (item != null) // It's an item { + previousParentFolderID = item.Folder; item.Folder = destinationFolderID; invService.DeleteItems(item.Owner, new List() { item.ID }); @@ -330,10 +347,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer if (folder != null) // It's a folder { + previousParentFolderID = folder.ParentID; folder.ParentID = destinationFolderID; invService.MoveFolder(folder); } } + + // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). + if (previousParentFolderID != null) + { + InventoryFolderBase previousParentFolder + = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); + previousParentFolder = invService.GetFolder(previousParentFolder); + scene.SendInventoryUpdate(client, previousParentFolder, true, true); + + scene.SendInventoryUpdate(client, destinationFolder, true, true); + } } } else if ( @@ -354,9 +383,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); item = invService.GetItem(item); InventoryFolderBase folder = null; + UUID? previousParentFolderID = null; if (item != null && trashFolder != null) { + previousParentFolderID = item.Folder; item.Folder = trashFolder.ID; // Diva comment: can't we just update this item??? @@ -372,6 +403,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer if (folder != null & trashFolder != null) { + previousParentFolderID = folder.ParentID; folder.ParentID = trashFolder.ID; invService.MoveFolder(folder); } @@ -391,6 +423,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer client.SendAgentAlertMessage("Unable to delete "+ "received inventory" + reason, false); } + // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). + else if (previousParentFolderID != null) + { + InventoryFolderBase previousParentFolder + = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); + previousParentFolder = invService.GetFolder(previousParentFolder); + scene.SendInventoryUpdate(client, previousParentFolder, true, true); + + scene.SendInventoryUpdate(client, trashFolder, true, true); + } ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index 92cf9d1616..9c369f6060 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -186,7 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure client.FirstName+" "+client.LastName, targetid, (byte)InstantMessageDialog.RequestTeleport, false, message, sessionID, false, presence.AbsolutePosition, - new Byte[0]); + new Byte[0], true); m.RegionID = client.Scene.RegionInfo.RegionID.Guid; m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message); diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index 2d4cffd224..6ce9556e67 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs @@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure client.FirstName+" "+client.LastName, targetid, (byte)InstantMessageDialog.RequestTeleport, false, message, dest, false, presence.AbsolutePosition, - new Byte[0]); + new Byte[0], true); if (m_TransferModule != null) { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b51570f0cc..617a3502d0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1068,6 +1068,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Scene initiatingScene) { Thread.Sleep(10000); + IMessageTransferModule im = initiatingScene.RequestModuleInterface(); if (im != null) { @@ -1080,11 +1081,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer (uint)(int)position.X, (uint)(int)position.Y, (uint)(int)position.Z); - GridInstantMessage m = new GridInstantMessage(initiatingScene, UUID.Zero, - "Region", agent.UUID, - (byte)InstantMessageDialog.GodLikeRequestTeleport, false, - "", gotoLocation, false, new Vector3(127, 0, 0), - new Byte[0]); + + GridInstantMessage m + = new GridInstantMessage( + initiatingScene, + UUID.Zero, + "Region", + agent.UUID, + (byte)InstantMessageDialog.GodLikeRequestTeleport, + false, + "", + gotoLocation, + false, + new Vector3(127, 0, 0), + new Byte[0], + false); + im.SendInstantMessage(m, delegate(bool success) { m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 3b59dc4866..b23ddb4330 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1424,7 +1424,7 @@ namespace OpenSim.Region.Framework.Scenes return newFolderID; } - private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems) + public void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems) { if (folder == null) return; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index a8e4d9060d..ffd4222935 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -148,7 +148,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC OnInstantMessage(this, new GridInstantMessage(m_scene, m_uuid, m_firstname + " " + m_lastname, target, 0, false, message, - UUID.Zero, false, Position, new byte[0])); + UUID.Zero, false, Position, new byte[0], true)); } public void SendAgentOffline(UUID[] agentIDs) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7fa6f05e08..7620df32f6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3978,7 +3978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api World.RegionInfo.RegionName+" "+ m_host.AbsolutePosition.ToString(), agentItem.ID, true, m_host.AbsolutePosition, - bucket); + bucket, true); // TODO: May actually send no timestamp m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); } @@ -6452,16 +6452,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_TransferModule != null) { byte[] bucket = new byte[] { (byte)AssetType.Folder }; - + + Vector3 pos = m_host.AbsolutePosition; + GridInstantMessage msg = new GridInstantMessage(World, - m_host.UUID, m_host.Name + ", an object owned by " + - resolveName(m_host.OwnerID) + ",", destID, + m_host.OwnerID, m_host.Name, destID, (byte)InstantMessageDialog.TaskInventoryOffered, - false, category + "\n" + m_host.Name + " is located at " + - World.RegionInfo.RegionName + " " + - m_host.AbsolutePosition.ToString(), - folderID, true, m_host.AbsolutePosition, - bucket); + false, string.Format("'{0}'"), +// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 +// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), + folderID, false, pos, + bucket, false); m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); } From 9de991301cfcb66721a5593dd9098fe84e090dec Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 6 Oct 2012 04:03:53 +0100 Subject: [PATCH 20/25] Make UserSessionID a class rather than a struct, so that later updates to value suceed (rather than having to pull the data out and reinsert back into the Dictionary). Fixes http://opensimulator.org/mantis/view.php?id=6338 --- .../Region/UserStatistics/WebStatsModule.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index c11ea0225a..b1795db5d1 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -319,6 +319,10 @@ namespace OpenSim.Region.UserStatistics private void OnMakeRootAgent(ScenePresence agent) { +// m_log.DebugFormat( +// "[WEB STATS MODULE]: Looking for session {0} for {1} in {2}", +// agent.ControllingClient.SessionId, agent.Name, agent.Scene.Name); + lock (m_sessions) { UserSessionID uid; @@ -427,7 +431,10 @@ namespace OpenSim.Region.UserStatistics m_log.WarnFormat("[WEB STATS MODULE]: no session for stat disclosure for agent {0}", agentID); return new UserSessionID(); } + uid = m_sessions[agentID]; + +// m_log.DebugFormat("[WEB STATS MODULE]: Got session {0} for {1}", uid.session_id, agentID); } else { @@ -499,6 +506,7 @@ namespace OpenSim.Region.UserStatistics usd.d_texture_kb = (float)downloads_map["texture_kbytes"].AsReal(); usd.d_world_kb = (float)downloads_map["workd_kbytes"].AsReal(); +// m_log.DebugFormat("[WEB STATS MODULE]: mmap[\"session_id\"] = [{0}]", mmap["session_id"].AsUUID()); usd.session_id = mmap["session_id"].AsUUID(); @@ -549,11 +557,18 @@ namespace OpenSim.Region.UserStatistics uid.session_data = usd; m_sessions[agentID] = uid; + +// m_log.DebugFormat( +// "[WEB STATS MODULE]: Parse data for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id); + return uid; } private void UpdateUserStats(UserSessionID uid, SqliteConnection db) { +// m_log.DebugFormat( +// "[WEB STATS MODULE]: Updating user stats for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id); + if (uid.session_id == UUID.Zero) return; @@ -740,7 +755,6 @@ VALUES s.min_ping = ArrayMin_f(__ping); s.max_ping = ArrayMax_f(__ping); s.mode_ping = ArrayMode_f(__ping); - } #region Statistics @@ -985,7 +999,7 @@ VALUES } #region structs - public struct UserSessionID + public class UserSessionID { public UUID session_id; public UUID region_id; From 13c4fd7271783d3e2c51da7b9509d08aeedf3131 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 6 Oct 2012 04:06:27 +0100 Subject: [PATCH 21/25] refactor: Rename UserSessioNID -> UserSession in WebStatsModule since this is what it actually represents --- .../Region/UserStatistics/WebStatsModule.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index b1795db5d1..625eba4b0a 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.UserStatistics /// /// User statistics sessions keyed by agent ID /// - private Dictionary m_sessions = new Dictionary(); + private Dictionary m_sessions = new Dictionary(); private List m_scenes = new List(); private Dictionary reports = new Dictionary(); @@ -325,12 +325,12 @@ namespace OpenSim.Region.UserStatistics lock (m_sessions) { - UserSessionID uid; + UserSession uid; if (!m_sessions.ContainsKey(agent.UUID)) { UserSessionData usd = UserSessionUtil.newUserSessionData(); - uid = new UserSessionID(); + uid = new UserSession(); uid.name_f = agent.Firstname; uid.name_l = agent.Lastname; uid.session_data = usd; @@ -415,9 +415,9 @@ namespace OpenSim.Region.UserStatistics return String.Empty; } - private UserSessionID ParseViewerStats(string request, UUID agentID) + private UserSession ParseViewerStats(string request, UUID agentID) { - UserSessionID uid = new UserSessionID(); + UserSession uid = new UserSession(); UserSessionData usd; OSD message = OSDParser.DeserializeLLSDXml(request); OSDMap mmap; @@ -429,7 +429,7 @@ namespace OpenSim.Region.UserStatistics if (!m_sessions.ContainsKey(agentID)) { m_log.WarnFormat("[WEB STATS MODULE]: no session for stat disclosure for agent {0}", agentID); - return new UserSessionID(); + return new UserSession(); } uid = m_sessions[agentID]; @@ -440,14 +440,14 @@ namespace OpenSim.Region.UserStatistics { // parse through the beginning to locate the session if (message.Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); mmap = (OSDMap)message; { UUID sessionID = mmap["session_id"].AsUUID(); if (sessionID == UUID.Zero) - return new UserSessionID(); + return new UserSession(); // search through each session looking for the owner @@ -466,7 +466,7 @@ namespace OpenSim.Region.UserStatistics // can't find a session if (agentID == UUID.Zero) { - return new UserSessionID(); + return new UserSession(); } } } @@ -475,12 +475,12 @@ namespace OpenSim.Region.UserStatistics usd = uid.session_data; if (message.Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); mmap = (OSDMap)message; { if (mmap["agent"].Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); OSDMap agent_map = (OSDMap)mmap["agent"]; usd.agent_id = agentID; usd.name_f = uid.name_f; @@ -500,7 +500,7 @@ namespace OpenSim.Region.UserStatistics (float)agent_map["fps"].AsReal()); if (mmap["downloads"].Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); OSDMap downloads_map = (OSDMap)mmap["downloads"]; usd.d_object_kb = (float)downloads_map["object_kbytes"].AsReal(); usd.d_texture_kb = (float)downloads_map["texture_kbytes"].AsReal(); @@ -511,7 +511,7 @@ namespace OpenSim.Region.UserStatistics usd.session_id = mmap["session_id"].AsUUID(); if (mmap["system"].Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); OSDMap system_map = (OSDMap)mmap["system"]; usd.s_cpu = system_map["cpu"].AsString(); @@ -520,13 +520,13 @@ namespace OpenSim.Region.UserStatistics usd.s_ram = system_map["ram"].AsInteger(); if (mmap["stats"].Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); OSDMap stats_map = (OSDMap)mmap["stats"]; { if (stats_map["failures"].Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); OSDMap stats_failures = (OSDMap)stats_map["failures"]; usd.f_dropped = stats_failures["dropped"].AsInteger(); usd.f_failed_resends = stats_failures["failed_resends"].AsInteger(); @@ -535,18 +535,18 @@ namespace OpenSim.Region.UserStatistics usd.f_send_packet = stats_failures["send_packet"].AsInteger(); if (stats_map["net"].Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); OSDMap stats_net = (OSDMap)stats_map["net"]; { if (stats_net["in"].Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); OSDMap net_in = (OSDMap)stats_net["in"]; usd.n_in_kb = (float)net_in["kbytes"].AsReal(); usd.n_in_pk = net_in["packets"].AsInteger(); if (stats_net["out"].Type != OSDType.Map) - return new UserSessionID(); + return new UserSession(); OSDMap net_out = (OSDMap)stats_net["out"]; usd.n_out_kb = (float)net_out["kbytes"].AsReal(); @@ -564,7 +564,7 @@ namespace OpenSim.Region.UserStatistics return uid; } - private void UpdateUserStats(UserSessionID uid, SqliteConnection db) + private void UpdateUserStats(UserSession uid, SqliteConnection db) { // m_log.DebugFormat( // "[WEB STATS MODULE]: Updating user stats for {0} {1}, session {2}", uid.name_f, uid.name_l, uid.session_id); @@ -999,7 +999,7 @@ VALUES } #region structs - public class UserSessionID + public class UserSession { public UUID session_id; public UUID region_id; From 90a39379f0976a00582e2096da4498395d71c109 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 8 Oct 2012 17:36:40 +0100 Subject: [PATCH 22/25] Allow other whitespace characters than spaces in Robust connection string --- OpenSim/Server/ServerMain.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs index 21fb6785c3..365a79adaa 100644 --- a/OpenSim/Server/ServerMain.cs +++ b/OpenSim/Server/ServerMain.cs @@ -60,7 +60,7 @@ namespace OpenSim.Server } string connList = serverConfig.GetString("ServiceConnectors", String.Empty); - string[] conns = connList.Split(new char[] {',', ' '}); + string[] conns = connList.Split(new char[] {',', ' ', '\n', '\r', '\t'}); // int i = 0; foreach (string c in conns) @@ -130,4 +130,4 @@ namespace OpenSim.Server return 0; } } -} \ No newline at end of file +} From ff92330523a3375b88dca017ed56d52e0859b561 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 8 Oct 2012 17:57:22 +0100 Subject: [PATCH 23/25] Add a ServiceList section to Robust .ini to get rid of the long string --- OpenSim/Server/ServerMain.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs index 365a79adaa..552e3a220b 100644 --- a/OpenSim/Server/ServerMain.cs +++ b/OpenSim/Server/ServerMain.cs @@ -60,6 +60,24 @@ namespace OpenSim.Server } string connList = serverConfig.GetString("ServiceConnectors", String.Empty); + + IConfig servicesConfig = m_Server.Config.Configs["ServiceList"]; + if (servicesConfig != null) + { + List servicesList = new List(); + if (connList != String.Empty) + servicesList.Add(connList); + + foreach (string k in servicesConfig.GetKeys()) + { + string v = servicesConfig.GetString(k); + if (v != String.Empty) + servicesList.Add(v); + } + + connList = servicesConfig.Join(","); + } + string[] conns = connList.Split(new char[] {',', ' ', '\n', '\r', '\t'}); // int i = 0; From 839aa57b42123a1ad7898caa572e8fd629b8be82 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 8 Oct 2012 18:01:56 +0100 Subject: [PATCH 24/25] Update the example --- bin/Robust.ini.example | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 5a9d61341c..2eb551d44b 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -13,7 +13,23 @@ ; * [[@]/][:] ; * [Startup] -ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003/OpenSim.Server.Handlers.dll:XInventoryInConnector,8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector,8003/OpenSim.Server.Handlers.dll:GridServiceConnector,8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector,8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector,8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector,8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector,8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector,8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector,8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector,8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector,8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector,8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector,8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector" + +[ServiceList] +AssetServiceConnector = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector" +InventoryInConnector = "8003/OpenSim.Server.Handlers.dll:XInventoryInConnector" +VoiceConnector = "8004/OpenSim.Server.Handlers.dll:FreeswitchServerConnector" +GridServiceConnector = "8003/OpenSim.Server.Handlers.dll:GridServiceConnector" +GridInfoServerInConnector = "8002/OpenSim.Server.Handlers.dll:GridInfoServerInConnector" +AuthenticationServiceConnector = "8003/OpenSim.Server.Handlers.dll:AuthenticationServiceConnector" +OpenIdServerConnector = "8002/OpenSim.Server.Handlers.dll:OpenIdServerConnector" +AvatarServiceConnector = "8003/OpenSim.Server.Handlers.dll:AvatarServiceConnector" +LLLoginServiceInConnector = "8002/OpenSim.Server.Handlers.dll:LLLoginServiceInConnector" +PresenceServiceConnector = "8003/OpenSim.Server.Handlers.dll:PresenceServiceConnector" +UserAccountServiceConnector = "8003/OpenSim.Server.Handlers.dll:UserAccountServiceConnector" +GridUserServiceConnector = "8003/OpenSim.Server.Handlers.dll:GridUserServiceConnector" +FriendsServiceConnector = "8003/OpenSim.Server.Handlers.dll:FriendsServiceConnector" +MapAddServiceConnector = "8003/OpenSim.Server.Handlers.dll:MapAddServiceConnector" +MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnector" ; * This is common for all services, it's the network setup for the entire ; * server instance, if none is specified above From f65218f8265e0dfb03f6a779d0190af36c866244 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 8 Oct 2012 19:02:21 +0100 Subject: [PATCH 25/25] Fix build break --- OpenSim/Server/ServerMain.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs index 552e3a220b..45c13fb944 100644 --- a/OpenSim/Server/ServerMain.cs +++ b/OpenSim/Server/ServerMain.cs @@ -75,7 +75,7 @@ namespace OpenSim.Server servicesList.Add(v); } - connList = servicesConfig.Join(","); + connList = String.Join(",", servicesList.ToArray()); } string[] conns = connList.Split(new char[] {',', ' ', '\n', '\r', '\t'});