From f2f33b75776539560e1dbfec12a6559f5b4be05e Mon Sep 17 00:00:00 2001 From: BlueWall Date: Thu, 4 Jul 2013 17:45:17 -0400 Subject: [PATCH 01/93] Some consistency fixes for the ini to stop parser breakage --- bin/OpenSim.ini.example | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 3015c088f1..1c53935dff 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -268,7 +268,7 @@ ; AllowedClients = ;# {BannedClients} {} {Bar (|) separated list of banned clients} {} - ;# Bar (|) separated list of viewers which may not gain access to the regions. + ;; Bar (|) separated list of viewers which may not gain access to the regions. ;; One can use a Substring of the viewer name to disable only certain ;; versions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" @@ -287,7 +287,7 @@ ;; both to set this to false and comment out the [Modules] MapImageServiceModule setting in config-include/ ; GenerateMaptiles = true - ;# {MapImageModule} [] {The map image module to use} {MapImageModule Warp3DImageModule} MapImageModule + ;# {MapImageModule} {} {The map image module to use} {MapImageModule Warp3DImageModule} MapImageModule ;; The module to use in order to generate map images. ;; MapImageModule is the default. Warp3DImageModule is an alternative experimental module that can ;; generate better images. @@ -474,7 +474,10 @@ ;# {XmlRpcPort} {} {Port for incoming llRemoteData xmlrpc calls} {} 20800 ;XmlRpcPort = 20800 - ;# {XmlRpcHubURI} {XmlRpcRouterModule} {URI for external service used to register xmlrpc channels created in the simulator. This depends on XmlRpcRouterModule being set to XmlRpcGridRouterModule} http://example.com + +;; {option} {depends on} {question to ask} {choices} default value + + ;# {XmlRpcHubURI} {XmlRpcRouterModule} {URI for external service used to register xmlrpc channels created in the simulator. This depends on XmlRpcRouterModule being set to XmlRpcGridRouterModule} {} http://example.com ;; If XmlRpcRouterModule is set to XmlRpcGridRouterModule, the simulator ;; will use this address to register xmlrpc channels on the external ;; service @@ -538,7 +541,7 @@ ;; Distance in meters that ordinary chat should travel. ; say_distance = 20 - ;# {shout_distance} {Distance at which a shout is heard, in meters?} {} 100 + ;# {shout_distance} {} {Distance at which a shout is heard, in meters?} {} 100 ;; Distance in meters that shouts should travel. ; shout_distance = 100 @@ -613,7 +616,8 @@ ;; the "password" parameter) ; access_password = "" - ;# List the IP addresses allowed to call RemoteAdmin + ;# {access_ip_addresses} {enabled:true} {List the IP addresses allowed to call RemoteAdmin?} {} + ;; List the IP addresses allowed to call RemoteAdmin ;; If access_ip_addresses isn't set, then all IP addresses can access RemoteAdmin. ;; access_ip_addresses = 0.0.0.0, 0.0.0.0 ... ; access_ip_addresses = @@ -798,7 +802,7 @@ ; ScriptStopStrategy = abort - ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true + ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} {true false} true ;; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false ;; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the ;; compiled scripts if you're recompiling OpenSim from source code and internal interfaces used From 8265a88c4a4b1c18f1bc0accfde250fe47b08c50 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 4 Jul 2013 14:51:18 -0700 Subject: [PATCH 02/93] Throttle the viewer's requests for region handles. Apparently Kokua is requesting this for all landmarks in inventory. Not sure why. But this seems to be the root cause of the login freeze mentioned before. This commit adds a blocking queue / process thread pattern. --- .../GridServiceThrottleModule.cs | 161 ++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 18 -- 2 files changed, 161 insertions(+), 18 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs diff --git a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs new file mode 100644 index 0000000000..5511fea9aa --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs @@ -0,0 +1,161 @@ +/* + * 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.Reflection; +using System.Threading; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Framework.Monitoring; +using OpenSim.Region.Framework.Scenes; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.CoreModules.Framework +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")] + public class GridServiceThrottleModule : ISharedRegionModule + { + private static readonly ILog m_log = LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private readonly List m_scenes = new List(); + + private OpenSim.Framework.BlockingQueue m_RequestQueue = new OpenSim.Framework.BlockingQueue(); + + public void Initialise(IConfigSource config) + { + Watchdog.StartThread( + ProcessQueue, + "GridServiceRequestThread", + ThreadPriority.BelowNormal, + true, + true); + } + + public void AddRegion(Scene scene) + { + lock (m_scenes) + { + m_scenes.Add(scene); + scene.EventManager.OnNewClient += OnNewClient; + } + } + + public void RegionLoaded(Scene scene) + { + } + + public void RemoveRegion(Scene scene) + { + lock (m_scenes) + { + m_scenes.Remove(scene); + scene.EventManager.OnNewClient -= OnNewClient; + } + } + + void OnNewClient(IClientAPI client) + { + client.OnRegionHandleRequest += OnRegionHandleRequest; + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "GridServiceThrottleModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void OnRegionHandleRequest(IClientAPI client, UUID regionID) + { + m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID); + ulong handle = 0; + if (IsLocalRegionHandle(regionID, out handle)) + { + client.SendRegionHandle(regionID, handle); + return; + } + + GridRegionRequest request = new GridRegionRequest(client, regionID); + m_RequestQueue.Enqueue(request); + + } + + private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle) + { + regionHandle = 0; + foreach (Scene s in m_scenes) + if (s.RegionInfo.RegionID == regionID) + { + regionHandle = s.RegionInfo.RegionHandle; + return true; + } + return false; + } + + private void ProcessQueue() + { + while (true) + { + GridRegionRequest request = m_RequestQueue.Dequeue(); + GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID); + + if (r != null && r.RegionHandle != 0) + request.client.SendRegionHandle(request.regionID, r.RegionHandle); + + } + } + } + + class GridRegionRequest + { + public IClientAPI client; + public UUID regionID; + + public GridRegionRequest(IClientAPI c, UUID r) + { + client = c; + regionID = r; + } + } +} diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index aa14529587..355e0eebde 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3103,7 +3103,6 @@ namespace OpenSim.Region.Framework.Scenes { //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; - client.OnRegionHandleRequest += RegionHandleRequest; } public virtual void SubscribeToClientNetworkEvents(IClientAPI client) @@ -3227,7 +3226,6 @@ namespace OpenSim.Region.Framework.Scenes { //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; - client.OnRegionHandleRequest -= RegionHandleRequest; } public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client) @@ -4887,22 +4885,6 @@ namespace OpenSim.Region.Framework.Scenes #endregion - public void RegionHandleRequest(IClientAPI client, UUID regionID) - { - m_log.DebugFormat("[SCENE]: RegionHandleRequest {0}", regionID); - ulong handle = 0; - if (regionID == RegionInfo.RegionID) - handle = RegionInfo.RegionHandle; - else - { - GridRegion r = GridService.GetRegionByUUID(UUID.Zero, regionID); - if (r != null) - handle = r.RegionHandle; - } - - if (handle != 0) - client.SendRegionHandle(regionID, handle); - } // Commented pending deletion since this method no longer appears to do anything at all // public bool NeedSceneCacheClear(UUID agentID) From ca26583e6bfdc9aa62e917a736f52ed5fdac75cd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 4 Jul 2013 15:17:06 -0700 Subject: [PATCH 03/93] Delete some verbose debug messages --- .../Region/CoreModules/Avatar/Friends/FriendsModule.cs | 8 ++++---- .../Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 2 +- .../GridServiceThrottle/GridServiceThrottleModule.cs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 6d4c65d77b..b693f2d5ef 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -498,7 +498,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected virtual void StatusNotify(List friendList, UUID userID, bool online) { - m_log.DebugFormat("[FRIENDS]: Entering StatusNotify for {0}", userID); + //m_log.DebugFormat("[FRIENDS]: Entering StatusNotify for {0}", userID); List friendStringIds = friendList.ConvertAll(friend => friend.Friend); List remoteFriendStringIds = new List(); @@ -527,15 +527,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // let's guard against sessions-gone-bad if (friendSession != null && friendSession.RegionID != UUID.Zero) { - m_log.DebugFormat("[FRIENDS]: Get region {0}", friendSession.RegionID); + //m_log.DebugFormat("[FRIENDS]: Get region {0}", friendSession.RegionID); GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); if (region != null) { m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online); } } - else - m_log.DebugFormat("[FRIENDS]: friend session is null or the region is UUID.Zero"); + //else + // m_log.DebugFormat("[FRIENDS]: friend session is null or the region is UUID.Zero"); } } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index a456009ca1..d00945ed16 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -252,7 +252,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected override void StatusNotify(List friendList, UUID userID, bool online) { - m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); + //m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); // First, let's divide the friends on a per-domain basis Dictionary> friendsPerDomain = new Dictionary>(); diff --git a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs index 5511fea9aa..a662731ab5 100644 --- a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs @@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Framework public void OnRegionHandleRequest(IClientAPI client, UUID regionID) { - m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID); + //m_log.DebugFormat("[GRIDSERVICE THROTTLE]: RegionHandleRequest {0}", regionID); ulong handle = 0; if (IsLocalRegionHandle(regionID, out handle)) { From dd15f954997333e007dbdc81b8a2e0fcd4583aa2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 5 Jul 2013 20:06:27 +0100 Subject: [PATCH 04/93] Add very basic regression test TestChildAgentSingleRegionCapabilities() which checks for addition and removal of capabilities on add/remove of child agent --- .../Tests/ScenePresenceCapabilityTests.cs | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs new file mode 100644 index 0000000000..5714042f62 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs @@ -0,0 +1,88 @@ +/* + * 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.Reflection; +using System.Text; +using System.Threading; +using System.Timers; +using Timer = System.Timers.Timer; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.ClientStack.Linden; +using OpenSim.Region.CoreModules.Framework; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; +using OpenSim.Region.CoreModules.World.Serialiser; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Region.Framework.Scenes.Tests +{ + [TestFixture] + public class ScenePresenceCapabilityTests : OpenSimTestCase + { + [Test] + public void TestChildAgentSingleRegionCapabilities() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + UUID spUuid = TestHelpers.ParseTail(0x1); + + // XXX: This is not great since the use of statics will mean that this has to be manually cleaned up for + // any subsequent test. + // XXX: May replace with a mock IHttpServer later. + BaseHttpServer httpServer = new BaseHttpServer(99999); + MainServer.AddHttpServer(httpServer); + MainServer.Instance = httpServer; + + CapabilitiesModule capsMod = new CapabilitiesModule(); + TestScene scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(scene, capsMod); + + ScenePresence sp = SceneHelpers.AddChildScenePresence(scene, spUuid); + Assert.That(capsMod.GetCapsForUser(spUuid), Is.Not.Null); + + // TODO: Need to add tests for other ICapabiltiesModule methods. + + scene.IncomingCloseAgent(sp.UUID, false); + Assert.That(capsMod.GetCapsForUser(spUuid), Is.Null); + + // TODO: Need to add tests for other ICapabiltiesModule methods. + } + } +} \ No newline at end of file From 5dbdd5f8b4856357340357394edc2f9e229a0582 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 6 Jul 2013 00:12:48 +0100 Subject: [PATCH 05/93] refactor: Make stats and sim status simpler by extending BaseStreamHandler like other handlers instead of implementing the IStreamedRequestHandler interface directly --- OpenSim/Region/Application/OpenSimBase.cs | 74 +++++-------------- .../Framework/Scenes/RegionStatsHandler.cs | 26 ++----- 2 files changed, 23 insertions(+), 77 deletions(-) diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 7ca87a3134..841069c5d3 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -759,73 +759,49 @@ namespace OpenSim /// /// Handler to supply the current status of this sim /// + /// /// Currently this is always OK if the simulator is still listening for connections on its HTTP service - public class SimStatusHandler : IStreamedRequestHandler + /// + public class SimStatusHandler : BaseStreamHandler { - public byte[] Handle(string path, Stream request, + public SimStatusHandler() : base("GET", "/simstatus", "SimStatus", "Simulator Status") {} + + public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return Util.UTF8.GetBytes("OK"); } - public string Name { get { return "SimStatus"; } } - public string Description { get { return "Simulator Status"; } } - - public string ContentType + public override string ContentType { get { return "text/plain"; } } - - public string HttpMethod - { - get { return "GET"; } - } - - public string Path - { - get { return "/simstatus"; } - } } /// /// Handler to supply the current extended status of this sim /// Sends the statistical data in a json serialization /// - public class XSimStatusHandler : IStreamedRequestHandler + public class XSimStatusHandler : BaseStreamHandler { OpenSimBase m_opensim; - string osXStatsURI = String.Empty; - - public string Name { get { return "XSimStatus"; } } - public string Description { get { return "Simulator XStatus"; } } - public XSimStatusHandler(OpenSimBase sim) + public XSimStatusHandler(OpenSimBase sim) + : base("GET", "/" + Util.SHA1Hash(sim.osSecret), "XSimStatus", "Simulator XStatus") { m_opensim = sim; - osXStatsURI = Util.SHA1Hash(sim.osSecret); } - public byte[] Handle(string path, Stream request, + public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest)); } - public string ContentType + public override string ContentType { get { return "text/plain"; } } - - public string HttpMethod - { - get { return "GET"; } - } - - public string Path - { - // This is for the OpenSimulator instance and is the osSecret hashed - get { return "/" + osXStatsURI; } - } } /// @@ -834,42 +810,26 @@ namespace OpenSim /// If the request contains a key, "callback" the response will be wrappend in the /// associated value for jsonp used with ajax/javascript /// - public class UXSimStatusHandler : IStreamedRequestHandler + public class UXSimStatusHandler : BaseStreamHandler { OpenSimBase m_opensim; - string osUXStatsURI = String.Empty; - - public string Name { get { return "UXSimStatus"; } } - public string Description { get { return "Simulator UXStatus"; } } public UXSimStatusHandler(OpenSimBase sim) + : base("GET", "/" + sim.userStatsURI, "UXSimStatus", "Simulator UXStatus") { - m_opensim = sim; - osUXStatsURI = sim.userStatsURI; - + m_opensim = sim; } - public byte[] Handle(string path, Stream request, + public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest)); } - public string ContentType + public override string ContentType { get { return "text/plain"; } } - - public string HttpMethod - { - get { return "GET"; } - } - - public string Path - { - // This is for the OpenSimulator instance and is the user provided URI - get { return "/" + osUXStatsURI; } - } } #endregion diff --git a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs index c11174dc4e..726becf3b5 100644 --- a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs +++ b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs @@ -46,47 +46,33 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.Framework.Scenes { - public class RegionStatsHandler : IStreamedRequestHandler + public class RegionStatsHandler : BaseStreamHandler { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private string osRXStatsURI = String.Empty; private string osXStatsURI = String.Empty; //private string osSecret = String.Empty; private OpenSim.Framework.RegionInfo regionInfo; public string localZone = TimeZone.CurrentTimeZone.StandardName; public TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); - public string Name { get { return "RegionStats"; } } - public string Description { get { return "Region Statistics"; } } - - public RegionStatsHandler(RegionInfo region_info) + public RegionStatsHandler(RegionInfo region_info) + : base("GET", "/" + Util.SHA1Hash(region_info.regionSecret), "RegionStats", "Region Statistics") { regionInfo = region_info; - osRXStatsURI = Util.SHA1Hash(regionInfo.regionSecret); osXStatsURI = Util.SHA1Hash(regionInfo.osSecret); } - public byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + public override byte[] Handle( + string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return Util.UTF8.GetBytes(Report()); } - public string ContentType + public override string ContentType { get { return "text/plain"; } } - - public string HttpMethod - { - get { return "GET"; } - } - - public string Path - { - // This is for the region and is the regionSecret hashed - get { return "/" + osRXStatsURI; } - } private string Report() { From 67407024a2e0b6e27f526cc2312e93fd867a855b Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 6 Jul 2013 00:29:19 +0100 Subject: [PATCH 06/93] Update thread watchdog on GridServiceRequestThread periodically and turn off alarming Unfortunately, alarm can spuriously go off if the thread blocks for a long time on an empty queue. --- .../GridServiceThrottle/GridServiceThrottleModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs index a662731ab5..f1eb1ad3a9 100644 --- a/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/GridServiceThrottle/GridServiceThrottleModule.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.CoreModules.Framework "GridServiceRequestThread", ThreadPriority.BelowNormal, true, - true); + false); } public void AddRegion(Scene scene) @@ -137,6 +137,8 @@ namespace OpenSim.Region.CoreModules.Framework { while (true) { + Watchdog.UpdateThread(); + GridRegionRequest request = m_RequestQueue.Dequeue(); GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, request.regionID); From a44ad0149213887b284b3fe65b9bddb0b63abff6 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 6 Jul 2013 00:32:11 +0100 Subject: [PATCH 07/93] Fix build break from recent commit dd15f95 on windows --- prebuild.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/prebuild.xml b/prebuild.xml index 3337894be7..74cfcb0423 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2965,6 +2965,7 @@ + From 55ac8c83c78d3b8d5fd027174328171849f8d1e2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 6 Jul 2013 00:34:22 +0100 Subject: [PATCH 08/93] Get InventoryWorkerThreads to update watchdog on processing requests --- OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 0e3cd6b283..b90df17622 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -347,6 +347,8 @@ namespace OpenSim.Region.ClientStack.Linden { while (true) { + Watchdog.UpdateThread(); + aPollRequest poolreq = m_queue.Dequeue(); poolreq.thepoll.Process(poolreq); From ccceb6d6d2d2359797b78b78f8057b57a6cd8bb4 Mon Sep 17 00:00:00 2001 From: justincc Date: Sat, 6 Jul 2013 00:52:54 +0100 Subject: [PATCH 09/93] Fix windows build break fromrecent dd1f95 for real this time - put new dll reference in the wrong place --- prebuild.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prebuild.xml b/prebuild.xml index 74cfcb0423..d9e32ea2c3 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2965,7 +2965,6 @@ - @@ -3197,6 +3196,7 @@ + From 98de67d57316a20fc813db853d6175fb8d8783ef Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 6 Jul 2013 00:55:14 +0100 Subject: [PATCH 10/93] Fix mono warning in LLImageManagerTests --- .../Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs index a0e0078c7f..83144e3bcd 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs @@ -73,7 +73,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests } [SetUp] - public void SetUp() + public override void SetUp() { base.SetUp(); From c358d5d168f349cbfbb10c1c4f1e992830b11fa4 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 5 Jul 2013 20:17:10 -0700 Subject: [PATCH 11/93] Changed a few bits in Inventory/Archiver/InventoryArchiveReadRequest.cs to be less dependent on a Scene. --- .../Archiver/InventoryArchiveReadRequest.cs | 32 +++++++++++-------- .../Archiver/InventoryArchiverModule.cs | 4 +-- .../Tests/InventoryArchiveLoadPathTests.cs | 12 +++---- .../Tests/InventoryArchiveSaveTests.cs | 2 +- .../Framework/Library/LibraryModule.cs | 4 +-- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 98285e9ab6..31c42d87d0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -67,10 +67,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// protected bool m_merge; - /// - /// We only use this to request modules - /// - protected Scene m_scene; + protected IInventoryService m_InventoryService; + protected IAssetService m_AssetService; + protected IUserAccountService m_UserAccountService; /// /// The stream from which the inventory archive will be loaded. @@ -118,9 +117,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver protected Dictionary m_creatorIdForAssetId = new Dictionary(); public InventoryArchiveReadRequest( - Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge) + IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) : this( - scene, + inv, + assets, + uacc, userInfo, invPath, new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress), @@ -129,9 +130,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } public InventoryArchiveReadRequest( - Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge) + IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge) { - m_scene = scene; + m_InventoryService = inv; + m_AssetService = assets; + m_UserAccountService = uacc; m_merge = merge; m_userInfo = userInfo; m_invPath = invPath; @@ -162,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver List folderCandidates = InventoryArchiveUtils.FindFoldersByPath( - m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); + m_InventoryService, m_userInfo.PrincipalID, m_invPath); if (folderCandidates.Count == 0) { @@ -297,7 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); List folderCandidates = InventoryArchiveUtils.FindFoldersByPath( - m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); + m_InventoryService, m_userInfo.PrincipalID, plainPath); if (folderCandidates.Count != 0) { @@ -380,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver = new InventoryFolderBase( newFolderId, newFolderName, m_userInfo.PrincipalID, (short)AssetType.Unknown, destFolder.ID, 1); - m_scene.InventoryService.AddFolder(destFolder); + m_InventoryService.AddFolder(destFolder); // Record that we have now created this folder iarPathExisting += rawDirsToCreate[i] + "/"; @@ -406,7 +409,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // Don't use the item ID that's in the file item.ID = UUID.Random(); - UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); + UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService); if (UUID.Zero != ospResolvedId) // The user exists in this grid { // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); @@ -436,7 +439,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // relying on native tar tools. m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; - m_scene.AddInventoryItem(item); + if (!m_InventoryService.AddItem(item)) + m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); return item; } @@ -533,7 +537,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); asset.Data = data; - m_scene.AssetService.Store(asset); + m_AssetService.Store(asset); return true; } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index 849449b323..797097ff0a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver try { - request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge); + request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge); } catch (EntryPointNotFoundException e) { @@ -342,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver try { - request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); + request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge); } catch (EntryPointNotFoundException e) { diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs index 95f562eefe..08f199adae 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs @@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { // Test replication of path1 - new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) + new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) .ReplicateArchivePathToUserInventory( iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), foldersCreated, nodesLoaded); @@ -246,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { // Test replication of path2 - new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) + new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) .ReplicateArchivePathToUserInventory( iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), foldersCreated, nodesLoaded); @@ -291,8 +291,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); - - new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) + + new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) .ReplicateArchivePathToUserInventory( itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), new Dictionary(), new HashSet()); @@ -342,8 +342,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); - - new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true) + + new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true) .ReplicateArchivePathToUserInventory( itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), new Dictionary(), new HashSet()); diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs index 5e7e24c148..b85739eba5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs @@ -86,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); InventoryArchiveReadRequest iarr - = new InventoryArchiveReadRequest(null, null, null, (Stream)null, false); + = new InventoryArchiveReadRequest(null, null, null, null, null, (Stream)null, false); iarr.LoadControlFile(filePath, data); Assert.That(iarr.ControlFileLoaded, Is.True); diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index d07cff4d28..69d7e16203 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName); simpleName = GetInventoryPathFromName(simpleName); - InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false); + InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false); try { HashSet nodes = archread.Execute(); @@ -185,7 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library // didn't find the subfolder with the given name; place it on the top m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName); archread.Close(); - archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); + archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, "/", iarFileName, false); archread.Execute(); } From 5f97c6f8f06f0b90ab815a1d44358dc256ec5a50 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 4 Jul 2013 12:16:33 -0700 Subject: [PATCH 12/93] BulletSim: non-functional updates. Comments and formatting. Update TODO list. --- .../Physics/BulletSPlugin/BSDynamics.cs | 14 +++- .../Region/Physics/BulletSPlugin/BSMotors.cs | 15 ++-- .../Region/Physics/BulletSPlugin/BSPrim.cs | 6 +- .../Physics/BulletSPlugin/BulletSimTODO.txt | 75 +++++++++++-------- 4 files changed, 67 insertions(+), 43 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index aa247dd01d..c27d3f04a4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -774,7 +774,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Since the computation of terrain height can be a little involved, this routine // is used to fetch the height only once for each vehicle simulation step. - Vector3 lastRememberedHeightPos; + Vector3 lastRememberedHeightPos = new Vector3(-1, -1, -1); private float GetTerrainHeight(Vector3 pos) { if ((m_knownHas & m_knownChangedTerrainHeight) == 0 || pos != lastRememberedHeightPos) @@ -788,14 +788,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Since the computation of water level can be a little involved, this routine // is used ot fetch the level only once for each vehicle simulation step. + Vector3 lastRememberedWaterHeightPos = new Vector3(-1, -1, -1); private float GetWaterLevel(Vector3 pos) { - if ((m_knownHas & m_knownChangedWaterLevel) == 0) + if ((m_knownHas & m_knownChangedWaterLevel) == 0 || pos != lastRememberedWaterHeightPos) { + lastRememberedWaterHeightPos = pos; m_knownWaterLevel = ControllingPrim.PhysScene.TerrainManager.GetWaterLevelAtXYZ(pos); m_knownHas |= m_knownChangedWaterLevel; } - return (float)m_knownWaterLevel; + return m_knownWaterLevel; } private Vector3 VehiclePosition @@ -991,11 +993,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin { Vector3 vel = VehicleVelocity; if ((m_flags & (VehicleFlag.NO_X)) != 0) + { vel.X = 0; + } if ((m_flags & (VehicleFlag.NO_Y)) != 0) + { vel.Y = 0; + } if ((m_flags & (VehicleFlag.NO_Z)) != 0) + { vel.Z = 0; + } VehicleVelocity = vel; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 121470364b..7693195763 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -188,6 +188,8 @@ public class BSVMotor : BSMotor CurrentValue = current; return Step(timeStep); } + // Given and error, computer a correction for this step. + // Simple scaling of the error by the timestep. public virtual Vector3 StepError(float timeStep, Vector3 error) { if (!Enabled) return Vector3.Zero; @@ -221,7 +223,7 @@ public class BSVMotor : BSMotor CurrentValue, TargetValue); LastError = BSMotor.InfiniteVector; - while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) + while (maxOutput-- > 0 && !ErrorIsZero()) { Vector3 lastStep = Step(timeStep); MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}", @@ -375,7 +377,6 @@ public class BSPIDVMotor : BSVMotor // The factors are vectors for the three dimensions. This is the proportional of each // that is applied. This could be multiplied through the actual factors but it // is sometimes easier to manipulate the factors and their mix separately. - // to public Vector3 FactorMix; // Arbritrary factor range. @@ -413,14 +414,14 @@ public class BSPIDVMotor : BSVMotor // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. // If efficiency is low (0f), use a factor value that overcorrects. // TODO: might want to vary contribution of different factor depending on efficiency. - float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; - // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; + // float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; + float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; proportionFactor = new Vector3(factor, factor, factor); integralFactor = new Vector3(factor, factor, factor); derivFactor = new Vector3(factor, factor, factor); - MDetailLog("{0},BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor); + MDetailLog("{0}, BSPIDVMotor.setEfficiency,eff={1},factor={2}", BSScene.DetailLogZero, Efficiency, factor); } } @@ -441,8 +442,8 @@ public class BSPIDVMotor : BSVMotor + derivitive / TimeScale * derivFactor * FactorMix.Z ; - MDetailLog("{0}, BSPIDVMotor.step,ts={1},err={2},runnInt={3},deriv={4},ret={5}", - BSScene.DetailLogZero, timeStep, error, RunningIntegration, derivitive, ret); + MDetailLog("{0}, BSPIDVMotor.step,ts={1},err={2},lerr={3},runnInt={4},deriv={5},ret={6}", + BSScene.DetailLogZero, timeStep, error, LastError, RunningIntegration, derivitive, ret); return ret; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index b2947c623d..f0858caa81 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -1125,7 +1125,9 @@ public class BSPrim : BSPhysObject OMV.Vector3 addForce = force; PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate() { - // Bullet adds this central force to the total force for this tick + // Bullet adds this central force to the total force for this tick. + // Deep down in Bullet: + // linearVelocity += totalForce / mass * timeStep; DetailLog("{0},BSPrim.addForce,taint,force={1}", LocalID, addForce); if (PhysBody.HasPhysicalBody) { @@ -1493,6 +1495,8 @@ public class BSPrim : BSPhysObject returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); // DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass); + DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3},pathB={4},pathE={5},profB={6},profE={7},siz={8}", + LocalID, Density, volume, returnMass, pathBegin, pathEnd, profileBegin, profileEnd, _size); return returnMass; }// end CalculateMass diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 4357ef15f6..0453376ca0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt @@ -3,25 +3,21 @@ CURRENT PROBLEMS TO FIX AND/OR LOOK AT Vehicle buoyancy. Computed correctly? Possibly creating very large effective mass. Interaction of llSetBuoyancy and vehicle buoyancy. Should be additive? Negative buoyancy computed correctly +Center-of-gravity Computation of mesh mass. How done? How should it be done? -Script changing rotation of child prim while vehicle moving (eg turning wheel) causes - the wheel to appear to jump back. Looks like sending position from previous update. Enable vehicle border crossings (at least as poorly as ODE) Terrain skirts Avatar created in previous region and not new region when crossing border Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) +User settable terrain mesh + Allow specifying as convex or concave and use different getHeight functions depending +Boats, when turning nose down into the water + Acts like rotation around Z is also effecting rotation around X and Y Deleting a linkset while standing on the root will leave the physical shape of the root behind. Not sure if it is because standing on it. Done with large prim linksets. Linkset child rotations. Nebadon spiral tube has middle sections which are rotated wrong. Select linked spiral tube. Delink and note where the middle section ends up. -Refarb compound linkset creation to create a pseudo-root for center-of-mass - Let children change their shape to physical indendently and just add shapes to compound -Vehicle angular vertical attraction -vehicle angular banking -Center-of-gravity -Vehicle angular deflection - Preferred orientation angular correction fix Teravus llMoveToTarget script debug Mixing of hover, buoyancy/gravity, moveToTarget, into one force Setting hover height to zero disables hover even if hover flags are on (from SL wiki) @@ -33,10 +29,16 @@ Vehicle script tuning/debugging Avanti speed script Weapon shooter script Move material definitions (friction, ...) into simulator. +osGetPhysicsEngineVerion() and create a version code for the C++ DLL One sided meshes? Should terrain be built into a closed shape? When meshes get partially wedged into the terrain, they cannot push themselves out. It is possible that Bullet processes collisions whether entering or leaving a mesh. Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869 +Small physical objects do not interact correctly + Create chain of .5x.5x.1 torui and make all but top physical so to hang. + The chain will fall apart and pairs will dance around on ground + Chains of 1x1x.2 will stay connected but will dance. + Chains above 2x2x.4 are more stable and get stablier as torui get larger. VEHICLES TODO LIST: ================================================= @@ -45,14 +47,12 @@ LINEAR_MOTOR_DIRECTION values should be clamped to reasonable numbers. Same for other velocity settings. UBit improvements to remove rubber-banding of avatars sitting on vehicle child prims: https://github.com/UbitUmarov/Ubit-opensim -Vehicles (Move smoothly) Some vehicles should not be able to turn if no speed or off ground. Cannot edit/move a vehicle being ridden: it jumps back to the origional position. Neb car jiggling left and right Happens on terrain and any other mesh object. Flat cubes are much smoother. This has been reduced but not eliminated. Implement referenceFrame for all the motion routines. -For limitMotorUp, use raycast down to find if vehicle is in the air. Verify llGetVel() is returning a smooth and good value for vehicle movement. llGetVel() should return the root's velocity if requested in a child prim. Implement function efficiency for lineaar and angular motion. @@ -93,29 +93,15 @@ Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. Duplicating a physical prim causes old prim to jump away Dup a phys prim and the original become unselected and thus interacts w/ selected prim. Scenes with hundred of thousands of static objects take a lot of physics CPU time. -BSPrim.Force should set a continious force on the prim. The force should be - applied each tick. Some limits? Gun sending shooter flying. Collision margin (gap between physical objects lying on each other) Boundry checking (crashes related to crossing boundry) Add check for border edge position for avatars and objects. Verify the events are created for border crossings. -Avatar rotation (check out changes to ScenePresence for physical rotation) -Avatar running (what does phys engine need to do?) -Small physical objects do not interact correctly - Create chain of .5x.5x.1 torui and make all but top physical so to hang. - The chain will fall apart and pairs will dance around on ground - Chains of 1x1x.2 will stay connected but will dance. - Chains above 2x2x.4 are more stable and get stablier as torui get larger. -Add PID motor for avatar movement (slow to stop, ...) -setForce should set a constant force. Different than AddImpulse. -Implement raycast. Implement ShapeCollection.Dispose() -Implement water as a plain so raycasting and collisions can happen with same. +Implement water as a plain or mesh so raycasting and collisions can happen with same. Add collision penetration return Add field passed back by BulletSim.dll and fill with info in ManifoldConstact.GetDistance() -Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE - Also osGetPhysicsEngineVerion() maybe. Linkset.Position and Linkset.Orientation requre rewrite to properly return child position. LinksetConstraint acts like it's at taint time!! Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F) @@ -127,9 +113,6 @@ Selecting and deselecting physical objects causes CPU processing time to jump Re-implement buoyancy as a separate force on the object rather than diddling gravity. Register a pre-step event to add the force. More efficient memory usage when passing hull information from BSPrim to BulletSim -Avatar movement motor check for zero or small movement. Somehow suppress small movements - when avatar has stopped and is just standing. Simple test for near zero has - the problem of preventing starting up (increase from zero) especially when falling. Physical and phantom will drop through the terrain @@ -172,7 +155,6 @@ Do we need to do convex hulls all the time? Can complex meshes be left meshes? There is some problem with meshes and collisions Hulls are not as detailed as meshes. Hulled vehicles insides are different shape. Debounce avatar contact so legs don't keep folding up when standing. -Implement LSL physics controls. Like STATUS_ROTATE_X. Add border extensions to terrain to help region crossings and objects leaving region. Use a different capsule shape for avatar when sitting LL uses a pyrimidal shape scaled by the avatar's bounding box @@ -205,8 +187,6 @@ Keep avatar scaling correct. http://pennycow.blogspot.fr/2011/07/matter-of-scale INTERNAL IMPROVEMENT/CLEANUP ================================================= -Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to - BSScene.TaintedObject() could immediately execute the callback if already in taint time. Create the physical wrapper classes (BulletBody, BulletShape) by methods on BSAPITemplate and make their actual implementation Bullet engine specific. For the short term, just call the existing functions in ShapeCollection. @@ -365,4 +345,35 @@ After getting off a vehicle, the root prim is phantom (can be walked through) Explore btGImpactMeshShape as alternative to convex hulls for simplified physical objects. Regular triangle meshes don't do physical collisions. (DONE: discovered GImpact is VERY CPU intensive) +Script changing rotation of child prim while vehicle moving (eg turning wheel) causes + the wheel to appear to jump back. Looks like sending position from previous update. + (DONE: redo of compound linksets fixed problem) +Refarb compound linkset creation to create a pseudo-root for center-of-mass + Let children change their shape to physical indendently and just add shapes to compound + (DONE: redo of compound linkset fixed problem) +Vehicle angular vertical attraction (DONE: vegaslon code) +vehicle angular banking (DONE: vegaslon code) +Vehicle angular deflection (DONE: vegaslon code) + Preferred orientation angular correction fix +Vehicles (Move smoothly) +For limitMotorUp, use raycast down to find if vehicle is in the air. + (WILL NOT BE DONE: gravity does the job well enough) +BSPrim.Force should set a continious force on the prim. The force should be + applied each tick. Some limits? + (DONE: added physical actors. Implemented SetForce, SetTorque, ...) +Implement LSL physics controls. Like STATUS_ROTATE_X. (DONE) +Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE +Avatar rotation (check out changes to ScenePresence for physical rotation) (DONE) +Avatar running (what does phys engine need to do?) (DONE: multiplies run factor by walking force) +setForce should set a constant force. Different than AddImpulse. (DONE) +Add PID motor for avatar movement (slow to stop, ...) (WNBD: current works ok) +Avatar movement motor check for zero or small movement. Somehow suppress small movements + when avatar has stopped and is just standing. Simple test for near zero has + the problem of preventing starting up (increase from zero) especially when falling. + (DONE: avatar movement actor knows if standing on stationary object and zeros motion) +Can the 'inTaintTime' flag be cleaned up and used? For instance, a call to + BSScene.TaintedObject() could immediately execute the callback if already in taint time. + (DONE) + + From 03268d85c41c94e7b35802b9dea1ce08299e5426 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 2 Jun 2013 10:04:15 -0700 Subject: [PATCH 13/93] BulletSim: comments and non-functional changes working toward the center-of-gravity implementation. --- .../BulletSPlugin/BSLinksetCompound.cs | 11 ++++---- .../Region/Physics/BulletSPlugin/BSParam.cs | 3 +++ .../Physics/BulletSPlugin/BSPrimDisplaced.cs | 26 ++++++++++++------- .../Physics/BulletSPlugin/BSPrimLinkable.cs | 19 +++++++++++--- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 308cf13b13..30f6c8c173 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -315,7 +315,6 @@ public sealed class BSLinksetCompound : BSLinkset // Note that this works for rebuilding just the root after a linkset is taken apart. // Called at taint time!! private bool UseBulletSimRootOffsetHack = false; // Attempt to have Bullet track the coords of root compound shape - private bool disableCOM = true; // For basic linkset debugging, turn off the center-of-mass setting private void RecomputeLinksetCompound() { try @@ -331,9 +330,7 @@ public sealed class BSLinksetCompound : BSLinkset // There is no reason to build all this physical stuff for a non-physical linkset. if (!LinksetRoot.IsPhysicallyActive) { - // Clean up any old linkset shape and make sure the root shape is set to the root object. DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID); - return; // Note the 'finally' clause at the botton which will get executed. } @@ -347,9 +344,9 @@ public sealed class BSLinksetCompound : BSLinkset OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation)); - // 'centerDisplacement' is the value to subtract from children to give physical offset position + // 'centerDisplacementV' is the value to subtract from children to give physical offset position OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation; - if (UseBulletSimRootOffsetHack || disableCOM) + if (UseBulletSimRootOffsetHack || !BSParam.LinksetOffsetCenterOfMass) { centerDisplacementV = OMV.Vector3.Zero; LinksetRoot.ClearDisplacement(); @@ -357,6 +354,8 @@ public sealed class BSLinksetCompound : BSLinkset else { LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV); + // The actual center-of-mass could have been set by the user. + centerDisplacementV = LinksetRoot.PositionDisplacement; } DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}", LinksetRoot.LocalID, LinksetRoot.RawPosition, centerOfMassW, centerDisplacementV); @@ -409,7 +408,7 @@ public sealed class BSLinksetCompound : BSLinkset { // Enable the physical position updator to return the position and rotation of the root shape. // This enables a feature in the C++ code to return the world coordinates of the first shape in the - // compound shape. This eleviates the need to offset the returned physical position by the + // compound shape. This aleviates the need to offset the returned physical position by the // center-of-mass offset. m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index d17c8e76c0..0f84bf7794 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -176,6 +176,7 @@ public static class BSParam // Linkset implementation parameters public static float LinksetImplementation { get; private set; } + public static bool LinksetOffsetCenterOfMass { get; private set; } public static bool LinkConstraintUseFrameOffset { get; private set; } public static bool LinkConstraintEnableTransMotor { get; private set; } public static float LinkConstraintTransMotorMaxVel { get; private set; } @@ -684,6 +685,8 @@ public static class BSParam new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", (float)BSLinkset.LinksetImplementation.Compound ), + new ParameterDefn("LinksetOffsetCenterOfMass", "If 'true', compute linkset center-of-mass and offset linkset position to account for same", + false ), new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", false ), new ParameterDefn("LinkConstraintEnableTransMotor", "Whether to enable translational motor on linkset constraints", diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs index f5ee671862..9a05349c7f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs @@ -44,12 +44,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public class BSPrimDisplaced : BSPrim { - // The purpose of this module is to do any mapping between what the simulator thinks + // The purpose of this subclass is to do any mapping between what the simulator thinks // the prim position and orientation is and what the physical position/orientation. // This difference happens because Bullet assumes the center-of-mass is the <0,0,0> - // of the prim/linkset. The simulator tracks the location of the prim/linkset by - // the location of the root prim. So, if center-of-mass is anywhere but the origin - // of the root prim, the physical origin is displaced from the simulator origin. + // of the prim/linkset. The simulator, on the other hand, tracks the location of + // the prim/linkset by the location of the root prim. So, if center-of-mass is anywhere + // but the origin of the root prim, the physical origin is displaced from the simulator origin. // // This routine works by capturing the Force* setting of position/orientation/... and // adjusting the simulator values (being set) into the physical values. @@ -61,6 +61,7 @@ public class BSPrimDisplaced : BSPrim public virtual OMV.Vector3 PositionDisplacement { get; set; } public virtual OMV.Quaternion OrientationDisplacement { get; set; } + public virtual OMV.Quaternion OrientationDisplacementOrigInv { get; set; } public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) @@ -99,7 +100,8 @@ public class BSPrimDisplaced : BSPrim // Remember the displacement from root as well as the origional rotation of the // new center-of-mass. PositionDisplacement = comDisp; - OrientationDisplacement = OMV.Quaternion.Identity; + OrientationDisplacement = Quaternion.Normalize(RawOrientation); + OrientationDisplacementOrigInv = Quaternion.Inverse(OrientationDisplacement); } } @@ -110,7 +112,7 @@ public class BSPrimDisplaced : BSPrim { if (PositionDisplacement != OMV.Vector3.Zero) { - OMV.Vector3 displacedPos = value - (PositionDisplacement * RawOrientation); + OMV.Vector3 displacedPos = value - (PositionDisplacement * (OrientationDisplacementOrigInv * RawOrientation)); DetailLog("{0},BSPrimDisplaced.ForcePosition,val={1},disp={2},newPos={3}", LocalID, value, PositionDisplacement, displacedPos); base.ForcePosition = displacedPos; } @@ -126,7 +128,8 @@ public class BSPrimDisplaced : BSPrim get { return base.ForceOrientation; } set { - // TODO: + // Changing orientation also changes the position of the center-of-mass since + // the orientation passed is for a rotation around the root prim's center. base.ForceOrientation = value; } } @@ -150,10 +153,13 @@ public class BSPrimDisplaced : BSPrim // Undo any center-of-mass displacement that might have been done. if (PositionDisplacement != OMV.Vector3.Zero || OrientationDisplacement != OMV.Quaternion.Identity) { - // Correct for any rotation around the center-of-mass - // TODO!!! + // The origional shape was offset from 'zero' by PositionDisplacement and rotated by OrientationDisplacement. + // These physical locations and rotation must be back converted to be centered around the displaced + // root shape. + + // The root position is the reported position displaced by the rotated displacement. + OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * (entprop.Rotation * OrientationDisplacementOrigInv)); - OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * entprop.Rotation); DetailLog("{0},BSPrimDisplaced.ForcePosition,physPos={1},disp={2},newPos={3}", LocalID, entprop.Position, PositionDisplacement, displacedPos); entprop.Position = displacedPos; // entprop.Rotation = something; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 87eed98c4b..6d7de35aba 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -37,6 +37,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public class BSPrimLinkable : BSPrimDisplaced { + // The purpose of this subclass is to add linkset functionality to the prim. This overrides + // operations necessary for keeping the linkset created and, additionally, this + // calls the linkset implementation for its creation and management. + + // This adds the overrides for link() and delink() so the prim is linkable. + public BSLinkset Linkset { get; set; } // The index of this child prim. public int LinksetChildIndex { get; set; } @@ -69,8 +75,8 @@ public class BSPrimLinkable : BSPrimDisplaced BSPrimLinkable parent = obj as BSPrimLinkable; if (parent != null) { - BSPhysObject parentBefore = Linkset.LinksetRoot; - int childrenBefore = Linkset.NumberOfChildren; + BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG + int childrenBefore = Linkset.NumberOfChildren; // DEBUG Linkset = parent.Linkset.AddMeToLinkset(this); @@ -85,8 +91,8 @@ public class BSPrimLinkable : BSPrimDisplaced // TODO: decide if this parent checking needs to happen at taint time // Race condition here: if link() and delink() in same simulation tick, the delink will not happen - BSPhysObject parentBefore = Linkset.LinksetRoot; - int childrenBefore = Linkset.NumberOfChildren; + BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG + int childrenBefore = Linkset.NumberOfChildren; // DEBUG Linkset = Linkset.RemoveMeFromLinkset(this); @@ -128,6 +134,7 @@ public class BSPrimLinkable : BSPrimDisplaced get { return Linkset.LinksetMass; } } + // Refresh the linkset structure and parameters when the prim's physical parameters are changed. public override void UpdatePhysicalParameters() { base.UpdatePhysicalParameters(); @@ -139,6 +146,7 @@ public class BSPrimLinkable : BSPrimDisplaced Linkset.Refresh(this); } + // When the prim is made dynamic or static, the linkset needs to change. protected override void MakeDynamic(bool makeStatic) { base.MakeDynamic(makeStatic); @@ -155,6 +163,8 @@ public class BSPrimLinkable : BSPrimDisplaced base.RemoveDependencies(); } + // Called after a simulation step for the changes in physical object properties. + // Do any filtering/modification needed for linksets. public override void UpdateProperties(EntityProperties entprop) { if (Linkset.IsRoot(this)) @@ -176,6 +186,7 @@ public class BSPrimLinkable : BSPrimDisplaced Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); } + // Called after a simulation step to post a collision with this object. public override bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { From 97698ae3119e01ecd2c98f7a17ad37204b9bfd9c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 10 Jun 2013 06:40:07 -0700 Subject: [PATCH 14/93] BulletSim: More tweaking on center-of-mass. Almost there. Changes have no effect if LinksetOffsetCenterOfMass=false (the default). --- .../BulletSPlugin/BSLinksetCompound.cs | 78 ++++--------------- .../Physics/BulletSPlugin/BSPrimDisplaced.cs | 63 ++++++--------- .../Physics/BulletSPlugin/BSPrimLinkable.cs | 10 +++ .../Region/Physics/BulletSPlugin/BSScene.cs | 1 - 4 files changed, 51 insertions(+), 101 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 30f6c8c173..96626ca50e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -35,62 +35,6 @@ using OMV = OpenMetaverse; namespace OpenSim.Region.Physics.BulletSPlugin { - /* -// When a child is linked, the relationship position of the child to the parent -// is remembered so the child's world position can be recomputed when it is -// removed from the linkset. -sealed class BSLinksetCompoundInfo : BSLinksetInfo -{ - public int Index; - public OMV.Vector3 OffsetFromRoot; - public OMV.Vector3 OffsetFromCenterOfMass; - public OMV.Quaternion OffsetRot; - public BSLinksetCompoundInfo(int indx, OMV.Vector3 p, OMV.Quaternion r) - { - Index = indx; - OffsetFromRoot = p; - OffsetFromCenterOfMass = p; - OffsetRot = r; - } - // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape) - public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement) - { - // Each child position and rotation is given relative to the center-of-mass. - OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation); - OMV.Vector3 displacementFromRoot = (child.RawPosition - root.RawPosition) * invRootOrientation; - OMV.Vector3 displacementFromCOM = displacementFromRoot - centerDisplacement; - OMV.Quaternion displacementRot = child.RawOrientation * invRootOrientation; - - // Save relative position for recomputing child's world position after moving linkset. - Index = indx; - OffsetFromRoot = displacementFromRoot; - OffsetFromCenterOfMass = displacementFromCOM; - OffsetRot = displacementRot; - } - public override void Clear() - { - Index = 0; - OffsetFromRoot = OMV.Vector3.Zero; - OffsetFromCenterOfMass = OMV.Vector3.Zero; - OffsetRot = OMV.Quaternion.Identity; - } - public override string ToString() - { - StringBuilder buff = new StringBuilder(); - buff.Append(""); - return buff.ToString(); - } -}; - */ - public sealed class BSLinksetCompound : BSLinkset { private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; @@ -151,7 +95,9 @@ public sealed class BSLinksetCompound : BSLinkset public override bool MakeStatic(BSPrimLinkable child) { bool ret = false; + DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); + child.ClearDisplacement(); if (IsRoot(child)) { // Schedule a rebuild to verify that the root shape is set to the real shape. @@ -364,16 +310,28 @@ public sealed class BSLinksetCompound : BSLinkset int memberIndex = 1; ForEachMember(delegate(BSPrimLinkable cPrim) { - // Root shape is always index zero. - cPrim.LinksetChildIndex = IsRoot(cPrim) ? 0 : memberIndex; + if (IsRoot(cPrim)) + { + // Root shape is always index zero. + cPrim.LinksetChildIndex = 0; + } + else + { + cPrim.LinksetChildIndex = memberIndex; + memberIndex++; + } // Get a reference to the shape of the child and add that shape to the linkset compound shape BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); + + // Offset the child shape from the center-of-mass and rotate it to vehicle relative OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacementV; OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation; + + // Add the child shape to the compound shape being built m_physicsScene.PE.AddChildShapeToCompoundShape(linksetShape.physShapeInfo, childShape.physShapeInfo, offsetPos, offsetRot); DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChild,indx={1},cShape={2},offPos={3},offRot={4}", - LinksetRoot.LocalID, memberIndex, childShape, offsetPos, offsetRot); + LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot); // Since we are borrowing the shape of the child, disable the origional child body if (!IsRoot(cPrim)) @@ -385,8 +343,6 @@ public sealed class BSLinksetCompound : BSLinkset cPrim.PhysBody.collisionType = CollisionType.LinksetChild; } - memberIndex++; - return false; // 'false' says to move onto the next child in the list }); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs index 9a05349c7f..a11bca0ba1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs @@ -51,7 +51,7 @@ public class BSPrimDisplaced : BSPrim // the prim/linkset by the location of the root prim. So, if center-of-mass is anywhere // but the origin of the root prim, the physical origin is displaced from the simulator origin. // - // This routine works by capturing the Force* setting of position/orientation/... and + // This routine works by capturing ForcePosition and // adjusting the simulator values (being set) into the physical values. // The conversion is also done in the opposite direction (physical origin -> simulator origin). // @@ -60,8 +60,6 @@ public class BSPrimDisplaced : BSPrim // class. public virtual OMV.Vector3 PositionDisplacement { get; set; } - public virtual OMV.Quaternion OrientationDisplacement { get; set; } - public virtual OMV.Quaternion OrientationDisplacementOrigInv { get; set; } public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical) @@ -70,15 +68,17 @@ public class BSPrimDisplaced : BSPrim ClearDisplacement(); } + // Clears any center-of-mass displacement introduced by linksets, etc. + // Does not clear the displacement set by the user. public void ClearDisplacement() { - PositionDisplacement = OMV.Vector3.Zero; - OrientationDisplacement = OMV.Quaternion.Identity; + SetEffectiveCenterOfMassDisplacement(OMV.Vector3.Zero); } // Set this sets and computes the displacement from the passed prim to the center-of-mass. // A user set value for center-of-mass overrides whatever might be passed in here. // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). + // Called at taint time. public virtual void SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) { Vector3 comDisp; @@ -87,21 +87,17 @@ public class BSPrimDisplaced : BSPrim else comDisp = centerOfMassDisplacement; + if (comDisp.ApproxEquals(Vector3.Zero, 0.01f) ) + comDisp = Vector3.Zero; + DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}", LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp); - if (comDisp == Vector3.Zero) + if ( comDisp != PositionDisplacement ) { - // If there is no diplacement. Things get reset. - PositionDisplacement = OMV.Vector3.Zero; - OrientationDisplacement = OMV.Quaternion.Identity; - } - else - { - // Remember the displacement from root as well as the origional rotation of the - // new center-of-mass. + // Displacement setting is changing. + // The relationship between the physical object and simulated object must be aligned. PositionDisplacement = comDisp; - OrientationDisplacement = Quaternion.Normalize(RawOrientation); - OrientationDisplacementOrigInv = Quaternion.Inverse(OrientationDisplacement); + this.ForcePosition = RawPosition; } } @@ -112,7 +108,11 @@ public class BSPrimDisplaced : BSPrim { if (PositionDisplacement != OMV.Vector3.Zero) { - OMV.Vector3 displacedPos = value - (PositionDisplacement * (OrientationDisplacementOrigInv * RawOrientation)); + // The displacement is always relative to the vehicle so, when setting position, + // the caller means to set the position of the root prim. + // This offsets the setting value to the center-of-mass and sends that to the + // physics engine. + OMV.Vector3 displacedPos = value - (PositionDisplacement * RawOrientation); DetailLog("{0},BSPrimDisplaced.ForcePosition,val={1},disp={2},newPos={3}", LocalID, value, PositionDisplacement, displacedPos); base.ForcePosition = displacedPos; } @@ -123,26 +123,12 @@ public class BSPrimDisplaced : BSPrim } } - public override Quaternion ForceOrientation - { - get { return base.ForceOrientation; } - set - { - // Changing orientation also changes the position of the center-of-mass since - // the orientation passed is for a rotation around the root prim's center. - base.ForceOrientation = value; - } - } - - // TODO: decide if this is the right place for these variables. - // Somehow incorporate the optional settability by the user. - // Is this used? + // These are also overridden by BSPrimLinkable if the prim can be part of a linkset public override OMV.Vector3 CenterOfMass { get { return RawPosition; } } - // Is this used? public override OMV.Vector3 GeometricCenter { get { return RawPosition; } @@ -151,18 +137,17 @@ public class BSPrimDisplaced : BSPrim public override void UpdateProperties(EntityProperties entprop) { // Undo any center-of-mass displacement that might have been done. - if (PositionDisplacement != OMV.Vector3.Zero || OrientationDisplacement != OMV.Quaternion.Identity) + if (PositionDisplacement != OMV.Vector3.Zero) { - // The origional shape was offset from 'zero' by PositionDisplacement and rotated by OrientationDisplacement. - // These physical locations and rotation must be back converted to be centered around the displaced + // The origional shape was offset from 'zero' by PositionDisplacement. + // These physical location must be back converted to be centered around the displaced // root shape. // The root position is the reported position displaced by the rotated displacement. - OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * (entprop.Rotation * OrientationDisplacementOrigInv)); - - DetailLog("{0},BSPrimDisplaced.ForcePosition,physPos={1},disp={2},newPos={3}", LocalID, entprop.Position, PositionDisplacement, displacedPos); + OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * entprop.Rotation); + DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},newPos={3}", + LocalID, entprop.Position, PositionDisplacement, displacedPos); entprop.Position = displacedPos; - // entprop.Rotation = something; } base.UpdateProperties(entprop); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 6d7de35aba..70586466cf 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -134,6 +134,16 @@ public class BSPrimLinkable : BSPrimDisplaced get { return Linkset.LinksetMass; } } + public override OMV.Vector3 CenterOfMass + { + get { return Linkset.CenterOfMass; } + } + + public override OMV.Vector3 GeometricCenter + { + get { return Linkset.GeometricCenter; } + } + // Refresh the linkset structure and parameters when the prim's physical parameters are changed. public override void UpdatePhysicalParameters() { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 1645c989d7..e56a6f6725 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -785,7 +785,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters { // The simulation of the time interval took less than realtime. // Do a sleep for the rest of realtime. - DetailLog("{0},BulletSPluginPhysicsThread,sleeping={1}", BSScene.DetailLogZero, simulationTimeVsRealtimeDifferenceMS); Thread.Sleep(simulationTimeVsRealtimeDifferenceMS); } else From a65cec3986431f5a2f4f9eb2424157def0d035c8 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 6 Jul 2013 08:22:59 -0700 Subject: [PATCH 15/93] BulletSim: implementation of linkset center-of-mass. Default off, for the moment, until more testing. Add separate thread and center-of-mass flags to OpenSimDefaults.ini. Clean up comments in OpenSimDefaults.ini. --- .../BulletSPlugin/BSLinksetCompound.cs | 20 ++++--- .../Physics/BulletSPlugin/BSPhysObject.cs | 3 + .../Region/Physics/BulletSPlugin/BSPrim.cs | 5 +- .../Physics/BulletSPlugin/BSPrimDisplaced.cs | 60 ++++++++++++++----- .../Physics/BulletSPlugin/BSPrimLinkable.cs | 11 ++-- bin/OpenSimDefaults.ini | 56 +++++++++++------ 6 files changed, 107 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 96626ca50e..1d941426a8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -271,6 +271,8 @@ public sealed class BSLinksetCompound : BSLinkset // to what they should be as if the root was not in a linkset. // Not that bad since we only get into this routine if there are children in the linkset and // something has been updated/changed. + // Have to do the rebuild before checking for physical because this might be a linkset + // being destructed and going non-physical. LinksetRoot.ForceBodyShapeRebuild(true); // There is no reason to build all this physical stuff for a non-physical linkset. @@ -283,28 +285,29 @@ public sealed class BSLinksetCompound : BSLinkset // Get a new compound shape to build the linkset shape in. BSShape linksetShape = BSShapeCompound.GetReference(m_physicsScene); - // The center of mass for the linkset is the geometric center of the group. // Compute a displacement for each component so it is relative to the center-of-mass. // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass OMV.Vector3 centerOfMassW = ComputeLinksetCenterOfMass(); OMV.Quaternion invRootOrientation = OMV.Quaternion.Normalize(OMV.Quaternion.Inverse(LinksetRoot.RawOrientation)); + OMV.Vector3 origRootPosition = LinksetRoot.RawPosition; - // 'centerDisplacementV' is the value to subtract from children to give physical offset position + // 'centerDisplacementV' is the vehicle relative distance from the simulator root position to the center-of-mass OMV.Vector3 centerDisplacementV = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation; if (UseBulletSimRootOffsetHack || !BSParam.LinksetOffsetCenterOfMass) { + // Zero everything if center-of-mass displacement is not being done. centerDisplacementV = OMV.Vector3.Zero; LinksetRoot.ClearDisplacement(); } else { - LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV); // The actual center-of-mass could have been set by the user. - centerDisplacementV = LinksetRoot.PositionDisplacement; + centerDisplacementV = LinksetRoot.SetEffectiveCenterOfMassDisplacement(centerDisplacementV); } + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,rootPos={1},com={2},comDisp={3}", - LinksetRoot.LocalID, LinksetRoot.RawPosition, centerOfMassW, centerDisplacementV); + LinksetRoot.LocalID, origRootPosition, centerOfMassW, centerDisplacementV); // Add the shapes of all the components of the linkset int memberIndex = 1; @@ -321,11 +324,11 @@ public sealed class BSLinksetCompound : BSLinkset memberIndex++; } - // Get a reference to the shape of the child and add that shape to the linkset compound shape + // Get a reference to the shape of the child for adding of that shape to the linkset compound shape BSShape childShape = cPrim.PhysShape.GetReference(m_physicsScene, cPrim); - // Offset the child shape from the center-of-mass and rotate it to vehicle relative - OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacementV; + // Offset the child shape from the center-of-mass and rotate it to vehicle relative. + OMV.Vector3 offsetPos = (cPrim.RawPosition - origRootPosition) * invRootOrientation - centerDisplacementV; OMV.Quaternion offsetRot = OMV.Quaternion.Normalize(cPrim.RawOrientation) * invRootOrientation; // Add the child shape to the compound shape being built @@ -366,6 +369,7 @@ public sealed class BSLinksetCompound : BSLinkset // This enables a feature in the C++ code to return the world coordinates of the first shape in the // compound shape. This aleviates the need to offset the returned physical position by the // center-of-mass offset. + // TODO: either debug this feature or remove it. m_physicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index a0d5c42172..738e2d0689 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -90,6 +90,8 @@ public abstract class BSPhysObject : PhysicsActor PhysBody = new BulletBody(localID); PhysShape = new BSShapeNull(); + UserSetCenterOfMassDisplacement = null; + PrimAssetState = PrimAssetCondition.Unknown; // Default material type. Also sets Friction, Restitution and Density. @@ -180,6 +182,7 @@ public abstract class BSPhysObject : PhysicsActor Material = (MaterialAttributes.Material)material; // Setting the material sets the material attributes also. + // TODO: decide if this is necessary -- the simulator does this. MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false); Friction = matAttrib.friction; Restitution = matAttrib.restitution; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index f0858caa81..ce4c3da2e1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -802,6 +802,7 @@ public class BSPrim : BSPhysObject // isSolid: other objects bounce off of this object // isVolumeDetect: other objects pass through but can generate collisions // collisionEvents: whether this object returns collision events + // NOTE: overloaded by BSPrimLinkable to also update linkset physical parameters. public virtual void UpdatePhysicalParameters() { if (!PhysBody.HasPhysicalBody) @@ -1532,6 +1533,8 @@ public class BSPrim : BSPhysObject // The physics engine says that properties have updated. Update same and inform // the world that things have changed. + // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimLinkable which modifies updates from root and children prims. + // NOTE: BSPrim.UpdateProperties is overloaded by BSPrimDisplaced which handles mapping physical position to simulator position. public override void UpdateProperties(EntityProperties entprop) { // Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator. @@ -1567,8 +1570,6 @@ public class BSPrim : BSPhysObject LastEntityProperties = CurrentEntityProperties; CurrentEntityProperties = entprop; - // Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims. - PhysScene.PostUpdate(this); } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs index a11bca0ba1..35d5a08b8b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs @@ -59,6 +59,7 @@ public class BSPrimDisplaced : BSPrim // are converted into simulator origin values before being passed to the base // class. + // PositionDisplacement is the vehicle relative distance from the root prim position to the center-of-mass. public virtual OMV.Vector3 PositionDisplacement { get; set; } public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, @@ -72,49 +73,77 @@ public class BSPrimDisplaced : BSPrim // Does not clear the displacement set by the user. public void ClearDisplacement() { - SetEffectiveCenterOfMassDisplacement(OMV.Vector3.Zero); + if (UserSetCenterOfMassDisplacement.HasValue) + PositionDisplacement = (OMV.Vector3)UserSetCenterOfMassDisplacement; + else + PositionDisplacement = OMV.Vector3.Zero; } // Set this sets and computes the displacement from the passed prim to the center-of-mass. // A user set value for center-of-mass overrides whatever might be passed in here. // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates). + // Returns the relative offset from the root position to the center-of-mass. // Called at taint time. - public virtual void SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) + public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) { + PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement"); Vector3 comDisp; if (UserSetCenterOfMassDisplacement.HasValue) comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; else comDisp = centerOfMassDisplacement; + // Eliminate any jitter caused be very slight differences in masses and positions if (comDisp.ApproxEquals(Vector3.Zero, 0.01f) ) comDisp = Vector3.Zero; DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}", LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp); - if ( comDisp != PositionDisplacement ) + if ( !comDisp.ApproxEquals(PositionDisplacement, 0.01f) ) { // Displacement setting is changing. // The relationship between the physical object and simulated object must be aligned. PositionDisplacement = comDisp; this.ForcePosition = RawPosition; } + + return PositionDisplacement; } + // 'ForcePosition' is the one way to set the physical position of the body in the physics engine. + // Displace the simulator idea of position (center of root prim) to the physical position. public override Vector3 ForcePosition { - get { return base.ForcePosition; } + get { + OMV.Vector3 physPosition = base.ForcePosition; + if (PositionDisplacement != OMV.Vector3.Zero) + { + // If there is some displacement, return the physical position (center-of-mass) + // location minus the displacement to give the center of the root prim. + OMV.Vector3 displacement = PositionDisplacement * ForceOrientation; + DetailLog("{0},BSPrimDisplaced.ForcePosition,get,physPos={1},disp={2},simPos={3}", + LocalID, physPosition, displacement, physPosition - displacement); + physPosition -= displacement; + } + return physPosition; + } set { if (PositionDisplacement != OMV.Vector3.Zero) { - // The displacement is always relative to the vehicle so, when setting position, - // the caller means to set the position of the root prim. - // This offsets the setting value to the center-of-mass and sends that to the - // physics engine. - OMV.Vector3 displacedPos = value - (PositionDisplacement * RawOrientation); - DetailLog("{0},BSPrimDisplaced.ForcePosition,val={1},disp={2},newPos={3}", LocalID, value, PositionDisplacement, displacedPos); - base.ForcePosition = displacedPos; + // This value is the simulator's idea of where the prim is: the center of the root prim + RawPosition = value; + + // Move the passed root prim postion to the center-of-mass position and set in the physics engine. + OMV.Vector3 displacement = PositionDisplacement * RawOrientation; + OMV.Vector3 displacedPos = RawPosition + displacement; + DetailLog("{0},BSPrimDisplaced.ForcePosition,set,simPos={1},disp={2},physPos={3}", + LocalID, RawPosition, displacement, displacedPos); + if (PhysBody.HasPhysicalBody) + { + PhysScene.PE.SetTranslation(PhysBody, displacedPos, RawOrientation); + ActivateIfPhysical(false); + } } else { @@ -143,10 +172,11 @@ public class BSPrimDisplaced : BSPrim // These physical location must be back converted to be centered around the displaced // root shape. - // The root position is the reported position displaced by the rotated displacement. - OMV.Vector3 displacedPos = entprop.Position + (PositionDisplacement * entprop.Rotation); - DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},newPos={3}", - LocalID, entprop.Position, PositionDisplacement, displacedPos); + // Move the returned center-of-mass location to the root prim location. + OMV.Vector3 displacement = PositionDisplacement * entprop.Rotation; + OMV.Vector3 displacedPos = entprop.Position - displacement; + DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},simPos={3}", + LocalID, entprop.Position, displacement, displacedPos); entprop.Position = displacedPos; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index 70586466cf..1fbcfcc6f0 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -160,10 +160,13 @@ public class BSPrimLinkable : BSPrimDisplaced protected override void MakeDynamic(bool makeStatic) { base.MakeDynamic(makeStatic); - if (makeStatic) - Linkset.MakeStatic(this); - else - Linkset.MakeDynamic(this); + if (Linkset != null) // null can happen during initialization + { + if (makeStatic) + Linkset.MakeStatic(this); + else + Linkset.MakeDynamic(this); + } } // Body is being taken apart. Remove physical dependencies and schedule a rebuild. diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 4a89fe2dc4..4a3104ee81 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -919,54 +919,72 @@ ; ## Joint support ; ## - ; if you would like physics joints to be enabled through a special naming convention in the client, set this to true. - ; (see NINJA Physics documentation, http://opensimulator.org/wiki/NINJA_Physics) - ; default is false + ; If you would like physics joints to be enabled through a special naming + ; convention in the client, set this to true. + ; (See NINJA Physics documentation, http://opensimulator.org/wiki/NINJA_Physics) + ; Default is false ;use_NINJA_physics_joints = true ; ## ; ## additional meshing options ; ## - ; physical collision mesh proxies are normally created for complex prim shapes, and collisions for simple boxes and - ; spheres are computed algorithmically. If you would rather have mesh proxies for simple prims, you can set this to - ; true. Note that this will increase memory usage and region startup time. Default is false. + ; Physical collision mesh proxies are normally created for complex prim shapes, + ; and collisions for simple boxes and spheres are computed algorithmically. + ; If you would rather have mesh proxies for simple prims, you can set this to + ; true. Note that this will increase memory usage and region startup time. + ; Default is false. ;force_simple_prim_meshing = true [BulletSim] - ; All the BulletSim parameters can be displayed with the console command "physics get all" - ; and all are defined in the source file OpenSim/Regions/Physics/BulletSPlugin/BSParam.cs. + ; All the BulletSim parameters can be displayed with the console command + ; "physics get all" and all are defined in the source file + ; OpenSim/Regions/Physics/BulletSPlugin/BSParam.cs. - ; There are two bullet physics libraries, bulletunmanaged is the default and is a native c++ dll - ; bulletxna is a managed C# dll. They have comparible functionality but the c++ one is much faster. + ; There are two bullet physics libraries, bulletunmanaged is the default and is a + ; native c++ dll bulletxna is a managed C# dll. They have comparible functionality + ; but the c++ one is much faster. BulletEngine = "bulletunmanaged" ; BulletEngine = "bulletxna" - ; Terrain Implementation - TerrainImplementation = 1 ; 0=Heightfield, 1=mesh - ; For mesh terrain, the detail of the created mesh. '1' gives 256x256 (heightfield resolution). '2' - ; gives 512x512. Etc. Cannot be larger than '4'. Higher magnification uses lots of memory. + ; BulletSim can run on its own thread independent of the simulator's heartbeat + ; thread. Enabling this will nto let the physics engine slow down avatar movement, etc. + UseSeparatePhysicsThread = false + + ; Terrain implementation can use either Bullet's heightField or BulletSim can build + ; a mesh. 0=heightField, 1=mesh + TerrainImplementation = 1 + ; For mesh terrain, the detail of the created mesh. '1' gives 256x256 (heightfield + ; resolution). '2' gives 512x512. Etc. Cannot be larger than '4'. Higher + ; magnification uses lots of memory. TerrainMeshMagnification = 2 - ; Avatar physics height adjustments. http://opensimulator.org/wiki/BulletSim#Adjusting_Avatar_Height + ; Avatar physics height adjustments. + ; http://opensimulator.org/wiki/BulletSim#Adjusting_Avatar_Height AvatarHeightLowFudge = -0.2 ; Adjustment at low end of height range AvatarHeightMidFudge = 0.1 ; Adjustment at mid point of avatar height range AvatarHeightHighFudge = 0.1 ; Adjustment at high end of height range ; Default linkset implmentation - ; 'Constraint' uses physics constraints to hold linkset together. 'Compound' builds a compound - ; shape from the children shapes to create a single physical shape. 'Compound' uses a lot less CPU time. + ; 'Constraint' uses physics constraints to hold linkset together. 'Compound' + ; builds a compound shape from the children shapes to create a single physical + ; shape. 'Compound' uses a lot less CPU time. LinkImplementation = 1 ; 0=constraint, 1=compound + ; If 'true', offset a linkset's origin based on mass of linkset parts. + LinksetOffsetCenterOfMass = false + ; If 'true', turn scuplties into meshes MeshSculptedPrim = true ; If 'true', force simple prims (box and sphere) to be meshed - ; If 'false', the Bullet native special case shape is used for square rectangles and even dimensioned spheres + ; If 'false', the Bullet native special case shape is used for square rectangles + ; and even dimensioned spheres. ForceSimplePrimMeshing = false ; If 'true', when creating meshes, remove all triangles that have two equal vertexes. - ; Happens often in sculpties. If turned off, there will be some doorways that cannot be walked through. + ; Happens often in sculpties. If turned off, there will be some doorways + ; that cannot be walked through. ShouldRemoveZeroWidthTriangles = true ; If 'true', use convex hull definition in mesh asset if present. From d838f15d97d5ae400af86aa52c9ea68f0ba299bb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sat, 6 Jul 2013 09:53:30 -0700 Subject: [PATCH 16/93] Add implementations for llSetVelocity and llSetAngularVelocity. --- .../Shared/Api/Implementation/LSL_Api.cs | 26 +++++++++++++++++++ .../Shared/Api/Interface/ILSL_Api.cs | 2 ++ .../Shared/Api/Runtime/LSL_Stub.cs | 10 +++++++ 3 files changed, 38 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c0b837393b..34e2b4d9f4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2382,6 +2382,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return force; } + public void llSetVelocity(LSL_Vector velocity, int local) + { + m_host.AddScriptLPS(1); + + if (!m_host.ParentGroup.IsDeleted) + { + if (local != 0) + velocity *= llGetRot(); + + m_host.ParentGroup.RootPart.Velocity = velocity; + } + } + + public void llSetAngularVelocity(LSL_Vector angularVelocity, int local) + { + m_host.AddScriptLPS(1); + + if (!m_host.ParentGroup.IsDeleted) + { + if (local != 0) + angularVelocity *= llGetRot(); + + m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity; + } + } + public LSL_Integer llTarget(LSL_Vector position, double range) { m_host.AddScriptLPS(1); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index ff13ee6144..340edb3ff5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -342,6 +342,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetDamage(double damage); void llSetForce(LSL_Vector force, int local); void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local); + void llSetVelocity(LSL_Vector velocity, int local); + void llSetAngularVelocity(LSL_Vector angularVelocity, int local); void llSetHoverHeight(double height, int water, double tau); void llSetInventoryPermMask(string item, int mask, int value); void llSetLinkAlpha(int linknumber, double alpha, int face); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 87cc342c17..7cd17e7bad 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1548,6 +1548,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetForceAndTorque(force, torque, local); } + public void llSetVelocity(LSL_Vector force, int local) + { + m_LSL_Functions.llSetVelocity(force, local); + } + + public void llSetAngularVelocity(LSL_Vector force, int local) + { + m_LSL_Functions.llSetAngularVelocity(force, local); + } + public void llSetHoverHeight(double height, int water, double tau) { m_LSL_Functions.llSetHoverHeight(height, water, tau); From b29a09ab8e4040cc09f8021f638d7604f2372bad Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 6 Jul 2013 15:17:55 -0700 Subject: [PATCH 17/93] Simina activity detector was too eager. Disabled it in case simian is not being used. --- .../Connectors/SimianGrid/SimianPresenceServiceConnector.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 7bb06fb451..0a39088fb3 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -65,7 +65,7 @@ namespace OpenSim.Services.Connectors.SimianGrid public void PostInitialise() { } public void Close() { } - public SimianPresenceServiceConnector() { m_activityDetector = new SimianActivityDetector(this); } + public SimianPresenceServiceConnector() { } public string Name { get { return "SimianPresenceServiceConnector"; } } public void AddRegion(Scene scene) { @@ -121,6 +121,7 @@ namespace OpenSim.Services.Connectors.SimianGrid if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) serviceUrl = serviceUrl + '/'; m_serverUrl = serviceUrl; + m_activityDetector = new SimianActivityDetector(this); m_Enabled = true; } } From 9b75d757241e87408c50b1f92996bf667960c348 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 6 Jul 2013 16:51:14 -0700 Subject: [PATCH 18/93] WARNING: BRUTE FORCE DEBUG AGAIN. AVOID USING THIS COMMIT --- .../Framework/UserManagement/UserManagementModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index a7cbc8fe3c..11227ef592 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -521,6 +521,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement lock (m_UserCache) m_UserCache.Remove(id); m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData, oldUser.HomeURL); + Util.PrintCallStack(); + } else { @@ -555,7 +557,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } catch (UriFormatException) { - m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); + m_log.DebugFormat("[SCENE]: Unable to parse Uri {0} from {1}", parts[0], creatorData); user.LastName = "@unknown"; } } From 1dd3a0bc576b04e8989e8ac16e96aff024c0d6cd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 6 Jul 2013 17:29:19 -0700 Subject: [PATCH 19/93] MORE DEBUG. DON"T USE THIS. --- .../Inventory/RemoteXInventoryServiceConnector.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 70ba9448be..8f41355d22 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -201,12 +201,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory List items = new List(invCol.Items); if (items != null && items.Count > 0) - Util.FireAndForget(delegate - { + //Util.FireAndForget(delegate + //{ foreach (InventoryItemBase item in items) if (!string.IsNullOrEmpty(item.CreatorData)) UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); - }); + //}); } return invCol; From 391633c072792fc36a188d6fa88e994fa150807d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 6 Jul 2013 18:02:17 -0700 Subject: [PATCH 20/93] Some more fixes on strange behaviors of Unknown User, esp. related to large messy inventories and esp. related to kokua --- .../UserManagement/UserManagementModule.cs | 5 ++-- .../RemoteXInventoryServiceConnector.cs | 25 ++++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 11227ef592..74608b34e6 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -514,9 +514,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement return; } - //try update unknown users - //and creator's home URL's - if ((oldUser.FirstName == "Unknown" && !creatorData.Contains("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith(oldUser.HomeURL))) + //try update unknown users, but don't update anyone else + if (oldUser.FirstName == "Unknown" && !creatorData.Contains("Unknown")) { lock (m_UserCache) m_UserCache.Remove(id); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 8f41355d22..7f78076335 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -195,19 +195,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory { InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); - if (invCol != null && UserManager != null) - { - // Protect ourselves against the caller subsequently modifying the items list - List items = new List(invCol.Items); + // Commenting this for now, because it's causing more grief than good + //if (invCol != null && UserManager != null) + //{ + // // Protect ourselves against the caller subsequently modifying the items list + // List items = new List(invCol.Items); - if (items != null && items.Count > 0) - //Util.FireAndForget(delegate - //{ - foreach (InventoryItemBase item in items) - if (!string.IsNullOrEmpty(item.CreatorData)) - UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); - //}); - } + // if (items != null && items.Count > 0) + // //Util.FireAndForget(delegate + // //{ + // foreach (InventoryItemBase item in items) + // if (!string.IsNullOrEmpty(item.CreatorData)) + // UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); + // //}); + //} return invCol; } From 71e26555bd67b8636cf71f71951cfc2aad68a2ee Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 6 Jul 2013 18:16:27 -0700 Subject: [PATCH 21/93] Revert "WARNING: BRUTE FORCE DEBUG AGAIN. AVOID USING THIS COMMIT" This reverts commit 9b75d757241e87408c50b1f92996bf667960c348. --- .../Framework/UserManagement/UserManagementModule.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 74608b34e6..524d1593ff 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -520,8 +520,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement lock (m_UserCache) m_UserCache.Remove(id); m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData, oldUser.HomeURL); - Util.PrintCallStack(); - } else { @@ -556,7 +554,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } catch (UriFormatException) { - m_log.DebugFormat("[SCENE]: Unable to parse Uri {0} from {1}", parts[0], creatorData); + m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); user.LastName = "@unknown"; } } From 803e5498b09c241a8bab8e8deeeff3a259766c2d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 6 Jul 2013 18:27:03 -0700 Subject: [PATCH 22/93] A little more debug --- OpenSim/Services/UserAccountService/GridUserService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs index fa9a4a8481..b1cdd451b7 100644 --- a/OpenSim/Services/UserAccountService/GridUserService.cs +++ b/OpenSim/Services/UserAccountService/GridUserService.cs @@ -156,7 +156,7 @@ namespace OpenSim.Services.UserAccountService public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) { - //m_log.DebugFormat("[Grid User Service]: SetLastPosition for {0}", userID); + m_log.DebugFormat("[GRID USER SERVICE]: SetLastPosition for {0}", userID); GridUserData d = m_Database.Get(userID); if (d == null) { From 128667735291234c4655216af0fdfc6f07355e20 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 6 Jul 2013 18:37:54 -0700 Subject: [PATCH 23/93] Try to normalize the creatorData of scene object parts with the trailing '/'. What a nightmare this '/' is! --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 482d958302..f287a34f14 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -505,7 +505,11 @@ namespace OpenSim.Region.Framework.Scenes CreatorID = uuid; } if (parts.Length >= 2) + { CreatorData = parts[1]; + if (!CreatorData.EndsWith("/")) + CreatorData += "/"; + } if (parts.Length >= 3) name = parts[2]; From 70d24a654b8eb0257ca927327d51bd0e47f85259 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 7 Jul 2013 05:46:24 -0700 Subject: [PATCH 24/93] BulletSim: rename position and orientation variables to remove the inconsistant use of Raw* and _* conventions. --- .../Physics/BulletSPlugin/BSCharacter.cs | 78 ++++++++--------- .../Physics/BulletSPlugin/BSPhysObject.cs | 4 +- .../Region/Physics/BulletSPlugin/BSPrim.cs | 84 ++++++++----------- 3 files changed, 71 insertions(+), 95 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 5ef69925f8..c9e3ca0ead 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs @@ -43,12 +43,10 @@ public sealed class BSCharacter : BSPhysObject private OMV.Vector3 _size; private bool _grabbed; private bool _selected; - private OMV.Vector3 _position; private float _mass; private float _avatarVolume; private float _collisionScore; private OMV.Vector3 _acceleration; - private OMV.Quaternion _orientation; private int _physicsActorType; private bool _isPhysical; private bool _flying; @@ -70,10 +68,10 @@ public sealed class BSCharacter : BSPhysObject : base(parent_scene, localID, avName, "BSCharacter") { _physicsActorType = (int)ActorTypes.Agent; - _position = pos; + RawPosition = pos; _flying = isFlying; - _orientation = OMV.Quaternion.Identity; + RawOrientation = OMV.Quaternion.Identity; RawVelocity = OMV.Vector3.Zero; _buoyancy = ComputeBuoyancyFromFlying(isFlying); Friction = BSParam.AvatarStandingFriction; @@ -133,7 +131,7 @@ public sealed class BSCharacter : BSPhysObject PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody); ZeroMotion(true); - ForcePosition = _position; + ForcePosition = RawPosition; // Set the velocity if (m_moveActor != null) @@ -272,38 +270,33 @@ public sealed class BSCharacter : BSPhysObject public override void LockAngularMotion(OMV.Vector3 axis) { return; } - public override OMV.Vector3 RawPosition - { - get { return _position; } - set { _position = value; } - } public override OMV.Vector3 Position { get { // Don't refetch the position because this function is called a zillion times - // _position = PhysicsScene.PE.GetObjectPosition(Scene.World, LocalID); - return _position; + // RawPosition = PhysicsScene.PE.GetObjectPosition(Scene.World, LocalID); + return RawPosition; } set { - _position = value; + RawPosition = value; PhysScene.TaintedObject("BSCharacter.setPosition", delegate() { - DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); PositionSanityCheck(); - ForcePosition = _position; + ForcePosition = RawPosition; }); } } public override OMV.Vector3 ForcePosition { get { - _position = PhysScene.PE.GetPosition(PhysBody); - return _position; + RawPosition = PhysScene.PE.GetPosition(PhysBody); + return RawPosition; } set { - _position = value; + RawPosition = value; if (PhysBody.HasPhysicalBody) { - PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); + PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation); } } } @@ -331,16 +324,16 @@ public sealed class BSCharacter : BSPhysObject float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition); if (Position.Z < terrainHeight) { - DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight); - _position.Z = terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters; + DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, RawPosition, terrainHeight); + RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters); ret = true; } if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) { - float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position); + float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition); if (Position.Z < waterHeight) { - _position.Z = waterHeight; + RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, waterHeight); ret = true; } } @@ -360,8 +353,8 @@ public sealed class BSCharacter : BSPhysObject // just assign to "Position" because of potential call loops. PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() { - DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); - ForcePosition = _position; + DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); + ForcePosition = RawPosition; }); ret = true; } @@ -466,19 +459,14 @@ public sealed class BSCharacter : BSPhysObject get { return _acceleration; } set { _acceleration = value; } } - public override OMV.Quaternion RawOrientation - { - get { return _orientation; } - set { _orientation = value; } - } public override OMV.Quaternion Orientation { - get { return _orientation; } + get { return RawOrientation; } set { // Orientation is set zillions of times when an avatar is walking. It's like // the viewer doesn't trust us. - if (_orientation != value) + if (RawOrientation != value) { - _orientation = value; + RawOrientation = value; PhysScene.TaintedObject("BSCharacter.setOrientation", delegate() { // Bullet assumes we know what we are doing when forcing orientation @@ -486,10 +474,10 @@ public sealed class BSCharacter : BSPhysObject // This forces rotation to be only around the Z axis and doesn't change any of the other axis. // This keeps us from flipping the capsule over which the veiwer does not understand. float oRoll, oPitch, oYaw; - _orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw); + RawOrientation.GetEulerAngles(out oRoll, out oPitch, out oYaw); OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw); // DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}", - // LocalID, _orientation, OMV.Vector3.UnitX * _orientation, + // LocalID, RawOrientation, OMV.Vector3.UnitX * RawOrientation, // trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation); ForceOrientation = trimmedOrientation; }); @@ -501,16 +489,16 @@ public sealed class BSCharacter : BSPhysObject { get { - _orientation = PhysScene.PE.GetOrientation(PhysBody); - return _orientation; + RawOrientation = PhysScene.PE.GetOrientation(PhysBody); + return RawOrientation; } set { - _orientation = value; + RawOrientation = value; if (PhysBody.HasPhysicalBody) { - // _position = PhysicsScene.PE.GetPosition(BSBody); - PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); + // RawPosition = PhysicsScene.PE.GetPosition(BSBody); + PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation); } } } @@ -723,9 +711,9 @@ public sealed class BSCharacter : BSPhysObject { // Don't change position if standing on a stationary object. if (!IsStationary) - _position = entprop.Position; + RawPosition = entprop.Position; - _orientation = entprop.Rotation; + RawOrientation = entprop.Rotation; // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar // and will send agent updates to the clients if velocity changes by more than @@ -740,8 +728,8 @@ public sealed class BSCharacter : BSPhysObject // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. if (PositionSanityCheck(true)) { - DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position); - entprop.Position = _position; + DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, RawPosition); + entprop.Position = RawPosition; } // remember the current and last set values @@ -755,7 +743,7 @@ public sealed class BSCharacter : BSPhysObject // base.RequestPhysicsterseUpdate(); DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", - LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity); + LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity); } } } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 738e2d0689..a41eaf8617 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -197,10 +197,10 @@ public abstract class BSPhysObject : PhysicsActor // Update the physical location and motion of the object. Called with data from Bullet. public abstract void UpdateProperties(EntityProperties entprop); - public abstract OMV.Vector3 RawPosition { get; set; } + public virtual OMV.Vector3 RawPosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; } - public abstract OMV.Quaternion RawOrientation { get; set; } + public virtual OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; } public OMV.Vector3 RawVelocity { get; set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index ce4c3da2e1..d43448e50d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs @@ -51,12 +51,8 @@ public class BSPrim : BSPhysObject private bool _isSelected; private bool _isVolumeDetect; - // _position is what the simulator thinks the positions of the prim is. - private OMV.Vector3 _position; - private float _mass; // the mass of this object private OMV.Vector3 _acceleration; - private OMV.Quaternion _orientation; private int _physicsActorType; private bool _isPhysical; private bool _flying; @@ -88,10 +84,10 @@ public class BSPrim : BSPhysObject { // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); _physicsActorType = (int)ActorTypes.Prim; - _position = pos; + RawPosition = pos; _size = size; Scale = size; // prims are the size the user wants them to be (different for BSCharactes). - _orientation = rotation; + RawOrientation = rotation; _buoyancy = 0f; RawVelocity = OMV.Vector3.Zero; _rotationalVelocity = OMV.Vector3.Zero; @@ -270,46 +266,42 @@ public class BSPrim : BSPhysObject return; } - public override OMV.Vector3 RawPosition - { - get { return _position; } - set { _position = value; } - } public override OMV.Vector3 Position { get { // don't do the GetObjectPosition for root elements because this function is called a zillion times. - // _position = ForcePosition; - return _position; + // RawPosition = ForcePosition; + return RawPosition; } set { // If the position must be forced into the physics engine, use ForcePosition. // All positions are given in world positions. - if (_position == value) + if (RawPosition == value) { - DetailLog("{0},BSPrim.setPosition,call,positionNotChanging,pos={1},orient={2}", LocalID, _position, _orientation); + DetailLog("{0},BSPrim.setPosition,call,positionNotChanging,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); return; } - _position = value; + RawPosition = value; PositionSanityCheck(false); PhysScene.TaintedObject("BSPrim.setPosition", delegate() { - DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); - ForcePosition = _position; + DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation); + ForcePosition = RawPosition; }); } } + // NOTE: overloaded by BSPrimDisplaced to handle offset for center-of-gravity. public override OMV.Vector3 ForcePosition { get { - _position = PhysScene.PE.GetPosition(PhysBody); - return _position; + RawPosition = PhysScene.PE.GetPosition(PhysBody); + return RawPosition; } set { - _position = value; + RawPosition = value; if (PhysBody.HasPhysicalBody) { - PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); + PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation); ActivateIfPhysical(false); } } @@ -343,10 +335,10 @@ public class BSPrim : BSPhysObject float targetHeight = terrainHeight + (Size.Z / 2f); // If the object is below ground it just has to be moved up because pushing will // not get it through the terrain - _position.Z = targetHeight; + RawPosition = new OMV.Vector3(RawPosition.X, RawPosition.Y, targetHeight); if (inTaintTime) { - ForcePosition = _position; + ForcePosition = RawPosition; } // If we are throwing the object around, zero its other forces ZeroMotion(inTaintTime); @@ -355,7 +347,7 @@ public class BSPrim : BSPhysObject if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) { - float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position); + float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition); // TODO: a floating motor so object will bob in the water if (Math.Abs(RawPosition.Z - waterHeight) > 0.1f) { @@ -364,7 +356,7 @@ public class BSPrim : BSPhysObject // Apply upforce and overcome gravity. OMV.Vector3 correctionForce = upForce - PhysScene.DefaultGravity; - DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, _position, upForce, correctionForce); + DetailLog("{0},BSPrim.PositionSanityCheck,applyForce,pos={1},upForce={2},correctionForce={3}", LocalID, RawPosition, upForce, correctionForce); AddForce(correctionForce, false, inTaintTime); ret = true; } @@ -383,11 +375,11 @@ public class BSPrim : BSPhysObject uint wayOutThere = Constants.RegionSize * Constants.RegionSize; // There have been instances of objects getting thrown way out of bounds and crashing // the border crossing code. - if ( _position.X < -Constants.RegionSize || _position.X > wayOutThere - || _position.Y < -Constants.RegionSize || _position.Y > wayOutThere - || _position.Z < -Constants.RegionSize || _position.Z > wayOutThere) + if ( RawPosition.X < -Constants.RegionSize || RawPosition.X > wayOutThere + || RawPosition.Y < -Constants.RegionSize || RawPosition.Y > wayOutThere + || RawPosition.Z < -Constants.RegionSize || RawPosition.Z > wayOutThere) { - _position = new OMV.Vector3(10, 10, 50); + RawPosition = new OMV.Vector3(10, 10, 50); ZeroMotion(inTaintTime); ret = true; } @@ -713,23 +705,19 @@ public class BSPrim : BSPhysObject get { return _acceleration; } set { _acceleration = value; } } - public override OMV.Quaternion RawOrientation - { - get { return _orientation; } - set { _orientation = value; } - } + public override OMV.Quaternion Orientation { get { - return _orientation; + return RawOrientation; } set { - if (_orientation == value) + if (RawOrientation == value) return; - _orientation = value; + RawOrientation = value; PhysScene.TaintedObject("BSPrim.setOrientation", delegate() { - ForceOrientation = _orientation; + ForceOrientation = RawOrientation; }); } } @@ -738,14 +726,14 @@ public class BSPrim : BSPhysObject { get { - _orientation = PhysScene.PE.GetOrientation(PhysBody); - return _orientation; + RawOrientation = PhysScene.PE.GetOrientation(PhysBody); + return RawOrientation; } set { - _orientation = value; + RawOrientation = value; if (PhysBody.HasPhysicalBody) - PhysScene.PE.SetTranslation(PhysBody, _position, _orientation); + PhysScene.PE.SetTranslation(PhysBody, RawPosition, RawOrientation); } } public override int PhysicsActorType { @@ -889,7 +877,7 @@ public class BSPrim : BSPhysObject // PhysicsScene.PE.ClearAllForces(BSBody); // For good measure, make sure the transform is set through to the motion state - ForcePosition = _position; + ForcePosition = RawPosition; ForceVelocity = RawVelocity; ForceRotationalVelocity = _rotationalVelocity; @@ -1543,8 +1531,8 @@ public class BSPrim : BSPhysObject // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG // Assign directly to the local variables so the normal set actions do not happen - _position = entprop.Position; - _orientation = entprop.Rotation; + RawPosition = entprop.Position; + RawOrientation = entprop.Rotation; // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be // very sensitive to velocity changes. if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold)) @@ -1557,13 +1545,13 @@ public class BSPrim : BSPhysObject // The sanity check can change the velocity and/or position. if (PositionSanityCheck(true /* inTaintTime */ )) { - entprop.Position = _position; + entprop.Position = RawPosition; entprop.Velocity = RawVelocity; entprop.RotationalVelocity = _rotationalVelocity; entprop.Acceleration = _acceleration; } - OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG + OMV.Vector3 direction = OMV.Vector3.UnitX * RawOrientation; // DEBUG DEBUG DEBUG DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction); // remember the current and last set values From 6026759406f20cb89cbc62fcfc3af324c61c5ab0 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 7 Jul 2013 05:47:41 -0700 Subject: [PATCH 25/93] BulletSim: fix jumping up and down of linksets when center-of-mass was enabled. Didn't effect the physical position but the viewer saw the linkset jumping between its simulator center and its physical center. --- OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs index 35d5a08b8b..2eb144049f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimDisplaced.cs @@ -23,11 +23,6 @@ * 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. - * - * The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial - * are Copyright (c) 2009 Linden Research, Inc and are used under their license - * of Creative Commons Attribution-Share Alike 3.0 - * (http://creativecommons.org/licenses/by-sa/3.0/). */ using System; @@ -115,7 +110,7 @@ public class BSPrimDisplaced : BSPrim public override Vector3 ForcePosition { get { - OMV.Vector3 physPosition = base.ForcePosition; + OMV.Vector3 physPosition = PhysScene.PE.GetPosition(PhysBody); if (PositionDisplacement != OMV.Vector3.Zero) { // If there is some displacement, return the physical position (center-of-mass) @@ -125,6 +120,7 @@ public class BSPrimDisplaced : BSPrim LocalID, physPosition, displacement, physPosition - displacement); physPosition -= displacement; } + RawPosition = physPosition; return physPosition; } set From bbc40fab620dd61e500d8f74fa1b0d64ecc7c3b6 Mon Sep 17 00:00:00 2001 From: Vegaslon Date: Sat, 6 Jul 2013 12:53:20 -0400 Subject: [PATCH 26/93] BulletSim: Different Implementation of Angular Deflection for vehicles, Activates it again and fixes problem with fighting with vertical attractor removing wobble of forward axis. Comments on testing welcome, May require adjustments of this force or other forces after this commit, exact tweaking to come after testing on other hardware. Signed-off-by: Robert Adams --- .../Physics/BulletSPlugin/BSDynamics.cs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index c27d3f04a4..82fe267c56 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -144,7 +144,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin public void SetupVehicleDebugging() { enableAngularVerticalAttraction = true; - enableAngularDeflection = false; + enableAngularDeflection = true; enableAngularBanking = true; if (BSParam.VehicleDebuggingEnable) { @@ -173,7 +173,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin switch (pParam) { case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: - m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); + m_angularDeflectionEfficiency = ClampInRange(0f, pValue, 1f); break; case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); @@ -1512,11 +1512,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // in that direction. // TODO: implement reference frame. public void ComputeAngularDeflection() - { - // Since angularMotorUp and angularDeflection are computed independently, they will calculate - // approximately the same X or Y correction. When added together (when contributions are combined) - // this creates an over-correction and then wabbling as the target is overshot. - // TODO: rethink how the different correction computations inter-relate. + { if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) { @@ -1531,10 +1527,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin // The direction the vehicle is pointing Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; - pointingDirection.Normalize(); + //Predict where the Vehicle will be pointing after AngularVelocity change is applied. This will keep + // from overshooting and allow this correction to merge with the Vertical Attraction peacefully. + Vector3 predictedPointingDirection = pointingDirection * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f); + predictedPointingDirection.Normalize(); // The difference between what is and what should be. - Vector3 deflectionError = movingDirection - pointingDirection; + // Vector3 deflectionError = movingDirection - predictedPointingDirection; + Vector3 deflectionError = Vector3.Cross(movingDirection, predictedPointingDirection); // Don't try to correct very large errors (not our job) // if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = PIOverTwo * Math.Sign(deflectionError.X); @@ -1547,15 +1547,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); // Scale the correction by recovery timescale and efficiency - deflectContributionV = (-deflectionError) * m_angularDeflectionEfficiency; - deflectContributionV /= m_angularDeflectionTimescale; - - VehicleRotationalVelocity += deflectContributionV * VehicleOrientation; + // Not modeling a spring so clamp the scale to no more then the arc + deflectContributionV = (-deflectionError) * ClampInRange(0, m_angularDeflectionEfficiency/m_angularDeflectionTimescale,1f); + //deflectContributionV /= m_angularDeflectionTimescale; + // VehicleRotationalVelocity += deflectContributionV * VehicleOrientation; + VehicleRotationalVelocity += deflectContributionV; VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", ControllingPrim.LocalID, movingDirection, pointingDirection, deflectionError, deflectContributionV); - VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", - ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); + VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3},PredictedPointingDir={4}", + ControllingPrim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale, predictedPointingDirection); } } From bbb9af363de5cabf44dec2b5aba6fb386a1e7fad Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 7 Jul 2013 20:43:42 -0700 Subject: [PATCH 27/93] Print out caller IP when unusual requests are received. --- OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 71a9e6fa41..b01de7aa6b 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -107,7 +107,7 @@ namespace OpenSim.Server.Handlers.Simulation } else { - m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message", method); + m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message (caller is {1})", method, Util.GetCallerIP(request)); responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed; responsedata["str_response_string"] = "Method not allowed"; From c66a9a08e4fed5cc675aac8a7a2999549049d79c Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 8 Jul 2013 08:41:18 -0700 Subject: [PATCH 28/93] Placed a throttle on UserManagementModule for name lookups. Singularity apparently is flooding the sims with name requests. --- .../UserManagement/HGUserManagementModule.cs | 2 +- .../UserManagement/UserManagementModule.cs | 66 ++++++++++++++++--- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs index ad3cf15ff3..245c808b6c 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if (umanmod == Name) { m_Enabled = true; - RegisterConsoleCmds(); + Init(); m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); } } diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 524d1593ff..a5280939fc 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -28,9 +28,11 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Threading; using OpenSim.Framework; using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; using OpenSim.Region.ClientStack.LindenUDP; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; @@ -57,6 +59,10 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement // The cache protected Dictionary m_UserCache = new Dictionary(); + // Throttle the name requests + private OpenSim.Framework.BlockingQueue m_RequestQueue = new OpenSim.Framework.BlockingQueue(); + + #region ISharedRegionModule public void Initialise(IConfigSource config) @@ -65,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if (umanmod == Name) { m_Enabled = true; - RegisterConsoleCmds(); + Init(); m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); } } @@ -160,16 +166,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement } else { - string[] names; - bool foundRealName = TryGetUserNames(uuid, out names); + NameRequest request = new NameRequest(remote_client, uuid); + m_RequestQueue.Enqueue(request); - if (names.Length == 2) - { - if (!foundRealName) - m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], uuid, remote_client.Name); - - remote_client.SendNameReply(uuid, names[0], names[1]); - } } } @@ -596,6 +595,18 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement #endregion IUserManagement + protected void Init() + { + RegisterConsoleCmds(); + Watchdog.StartThread( + ProcessQueue, + "NameRequestThread", + ThreadPriority.BelowNormal, + true, + false); + + } + protected void RegisterConsoleCmds() { MainConsole.Instance.Commands.AddCommand("Users", true, @@ -662,5 +673,40 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement MainConsole.Instance.Output(cdt.ToString()); } + + private void ProcessQueue() + { + while (true) + { + Watchdog.UpdateThread(); + + NameRequest request = m_RequestQueue.Dequeue(); + string[] names; + bool foundRealName = TryGetUserNames(request.uuid, out names); + + if (names.Length == 2) + { + if (!foundRealName) + m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], request.uuid, request.client.Name); + + request.client.SendNameReply(request.uuid, names[0], names[1]); + } + + } + } + } + + class NameRequest + { + public IClientAPI client; + public UUID uuid; + + public NameRequest(IClientAPI c, UUID n) + { + client = c; + uuid = n; + } + } + } \ No newline at end of file From a38c2abae4a5262ec0332426c9721b8718d4e85f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 18:07:04 +0100 Subject: [PATCH 29/93] Make dictionary read/write locking consistent in CapabilitiesModule, rename two dictionary fields to standard m_ format --- .../Framework/Caps/CapabilitiesModule.cs | 132 +++++++++++------- 1 file changed, 83 insertions(+), 49 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index 6ae9448af4..c8b341ba91 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs @@ -57,8 +57,8 @@ namespace OpenSim.Region.CoreModules.Framework /// protected Dictionary m_capsObjects = new Dictionary(); - protected Dictionary capsPaths = new Dictionary(); - protected Dictionary> childrenSeeds + protected Dictionary m_capsPaths = new Dictionary(); + protected Dictionary> m_childrenSeeds = new Dictionary>(); public void Initialise(IConfigSource source) @@ -105,35 +105,42 @@ namespace OpenSim.Region.CoreModules.Framework if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) return; + Caps caps; String capsObjectPath = GetCapsPath(agentId); - if (m_capsObjects.ContainsKey(agentId)) + lock (m_capsObjects) { - Caps oldCaps = m_capsObjects[agentId]; - - m_log.DebugFormat( - "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", - agentId, oldCaps.CapsObjectPath, capsObjectPath); - // This should not happen. The caller code is confused. We need to fix that. - // CAPs can never be reregistered, or the client will be confused. - // Hence this return here. - //return; + if (m_capsObjects.ContainsKey(agentId)) + { + Caps oldCaps = m_capsObjects[agentId]; + + m_log.DebugFormat( + "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", + agentId, oldCaps.CapsObjectPath, capsObjectPath); + // This should not happen. The caller code is confused. We need to fix that. + // CAPs can never be reregistered, or the client will be confused. + // Hence this return here. + //return; + } + + caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, + (MainServer.Instance == null) ? 0: MainServer.Instance.Port, + capsObjectPath, agentId, m_scene.RegionInfo.RegionName); + + m_capsObjects[agentId] = caps; } - Caps caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, - (MainServer.Instance == null) ? 0: MainServer.Instance.Port, - capsObjectPath, agentId, m_scene.RegionInfo.RegionName); - - m_capsObjects[agentId] = caps; - m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); } public void RemoveCaps(UUID agentId) { - if (childrenSeeds.ContainsKey(agentId)) + lock (m_childrenSeeds) { - childrenSeeds.Remove(agentId); + if (m_childrenSeeds.ContainsKey(agentId)) + { + m_childrenSeeds.Remove(agentId); + } } lock (m_capsObjects) @@ -168,16 +175,22 @@ namespace OpenSim.Region.CoreModules.Framework public void SetAgentCapsSeeds(AgentCircuitData agent) { - capsPaths[agent.AgentID] = agent.CapsPath; - childrenSeeds[agent.AgentID] - = ((agent.ChildrenCapSeeds == null) ? new Dictionary() : agent.ChildrenCapSeeds); + lock (m_capsPaths) + m_capsPaths[agent.AgentID] = agent.CapsPath; + + lock (m_childrenSeeds) + m_childrenSeeds[agent.AgentID] + = ((agent.ChildrenCapSeeds == null) ? new Dictionary() : agent.ChildrenCapSeeds); } public string GetCapsPath(UUID agentId) { - if (capsPaths.ContainsKey(agentId)) + lock (m_capsPaths) { - return capsPaths[agentId]; + if (m_capsPaths.ContainsKey(agentId)) + { + return m_capsPaths[agentId]; + } } return null; @@ -186,17 +199,24 @@ namespace OpenSim.Region.CoreModules.Framework public Dictionary GetChildrenSeeds(UUID agentID) { Dictionary seeds = null; - if (childrenSeeds.TryGetValue(agentID, out seeds)) - return seeds; + + lock (m_childrenSeeds) + if (m_childrenSeeds.TryGetValue(agentID, out seeds)) + return seeds; + return new Dictionary(); } public void DropChildSeed(UUID agentID, ulong handle) { Dictionary seeds; - if (childrenSeeds.TryGetValue(agentID, out seeds)) + + lock (m_childrenSeeds) { - seeds.Remove(handle); + if (m_childrenSeeds.TryGetValue(agentID, out seeds)) + { + seeds.Remove(handle); + } } } @@ -204,30 +224,41 @@ namespace OpenSim.Region.CoreModules.Framework { Dictionary seeds; string returnval; - if (childrenSeeds.TryGetValue(agentID, out seeds)) + + lock (m_childrenSeeds) { - if (seeds.TryGetValue(handle, out returnval)) - return returnval; + if (m_childrenSeeds.TryGetValue(agentID, out seeds)) + { + if (seeds.TryGetValue(handle, out returnval)) + return returnval; + } } + return null; } public void SetChildrenSeed(UUID agentID, Dictionary seeds) { //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count); - childrenSeeds[agentID] = seeds; + + lock (m_childrenSeeds) + m_childrenSeeds[agentID] = seeds; } public void DumpChildrenSeeds(UUID agentID) { m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================"); - foreach (KeyValuePair kvp in childrenSeeds[agentID]) + + lock (m_childrenSeeds) { - uint x, y; - Utils.LongToUInts(kvp.Key, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - m_log.Info(" >> "+x+", "+y+": "+kvp.Value); + foreach (KeyValuePair kvp in m_childrenSeeds[agentID]) + { + uint x, y; + Utils.LongToUInts(kvp.Key, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + m_log.Info(" >> "+x+", "+y+": "+kvp.Value); + } } } @@ -236,21 +267,24 @@ namespace OpenSim.Region.CoreModules.Framework StringBuilder caps = new StringBuilder(); caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); - foreach (KeyValuePair kvp in m_capsObjects) + lock (m_capsObjects) { - caps.AppendFormat("** User {0}:\n", kvp.Key); - - for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) + foreach (KeyValuePair kvp in m_capsObjects) { - Uri uri = new Uri(kvp2.Value.ToString()); - caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery); - } + caps.AppendFormat("** User {0}:\n", kvp.Key); - foreach (KeyValuePair kvp3 in kvp.Value.ExternalCapsHandlers) - caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value); + for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) + { + Uri uri = new Uri(kvp2.Value.ToString()); + caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery); + } + + foreach (KeyValuePair kvp3 in kvp.Value.ExternalCapsHandlers) + caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value); + } } MainConsole.Instance.Output(caps.ToString()); } } -} +} \ No newline at end of file From e19defde36ddbd5ff90d8304c6fe3b57110f8078 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 22:03:07 +0100 Subject: [PATCH 30/93] Add "show caps stats by user" and "show caps stats by cap" console commands to print various counts of capability invocation by user and by cap This currently prints caps requests received and handled, so that overload of received compared to handled or deadlock can be detected. This involves making BaseStreamHandler and BaseOutputStream record the ints, which means inheritors should subclass ProcessRequest() instead of Handle() However, existing inheriting classes overriding Handle() will still work, albeit without stats recording. "show caps" becomes "show caps list" to disambiguate between show caps commands --- .../HGGroupsServiceRobustConnector.cs | 2 +- .../Remote/GroupsServiceRobustConnector.cs | 2 +- .../Remote/OfflineIMServiceRobustConnector.cs | 2 +- OpenSim/Capabilities/CapsHandlers.cs | 16 +- .../AvatarPickerSearchHandler.cs | 2 +- .../Handlers/GetTexture/GetTextureHandler.cs | 2 +- OpenSim/Capabilities/LLSDStreamHandler.cs | 2 +- .../Servers/HttpServer/BaseRequestHandler.cs | 4 + .../Servers/HttpServer/BaseStreamHandler.cs | 27 +- .../Servers/HttpServer/BinaryStreamHandler.cs | 2 +- .../HttpServer/Interfaces/IStreamHandler.cs | 15 +- .../HttpServer/RestDeserialiseHandler.cs | 4 +- .../Servers/HttpServer/RestSessionService.cs | 13 +- .../Servers/HttpServer/RestStreamHandler.cs | 2 +- OpenSim/Region/Application/OpenSimBase.cs | 8 +- .../Linden/Caps/RegionConsoleModule.cs | 2 +- .../Avatar/Friends/FriendsRequestHandler.cs | 2 +- .../Framework/Caps/CapabilitiesModule.cs | 234 +++++++++++++++++- .../World/Estate/XEstateRequestHandler.cs | 2 +- .../Framework/Scenes/RegionStatsHandler.cs | 2 +- .../ViewerSupport/DynamicMenuModule.cs | 2 +- .../WorldView/WorldViewRequestHandler.cs | 2 +- .../Asset/AssetServerDeleteHandler.cs | 2 +- .../Handlers/Asset/AssetServerGetHandler.cs | 2 +- .../Handlers/Asset/AssetServerPostHandler.cs | 2 +- .../AuthenticationServerPostHandler.cs | 2 +- .../Authentication/OpenIdServerHandler.cs | 30 +-- .../AuthorizationServerPostHandler.cs | 2 +- .../Avatar/AvatarServerPostHandler.cs | 2 +- .../Friends/FriendsServerPostHandler.cs | 2 +- .../Handlers/Grid/GridServerPostHandler.cs | 2 +- .../GridUser/GridUserServerPostHandler.cs | 2 +- .../Hypergrid/HGFriendsServerPostHandler.cs | 2 +- .../Handlers/Hypergrid/HeloServerConnector.cs | 2 +- .../Handlers/Hypergrid/HomeAgentHandlers.cs | 1 + .../InventoryServerMoveItemsHandler.cs | 2 +- .../Inventory/XInventoryInConnector.cs | 2 +- .../Handlers/Map/MapAddServerConnector.cs | 2 +- .../Handlers/Map/MapGetServerConnector.cs | 2 +- .../Handlers/Neighbour/NeighbourHandlers.cs | 8 +- .../Presence/PresenceServerPostHandler.cs | 2 +- .../Handlers/Simulation/AgentHandlers.cs | 4 +- .../UserAccountServerPostHandler.cs | 2 +- 43 files changed, 346 insertions(+), 80 deletions(-) diff --git a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs index 3584f78c52..67750f50e8 100644 --- a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs @@ -113,7 +113,7 @@ namespace OpenSim.Groups m_GroupsService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs index 28f7acc1a2..515b818cc5 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs @@ -75,7 +75,7 @@ namespace OpenSim.Groups m_GroupsService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Addons/OfflineIM/Remote/OfflineIMServiceRobustConnector.cs b/OpenSim/Addons/OfflineIM/Remote/OfflineIMServiceRobustConnector.cs index 2b3a01d32d..32c24db42d 100644 --- a/OpenSim/Addons/OfflineIM/Remote/OfflineIMServiceRobustConnector.cs +++ b/OpenSim/Addons/OfflineIM/Remote/OfflineIMServiceRobustConnector.cs @@ -75,7 +75,7 @@ namespace OpenSim.OfflineIM m_OfflineIMService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Capabilities/CapsHandlers.cs b/OpenSim/Capabilities/CapsHandlers.cs index 458272d10c..890df9091c 100644 --- a/OpenSim/Capabilities/CapsHandlers.cs +++ b/OpenSim/Capabilities/CapsHandlers.cs @@ -39,7 +39,7 @@ namespace OpenSim.Framework.Capabilities /// public class CapsHandlers { - private Dictionary m_capsHandlers = new Dictionary(); + private Dictionary m_capsHandlers = new Dictionary(); private IHttpServer m_httpListener; private string m_httpListenerHostName; private uint m_httpListenerPort; @@ -184,5 +184,17 @@ namespace OpenSim.Framework.Capabilities return caps; } + + /// + /// Returns a copy of the dictionary of all the HTTP cap handlers + /// + /// + /// The dictionary copy. The key is the capability name, the value is the HTTP handler. + /// + public Dictionary GetCapsHandlers() + { + lock (m_capsHandlers) + return new Dictionary(m_capsHandlers); + } } -} +} \ No newline at end of file diff --git a/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs b/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs index 4dca59231e..426174d252 100644 --- a/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs +++ b/OpenSim/Capabilities/Handlers/AvatarPickerSearch/AvatarPickerSearchHandler.cs @@ -56,7 +56,7 @@ namespace OpenSim.Capabilities.Handlers m_PeopleService = peopleService; } - public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // Try to parse the texture ID from the request URL NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 9f3cc1992d..789bf2b33d 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -64,7 +64,7 @@ namespace OpenSim.Capabilities.Handlers m_assetService = assService; } - public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // Try to parse the texture ID from the request URL NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); diff --git a/OpenSim/Capabilities/LLSDStreamHandler.cs b/OpenSim/Capabilities/LLSDStreamHandler.cs index 5df24b2cc1..4fa1153cd6 100644 --- a/OpenSim/Capabilities/LLSDStreamHandler.cs +++ b/OpenSim/Capabilities/LLSDStreamHandler.cs @@ -48,7 +48,7 @@ namespace OpenSim.Framework.Capabilities m_method = method; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { //Encoding encoding = Util.UTF8; diff --git a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs index ae7aaf2e3e..bbac699d3e 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseRequestHandler.cs @@ -31,6 +31,10 @@ namespace OpenSim.Framework.Servers.HttpServer { public abstract class BaseRequestHandler { + public int RequestsReceived { get; protected set; } + + public int RequestsHandled { get; protected set; } + public virtual string ContentType { get { return "application/xml"; } diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs index 6342983a55..252cc2ad81 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs @@ -29,14 +29,35 @@ using System.IO; namespace OpenSim.Framework.Servers.HttpServer { + /// + /// Base streamed request handler. + /// + /// + /// Inheriting classes should override ProcessRequest() rather than Handle() + /// public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler { - public abstract byte[] Handle(string path, Stream request, - IOSHttpRequest httpRequest, IOSHttpResponse httpResponse); - protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} protected BaseStreamHandler(string httpMethod, string path, string name, string description) : base(httpMethod, path, name, description) {} + + public virtual byte[] Handle( + string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + RequestsReceived++; + + byte[] result = ProcessRequest(path, request, httpRequest, httpResponse); + + RequestsHandled++; + + return result; + } + + protected virtual byte[] ProcessRequest( + string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + return null; + } } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs index b94bfb4311..1b03f543d3 100644 --- a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs @@ -45,7 +45,7 @@ namespace OpenSim.Framework.Servers.HttpServer m_method = binaryMethod; } - public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { byte[] data = ReadFully(request); string param = GetParam(path); diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs index cb5cce5f79..b8541cbe4c 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IStreamHandler.cs @@ -32,7 +32,6 @@ namespace OpenSim.Framework.Servers.HttpServer { public interface IRequestHandler { - /// /// Name for this handler. /// @@ -59,6 +58,19 @@ namespace OpenSim.Framework.Servers.HttpServer // Return path string Path { get; } + + /// + /// Number of requests received by this handler + /// + int RequestsReceived { get; } + + /// + /// Number of requests handled. + /// + /// + /// Should be equal to RequestsReceived unless requested are being handled slowly or there is deadlock. + /// + int RequestsHandled { get; } } public interface IStreamedRequestHandler : IRequestHandler @@ -69,7 +81,6 @@ namespace OpenSim.Framework.Servers.HttpServer public interface IStreamHandler : IRequestHandler { - // Handle request stream, return byte array void Handle(string path, Stream request, Stream response, IOSHttpRequest httpReqbuest, IOSHttpResponse httpResponse); } diff --git a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs index 07082a8ebb..bd55657815 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestDeserialiseHandler.cs @@ -33,7 +33,7 @@ namespace OpenSim.Framework.Servers.HttpServer { public delegate TResponse RestDeserialiseMethod(TRequest request); - public class RestDeserialiseHandler : BaseRequestHandler, IStreamHandler + public class RestDeserialiseHandler : BaseOutputStreamHandler, IStreamHandler where TRequest : new() { private RestDeserialiseMethod m_method; @@ -48,7 +48,7 @@ namespace OpenSim.Framework.Servers.HttpServer m_method = method; } - public void Handle(string path, Stream request, Stream responseStream, + protected override void ProcessRequest(string path, Stream request, Stream responseStream, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { TRequest deserial; diff --git a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs index edcd134cae..83c9848e0d 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestSessionService.cs @@ -183,7 +183,7 @@ namespace OpenSim.Framework.Servers.HttpServer public delegate bool CheckIdentityMethod(string sid, string aid); - public class RestDeserialiseSecureHandler : BaseRequestHandler, IStreamHandler + public class RestDeserialiseSecureHandler : BaseOutputStreamHandler, IStreamHandler where TRequest : new() { private static readonly ILog m_log @@ -201,7 +201,7 @@ namespace OpenSim.Framework.Servers.HttpServer m_method = method; } - public void Handle(string path, Stream request, Stream responseStream, + protected override void ProcessRequest(string path, Stream request, Stream responseStream, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { RestSessionObject deserial = default(RestSessionObject); @@ -237,7 +237,7 @@ namespace OpenSim.Framework.Servers.HttpServer public delegate bool CheckTrustedSourceMethod(IPEndPoint peer); - public class RestDeserialiseTrustedHandler : BaseRequestHandler, IStreamHandler + public class RestDeserialiseTrustedHandler : BaseOutputStreamHandler, IStreamHandler where TRequest : new() { private static readonly ILog m_log @@ -260,7 +260,7 @@ namespace OpenSim.Framework.Servers.HttpServer m_method = method; } - public void Handle(string path, Stream request, Stream responseStream, + protected override void ProcessRequest(string path, Stream request, Stream responseStream, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { TRequest deserial = default(TRequest); @@ -292,6 +292,5 @@ namespace OpenSim.Framework.Servers.HttpServer serializer.Serialize(xmlWriter, response); } } - } - -} + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs index 1f17fee0d0..0305dee118 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs @@ -48,7 +48,7 @@ namespace OpenSim.Framework.Servers.HttpServer m_restMethod = restMethod; } - public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { Encoding encoding = Encoding.UTF8; StreamReader streamReader = new StreamReader(request, encoding); diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 841069c5d3..f0c088a52b 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -766,7 +766,7 @@ namespace OpenSim { public SimStatusHandler() : base("GET", "/simstatus", "SimStatus", "Simulator Status") {} - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return Util.UTF8.GetBytes("OK"); @@ -792,7 +792,7 @@ namespace OpenSim m_opensim = sim; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest)); @@ -810,7 +810,7 @@ namespace OpenSim /// If the request contains a key, "callback" the response will be wrappend in the /// associated value for jsonp used with ajax/javascript /// - public class UXSimStatusHandler : BaseStreamHandler + protected class UXSimStatusHandler : BaseStreamHandler { OpenSimBase m_opensim; @@ -820,7 +820,7 @@ namespace OpenSim m_opensim = sim; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return Util.UTF8.GetBytes(m_opensim.StatReport(httpRequest)); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs index 69dd76fe45..a133a69c8b 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs @@ -176,7 +176,7 @@ namespace OpenSim.Region.ClientStack.Linden m_isGod = m_scene.Permissions.IsGod(agentID); } - public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader reader = new StreamReader(request); string message = reader.ReadToEnd(); diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs index 08196f14bb..21166053a0 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs @@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends m_FriendsModule = fmodule; } - public override byte[] Handle( + protected override byte[] ProcessRequest( string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index c8b341ba91..bd60611d3d 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Text; using log4net; @@ -37,6 +38,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Caps=OpenSim.Framework.Capabilities.Caps; @@ -58,6 +60,7 @@ namespace OpenSim.Region.CoreModules.Framework protected Dictionary m_capsObjects = new Dictionary(); protected Dictionary m_capsPaths = new Dictionary(); + protected Dictionary> m_childrenSeeds = new Dictionary>(); @@ -70,9 +73,24 @@ namespace OpenSim.Region.CoreModules.Framework m_scene = scene; m_scene.RegisterModuleInterface(this); - MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps", - "show caps", - "Shows all registered capabilities for users", HandleShowCapsCommand); + MainConsole.Instance.Commands.AddCommand( + "Comms", false, "show caps list", + "show caps list", + "Shows list of registered capabilities for users.", HandleShowCapsListCommand); + + MainConsole.Instance.Commands.AddCommand( + "Comms", false, "show caps stats by user", + "show caps stats [ ]", + "Shows statistics on capabilities use by user.", + "If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.", + HandleShowCapsStatsByUserCommand); + + MainConsole.Instance.Commands.AddCommand( + "Comms", false, "show caps stats by cap", + "show caps stats by cap []", + "Shows statistics on capabilities use by capability.", + "If a capability name is given, then prints a detailed breakdown of use by each user.", + HandleShowCapsStatsByCapCommand); } public void RegionLoaded(Scene scene) @@ -262,8 +280,11 @@ namespace OpenSim.Region.CoreModules.Framework } } - private void HandleShowCapsCommand(string module, string[] cmdparams) + private void HandleShowCapsListCommand(string module, string[] cmdParams) { + if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) + return; + StringBuilder caps = new StringBuilder(); caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); @@ -286,5 +307,210 @@ namespace OpenSim.Region.CoreModules.Framework MainConsole.Instance.Output(caps.ToString()); } + + private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams) + { + if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) + return; + + if (cmdParams.Length != 5 && cmdParams.Length != 6) + { + MainConsole.Instance.Output("Usage: show caps stats by cap []"); + return; + } + + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Region {0}:\n", m_scene.Name); + + if (cmdParams.Length == 5) + { + BuildSummaryStatsByCapReport(sb); + } + else if (cmdParams.Length == 6) + { + BuildDetailedStatsByCapReport(sb, cmdParams[5]); + } + + MainConsole.Instance.Output(sb.ToString()); + } + + private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName) + { + sb.AppendFormat("Capability name {0}\n", capName); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("User Name", 34); + cdt.AddColumn("Req Received", 12); + cdt.AddColumn("Req Handled", 12); + cdt.Indent = 2; + + Dictionary receivedStats = new Dictionary(); + Dictionary handledStats = new Dictionary(); + + m_scene.ForEachScenePresence( + sp => + { + Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); + + if (caps == null) + return; + + Dictionary capsHandlers = caps.CapsHandlers.GetCapsHandlers(); + + IRequestHandler reqHandler; + if (capsHandlers.TryGetValue(capName, out reqHandler)) + { + receivedStats[sp.Name] = reqHandler.RequestsReceived; + handledStats[sp.Name] = reqHandler.RequestsHandled; + } + } + ); + + foreach (KeyValuePair kvp in receivedStats.OrderByDescending(kp => kp.Value)) + { + cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]); + } + + sb.Append(cdt.ToString()); + } + + private void BuildSummaryStatsByCapReport(StringBuilder sb) + { + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Name", 34); + cdt.AddColumn("Req Received", 12); + cdt.AddColumn("Req Handled", 12); + cdt.Indent = 2; + + Dictionary receivedStats = new Dictionary(); + Dictionary handledStats = new Dictionary(); + + m_scene.ForEachScenePresence( + sp => + { + Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); + + if (caps == null) + return; + + Dictionary capsHandlers = caps.CapsHandlers.GetCapsHandlers(); + + foreach (IRequestHandler reqHandler in capsHandlers.Values) + { + string reqName = reqHandler.Name ?? ""; + + if (!receivedStats.ContainsKey(reqName)) + { + receivedStats[reqName] = reqHandler.RequestsReceived; + handledStats[reqName] = reqHandler.RequestsHandled; + } + else + { + receivedStats[reqName] += reqHandler.RequestsReceived; + handledStats[reqName] += reqHandler.RequestsHandled; + } + } + } + ); + + foreach (KeyValuePair kvp in receivedStats.OrderByDescending(kp => kp.Value)) + cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]); + + sb.Append(cdt.ToString()); + } + + private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams) + { + if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) + return; + + if (cmdParams.Length != 5 && cmdParams.Length != 7) + { + MainConsole.Instance.Output("Usage: show caps stats by user [ ]"); + return; + } + + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Region {0}:\n", m_scene.Name); + + if (cmdParams.Length == 5) + { + BuildSummaryStatsByUserReport(sb); + } + else if (cmdParams.Length == 7) + { + string firstName = cmdParams[5]; + string lastName = cmdParams[6]; + + ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); + + if (sp == null) + return; + + BuildDetailedStatsByUserReport(sb, sp); + } + + MainConsole.Instance.Output(sb.ToString()); + } + + private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp) + { + sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root"); + + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Cap Name", 34); + cdt.AddColumn("Req Received", 12); + cdt.AddColumn("Req Handled", 12); + cdt.Indent = 2; + + Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); + + if (caps == null) + return; + + Dictionary capsHandlers = caps.CapsHandlers.GetCapsHandlers(); + + foreach (IRequestHandler reqHandler in capsHandlers.Values.OrderByDescending(rh => rh.RequestsReceived)) + { + cdt.AddRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled); + } + + sb.Append(cdt.ToString()); + } + + private void BuildSummaryStatsByUserReport(StringBuilder sb) + { + ConsoleDisplayTable cdt = new ConsoleDisplayTable(); + cdt.AddColumn("Name", 32); + cdt.AddColumn("Type", 5); + cdt.AddColumn("Req Received", 12); + cdt.AddColumn("Req Handled", 12); + cdt.Indent = 2; + + m_scene.ForEachScenePresence( + sp => + { + Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); + + if (caps == null) + return; + + Dictionary capsHandlers = caps.CapsHandlers.GetCapsHandlers(); + + int totalRequestsReceived = 0; + int totalRequestsHandled = 0; + + foreach (IRequestHandler reqHandler in capsHandlers.Values) + { + totalRequestsReceived += reqHandler.RequestsReceived; + totalRequestsHandled += reqHandler.RequestsHandled; + } + + cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled); + } + ); + + sb.Append(cdt.ToString()); + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs b/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs index eb74cdab76..236676777c 100644 --- a/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs +++ b/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_EstateModule = fmodule; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs index 726becf3b5..f208afb758 100644 --- a/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs +++ b/OpenSim/Region/Framework/Scenes/RegionStatsHandler.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.Framework.Scenes osXStatsURI = Util.SHA1Hash(regionInfo.osSecret); } - public override byte[] Handle( + protected override byte[] ProcessRequest( string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return Util.UTF8.GetBytes(Report()); diff --git a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs index 1ea1c20284..6e0a80abaf 100644 --- a/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs +++ b/OpenSim/Region/OptionalModules/ViewerSupport/DynamicMenuModule.cs @@ -281,7 +281,7 @@ namespace OpenSim.Region.OptionalModules.ViewerSupport m_module = module; } - public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader reader = new StreamReader(request); string requestBody = reader.ReadToEnd(); diff --git a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs index 550b5d437a..8720cc78c5 100644 --- a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs +++ b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.World.WorldView m_WorldViewModule = fmodule; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { httpResponse.ContentType = "image/jpeg"; diff --git a/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs b/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs index 986394bf59..941b97d2f0 100644 --- a/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs +++ b/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs @@ -70,7 +70,7 @@ namespace OpenSim.Server.Handlers.Asset m_allowedTypes = allowedTypes; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { bool result = false; diff --git a/OpenSim/Server/Handlers/Asset/AssetServerGetHandler.cs b/OpenSim/Server/Handlers/Asset/AssetServerGetHandler.cs index 8f7412bd77..8b23a832ac 100644 --- a/OpenSim/Server/Handlers/Asset/AssetServerGetHandler.cs +++ b/OpenSim/Server/Handlers/Asset/AssetServerGetHandler.cs @@ -54,7 +54,7 @@ namespace OpenSim.Server.Handlers.Asset m_AssetService = service; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { byte[] result = new byte[0]; diff --git a/OpenSim/Server/Handlers/Asset/AssetServerPostHandler.cs b/OpenSim/Server/Handlers/Asset/AssetServerPostHandler.cs index a006fa8395..8eebc61609 100644 --- a/OpenSim/Server/Handlers/Asset/AssetServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Asset/AssetServerPostHandler.cs @@ -54,7 +54,7 @@ namespace OpenSim.Server.Handlers.Asset m_AssetService = service; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { AssetBase asset; diff --git a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs index 6b93cd9035..16e011aaea 100644 --- a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs @@ -70,7 +70,7 @@ namespace OpenSim.Server.Handlers.Authentication } } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { string[] p = SplitParams(path); diff --git a/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs b/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs index 18cef154e5..66a26fc78d 100644 --- a/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs @@ -147,7 +147,7 @@ namespace OpenSim.Server.Handlers.Authentication #endregion } - public class OpenIdStreamHandler : IStreamHandler + public class OpenIdStreamHandler : BaseOutputStreamHandler { #region HTML @@ -191,42 +191,34 @@ For more information, see http://openid.net/. #endregion HTML - public string Name { get { return "OpenId"; } } - public string Description { get { return null; } } - public string ContentType { get { return m_contentType; } } - public string HttpMethod { get { return m_httpMethod; } } - public string Path { get { return m_path; } } - - string m_contentType; - string m_httpMethod; - string m_path; IAuthenticationService m_authenticationService; IUserAccountService m_userAccountService; ProviderMemoryStore m_openidStore = new ProviderMemoryStore(); + public override string ContentType { get { return "text/html"; } } + /// /// Constructor /// - public OpenIdStreamHandler(string httpMethod, string path, IUserAccountService userService, IAuthenticationService authService) + public OpenIdStreamHandler( + string httpMethod, string path, IUserAccountService userService, IAuthenticationService authService) + : base(httpMethod, path, "OpenId", "OpenID stream handler") { m_authenticationService = authService; m_userAccountService = userService; - m_httpMethod = httpMethod; - m_path = path; - - m_contentType = "text/html"; } /// /// Handles all GET and POST requests for OpenID identifier pages and endpoint /// server communication /// - public void Handle(string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override void ProcessRequest( + string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { Uri providerEndpoint = new Uri(String.Format("{0}://{1}{2}", httpRequest.Url.Scheme, httpRequest.Url.Authority, httpRequest.Url.AbsolutePath)); // Defult to returning HTML content - m_contentType = "text/html"; + httpResponse.ContentType = ContentType; try { @@ -276,7 +268,7 @@ For more information, see http://openid.net/. string[] contentTypeValues = provider.Request.Response.Headers.GetValues("Content-Type"); if (contentTypeValues != null && contentTypeValues.Length == 1) - m_contentType = contentTypeValues[0]; + httpResponse.ContentType = contentTypeValues[0]; // Set the response code and document body based on the OpenID result httpResponse.StatusCode = (int)provider.Request.Response.Code; @@ -344,4 +336,4 @@ For more information, see http://openid.net/. return false; } } -} +} \ No newline at end of file diff --git a/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs b/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs index bcf9d477e3..c9b4e9b0d2 100644 --- a/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Authorization/AuthorizationServerPostHandler.cs @@ -54,7 +54,7 @@ namespace OpenSim.Server.Handlers.Authorization m_AuthorizationService = service; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { XmlSerializer xs = new XmlSerializer(typeof (AuthorizationRequest)); diff --git a/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs b/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs index 8cd747ee17..d6bbb8fc4e 100644 --- a/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs @@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.Avatar m_AvatarService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs index 47a85581af..ca0a24c36f 100644 --- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -57,7 +57,7 @@ namespace OpenSim.Server.Handlers.Friends m_FriendsService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index ef5f33e173..89cba8a7d8 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -57,7 +57,7 @@ namespace OpenSim.Server.Handlers.Grid m_GridService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs b/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs index 7483395124..0b98e9a12b 100644 --- a/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs +++ b/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs @@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.GridUser m_GridUserService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs index 0aa272973f..a2bdadb1aa 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -68,7 +68,7 @@ namespace OpenSim.Server.Handlers.Hypergrid m_log.ErrorFormat("[HGFRIENDS HANDLER]: TheService is null!"); } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Server/Handlers/Hypergrid/HeloServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HeloServerConnector.cs index f306b1c757..06eaf2ec8d 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HeloServerConnector.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HeloServerConnector.cs @@ -91,7 +91,7 @@ namespace OpenSim.Server.Handlers.Hypergrid m_HandlersType = handlersType; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { return OKResponse(httpResponse); diff --git a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs index df875af14d..f37f2f1e24 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs @@ -68,6 +68,7 @@ namespace OpenSim.Server.Handlers.Hypergrid { return new ExtendedAgentDestinationData(); } + protected override void UnpackData(OSDMap args, AgentDestinationData d, Hashtable request) { base.UnpackData(args, d, request); diff --git a/OpenSim/Server/Handlers/Inventory/InventoryServerMoveItemsHandler.cs b/OpenSim/Server/Handlers/Inventory/InventoryServerMoveItemsHandler.cs index 231e32f6fb..e2c50fe1fa 100644 --- a/OpenSim/Server/Handlers/Inventory/InventoryServerMoveItemsHandler.cs +++ b/OpenSim/Server/Handlers/Inventory/InventoryServerMoveItemsHandler.cs @@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.Inventory m_InventoryService = service; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { XmlSerializer xs = new XmlSerializer(typeof (List)); diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index 9d28dc3c6d..0d7c13669c 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -87,7 +87,7 @@ namespace OpenSim.Server.Handlers.Asset m_InventoryService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs index 4a619698bc..d438fc7487 100644 --- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -99,7 +99,7 @@ namespace OpenSim.Server.Handlers.MapImage m_Proxy = proxy; } - public override byte[] Handle(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path); StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs index fb85d1ce1c..7bb2f39820 100644 --- a/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapGetServerConnector.cs @@ -80,7 +80,7 @@ namespace OpenSim.Server.Handlers.MapImage m_MapService = service; } - public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { byte[] result = new byte[0]; diff --git a/OpenSim/Server/Handlers/Neighbour/NeighbourHandlers.cs b/OpenSim/Server/Handlers/Neighbour/NeighbourHandlers.cs index 8a1f824dbd..3525a01a71 100644 --- a/OpenSim/Server/Handlers/Neighbour/NeighbourHandlers.cs +++ b/OpenSim/Server/Handlers/Neighbour/NeighbourHandlers.cs @@ -58,7 +58,7 @@ namespace OpenSim.Server.Handlers.Neighbour // TODO: unused: m_AuthenticationService = authentication; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // Not implemented yet @@ -83,7 +83,7 @@ namespace OpenSim.Server.Handlers.Neighbour // TODO: unused: m_AllowForeignGuests = foreignGuests; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { byte[] result = new byte[0]; @@ -176,7 +176,7 @@ namespace OpenSim.Server.Handlers.Neighbour // TODO: unused: m_AuthenticationService = authentication; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // Not implemented yet @@ -197,7 +197,7 @@ namespace OpenSim.Server.Handlers.Neighbour // TODO: unused: m_AuthenticationService = authentication; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // Not implemented yet diff --git a/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs b/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs index 2d67c6db0c..abb4b19642 100644 --- a/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Presence/PresenceServerPostHandler.cs @@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.Presence m_PresenceService = service; } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 71a9e6fa41..a9fd4ed4a4 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -251,7 +251,7 @@ namespace OpenSim.Server.Handlers.Simulation m_SimulationService = null; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // m_log.DebugFormat("[SIMULATION]: Stream handler called"); @@ -457,7 +457,7 @@ namespace OpenSim.Server.Handlers.Simulation m_SimulationService = null; } - public override byte[] Handle(string path, Stream request, + protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // m_log.DebugFormat("[SIMULATION]: Stream handler called"); diff --git a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs index 72551ef404..24c9de6a9d 100644 --- a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs +++ b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs @@ -68,7 +68,7 @@ namespace OpenSim.Server.Handlers.UserAccounts } } - public override byte[] Handle(string path, Stream requestData, + protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { StreamReader sr = new StreamReader(requestData); From b2d4b8b1da10e88d0f2471fb9cd502a8ed7dd095 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 8 Jul 2013 14:12:11 -0700 Subject: [PATCH 31/93] BaseHttpServer: if the handler sets the content length, don't override it. This happens in HEAD handlers. --- OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index 40b8c5c1ed..6863e0e37b 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -688,7 +688,7 @@ namespace OpenSim.Framework.Servers.HttpServer if (buffer != null) { - if (!response.SendChunked) + if (!response.SendChunked && response.ContentLength64 <= 0) response.ContentLength64 = buffer.LongLength; response.OutputStream.Write(buffer, 0, buffer.Length); From 013710168b3878fc0a93a92a1c026efb49da9935 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 22:39:07 +0100 Subject: [PATCH 32/93] For stat purposes, add names to capability request handlers where these were not set --- OpenSim/Capabilities/Caps.cs | 1 - .../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 10 ++++++++-- .../Linden/Caps/EventQueue/EventQueueGetModule.cs | 3 ++- OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | 6 +++--- .../OptionalModules/Materials/MaterialsDemoModule.cs | 11 +++++++---- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs index bc6f6f99a9..1bed1a5e5f 100644 --- a/OpenSim/Capabilities/Caps.cs +++ b/OpenSim/Capabilities/Caps.cs @@ -144,7 +144,6 @@ namespace OpenSim.Framework.Capabilities public void RegisterHandler(string capName, IRequestHandler handler) { m_capsHandlers[capName] = handler; - //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path); } /// diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index a46c24a637..5c6bc1c002 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -207,9 +207,15 @@ namespace OpenSim.Region.ClientStack.Linden m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); - IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData); + + IRequestHandler getObjectPhysicsDataHandler + = new RestStreamHandler( + "POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null); m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler); - IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler("POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation); + + IRequestHandler UpdateAgentInformationHandler + = new RestStreamHandler( + "POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation, "UpdateAgentInformation", null); m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler); m_HostCapsObj.RegisterHandler( diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index e73a04af7f..50bfda1b77 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -366,7 +366,8 @@ namespace OpenSim.Region.ClientStack.Linden // EventQueueGet when it receive capability information, but then we replace the rest handler immediately // afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but // really it should be possible to directly register the poll handler as a capability. - caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null)); + caps.RegisterHandler( + "EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null, "EventQueueGet", null)); // delegate(Hashtable m_dhttpMethod) // { // return ProcessQueue(m_dhttpMethod, agentID, caps); diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index a542d626ed..0cd495c5a4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs @@ -122,9 +122,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods { string uri = "/CAPS/" + UUID.Random(); - caps.RegisterHandler("UntrustedSimulatorMessage", - new RestStreamHandler("POST", uri, - HandleUntrustedSimulatorMessage)); + caps.RegisterHandler( + "UntrustedSimulatorMessage", + new RestStreamHandler("POST", uri, HandleUntrustedSimulatorMessage, "UntrustedSimulatorMessage", null)); } private string HandleUntrustedSimulatorMessage(string request, diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs index 3a39971078..00504d0da8 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs @@ -139,18 +139,21 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule { string capsBase = "/CAPS/" + caps.CapsObjectPath; - IRequestHandler renderMaterialsPostHandler = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap); - caps.RegisterHandler("RenderMaterials", renderMaterialsPostHandler); + IRequestHandler renderMaterialsPostHandler + = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap, "RenderMaterialsPost", null); + caps.RegisterHandler("RenderMaterialsPost", renderMaterialsPostHandler); // OpenSimulator CAPs infrastructure seems to be somewhat hostile towards any CAP that requires both GET // and POST handlers, (at least at the time this was originally written), so we first set up a POST // handler normally and then add a GET handler via MainServer - IRequestHandler renderMaterialsGetHandler = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap); + IRequestHandler renderMaterialsGetHandler + = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap, "RenderMaterialsGet", null); MainServer.Instance.AddStreamHandler(renderMaterialsGetHandler); // materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well - IRequestHandler renderMaterialsPutHandler = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap); + IRequestHandler renderMaterialsPutHandler + = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap, "RenderMaterialsPut", null); MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler); } From 8be59829d1fcf4c4f42a1a859aef6aa5f4f29073 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 22:41:24 +0100 Subject: [PATCH 33/93] minor: Add back commented out logging message in Caps.RegisterHandler() that I accidentally removed. --- OpenSim/Capabilities/Caps.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Capabilities/Caps.cs b/OpenSim/Capabilities/Caps.cs index 1bed1a5e5f..6c95d8b06c 100644 --- a/OpenSim/Capabilities/Caps.cs +++ b/OpenSim/Capabilities/Caps.cs @@ -143,6 +143,7 @@ namespace OpenSim.Framework.Capabilities /// public void RegisterHandler(string capName, IRequestHandler handler) { + //m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path); m_capsHandlers[capName] = handler; } From eccec4f8f654633ee97942a2decf8a7ba3a2b153 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 23:32:19 +0100 Subject: [PATCH 34/93] minor: remove now unused migration-hack bool from DAMap --- OpenSim/Framework/DAMap.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OpenSim/Framework/DAMap.cs b/OpenSim/Framework/DAMap.cs index 5c729e883f..4995a92de0 100644 --- a/OpenSim/Framework/DAMap.cs +++ b/OpenSim/Framework/DAMap.cs @@ -132,10 +132,6 @@ namespace OpenSim.Framework { List keysToRemove = null; - // Hard-coded special case that needs to be removed in the future. Normally, modules themselves should - // handle reading data from old locations - bool osMaterialsMigrationRequired = false; - OSDMap namespacesMap = daMap.m_map; foreach (string key in namespacesMap.Keys) From 047ef9c2a5cb573c0a506fecd0f2a7e8dc85c023 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 23:36:57 +0100 Subject: [PATCH 35/93] minor: remove some mono compiler warnings in OdePlugin --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 1 - OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 0d66496338..13c69d6f0f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -108,7 +108,6 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_taintAngularLock = Vector3.One; private IntPtr Amotor = IntPtr.Zero; - private object m_assetsLock = new object(); private bool m_assetFailed = false; private Vector3 m_PIDTarget; diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 07663b3113..7e652fc022 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -46,7 +46,7 @@ namespace OpenSim.Region.Physics.OdePlugin /// public class OdePlugin : IPhysicsPlugin { - private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private OdeScene m_scene; From 2025dd25f6041e276e9ecde6829d0c51a565fae5 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 23:50:40 +0100 Subject: [PATCH 36/93] Add missing file BaseOutputStreamHandler.cs from recent commit e19defd --- .../HttpServer/BaseOutputStreamHandler.cs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 OpenSim/Framework/Servers/HttpServer/BaseOutputStreamHandler.cs diff --git a/OpenSim/Framework/Servers/HttpServer/BaseOutputStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseOutputStreamHandler.cs new file mode 100644 index 0000000000..72b3065172 --- /dev/null +++ b/OpenSim/Framework/Servers/HttpServer/BaseOutputStreamHandler.cs @@ -0,0 +1,60 @@ +/* + * 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.IO; + +namespace OpenSim.Framework.Servers.HttpServer +{ + /// + /// Base handler for writing to an output stream + /// + /// + /// Inheriting classes should override ProcessRequest() rather than Handle() + /// + public abstract class BaseOutputStreamHandler : BaseRequestHandler, IRequestHandler + { + protected BaseOutputStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} + + protected BaseOutputStreamHandler(string httpMethod, string path, string name, string description) + : base(httpMethod, path, name, description) {} + + public virtual void Handle( + string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + RequestsReceived++; + + ProcessRequest(path, request, response, httpRequest, httpResponse); + + RequestsHandled++; + } + + protected virtual void ProcessRequest( + string path, Stream request, Stream response, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + } + } +} \ No newline at end of file From af9b17c54570a1634d078df0feb8f1b53ffb0726 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 23:52:40 +0100 Subject: [PATCH 37/93] minor: remove mono compiler warnings related to keyframe code --- OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | 9 +++------ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 -- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index 8a40278b9a..29652aaa66 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -55,7 +55,6 @@ namespace OpenSim.Region.Framework.Scenes private object m_lockObject = new object(); private object m_timerLock = new object(); private const double m_tickDuration = 50.0; - private Scene m_scene; public double TickDuration { @@ -69,8 +68,6 @@ namespace OpenSim.Region.Framework.Scenes m_timer.AutoReset = true; m_timer.Elapsed += OnTimer; - m_scene = scene; - m_timer.Start(); } @@ -94,13 +91,13 @@ namespace OpenSim.Region.Framework.Scenes { m.OnTimer(TickDuration); } - catch (Exception inner) + catch (Exception) { // Don't stop processing } } } - catch (Exception e) + catch (Exception) { // Keep running no matter what } @@ -157,7 +154,7 @@ namespace OpenSim.Region.Framework.Scenes [Serializable] public class KeyframeMotion { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public enum PlayMode : int { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f287a34f14..f361acb1f8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -354,8 +354,6 @@ namespace OpenSim.Region.Framework.Scenes private UUID m_collisionSound; private float m_collisionSoundVolume; - private KeyframeMotion m_keyframeMotion = null; - public KeyframeMotion KeyframeMotion { get; set; From 83da14008f9a8a4ad0cf0dd5487327e4a319fd5d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 8 Jul 2013 23:57:05 +0100 Subject: [PATCH 38/93] minor: remove some mono compiler warnings in new groups code --- OpenSim/Addons/Groups/GroupsModule.cs | 2 +- .../Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs | 1 - .../Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs | 2 -- OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs | 4 ---- 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index 5959baca40..82e2d6fe14 100644 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -485,7 +485,7 @@ namespace OpenSim.Groups return; //// 16 bytes are the UUID. Maybe. - UUID folderID = new UUID(im.binaryBucket, 0); +// UUID folderID = new UUID(im.binaryBucket, 0); UUID noticeID = new UUID(im.imSessionID); GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID); diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index cff7adf53c..c3c759e2da 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs @@ -543,7 +543,6 @@ namespace OpenSim.Groups List urls = new List(); foreach (GroupMembersData m in members) { - UUID userID = UUID.Zero; if (!m_UserManagement.IsLocalGridUser(m.AgentID)) { string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI"); diff --git a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs index 67750f50e8..d2bcba5c4b 100644 --- a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs @@ -47,7 +47,6 @@ namespace OpenSim.Groups private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private HGGroupsService m_GroupsService; - private string m_HomeURI = string.Empty; private string m_ConfigName = "Groups"; // Called by Robust shell @@ -209,7 +208,6 @@ namespace OpenSim.Groups UUID groupID = new UUID(request["GroupID"].ToString()); string agentID = request["AgentID"].ToString(); string token = request["AccessToken"].ToString(); - string reason = string.Empty; m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token); } diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs index 515b818cc5..106c6c4285 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs @@ -269,7 +269,6 @@ namespace OpenSim.Groups UUID groupID = new UUID(request["GroupID"].ToString()); string agentID = request["AgentID"].ToString(); string requestingAgentID = request["RequestingAgentID"].ToString(); - string reason = string.Empty; m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID); } @@ -500,7 +499,6 @@ namespace OpenSim.Groups else { string op = request["OP"].ToString(); - string reason = string.Empty; bool success = false; if (op == "ADD") @@ -568,7 +566,6 @@ namespace OpenSim.Groups else { string op = request["OP"].ToString(); - string reason = string.Empty; if (op == "GROUP") { @@ -631,7 +628,6 @@ namespace OpenSim.Groups else { string op = request["OP"].ToString(); - string reason = string.Empty; if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID")) { From 5f58b9b5526c401e039d27b8c92603ff02421fb8 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 9 Jul 2013 00:04:46 +0100 Subject: [PATCH 39/93] minor: remove some mono compiler warnings in UserProfileModule --- .../Avatar/UserProfiles/UserProfileModule.cs | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 161f160ba3..44edd7f0a5 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -304,7 +304,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(targetID, out serverURI); +// bool foreign = GetUserProfileServerURI(targetID, out serverURI); UUID creatorId = UUID.Zero; OSDMap parameters= new OSDMap(); @@ -369,7 +369,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(target, out serverURI); +// bool foreign = GetUserProfileServerURI(target, out serverURI); object Ad = (object)ad; if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString())) @@ -438,10 +438,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); ScenePresence p = FindPresence(remoteClient.AgentId); - Vector3 avaPos = p.AbsolutePosition; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); +// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); if (land == null) { @@ -488,7 +487,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient) { string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); +// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); UUID classifiedId; OSDMap parameters= new OSDMap(); @@ -538,7 +537,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(targetId, out serverURI); +// bool foreign = GetUserProfileServerURI(targetId, out serverURI); OSDMap parameters= new OSDMap(); parameters.Add("creatorId", OSD.FromUUID(targetId)); @@ -589,7 +588,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles UUID targetID; UUID.TryParse(args[0], out targetID); string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(targetID, out serverURI); +// bool foreign = GetUserProfileServerURI(targetID, out serverURI); IClientAPI remoteClient = (IClientAPI)sender; UserProfilePick pick = new UserProfilePick(); @@ -657,7 +656,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); UserProfilePick pick = new UserProfilePick(); string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); +// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); ScenePresence p = FindPresence(remoteClient.AgentId); Vector3 avaPos = p.AbsolutePosition; @@ -717,7 +716,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles public void PickDelete(IClientAPI remoteClient, UUID queryPickID) { string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); +// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); OSDMap parameters= new OSDMap(); parameters.Add("pickId", OSD.FromUUID(queryPickID)); @@ -752,7 +751,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles IClientAPI remoteClient = (IClientAPI)sender; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); +// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); note.TargetId = remoteClient.AgentId; UUID.TryParse(args[0], out note.UserId); @@ -788,7 +787,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles note.Notes = queryNotes; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); +// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Note = note; if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) @@ -833,7 +832,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles prop.Language = languages; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); +// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Param = prop; if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString())) @@ -955,7 +954,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles prop.FirstLifeText = newProfile.FirstLifeAboutText; string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); +// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Prop = prop; @@ -994,7 +993,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; - bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI); +// bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI); // This is checking a friend on the home grid // Not HG friend @@ -1247,7 +1246,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles return false; } - byte[] buf = new byte[8192]; Stream rstream = webResponse.GetResponseStream(); OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream); @@ -1313,7 +1311,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles return false; } - byte[] buf = new byte[8192]; Stream rstream = webResponse.GetResponseStream(); OSDMap response = new OSDMap(); From 76b2b20f7e89d521114cea60746212fade90c14c Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 9 Jul 2013 00:06:22 +0100 Subject: [PATCH 40/93] minor: remove mono compiler warnings from HGSuitcaseInventoryService --- .../Services/HypergridService/HGSuitcaseInventoryService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs index 410916f5c5..2567c8f799 100644 --- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs @@ -54,7 +54,7 @@ namespace OpenSim.Services.HypergridService LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); - private string m_HomeURL; +// private string m_HomeURL; private IUserAccountService m_UserAccountService; private IAvatarService m_AvatarService; @@ -96,8 +96,8 @@ namespace OpenSim.Services.HypergridService if (m_AvatarService == null) throw new Exception(String.Format("Unable to create m_AvatarService from {0}", avatarDll)); - m_HomeURL = Util.GetConfigVarFromSections(config, "HomeURI", - new string[] { "Startup", "Hypergrid", m_ConfigName }, String.Empty); +// m_HomeURL = Util.GetConfigVarFromSections(config, "HomeURI", +// new string[] { "Startup", "Hypergrid", m_ConfigName }, String.Empty); // m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); } From fad4241e4ea898b0dca0176cc9b428d03ba44d1c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 8 Jul 2013 16:21:10 -0700 Subject: [PATCH 41/93] BulletSim: make all the different angularVerticalAttraction algorithms selectable from configuration paramters. Changed default algorithm to "1" from previous default as it seems to handle Y axis correction a little better. Add config file independent enablement of vehicle angular forces to make debugging easier (independent testing of forces). --- .../Physics/BulletSPlugin/BSDynamics.cs | 261 +++++++++--------- .../Region/Physics/BulletSPlugin/BSParam.cs | 15 +- .../Region/Physics/BulletSPlugin/BSScene.cs | 4 +- .../BulletSPlugin/Tests/BasicVehicles.cs | 4 +- 4 files changed, 146 insertions(+), 138 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 82fe267c56..a5f2e9849c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -125,33 +125,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin static readonly float PIOverFour = ((float)Math.PI) / 4f; static readonly float PIOverTwo = ((float)Math.PI) / 2f; - // For debugging, flags to turn on and off individual corrections. - public bool enableAngularVerticalAttraction; - public bool enableAngularDeflection; - public bool enableAngularBanking; - public BSDynamics(BSScene myScene, BSPrim myPrim, string actorName) : base(myScene, myPrim, actorName) { ControllingPrim = myPrim; Type = Vehicle.TYPE_NONE; m_haveRegisteredForSceneEvents = false; - SetupVehicleDebugging(); - } - - // Stopgap debugging enablement. Allows source level debugging but still checking - // in changes by making enablement of debugging flags from INI file. - public void SetupVehicleDebugging() - { - enableAngularVerticalAttraction = true; - enableAngularDeflection = true; - enableAngularBanking = true; - if (BSParam.VehicleDebuggingEnable) - { - enableAngularVerticalAttraction = true; - enableAngularDeflection = false; - enableAngularBanking = false; - } } // Return 'true' if this vehicle is doing vehicle things @@ -556,10 +535,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin } m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, m_linearMotorDecayTimescale, 1f); - m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + // m_linearMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, m_angularMotorDecayTimescale, 1f); - m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + // m_angularMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG DEBUG (enables detail logging) /* Not implemented m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, @@ -1393,116 +1372,134 @@ namespace OpenSim.Region.Physics.BulletSPlugin { // If vertical attaction timescale is reasonable - if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) + if (BSParam.VehicleEnableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { - //Another formula to try got from : - //http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html - - Vector3 VehicleUpAxis = Vector3.UnitZ * VehicleOrientation; - - // Flipping what was originally a timescale into a speed variable and then multiplying it by 2 - // since only computing half the distance between the angles. - float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f; - - // Make a prediction of where the up axis will be when this is applied rather then where it is now as - // this makes for a smoother adjustment and less fighting between the various forces. - Vector3 predictedUp = VehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f); - - // This is only half the distance to the target so it will take 2 seconds to complete the turn. - Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ); - - // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared - Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed; - - VehicleRotationalVelocity += vertContributionV; - - VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}", - ControllingPrim.LocalID, - VehicleUpAxis, - predictedUp, - torqueVector, - vertContributionV); - //===================================================================== - /* - // Possible solution derived from a discussion at: - // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no - - // Create a rotation that is only the vehicle's rotation around Z - Vector3 currentEuler = Vector3.Zero; - VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z); - Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z); - - // Create the axis that is perpendicular to the up vector and the rotated up vector. - Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); - // Compute the angle between those to vectors. - double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation))); - // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical - - // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied. - // TODO: add 'efficiency'. - differenceAngle /= m_verticalAttractionTimescale; - - // Create the quaterian representing the correction angle - Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle); - - // Turn that quaternion into Euler values to make it into velocities to apply. - Vector3 vertContributionV = Vector3.Zero; - correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z); - vertContributionV *= -1f; - - VehicleRotationalVelocity += vertContributionV; - - VDetailLog("{0}, MoveAngular,verticalAttraction,diffAxis={1},diffAng={2},corrRot={3},contrib={4}", - ControllingPrim.LocalID, - differenceAxis, - differenceAngle, - correctionRotation, - vertContributionV); - */ - - // =================================================================== - /* - Vector3 vertContributionV = Vector3.Zero; - Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG - - // Take a vector pointing up and convert it from world to vehicle relative coords. - Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation); - - // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) - // is now: - // leaning to one side: rotated around the X axis with the Y value going - // from zero (nearly straight up) to one (completely to the side)) or - // leaning front-to-back: rotated around the Y axis with the value of X being between - // zero and one. - // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. - - // Y error means needed rotation around X axis and visa versa. - // Since the error goes from zero to one, the asin is the corresponding angle. - vertContributionV.X = (float)Math.Asin(verticalError.Y); - // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) - vertContributionV.Y = -(float)Math.Asin(verticalError.X); - - // If verticalError.Z is negative, the vehicle is upside down. Add additional push. - if (verticalError.Z < 0f) + Vector3 vehicleUpAxis = Vector3.UnitZ * VehicleOrientation; + switch (BSParam.VehicleAngularVerticalAttractionAlgorithm) { - vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour; - // vertContribution.Y -= PIOverFour; + case 0: + { + //Another formula to try got from : + //http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html + + // Flipping what was originally a timescale into a speed variable and then multiplying it by 2 + // since only computing half the distance between the angles. + float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f; + + // Make a prediction of where the up axis will be when this is applied rather then where it is now as + // this makes for a smoother adjustment and less fighting between the various forces. + Vector3 predictedUp = vehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f); + + // This is only half the distance to the target so it will take 2 seconds to complete the turn. + Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ); + + // Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared + Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed; + + VehicleRotationalVelocity += vertContributionV; + + VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},PredictedUp={2},torqueVector={3},contrib={4}", + ControllingPrim.LocalID, + vehicleUpAxis, + predictedUp, + torqueVector, + vertContributionV); + break; + } + case 1: + { + // Possible solution derived from a discussion at: + // http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no + + // Create a rotation that is only the vehicle's rotation around Z + Vector3 currentEuler = Vector3.Zero; + VehicleOrientation.GetEulerAngles(out currentEuler.X, out currentEuler.Y, out currentEuler.Z); + Quaternion justZOrientation = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, currentEuler.Z); + + // Create the axis that is perpendicular to the up vector and the rotated up vector. + Vector3 differenceAxis = Vector3.Cross(Vector3.UnitZ * justZOrientation, Vector3.UnitZ * VehicleOrientation); + // Compute the angle between those to vectors. + double differenceAngle = Math.Acos((double)Vector3.Dot(Vector3.UnitZ, Vector3.Normalize(Vector3.UnitZ * VehicleOrientation))); + // 'differenceAngle' is the angle to rotate and 'differenceAxis' is the plane to rotate in to get the vehicle vertical + + // Reduce the change by the time period it is to change in. Timestep is handled when velocity is applied. + // TODO: add 'efficiency'. + differenceAngle /= m_verticalAttractionTimescale; + + // Create the quaterian representing the correction angle + Quaternion correctionRotation = Quaternion.CreateFromAxisAngle(differenceAxis, (float)differenceAngle); + + // Turn that quaternion into Euler values to make it into velocities to apply. + Vector3 vertContributionV = Vector3.Zero; + correctionRotation.GetEulerAngles(out vertContributionV.X, out vertContributionV.Y, out vertContributionV.Z); + vertContributionV *= -1f; + + VehicleRotationalVelocity += vertContributionV; + + VDetailLog("{0}, MoveAngular,verticalAttraction,upAxis={1},diffAxis={2},diffAng={3},corrRot={4},contrib={5}", + ControllingPrim.LocalID, + vehicleUpAxis, + differenceAxis, + differenceAngle, + correctionRotation, + vertContributionV); + break; + } + case 2: + { + Vector3 vertContributionV = Vector3.Zero; + Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG + + // Take a vector pointing up and convert it from world to vehicle relative coords. + Vector3 verticalError = Vector3.Normalize(Vector3.UnitZ * VehicleOrientation); + + // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) + // is now: + // leaning to one side: rotated around the X axis with the Y value going + // from zero (nearly straight up) to one (completely to the side)) or + // leaning front-to-back: rotated around the Y axis with the value of X being between + // zero and one. + // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. + + // Y error means needed rotation around X axis and visa versa. + // Since the error goes from zero to one, the asin is the corresponding angle. + vertContributionV.X = (float)Math.Asin(verticalError.Y); + // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) + vertContributionV.Y = -(float)Math.Asin(verticalError.X); + + // If verticalError.Z is negative, the vehicle is upside down. Add additional push. + if (verticalError.Z < 0f) + { + vertContributionV.X += Math.Sign(vertContributionV.X) * PIOverFour; + // vertContribution.Y -= PIOverFour; + } + + // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. + // Correction happens over a number of seconds. + Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG + + // The correction happens over the user's time period + vertContributionV /= m_verticalAttractionTimescale; + + // Rotate the vehicle rotation to the world coordinates. + VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); + + VDetailLog("{0}, MoveAngular,verticalAttraction,,upAxis={1},origRotVW={2},vertError={3},unscaledV={4},eff={5},ts={6},vertContribV={7}", + ControllingPrim.LocalID, + vehicleUpAxis, + origRotVelW, + verticalError, + unscaledContribVerticalErrorV, + m_verticalAttractionEfficiency, + m_verticalAttractionTimescale, + vertContributionV); + break; + } + default: + { + break; + } } - - // 'vertContrbution' is now the necessary angular correction to correct tilt in one second. - // Correction happens over a number of seconds. - Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG - - // The correction happens over the user's time period - vertContributionV /= m_verticalAttractionTimescale; - - // Rotate the vehicle rotation to the world coordinates. - VehicleRotationalVelocity += (vertContributionV * VehicleOrientation); - - VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}", - Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV, - m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV); - */ } } @@ -1514,7 +1511,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin public void ComputeAngularDeflection() { - if (enableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) + if (BSParam.VehicleEnableAngularDeflection && m_angularDeflectionEfficiency != 0 && VehicleForwardSpeed > 0.2) { Vector3 deflectContributionV = Vector3.Zero; @@ -1593,7 +1590,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // make a sluggish vehicle by giving it a timescale of several seconds. public void ComputeAngularBanking() { - if (enableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) + if (BSParam.VehicleEnableAngularBanking && m_bankingEfficiency != 0 && m_verticalAttractionTimescale < m_verticalAttractionCutoff) { Vector3 bankingContributionV = Vector3.Zero; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 0f84bf7794..75c3399d25 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -155,7 +155,10 @@ public static class BSParam public static Vector3 VehicleInertiaFactor { get; private set; } public static float VehicleGroundGravityFudge { get; private set; } public static float VehicleAngularBankingTimescaleFudge { get; private set; } - public static bool VehicleDebuggingEnable { get; private set; } + public static bool VehicleEnableAngularVerticalAttraction { get; private set; } + public static int VehicleAngularVerticalAttractionAlgorithm { get; private set; } + public static bool VehicleEnableAngularDeflection { get; private set; } + public static bool VehicleEnableAngularBanking { get; private set; } // Convex Hulls public static int CSHullMaxDepthSplit { get; private set; } @@ -606,8 +609,14 @@ public static class BSParam 0.2f ), new ParameterDefn("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.", 60.0f ), - new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging", - false ), + new ParameterDefn("VehicleEnableAngularVerticalAttraction", "Turn on/off vehicle angular vertical attraction effect", + true ), + new ParameterDefn("VehicleAngularVerticalAttractionAlgorithm", "Select vertical attraction algo. You need to look at the source.", + 1 ), + new ParameterDefn("VehicleEnableAngularDeflection", "Turn on/off vehicle angular deflection effect", + true ), + new ParameterDefn("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect", + true ), new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 0f, diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index e56a6f6725..214271b247 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -648,7 +648,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters simTime = Util.EnvironmentTickCountSubtract(beforeTime); if (PhysicsLogging.Enabled) { - DetailLog("{0},DoPhysicsStep,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", + DetailLog("{0},DoPhysicsStep,complete,frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}, objWColl={7}", DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount, ObjectsWithCollisions.Count); } diff --git a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs index 583c436872..48d37428da 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Tests/BasicVehicles.cs @@ -57,6 +57,8 @@ public class BasicVehicles : OpenSimTestCase public void Init() { Dictionary engineParams = new Dictionary(); + engineParams.Add("VehicleEnableAngularVerticalAttraction", "true"); + engineParams.Add("VehicleAngularVerticalAttractionAlgorithm", "1"); PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams); PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere(); @@ -119,7 +121,7 @@ public class BasicVehicles : OpenSimTestCase { vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency); vehicleActor.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale); - vehicleActor.enableAngularVerticalAttraction = true; + // vehicleActor.enableAngularVerticalAttraction = true; TestVehicle.IsPhysical = true; PhysicsScene.ProcessTaints(); From 33eea62606908ca39ac90eb9c99b0eee3c5f39de Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 8 Jul 2013 17:12:39 -0700 Subject: [PATCH 42/93] remove an invalid null UUID check which caused a warning --- .../OptionalModules/Materials/MaterialsDemoModule.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs index 00504d0da8..b997d4d85f 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs @@ -416,14 +416,7 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule if (te.DefaultTexture == null) m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture is null"); else - { - if (te.DefaultTexture.MaterialID == null) - m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture.MaterialID is null"); - else - { - te.DefaultTexture.MaterialID = id; - } - } + te.DefaultTexture.MaterialID = id; } else { From 065f8f56a248724c34d115f77a4d5b1a422f26f4 Mon Sep 17 00:00:00 2001 From: dahlia Date: Mon, 8 Jul 2013 19:18:01 -0700 Subject: [PATCH 43/93] remove some cruft and trigger a rebuild --- OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs index b997d4d85f..0a0d65c656 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs @@ -397,7 +397,6 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule m_log.Debug("[MaterialsDemoModule]: null SOP for localId: " + matLocalID.ToString()); else { - //var te = sop.Shape.Textures; var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); if (te == null) From 2c761cef192670a6f54fe10bb5b5894b5371ea7c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 9 Jul 2013 09:33:46 -0700 Subject: [PATCH 44/93] BulletSim: add parameter to optionally disable vehicle linear deflection. Add parameter to not apply vehicle linear deflection Z forces if vehicle is not colliding. This defaults to 'true' so vehicles will fall even if there is some linear deflection to apply. --- .../Physics/BulletSPlugin/BSDynamics.cs | 42 ++++++++++++------- .../Region/Physics/BulletSPlugin/BSParam.cs | 8 +++- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index a5f2e9849c..0204967368 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -905,6 +905,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin return VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); } } + private float VehicleForwardSpeed { get @@ -1040,26 +1041,37 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 linearDeflectionV = Vector3.Zero; Vector3 velocityV = VehicleForwardVelocity; - // Velocity in Y and Z dimensions is movement to the side or turning. - // Compute deflection factor from the to the side and rotational velocity - linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y); - linearDeflectionV.Z = SortedClampInRange(0, (velocityV.Z * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Z); + if (BSParam.VehicleEnableLinearDeflection) + { + // Velocity in Y and Z dimensions is movement to the side or turning. + // Compute deflection factor from the to the side and rotational velocity + linearDeflectionV.Y = SortedClampInRange(0, (velocityV.Y * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Y); + linearDeflectionV.Z = SortedClampInRange(0, (velocityV.Z * m_linearDeflectionEfficiency) / m_linearDeflectionTimescale, velocityV.Z); - // Velocity to the side and around is corrected and moved into the forward direction - linearDeflectionV.X += Math.Abs(linearDeflectionV.Y); - linearDeflectionV.X += Math.Abs(linearDeflectionV.Z); + // Velocity to the side and around is corrected and moved into the forward direction + linearDeflectionV.X += Math.Abs(linearDeflectionV.Y); + linearDeflectionV.X += Math.Abs(linearDeflectionV.Z); - // Scale the deflection to the fractional simulation time - linearDeflectionV *= pTimestep; + // Scale the deflection to the fractional simulation time + linearDeflectionV *= pTimestep; - // Subtract the sideways and rotational velocity deflection factors while adding the correction forward - linearDeflectionV *= new Vector3(1,-1,-1); + // Subtract the sideways and rotational velocity deflection factors while adding the correction forward + linearDeflectionV *= new Vector3(1, -1, -1); - // Correciont is vehicle relative. Convert to world coordinates and add to the velocity - VehicleVelocity += linearDeflectionV * VehicleOrientation; + // Correction is vehicle relative. Convert to world coordinates. + Vector3 linearDeflectionW = linearDeflectionV * VehicleOrientation; - VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}", - ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV); + // Optionally, if not colliding, don't effect world downward velocity. Let falling things fall. + if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.IsColliding) + { + linearDeflectionW.Z = 0f; + } + + VehicleVelocity += linearDeflectionW; + + VDetailLog("{0}, MoveLinear,LinearDeflection,linDefEff={1},linDefTS={2},linDeflectionV={3}", + ControllingPrim.LocalID, m_linearDeflectionEfficiency, m_linearDeflectionTimescale, linearDeflectionV); + } } public void ComputeLinearTerrainHeightCorrection(float pTimestep) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 75c3399d25..dcf1e830ef 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -155,6 +155,8 @@ public static class BSParam public static Vector3 VehicleInertiaFactor { get; private set; } public static float VehicleGroundGravityFudge { get; private set; } public static float VehicleAngularBankingTimescaleFudge { get; private set; } + public static bool VehicleEnableLinearDeflection { get; private set; } + public static bool VehicleLinearDeflectionNotCollidingNoZ { get; private set; } public static bool VehicleEnableAngularVerticalAttraction { get; private set; } public static int VehicleAngularVerticalAttractionAlgorithm { get; private set; } public static bool VehicleEnableAngularDeflection { get; private set; } @@ -609,10 +611,14 @@ public static class BSParam 0.2f ), new ParameterDefn("VehicleAngularBankingTimescaleFudge", "Factor to multiple angular banking timescale. Tune to increase realism.", 60.0f ), + new ParameterDefn("VehicleEnableLinearDeflection", "Turn on/off vehicle linear deflection effect", + true ), + new ParameterDefn("VehicleLinearDeflectionNotCollidingNoZ", "Turn on/off linear deflection Z effect on non-colliding vehicles", + true ), new ParameterDefn("VehicleEnableAngularVerticalAttraction", "Turn on/off vehicle angular vertical attraction effect", true ), new ParameterDefn("VehicleAngularVerticalAttractionAlgorithm", "Select vertical attraction algo. You need to look at the source.", - 1 ), + 0 ), new ParameterDefn("VehicleEnableAngularDeflection", "Turn on/off vehicle angular deflection effect", true ), new ParameterDefn("VehicleEnableAngularBanking", "Turn on/off vehicle angular banking effect", From 67e500383eb024fe4dd2681d0c5d902f289b65d8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 9 Jul 2013 14:12:52 -0700 Subject: [PATCH 45/93] Put guards on a bunch of exception-inducing code, as seen in logs from load test. --- .../Framework/EntityTransfer/HGEntityTransferModule.cs | 6 +++--- .../Framework/InventoryAccess/HGInventoryAccessModule.cs | 2 +- .../ServiceConnectorsOut/GridUser/ActivityDetector.cs | 5 +++++ OpenSim/Region/Framework/Scenes/Scene.cs | 4 +++- .../Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | 6 ++++++ OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 3 ++- 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 630d1c376f..759155a799 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -171,11 +171,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!so.IsAttachment) return; - if (so.Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) + if (so.AttachedAvatar == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) return; // foreign user - AgentCircuitData aCircuit = so.Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); + AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) { if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) @@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); Dictionary ids = new Dictionary(); - HGUuidGatherer uuidGatherer = new HGUuidGatherer(so.Scene.AssetService, url); + HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url); uuidGatherer.GatherAssetUuids(so, ids); foreach (KeyValuePair kvp in ids) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 1eae0ac4a1..e0c8ea68a4 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -135,7 +135,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (sp is ScenePresence) { AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); - if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) + if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) { if (m_RestrictInventoryAccessAbroad) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 221f81584d..e05d186d20 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs @@ -81,6 +81,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser public void OnConnectionClose(IClientAPI client) { + if (client == null) + return; + if (client.SceneAgent == null) + return; + if (client.SceneAgent.IsChildAgent) return; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 355e0eebde..54956ee3bf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3687,7 +3687,9 @@ namespace OpenSim.Region.Framework.Scenes "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", sp.Name, sp.UUID, RegionInfo.RegionName); - sp.ControllingClient.Close(true); + if (sp.ControllingClient != null) + sp.ControllingClient.Close(true); + sp = null; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index dcb62f88e8..527ca35248 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -67,6 +67,12 @@ namespace OpenSim.Region.Framework.Scenes { int scriptsStarted = 0; + if (m_scene == null) + { + m_log.DebugFormat("[PRIM INVENTORY]: m_scene is null. Unable to create script instances"); + return 0; + } + // Don't start scripts if they're turned off in the region! if (!m_scene.RegionInfo.RegionSettings.DisableScripts) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 7dba7c8e62..3f223a3c73 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -553,7 +553,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void StopScriptInstance(TaskInventoryItem item) { - m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID); + if (m_part.ParentGroup.Scene != null) + m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID); // At the moment, even stopped scripts are counted as active, which is probably wrong. // m_part.ParentGroup.AddActiveScriptCount(-1); From 095066b1cefa7e25ba5983ead1818727c2d64ccc Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 9 Jul 2013 23:39:29 +0100 Subject: [PATCH 46/93] Handle UUIDNameRequest UDP packet processing async instead of within the main inbound UDP processing loop, to avoid any chance that this is delaying the main udp in loop. The potential impact of this should be lower now that these requests are being placed on a queue. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9784d15b3d..bd61c3f268 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5390,7 +5390,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); - AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false); + AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest); AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest); AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest); AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false); From cec8e6d0f7d073d69166a7bc3594772ae51820e2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 9 Jul 2013 23:52:47 +0100 Subject: [PATCH 47/93] If a sensor is in an attachment, avoid throwing an exception if the attachee is removed from the scene before we try to retrieve them. --- .../Shared/Api/Implementation/Plugins/SensorRepeat.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 88ab51545e..6e74227782 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -353,6 +353,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Position of a sensor in a child prim attached to an avatar // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); + + // Don't proceed if the avatar for this attachment has since been removed from the scene. + if (avatar == null) + return sensedEntities; + q = avatar.GetWorldRotation() * q; } @@ -480,6 +485,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Position of a sensor in a child prim attached to an avatar // will be still wrong. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); + + // Don't proceed if the avatar for this attachment has since been removed from the scene. + if (avatar == null) + return sensedEntities; + q = avatar.GetWorldRotation() * q; } From bb6fb65392dfa2249eeade137ea3316b3b3364c9 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 9 Jul 2013 18:24:39 -0700 Subject: [PATCH 48/93] Revert "minor: remove some mono compiler warnings in UserProfileModule" Revert until we understand why all the calls to GetUserProfileServerURI were also commented out. This reverts commit 5f58b9b5526c401e039d27b8c92603ff02421fb8. --- .../Avatar/UserProfiles/UserProfileModule.cs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 44edd7f0a5..161f160ba3 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -304,7 +304,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(targetID, out serverURI); + bool foreign = GetUserProfileServerURI(targetID, out serverURI); UUID creatorId = UUID.Zero; OSDMap parameters= new OSDMap(); @@ -369,7 +369,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(target, out serverURI); + bool foreign = GetUserProfileServerURI(target, out serverURI); object Ad = (object)ad; if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString())) @@ -438,9 +438,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); ScenePresence p = FindPresence(remoteClient.AgentId); + Vector3 avaPos = p.AbsolutePosition; string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); if (land == null) { @@ -487,7 +488,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient) { string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); UUID classifiedId; OSDMap parameters= new OSDMap(); @@ -537,7 +538,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(targetId, out serverURI); + bool foreign = GetUserProfileServerURI(targetId, out serverURI); OSDMap parameters= new OSDMap(); parameters.Add("creatorId", OSD.FromUUID(targetId)); @@ -588,7 +589,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles UUID targetID; UUID.TryParse(args[0], out targetID); string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(targetID, out serverURI); + bool foreign = GetUserProfileServerURI(targetID, out serverURI); IClientAPI remoteClient = (IClientAPI)sender; UserProfilePick pick = new UserProfilePick(); @@ -656,7 +657,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); UserProfilePick pick = new UserProfilePick(); string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); ScenePresence p = FindPresence(remoteClient.AgentId); Vector3 avaPos = p.AbsolutePosition; @@ -716,7 +717,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles public void PickDelete(IClientAPI remoteClient, UUID queryPickID) { string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); OSDMap parameters= new OSDMap(); parameters.Add("pickId", OSD.FromUUID(queryPickID)); @@ -751,7 +752,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles IClientAPI remoteClient = (IClientAPI)sender; string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); note.TargetId = remoteClient.AgentId; UUID.TryParse(args[0], out note.UserId); @@ -787,7 +788,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles note.Notes = queryNotes; string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Note = note; if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) @@ -832,7 +833,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles prop.Language = languages; string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Param = prop; if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString())) @@ -954,7 +955,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles prop.FirstLifeText = newProfile.FirstLifeAboutText; string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); + bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Prop = prop; @@ -993,7 +994,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } string serverURI = string.Empty; -// bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI); + bool foreign = GetUserProfileServerURI(properties.UserId, out serverURI); // This is checking a friend on the home grid // Not HG friend @@ -1246,6 +1247,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles return false; } + byte[] buf = new byte[8192]; Stream rstream = webResponse.GetResponseStream(); OSDMap mret = (OSDMap)OSDParser.DeserializeJson(rstream); @@ -1311,6 +1313,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles return false; } + byte[] buf = new byte[8192]; Stream rstream = webResponse.GetResponseStream(); OSDMap response = new OSDMap(); From 38e6da5522a53c7f65eac64ae7b0af929afb1ae6 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 9 Jul 2013 18:34:24 -0700 Subject: [PATCH 49/93] Comment out old inbound UDP throttling hack. This would cause the UDP reception thread to sleep for 30ms if the number of available user worker threads got low. It doesn't look like any of the UDP packet types are marked async so this check is 1) unnecessary and 2) really crazy since it stops up the reception thread under heavy load without any indication. --- OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 82fad11731..2aab4f9839 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1615,6 +1615,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { IncomingPacket incomingPacket = null; + /* // HACK: This is a test to try and rate limit packet handling on Mono. // If it works, a more elegant solution can be devised if (Util.FireAndForgetCount() < 2) @@ -1622,6 +1623,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping"); Thread.Sleep(30); } + */ if (packetInbox.Dequeue(100, ref incomingPacket)) { From 59d19f038a3fdac0c347844c7884e813f5c5c136 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Wed, 10 Jul 2013 08:55:54 -0700 Subject: [PATCH 50/93] Remove a null reference exception in SimianPresenceServiceConnector that occurs when GetGridUserInfo cannot find the requested user info. --- .../SimianGrid/SimianPresenceServiceConnector.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 0a39088fb3..01163aae0b 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -315,11 +315,15 @@ namespace OpenSim.Services.Connectors.SimianGrid UUID userID = new UUID(user); OSDMap userResponse = GetUserData(userID); - if (userResponse != null) - return ResponseToGridUserInfo(userResponse); - m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}: {1}",userID,userResponse["Message"].AsString()); - return null; + if (userResponse == null) + { + m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}", userID); + } + + // Note that ResponseToGridUserInfo properly checks for and returns a null if passed a null. + return ResponseToGridUserInfo(userResponse); + } #endregion From 1b265b213b65076ee346d85f62d2d61a72ea3ca6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 10 Jul 2013 16:09:45 -0700 Subject: [PATCH 51/93] Added show client-stats [first last] command to expose what viewers are requesting. --- OpenSim/Framework/ClientInfo.cs | 11 +- .../ClientStack/Linden/UDP/LLClientView.cs | 18 ++- .../ClientStack/Linden/UDP/LLUDPClient.cs | 23 ++-- .../Agent/UDP/Linden/LindenUDPInfoModule.cs | 109 +++++++++++++++++- 4 files changed, 143 insertions(+), 18 deletions(-) diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs index 62acb70566..9021315084 100644 --- a/OpenSim/Framework/ClientInfo.cs +++ b/OpenSim/Framework/ClientInfo.cs @@ -33,12 +33,13 @@ namespace OpenSim.Framework { public class ClientInfo { - public AgentCircuitData agentcircuit; + public readonly DateTime StartedTime = DateTime.Now; + public AgentCircuitData agentcircuit = null; public Dictionary needAck; - public List out_packets; - public Dictionary pendingAcks; + public List out_packets = new List(); + public Dictionary pendingAcks = new Dictionary(); public EndPoint proxyEP; public uint sequence; @@ -53,5 +54,9 @@ namespace OpenSim.Framework public int assetThrottle; public int textureThrottle; public int totalThrottle; + + public Dictionary SyncRequests = new Dictionary(); + public Dictionary AsyncRequests = new Dictionary(); + public Dictionary GenericRequests = new Dictionary(); } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index bd61c3f268..3d927054c9 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -678,12 +678,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP //there is a local handler for this packet type if (pprocessor.Async) { + ClientInfo cinfo = UDPClient.GetClientInfo(); + if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString())) + cinfo.AsyncRequests[packet.Type.ToString()] = 0; + cinfo.AsyncRequests[packet.Type.ToString()]++; + object obj = new AsyncPacketProcess(this, pprocessor.method, packet); Util.FireAndForget(ProcessSpecificPacketAsync, obj); result = true; } else { + ClientInfo cinfo = UDPClient.GetClientInfo(); + if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString())) + cinfo.SyncRequests[packet.Type.ToString()] = 0; + cinfo.SyncRequests[packet.Type.ToString()]++; + result = pprocessor.method(this, packet); } } @@ -698,6 +708,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP } if (found) { + ClientInfo cinfo = UDPClient.GetClientInfo(); + if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString())) + cinfo.GenericRequests[packet.Type.ToString()] = 0; + cinfo.GenericRequests[packet.Type.ToString()]++; + result = method(this, packet); } } @@ -12030,7 +12045,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP ClientInfo info = m_udpClient.GetClientInfo(); info.proxyEP = null; - info.agentcircuit = RequestClientInfo(); + if (info.agentcircuit == null) + info.agentcircuit = RequestClientInfo(); return info; } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index 621e0fd1ff..7749446f52 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -159,6 +159,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC private int m_maxRTO = 60000; + private ClientInfo m_info = new ClientInfo(); + /// /// Default constructor /// @@ -240,20 +242,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP // TODO: This data structure is wrong in so many ways. Locking and copying the entire lists // of pending and needed ACKs for every client every time some method wants information about // this connection is a recipe for poor performance - ClientInfo info = new ClientInfo(); - info.pendingAcks = new Dictionary(); - info.needAck = new Dictionary(); - info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate; - info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; - info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; - info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; - info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; - info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; - info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; - info.totalThrottle = (int)m_throttleCategory.DripRate; + m_info.resendThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Resend].DripRate; + m_info.landThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Land].DripRate; + m_info.windThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Wind].DripRate; + m_info.cloudThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].DripRate; + m_info.taskThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Task].DripRate; + m_info.assetThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Asset].DripRate; + m_info.textureThrottle = (int)m_throttleCategories[(int)ThrottleOutPacketType.Texture].DripRate; + m_info.totalThrottle = (int)m_throttleCategory.DripRate; - return info; + return m_info; } /// diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs index 992f38ecb9..b1aec8172d 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Text; using log4net; @@ -51,7 +52,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LindenUDPInfoModule")] public class LindenUDPInfoModule : ISharedRegionModule { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Dictionary m_scenes = new Dictionary(); @@ -130,6 +131,15 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden "Go on/off emergency monitoring mode", "Go on/off emergency monitoring mode", HandleEmergencyMonitoring); + + scene.AddCommand( + "Comms", this, "show client-stats", + "show client-stats [first_name last_name]", + "Show client request stats", + "Without the 'first_name last_name' option, all clients are shown." + + " With the 'first_name last_name' option only a specific client is shown.", + (mod, cmd) => MainConsole.Instance.Output(HandleClientStatsReport(cmd))); + } public void RemoveRegion(Scene scene) @@ -587,6 +597,101 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden (throttleRates.Asset * 8) / 1000); return report.ToString(); - } + } + + /// + /// Show client stats data + /// + /// + /// + protected string HandleClientStatsReport(string[] showParams) + { + // NOTE: This writes to m_log on purpose. We want to store this information + // in case we need to analyze it later. + // + if (showParams.Length <= 3) + { + m_log.InfoFormat("[INFO]: {0,-12} {1,20} {2,6} {3,11} {4, 10}", "Region", "Name", "Root", "Time", "Reqs/min"); + foreach (Scene scene in m_scenes.Values) + { + scene.ForEachClient( + delegate(IClientAPI client) + { + if (client is LLClientView) + { + LLClientView llClient = client as LLClientView; + ClientInfo cinfo = llClient.UDPClient.GetClientInfo(); + int avg_reqs = cinfo.AsyncRequests.Count + cinfo.GenericRequests.Count + cinfo.SyncRequests.Count; + avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); + + m_log.InfoFormat("[INFO]: {0,-12} {1,20} {2,4} {3,9}min {4,10}", + scene.RegionInfo.RegionName, llClient.Name, + (llClient.SceneAgent.IsChildAgent ? "N" : "Y"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs); + } + }); + } + return string.Empty; + } + + string fname = "", lname = ""; + + if (showParams.Length > 2) + fname = showParams[2]; + if (showParams.Length > 3) + lname = showParams[3]; + + foreach (Scene scene in m_scenes.Values) + { + scene.ForEachClient( + delegate(IClientAPI client) + { + if (client is LLClientView) + { + LLClientView llClient = client as LLClientView; + + if (llClient.Name == fname + " " + lname) + { + + ClientInfo cinfo = llClient.GetClientInfo(); + AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(llClient.CircuitCode); + if (aCircuit == null) // create a dummy one + aCircuit = new AgentCircuitData(); + + if (!llClient.SceneAgent.IsChildAgent) + m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, aCircuit.Viewer, aCircuit.Id0); + + int avg_reqs = cinfo.AsyncRequests.Count + cinfo.GenericRequests.Count + cinfo.SyncRequests.Count; + avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); + + m_log.InfoFormat("[INFO]:"); + m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName, + (llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs); + + Dictionary sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry) + .ToDictionary(pair => pair.Key, pair => pair.Value); + + m_log.InfoFormat("[INFO]: {0,25}", "TOP ASYNC"); + foreach (KeyValuePair kvp in sortedDict.Take(12)) + m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); + + m_log.InfoFormat("[INFO]:"); + sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry) + .ToDictionary(pair => pair.Key, pair => pair.Value); + m_log.InfoFormat("[INFO]: {0,25}", "TOP SYNC"); + foreach (KeyValuePair kvp in sortedDict.Take(12)) + m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); + + m_log.InfoFormat("[INFO]:"); + sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry) + .ToDictionary(pair => pair.Key, pair => pair.Value); + m_log.InfoFormat("[INFO]: {0,25}", "TOP GENERIC"); + foreach (KeyValuePair kvp in sortedDict.Take(12)) + m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); + } + } + }); + } + return string.Empty; + } } } \ No newline at end of file From bdaeb02863cb56e0d543b1e97eb3356571911f90 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 10 Jul 2013 17:14:20 -0700 Subject: [PATCH 52/93] show client stats: Fixed the requests/min. Also changed the spelling of the command, not without the dash. --- .../Agent/UDP/Linden/LindenUDPInfoModule.cs | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs index b1aec8172d..79509ab0a0 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs @@ -133,8 +133,8 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden HandleEmergencyMonitoring); scene.AddCommand( - "Comms", this, "show client-stats", - "show client-stats [first_name last_name]", + "Comms", this, "show client stats", + "show client stats [first_name last_name]", "Show client request stats", "Without the 'first_name last_name' option, all clients are shown." + " With the 'first_name last_name' option only a specific client is shown.", @@ -609,7 +609,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden // NOTE: This writes to m_log on purpose. We want to store this information // in case we need to analyze it later. // - if (showParams.Length <= 3) + if (showParams.Length <= 4) { m_log.InfoFormat("[INFO]: {0,-12} {1,20} {2,6} {3,11} {4, 10}", "Region", "Name", "Root", "Time", "Reqs/min"); foreach (Scene scene in m_scenes.Values) @@ -621,7 +621,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden { LLClientView llClient = client as LLClientView; ClientInfo cinfo = llClient.UDPClient.GetClientInfo(); - int avg_reqs = cinfo.AsyncRequests.Count + cinfo.GenericRequests.Count + cinfo.SyncRequests.Count; + int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); m_log.InfoFormat("[INFO]: {0,-12} {1,20} {2,4} {3,9}min {4,10}", @@ -635,10 +635,10 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden string fname = "", lname = ""; - if (showParams.Length > 2) - fname = showParams[2]; if (showParams.Length > 3) - lname = showParams[3]; + fname = showParams[3]; + if (showParams.Length > 4) + lname = showParams[4]; foreach (Scene scene in m_scenes.Values) { @@ -660,7 +660,7 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden if (!llClient.SceneAgent.IsChildAgent) m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, aCircuit.Viewer, aCircuit.Id0); - int avg_reqs = cinfo.AsyncRequests.Count + cinfo.GenericRequests.Count + cinfo.SyncRequests.Count; + int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); m_log.InfoFormat("[INFO]:"); @@ -669,29 +669,30 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden Dictionary sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry) .ToDictionary(pair => pair.Key, pair => pair.Value); + PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum()); - m_log.InfoFormat("[INFO]: {0,25}", "TOP ASYNC"); - foreach (KeyValuePair kvp in sortedDict.Take(12)) - m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); - - m_log.InfoFormat("[INFO]:"); sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry) .ToDictionary(pair => pair.Key, pair => pair.Value); - m_log.InfoFormat("[INFO]: {0,25}", "TOP SYNC"); - foreach (KeyValuePair kvp in sortedDict.Take(12)) - m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); + PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum()); - m_log.InfoFormat("[INFO]:"); sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry) .ToDictionary(pair => pair.Key, pair => pair.Value); - m_log.InfoFormat("[INFO]: {0,25}", "TOP GENERIC"); - foreach (KeyValuePair kvp in sortedDict.Take(12)) - m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); + PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum()); } } }); } return string.Empty; - } + } + + private void PrintRequests(string type, Dictionary sortedDict, int sum) + { + m_log.InfoFormat("[INFO]:"); + m_log.InfoFormat("[INFO]: {0,25}", type); + foreach (KeyValuePair kvp in sortedDict.Take(12)) + m_log.InfoFormat("[INFO]: {0,25} {1,-6}", kvp.Key, kvp.Value); + m_log.InfoFormat("[INFO]: {0,25}", "..."); + m_log.InfoFormat("[INFO]: {0,25} {1,-6}", "Total", sum); + } } } \ No newline at end of file From fe5da43d15506d029be260b2e60a69787686d062 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 10 Jul 2013 19:29:14 -0700 Subject: [PATCH 53/93] EXPERIMENTAL: make RequestImage (UDP packet handler) sync instead of async. This _shouldn't_ screw things up, given that all this does is to dump the request in a queue. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 3d927054c9..16e7207e65 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5373,7 +5373,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.ScriptAnswerYes, HandleScriptAnswerYes, false); AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false); AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false); - AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage); + AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false); AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest); AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest); AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer); From 9173130fde7dd93d6d9ad5dea317e5f1f0e66b40 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 10 Jul 2013 20:48:13 -0700 Subject: [PATCH 54/93] Switched RegionHandshakeReply to Sync, because it's not doing anything blocking. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 16e7207e65..c5b6ac6267 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5312,7 +5312,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject); AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject); AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand); - AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply); + AddLocalPacketHandler(PacketType.RegionHandshakeReply, HandlerRegionHandshakeReply, false); AddLocalPacketHandler(PacketType.AgentWearablesRequest, HandlerAgentWearablesRequest); AddLocalPacketHandler(PacketType.AgentSetAppearance, HandlerAgentSetAppearance); AddLocalPacketHandler(PacketType.AgentIsNowWearing, HandlerAgentIsNowWearing); From 0120e858b7985b0f9571461d036a9099a25af9ad Mon Sep 17 00:00:00 2001 From: dahlia Date: Wed, 10 Jul 2013 22:30:41 -0700 Subject: [PATCH 55/93] remove names from Capability handlers (added by justincc in commit 013710168b3878fc0a93a92a1c026efb49da9935) as they seem to disable the use of multiple access methods for a single Capability in MaterialsDemoModule --- .../OptionalModules/Materials/MaterialsDemoModule.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs index 0a0d65c656..088eb0f72a 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs @@ -139,21 +139,18 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule { string capsBase = "/CAPS/" + caps.CapsObjectPath; - IRequestHandler renderMaterialsPostHandler - = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap, "RenderMaterialsPost", null); - caps.RegisterHandler("RenderMaterialsPost", renderMaterialsPostHandler); + IRequestHandler renderMaterialsPostHandler = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap); + caps.RegisterHandler("RenderMaterials", renderMaterialsPostHandler); // OpenSimulator CAPs infrastructure seems to be somewhat hostile towards any CAP that requires both GET // and POST handlers, (at least at the time this was originally written), so we first set up a POST // handler normally and then add a GET handler via MainServer - IRequestHandler renderMaterialsGetHandler - = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap, "RenderMaterialsGet", null); + IRequestHandler renderMaterialsGetHandler = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap); MainServer.Instance.AddStreamHandler(renderMaterialsGetHandler); // materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well - IRequestHandler renderMaterialsPutHandler - = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap, "RenderMaterialsPut", null); + IRequestHandler renderMaterialsPutHandler = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap); MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler); } From 3b48b6a7927796c3d830a83afe8c8ad558ddf1f8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 11 Jul 2013 09:44:48 -0700 Subject: [PATCH 56/93] Switched TransferRequest (UDP packet handler) to sync. The permissions checks may block, so they get a FireAndForget. Everything else is non-blocking. --- .../ClientStack/Linden/UDP/LLClientView.cs | 236 ++++++++++-------- 1 file changed, 126 insertions(+), 110 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index c5b6ac6267..ef4f190134 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5374,7 +5374,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false); AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false); AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false); - AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest); + AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false); AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest); AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer); AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket); @@ -7751,129 +7751,145 @@ namespace OpenSim.Region.ClientStack.LindenUDP //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request"); TransferRequestPacket transfer = (TransferRequestPacket)Pack; - //m_log.Debug("Transfer Request: " + transfer.ToString()); - // Validate inventory transfers - // Has to be done here, because AssetCache can't do it - // UUID taskID = UUID.Zero; if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) { - taskID = new UUID(transfer.TransferInfo.Params, 48); - UUID itemID = new UUID(transfer.TransferInfo.Params, 64); - UUID requestID = new UUID(transfer.TransferInfo.Params, 80); - -// m_log.DebugFormat( -// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}", -// requestID, itemID, taskID, Name); - if (!(((Scene)m_scene).Permissions.BypassPermissions())) { - if (taskID != UUID.Zero) // Prim + // We're spawning a thread because the permissions check can block this thread + Util.FireAndForget(delegate { - SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID); - - if (part == null) - { - m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist", - Name, requestID, itemID, taskID); - return true; - } - - TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID); - if (tii == null) - { - m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist", - Name, requestID, itemID, taskID); - return true; - } - - if (tii.Type == (int)AssetType.LSLText) - { - if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId)) - return true; - } - else if (tii.Type == (int)AssetType.Notecard) - { - if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId)) - return true; - } - else - { - // TODO: Change this code to allow items other than notecards and scripts to be successfully - // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule - if (part.OwnerID != AgentId) - { - m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}", - Name, requestID, itemID, taskID, part.OwnerID); - return true; - } - - if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) - { - m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set", - Name, requestID, itemID, taskID); - return true; - } - - if (tii.OwnerID != AgentId) - { - m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}", - Name, requestID, itemID, taskID, tii.OwnerID); - return true; - } - - if (( - tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) - != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) - { - m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer", - Name, requestID, itemID, taskID); - return true; - } - - if (tii.AssetID != requestID) - { - m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}", - Name, requestID, itemID, taskID, tii.AssetID); - return true; - } - } - } - else // Agent - { - IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); - if (invAccess != null) - { - if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID)) - return false; - } - else - { - return false; - } - } + // This requests the asset if needed + HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer); + }); + return true; } } - else - if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate) - { - //TransferRequestPacket does not include covenant uuid? - //get scene covenant uuid - taskID = m_scene.RegionInfo.RegionSettings.Covenant; - } + else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate) + { + //TransferRequestPacket does not include covenant uuid? + //get scene covenant uuid + taskID = m_scene.RegionInfo.RegionSettings.Covenant; + } + // This is non-blocking MakeAssetRequest(transfer, taskID); return true; } + private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer) + { + UUID taskID = new UUID(transfer.TransferInfo.Params, 48); + UUID itemID = new UUID(transfer.TransferInfo.Params, 64); + UUID requestID = new UUID(transfer.TransferInfo.Params, 80); + + //m_log.DebugFormat( + // "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}", + // requestID, itemID, taskID, Name); + + //m_log.Debug("Transfer Request: " + transfer.ToString()); + // Validate inventory transfers + // Has to be done here, because AssetCache can't do it + // + if (taskID != UUID.Zero) // Prim + { + SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID); + + if (part == null) + { + m_log.WarnFormat( + "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist", + Name, requestID, itemID, taskID); + return; + } + + TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID); + if (tii == null) + { + m_log.WarnFormat( + "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist", + Name, requestID, itemID, taskID); + return; + } + + if (tii.Type == (int)AssetType.LSLText) + { + if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId)) + return; + } + else if (tii.Type == (int)AssetType.Notecard) + { + if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId)) + return; + } + else + { + // TODO: Change this code to allow items other than notecards and scripts to be successfully + // shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule + if (part.OwnerID != AgentId) + { + m_log.WarnFormat( + "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}", + Name, requestID, itemID, taskID, part.OwnerID); + return; + } + + if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) + { + m_log.WarnFormat( + "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set", + Name, requestID, itemID, taskID); + return; + } + + if (tii.OwnerID != AgentId) + { + m_log.WarnFormat( + "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}", + Name, requestID, itemID, taskID, tii.OwnerID); + return; + } + + if (( + tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) + != ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer)) + { + m_log.WarnFormat( + "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer", + Name, requestID, itemID, taskID); + return; + } + + if (tii.AssetID != requestID) + { + m_log.WarnFormat( + "[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}", + Name, requestID, itemID, taskID, tii.AssetID); + return; + } + } + } + else // Agent + { + IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); + if (invAccess != null) + { + if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID)) + return; + } + else + { + return; + } + } + + // Permissions out of the way, let's request the asset + MakeAssetRequest(transfer, taskID); + + } + + private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack) { AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; From 604967b31e0ce4500587d0b88b81e6eecc4efdae Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 11 Jul 2013 09:47:46 -0700 Subject: [PATCH 57/93] Switched UUIDNameRequest and RegionHandleRequest to Sync, because now they are also non-blocking handlers. --- OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index ef4f190134..79c80a7032 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -5405,8 +5405,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.TeleportLandmarkRequest, HandleTeleportLandmarkRequest); AddLocalPacketHandler(PacketType.TeleportCancel, HandleTeleportCancel); AddLocalPacketHandler(PacketType.TeleportLocationRequest, HandleTeleportLocationRequest); - AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest); - AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest); + AddLocalPacketHandler(PacketType.UUIDNameRequest, HandleUUIDNameRequest, false); + AddLocalPacketHandler(PacketType.RegionHandleRequest, HandleRegionHandleRequest, false); AddLocalPacketHandler(PacketType.ParcelInfoRequest, HandleParcelInfoRequest); AddLocalPacketHandler(PacketType.ParcelAccessListRequest, HandleParcelAccessListRequest, false); AddLocalPacketHandler(PacketType.ParcelAccessListUpdate, HandleParcelAccessListUpdate, false); From c4f1ec1fd643ab3748235dfb89bc1e66165558f9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 11 Jul 2013 10:21:20 -0700 Subject: [PATCH 58/93] Changed the UserProfileModule so that it's less greedy in terms of thread usage. --- .../Avatar/UserProfiles/UserProfileModule.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 161f160ba3..c04098c26d 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -173,7 +173,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles if(obj.PresenceType == PresenceType.Npc) return; - GetImageAssets(((IScenePresence)obj).UUID); + Util.FireAndForget(delegate + { + GetImageAssets(((IScenePresence)obj).UUID); + }); } /// @@ -1044,12 +1047,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles { OSDString assetId = (OSDString)asset; - Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString()), this, - delegate (string assetID, Object s, AssetBase a) - { - // m_log.DebugFormat("[PROFILES]: Getting Image Assets {0}", assetID); - return; - }); + Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString())); } return true; } From 51d106cff88334e1b9eb3628f7bdb8d6a18af4f6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 11 Jul 2013 14:21:57 -0700 Subject: [PATCH 59/93] Added a test for the asset service --- OpenSim/Tests/Clients/Assets/AssetsClient.cs | 99 ++++++++++++++++++++ prebuild.xml | 27 ++++++ 2 files changed, 126 insertions(+) create mode 100644 OpenSim/Tests/Clients/Assets/AssetsClient.cs diff --git a/OpenSim/Tests/Clients/Assets/AssetsClient.cs b/OpenSim/Tests/Clients/Assets/AssetsClient.cs new file mode 100644 index 0000000000..dd168a195b --- /dev/null +++ b/OpenSim/Tests/Clients/Assets/AssetsClient.cs @@ -0,0 +1,99 @@ +/* + * 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.Net; +using System.Text; +using System.Reflection; +using System.Threading; + +using OpenMetaverse; +using log4net; +using log4net.Appender; +using log4net.Layout; + +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors; + +namespace OpenSim.Tests.Clients.AssetsClient +{ + public class AssetsClient + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private static int m_MaxThreadID = 0; + private static readonly int NREQS = 150; + private static int m_NReceived = 0; + + public static void Main(string[] args) + { + ConsoleAppender consoleAppender = new ConsoleAppender(); + consoleAppender.Layout = + new PatternLayout("[%thread] - %message%newline"); + log4net.Config.BasicConfigurator.Configure(consoleAppender); + + string serverURI = "http://127.0.0.1:8003"; + if (args.Length > 1) + serverURI = args[1]; + int max1, max2; + ThreadPool.GetMaxThreads(out max1, out max2); + m_log.InfoFormat("[ASSET CLIENT]: Connecting to {0} max threads = {1} - {2}", serverURI, max1, max2); + ThreadPool.GetMinThreads(out max1, out max2); + m_log.InfoFormat("[ASSET CLIENT]: Connecting to {0} min threads = {1} - {2}", serverURI, max1, max2); + ThreadPool.SetMinThreads(1, 1); + ThreadPool.SetMaxThreads(10, 3); + ServicePointManager.DefaultConnectionLimit = 12; + + AssetServicesConnector m_Connector = new AssetServicesConnector(serverURI); + m_Connector.MaxAssetRequestConcurrency = 30; + + for (int i = 0; i < NREQS; i++) + { + UUID uuid = UUID.Random(); + m_Connector.Get(uuid.ToString(), null, ResponseReceived); + m_log.InfoFormat("[ASSET CLIENT]: [{0}] requested asset {1}", i, uuid); + } + + Thread.Sleep(20 * 1000); + m_log.InfoFormat("[ASSET CLIENT]: Received responses {0}", m_NReceived); + } + + private static void ResponseReceived(string id, Object sender, AssetBase asset) + { + if (Thread.CurrentThread.ManagedThreadId > m_MaxThreadID) + m_MaxThreadID = Thread.CurrentThread.ManagedThreadId; + int max1, max2; + ThreadPool.GetAvailableThreads(out max1, out max2); + m_log.InfoFormat("[ASSET CLIENT]: Received asset {0} ({1}) ({2}-{3})", id, m_MaxThreadID, max1, max2); + m_NReceived++; + } + } +} diff --git a/prebuild.xml b/prebuild.xml index d9e32ea2c3..c7463e42ba 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2631,6 +2631,33 @@ + + + + ../../../../bin/ + + + + + ../../../../bin/ + + + + ../../../../bin/ + + + + + + + + + + + + + + From ee51a9f9c902e1587023b900438331c086680b30 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 11 Jul 2013 14:23:37 -0700 Subject: [PATCH 60/93] Added property to make for more flexible testing. --- OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index 7f7f251c9f..8b04d7f4f3 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs @@ -55,6 +55,11 @@ namespace OpenSim.Services.Connectors // Maps: Asset ID -> Handlers which will be called when the asset has been loaded private Dictionary m_AssetHandlers = new Dictionary(); + public int MaxAssetRequestConcurrency + { + get { return m_maxAssetRequestConcurrency; } + set { m_maxAssetRequestConcurrency = value; } + } public AssetServicesConnector() { From 44e9849ed1190dbc29ffa97fa5df286dc9794edb Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 11 Jul 2013 23:02:30 +0100 Subject: [PATCH 61/93] Fix regression where llHTTPRequests which did not get an OK response returned 499 and the exception message in the http_response event rather than the actual response code and body. This was a regression since commit 831e4c3 (Thu Apr 4 00:36:15 2013) This commit also adds a regression test for this case, though this currently only works with Mono This aims to address http://opensimulator.org/mantis/view.php?id=6704 --- OpenSim/Framework/Util.cs | 7 +- .../HttpRequest/ScriptsHttpRequests.cs | 77 ++++--- .../Tests/ScriptsHttpRequestsTests.cs | 201 ++++++++++++++++++ prebuild.xml | 1 + 4 files changed, 245 insertions(+), 41 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index ba6cc75e12..cafe103135 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -141,6 +141,11 @@ namespace OpenSim.Framework public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool; public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod; + public static bool IsPlatformMono + { + get { return Type.GetType("Mono.Runtime") != null; } + } + /// /// Gets the name of the directory where the current running executable /// is located @@ -1326,7 +1331,7 @@ namespace OpenSim.Framework ru = "OSX/Mono"; else { - if (Type.GetType("Mono.Runtime") != null) + if (IsPlatformMono) ru = "Win/Mono"; else ru = "Win/.NET"; diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 6793fc8226..1a62405078 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -419,7 +419,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest get { return _reqID; } set { _reqID = value; } } - public HttpWebRequest Request; + public WebRequest Request; public string ResponseBody; public List ResponseMetadata; public Dictionary ResponseHeaders; @@ -431,18 +431,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest SendRequest(); } - /* - * TODO: More work on the response codes. Right now - * returning 200 for success or 499 for exception - */ - public void SendRequest() { - HttpWebResponse response = null; - try { - Request = (HttpWebRequest) WebRequest.Create(Url); + Request = WebRequest.Create(Url); Request.Method = HttpMethod; Request.ContentType = HttpMIMEType; @@ -480,14 +473,17 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest } } - foreach (KeyValuePair entry in ResponseHeaders) - if (entry.Key.ToLower().Equals("user-agent")) - Request.UserAgent = entry.Value; - else - Request.Headers[entry.Key] = entry.Value; + if (ResponseHeaders != null) + { + foreach (KeyValuePair entry in ResponseHeaders) + if (entry.Key.ToLower().Equals("user-agent") && Request is HttpWebRequest) + ((HttpWebRequest)Request).UserAgent = entry.Value; + else + Request.Headers[entry.Key] = entry.Value; + } // Encode outbound data - if (OutboundBody.Length > 0) + if (OutboundBody != null && OutboundBody.Length > 0) { byte[] data = Util.UTF8.GetBytes(OutboundBody); @@ -510,12 +506,19 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { throw; } - response = (HttpWebResponse)e.Response; + + HttpWebResponse response = (HttpWebResponse)e.Response; + + Status = (int)response.StatusCode; + ResponseBody = response.StatusDescription; _finished = true; } } catch (Exception e) { +// m_log.Debug( +// string.Format("[SCRIPTS HTTP REQUESTS]: Exception on request to {0} for {1} ", Url, ItemID), e); + Status = (int)OSHttpStatusCode.ClientErrorJoker; ResponseBody = e.Message; _finished = true; @@ -528,33 +531,27 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest try { - response = (HttpWebResponse)Request.EndGetResponse(ar); + try + { + response = (HttpWebResponse)Request.EndGetResponse(ar); + } + catch (WebException e) + { + if (e.Status != WebExceptionStatus.ProtocolError) + { + throw; + } + + response = (HttpWebResponse)e.Response; + } + Status = (int)response.StatusCode; - Stream resStream = response.GetResponseStream(); - StringBuilder sb = new StringBuilder(); - byte[] buf = new byte[8192]; - string tempString = null; - int count = 0; - - do + using (Stream stream = response.GetResponseStream()) { - // fill the buffer with data - count = resStream.Read(buf, 0, buf.Length); - - // make sure we read some data - if (count != 0) - { - // translate from bytes to ASCII text - tempString = Util.UTF8.GetString(buf, 0, count); - - // continue building the string - sb.Append(tempString); - } + StreamReader reader = new StreamReader(stream, Encoding.UTF8); + ResponseBody = reader.ReadToEnd(); } - while (count > 0); // any more data to read? - - ResponseBody = sb.ToString(); } catch (Exception e) { @@ -587,4 +584,4 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest Request.Abort(); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs new file mode 100644 index 0000000000..f638f9161b --- /dev/null +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs @@ -0,0 +1,201 @@ +/* + * 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.Net; +using System.Reflection; +using System.Runtime.Serialization; +using System.Text; +using System.Threading; +using log4net.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenMetaverse.Assets; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Scripting.HttpRequest; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests +{ + class TestWebRequestCreate : IWebRequestCreate + { + public TestWebRequest NextRequest { get; set; } + + public WebRequest Create(Uri uri) + { +// NextRequest.RequestUri = uri; + + return NextRequest; + +// return new TestWebRequest(new SerializationInfo(typeof(TestWebRequest), new FormatterConverter()), new StreamingContext()); + } + } + + class TestWebRequest : WebRequest + { + public override string ContentType { get; set; } + public override string Method { get; set; } + + public Func OnEndGetResponse { get; set; } + + public TestWebRequest() : base() + { +// Console.WriteLine("created"); + } + +// public TestWebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext) +// : base(serializationInfo, streamingContext) +// { +// Console.WriteLine("created"); +// } + + public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state) + { +// Console.WriteLine("bish"); + TestAsyncResult tasr = new TestAsyncResult(); + callback(tasr); + + return tasr; + } + + public override WebResponse EndGetResponse(IAsyncResult asyncResult) + { +// Console.WriteLine("bosh"); + return OnEndGetResponse(asyncResult); + } + } + + class TestHttpWebResponse : HttpWebResponse + { + public string Response { get; set; } + + public TestHttpWebResponse(SerializationInfo serializationInfo, StreamingContext streamingContext) + : base(serializationInfo, streamingContext) {} + + public override Stream GetResponseStream() + { + return new MemoryStream(Encoding.UTF8.GetBytes(Response)); + } + } + + class TestAsyncResult : IAsyncResult + { + WaitHandle m_wh = new ManualResetEvent(true); + + object IAsyncResult.AsyncState + { + get { + throw new System.NotImplementedException (); + } + } + + WaitHandle IAsyncResult.AsyncWaitHandle + { + get { return m_wh; } + } + + bool IAsyncResult.CompletedSynchronously + { + get { return false; } + } + + bool IAsyncResult.IsCompleted + { + get { return true; } + } + } + + /// + /// Test script http request code. + /// + /// + /// This class uses some very hacky workarounds in order to mock HttpWebResponse which are Mono dependent (though + /// alternative code can be written to make this work for Windows). However, the value of being able to + /// regression test this kind of code is very high. + /// + [TestFixture] + public class ScriptsHttpRequestsTests : OpenSimTestCase + { + /// + /// Test what happens when we get a 404 response from a call. + /// + [Test] + public void Test404Response() + { + TestHelpers.InMethod(); + TestHelpers.EnableLogging(); + + if (!Util.IsPlatformMono) + Assert.Ignore("Ignoring test since can only currently run on Mono"); + + string rawResponse = "boom"; + + TestWebRequestCreate twrc = new TestWebRequestCreate(); + + TestWebRequest twr = new TestWebRequest(); + //twr.OnEndGetResponse += ar => new TestHttpWebResponse(null, new StreamingContext()); + twr.OnEndGetResponse += ar => + { + SerializationInfo si = new SerializationInfo(typeof(HttpWebResponse), new FormatterConverter()); + StreamingContext sc = new StreamingContext(); +// WebHeaderCollection headers = new WebHeaderCollection(); +// si.AddValue("m_HttpResponseHeaders", headers); + si.AddValue("uri", new Uri("test://arrg")); +// si.AddValue("m_Certificate", null); + si.AddValue("version", HttpVersion.Version11); + si.AddValue("statusCode", HttpStatusCode.NotFound); + si.AddValue("contentLength", 0); + si.AddValue("method", "GET"); + si.AddValue("statusDescription", "Not Found"); + si.AddValue("contentType", null); + si.AddValue("cookieCollection", new CookieCollection()); + + TestHttpWebResponse thwr = new TestHttpWebResponse(si, sc); + thwr.Response = rawResponse; + + throw new WebException("no message", null, WebExceptionStatus.ProtocolError, thwr); + }; + + twrc.NextRequest = twr; + + WebRequest.RegisterPrefix("test", twrc); + HttpRequestClass hr = new HttpRequestClass(); + hr.Url = "test://something"; + hr.SendRequest(); + + while (!hr.Finished) + Thread.Sleep(100); + + Assert.That(hr.Status, Is.EqualTo((int)HttpStatusCode.NotFound)); + Assert.That(hr.ResponseBody, Is.EqualTo(rawResponse)); + } + } +} \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index d9e32ea2c3..d32287a0d5 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3102,6 +3102,7 @@ + From e15a15688bbee6b7a76bb29f7879e0c59491449a Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 11 Jul 2013 23:11:35 +0100 Subject: [PATCH 62/93] minor: Take out unnecessary clumsy sleep at the end of regression Test404Response(). This wasn't actually necessary in the end but was accidentally left in. --- .../Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs index f638f9161b..180a046631 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs @@ -191,9 +191,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests hr.Url = "test://something"; hr.SendRequest(); - while (!hr.Finished) - Thread.Sleep(100); - Assert.That(hr.Status, Is.EqualTo((int)HttpStatusCode.NotFound)); Assert.That(hr.ResponseBody, Is.EqualTo(rawResponse)); } From 7c2e4786ce9b85459b8c8973f658aa9a221925dc Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 11 Jul 2013 23:19:55 +0100 Subject: [PATCH 63/93] minor: remove some regression test logging switches accidentally left uncommented. --- .../Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs | 2 +- .../Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs index 180a046631..e812d816dc 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs @@ -151,7 +151,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests public void Test404Response() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); if (!Util.IsPlatformMono) Assert.Ignore("Ignoring test since can only currently run on Mono"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs index 5714042f62..b6fb730840 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests public void TestChildAgentSingleRegionCapabilities() { TestHelpers.InMethod(); - TestHelpers.EnableLogging(); +// TestHelpers.EnableLogging(); UUID spUuid = TestHelpers.ParseTail(0x1); From ba8f9c9d0a7d07b7587663baef9c52293a3ac404 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 11 Jul 2013 23:51:10 +0100 Subject: [PATCH 64/93] Try naming the materials handlers again, this time registering the POST as RenderMaterials This was probably the mistake. The other handlers are named RenderMaterials as well but this actully has no affect apart from on stats, due to a (counterintuitive) disconnect between the registration name and the name of the request handler. Will be tested very soon and reverted if this still does not work. --- .../OptionalModules/Materials/MaterialsDemoModule.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs index 088eb0f72a..d8f5563624 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsDemoModule.cs @@ -139,18 +139,21 @@ namespace OpenSim.Region.OptionalModules.MaterialsDemoModule { string capsBase = "/CAPS/" + caps.CapsObjectPath; - IRequestHandler renderMaterialsPostHandler = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap); + IRequestHandler renderMaterialsPostHandler + = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap, "RenderMaterials", null); caps.RegisterHandler("RenderMaterials", renderMaterialsPostHandler); // OpenSimulator CAPs infrastructure seems to be somewhat hostile towards any CAP that requires both GET // and POST handlers, (at least at the time this was originally written), so we first set up a POST // handler normally and then add a GET handler via MainServer - IRequestHandler renderMaterialsGetHandler = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap); + IRequestHandler renderMaterialsGetHandler + = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap, "RenderMaterials", null); MainServer.Instance.AddStreamHandler(renderMaterialsGetHandler); // materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well - IRequestHandler renderMaterialsPutHandler = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap); + IRequestHandler renderMaterialsPutHandler + = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap, "RenderMaterials", null); MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler); } From 83d1680057419229b0708bde59b12159006195cd Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 11 Jul 2013 16:43:43 -0700 Subject: [PATCH 65/93] Added a few more thingies to the asset client test to poke the threadpool. --- OpenSim/Tests/Clients/Assets/AssetsClient.cs | 21 ++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/OpenSim/Tests/Clients/Assets/AssetsClient.cs b/OpenSim/Tests/Clients/Assets/AssetsClient.cs index dd168a195b..26d740b771 100644 --- a/OpenSim/Tests/Clients/Assets/AssetsClient.cs +++ b/OpenSim/Tests/Clients/Assets/AssetsClient.cs @@ -82,7 +82,16 @@ namespace OpenSim.Tests.Clients.AssetsClient m_log.InfoFormat("[ASSET CLIENT]: [{0}] requested asset {1}", i, uuid); } - Thread.Sleep(20 * 1000); + for (int i = 0; i < 500; i++) + { + var x = i; + ThreadPool.QueueUserWorkItem(delegate + { + Dummy(x); + }); + } + + Thread.Sleep(30 * 1000); m_log.InfoFormat("[ASSET CLIENT]: Received responses {0}", m_NReceived); } @@ -92,8 +101,16 @@ namespace OpenSim.Tests.Clients.AssetsClient m_MaxThreadID = Thread.CurrentThread.ManagedThreadId; int max1, max2; ThreadPool.GetAvailableThreads(out max1, out max2); - m_log.InfoFormat("[ASSET CLIENT]: Received asset {0} ({1}) ({2}-{3})", id, m_MaxThreadID, max1, max2); + m_log.InfoFormat("[ASSET CLIENT]: Received asset {0} ({1}) ({2}-{3}) {4}", id, m_MaxThreadID, max1, max2, DateTime.Now.ToString("hh:mm:ss")); m_NReceived++; } + + private static void Dummy(int i) + { + int max1, max2; + ThreadPool.GetAvailableThreads(out max1, out max2); + m_log.InfoFormat("[ASSET CLIENT]: ({0}) Hello! {1} - {2} {3}", i, max1, max2, DateTime.Now.ToString("hh:mm:ss")); + Thread.Sleep(2000); + } } } From 1909ee70f8f3df6558ce2abfc8b1d03fc5565a63 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 11 Jul 2013 16:57:07 -0700 Subject: [PATCH 66/93] Centralize duplicated code in SceneObjectPart for subscribing to collision events. Improve logic for knowing when to add processing routine to physics actor. --- .../Framework/Scenes/SceneObjectPart.cs | 97 ++++++++----------- 1 file changed, 43 insertions(+), 54 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f361acb1f8..830fe31319 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4213,31 +4213,12 @@ namespace OpenSim.Region.Framework.Scenes AddToPhysics(UsePhysics, SetPhantom, false); pa = PhysActor; - if (pa != null) { pa.SetMaterial(Material); DoPhysicsPropertyUpdate(UsePhysics, true); - - if ( - ((AggregateScriptEvents & scriptEvents.collision) != 0) || - ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || - ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || - (CollisionSound != UUID.Zero) - ) - { - pa.OnCollisionUpdate += PhysicsCollision; - pa.SubscribeEvents(1000); - } + + SubscribeForCollisionEvents(); } } else // it already has a physical representation @@ -4291,6 +4272,46 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); } + // Subscribe for physics collision events if needed for scripts and sounds + public void SubscribeForCollisionEvents() + { + if (PhysActor != null) + { + if ( + ((AggregateScriptEvents & scriptEvents.collision) != 0) || + ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || + ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || + ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || + ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || + ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || + ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || + (CollisionSound != UUID.Zero) + ) + { + if (!PhysActor.SubscribedEvents()) + { + // If not already subscribed for event, set up for a collision event. + PhysActor.OnCollisionUpdate += PhysicsCollision; + PhysActor.SubscribeEvents(1000); + } + } + else + { + // There is no need to be subscribed to collisions so, if subscribed, remove subscription + if (PhysActor.SubscribedEvents()) + { + PhysActor.OnCollisionUpdate -= PhysicsCollision; + PhysActor.UnSubscribeEvents(); + } + } + } + } + /// /// Adds this part to the physics scene. /// @@ -4680,39 +4701,7 @@ namespace OpenSim.Region.Framework.Scenes objectflagupdate |= (uint) PrimFlags.AllowInventoryDrop; } - PhysicsActor pa = PhysActor; - - if ( - ((AggregateScriptEvents & scriptEvents.collision) != 0) || - ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || - ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || - ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_end) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.collision_start) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision) != 0) || - ((ParentGroup.RootPart.AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || - (CollisionSound != UUID.Zero) - ) - { - // subscribe to physics updates. - if (pa != null) - { - pa.OnCollisionUpdate += PhysicsCollision; - pa.SubscribeEvents(1000); - } - } - else - { - if (pa != null) - { - pa.UnSubscribeEvents(); - pa.OnCollisionUpdate -= PhysicsCollision; - } - } + SubscribeForCollisionEvents(); //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) //{ From 65239b059fc8a92eee1d27655a6f85826c99306b Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 11 Jul 2013 20:55:32 -0700 Subject: [PATCH 67/93] Enhance NullEstateData to remember stored estate values and return them next time asked. This keeps any estate settings from being reset when the estate dialog is opened in a region with null estate storage. --- OpenSim/Data/Null/NullEstateData.cs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/OpenSim/Data/Null/NullEstateData.cs b/OpenSim/Data/Null/NullEstateData.cs index d64136de8d..1df397d943 100755 --- a/OpenSim/Data/Null/NullEstateData.cs +++ b/OpenSim/Data/Null/NullEstateData.cs @@ -42,6 +42,22 @@ namespace OpenSim.Data.Null // private string m_connectionString; + private Dictionary m_knownEstates = new Dictionary(); + private EstateSettings m_estate = null; + + private EstateSettings GetEstate() + { + if (m_estate == null) + { + // This fools the initialization caller into thinking an estate was fetched (a check in OpenSimBase). + // The estate info is pretty empty so don't try banning anyone. + m_estate = new EstateSettings(); + m_estate.EstateID = 1; + m_estate.OnSave += StoreEstateSettings; + } + return m_estate; + } + protected virtual Assembly Assembly { get { return GetType().Assembly; } @@ -68,21 +84,18 @@ namespace OpenSim.Data.Null public EstateSettings LoadEstateSettings(UUID regionID, bool create) { - // This fools the initialization caller into thinking an estate was fetched (a check in OpenSimBase). - // The estate info is pretty empty so don't try banning anyone. - EstateSettings oneEstate = new EstateSettings(); - oneEstate.EstateID = 1; - return oneEstate; + return GetEstate(); } public void StoreEstateSettings(EstateSettings es) { + m_estate = es; return; } public EstateSettings LoadEstateSettings(int estateID) { - return new EstateSettings(); + return GetEstate(); } public EstateSettings CreateNewEstate() @@ -93,13 +106,14 @@ namespace OpenSim.Data.Null public List LoadEstateSettingsAll() { List allEstateSettings = new List(); - allEstateSettings.Add(new EstateSettings()); + allEstateSettings.Add(GetEstate()); return allEstateSettings; } public List GetEstatesAll() { List result = new List(); + result.Add((int)GetEstate().EstateID); return result; } From 29f6ae199efd705052422b2fe9dd0e815447b0a8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 12 Jul 2013 12:53:58 -0700 Subject: [PATCH 68/93] Changed UploadBakedTextureModule so that it uses the same pattern as the others, in preparation for experiments to direct baked texture uploads to a robust instance. No functional or configuration changes -- should work exactly as before. --- .../Linden/Caps/UploadBakedTextureModule.cs | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index 3b0ccd75ec..79a935d76d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -63,9 +63,16 @@ namespace OpenSim.Region.ClientStack.Linden private Scene m_scene; private bool m_persistBakedTextures; + private string m_URL; public void Initialise(IConfigSource source) { + IConfig config = source.Configs["ClientStack.LindenCaps"]; + if (config == null) + return; + + m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty); + IConfig appearanceConfig = source.Configs["Appearance"]; if (appearanceConfig != null) m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); @@ -100,15 +107,27 @@ namespace OpenSim.Region.ClientStack.Linden public void RegisterCaps(UUID agentID, Caps caps) { - caps.RegisterHandler( - "UploadBakedTexture", - new RestStreamHandler( - "POST", - "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, - new UploadBakedTextureHandler( - caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture, + UUID capID = UUID.Random(); + + //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + if (m_URL == "localhost") + { + caps.RegisterHandler( "UploadBakedTexture", - agentID.ToString())); + new RestStreamHandler( + "POST", + "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, + new UploadBakedTextureHandler( + caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture, + "UploadBakedTexture", + agentID.ToString())); + + } + else + { + caps.RegisterHandler("UploadBakedTexture", m_URL); + } + } } } \ No newline at end of file From fa02f28dbfef9b9dc3621f5bbd6b026c827459a5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 12 Jul 2013 14:04:14 -0700 Subject: [PATCH 69/93] Add ToOSDMap() overrides to the Stat subclass CounterStat. Add a GetStatsAsOSDMap method to StatsManager which allows the filtered fetching of stats for eventual returning over the internets. --- .../Framework/Monitoring/Stats/CounterStat.cs | 21 ++++++ OpenSim/Framework/Monitoring/Stats/Stat.cs | 1 + OpenSim/Framework/Monitoring/StatsManager.cs | 66 +++++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/OpenSim/Framework/Monitoring/Stats/CounterStat.cs b/OpenSim/Framework/Monitoring/Stats/CounterStat.cs index caea30dd5d..04442c35b1 100755 --- a/OpenSim/Framework/Monitoring/Stats/CounterStat.cs +++ b/OpenSim/Framework/Monitoring/Stats/CounterStat.cs @@ -224,5 +224,26 @@ public class CounterStat : Stat } } } + + // CounterStat is a basic stat plus histograms + public override OSDMap ToOSDMap() + { + // Get the foundational instance + OSDMap map = base.ToOSDMap(); + + map["StatType"] = "CounterStat"; + + // If there are any histograms, add a new field that is an array of histograms as OSDMaps + if (m_histograms.Count > 0) + { + OSDArray histos = new OSDArray(); + foreach (EventHistogram histo in m_histograms.Values) + { + histos.Add(histo.GetHistogramAsOSDMap()); + } + map.Add("Histograms", histos); + } + return map; + } } } diff --git a/OpenSim/Framework/Monitoring/Stats/Stat.cs b/OpenSim/Framework/Monitoring/Stats/Stat.cs index c57ee0c3e8..9629b6e654 100644 --- a/OpenSim/Framework/Monitoring/Stats/Stat.cs +++ b/OpenSim/Framework/Monitoring/Stats/Stat.cs @@ -242,6 +242,7 @@ namespace OpenSim.Framework.Monitoring ret.Add("Description", OSD.FromString(Description)); ret.Add("UnitName", OSD.FromString(UnitName)); ret.Add("Value", OSD.FromReal(Value)); + ret.Add("StatType", "Stat"); // used by overloading classes to denote type of stat return ret; } diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs index 12d3a75d50..a5b54c9bf9 100644 --- a/OpenSim/Framework/Monitoring/StatsManager.cs +++ b/OpenSim/Framework/Monitoring/StatsManager.cs @@ -30,6 +30,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using OpenMetaverse.StructuredData; + namespace OpenSim.Framework.Monitoring { /// @@ -168,6 +170,70 @@ namespace OpenSim.Framework.Monitoring } } + // Creates an OSDMap of the format: + // { categoryName: { + // containerName: { + // statName: { + // "Name": name, + // "ShortName": shortName, + // ... + // }, + // statName: { + // "Name": name, + // "ShortName": shortName, + // ... + // }, + // ... + // }, + // containerName: { + // ... + // }, + // ... + // }, + // categoryName: { + // ... + // }, + // ... + // } + // The passed in parameters will filter the categories, containers and stats returned. If any of the + // parameters are either EmptyOrNull or the AllSubCommand value, all of that type will be returned. + // Case matters. + public static OSDMap GetStatsAsOSDMap(string pCategoryName, string pContainerName, string pStatName) + { + OSDMap map = new OSDMap(); + + foreach (string catName in RegisteredStats.Keys) + { + // Do this category if null spec, "all" subcommand or category name matches passed parameter. + // Skip category if none of the above. + if (!(String.IsNullOrEmpty(pCategoryName) || pCategoryName == AllSubCommand || pCategoryName == catName)) + continue; + + OSDMap contMap = new OSDMap(); + foreach (string contName in RegisteredStats[catName].Keys) + { + if (!(string.IsNullOrEmpty(pContainerName) || pContainerName == AllSubCommand || pContainerName == contName)) + continue; + + OSDMap statMap = new OSDMap(); + + SortedDictionary theStats = RegisteredStats[catName][contName]; + foreach (string statName in theStats.Keys) + { + if (!(String.IsNullOrEmpty(pStatName) || pStatName == AllSubCommand || pStatName == statName)) + continue; + + statMap.Add(statName, theStats[statName].ToOSDMap()); + } + + contMap.Add(contName, statMap); + } + map.Add(catName, contMap); + } + + return map; + } + // /// // /// Start collecting statistics related to assets. // /// Should only be called once. From 3d118fb580ea0a5e9d9b23f5f876fca80cd17d0e Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 12 Jul 2013 18:53:27 +0100 Subject: [PATCH 70/93] In co-op termination, extend EventWaitHandle to give this an indefinite lifetime in order to avoid a later RemotingException if scripts are being loaded into their own domains. This is necessary because XEngineScriptBase now retains a reference to an EventWaitHandle when co-op termination is active. Aims to address http://opensimulator.org/mantis/view.php?id=6634 --- .../Shared/Instance/ScriptInstance.cs | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 887a31765a..229180fe87 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -241,7 +241,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") { m_coopTermination = true; - m_coopSleepHandle = new AutoResetEvent(false); + m_coopSleepHandle = new XEngineEventWaitHandle(false, EventResetMode.AutoReset); } } @@ -1201,4 +1201,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance Suspended = false; } } -} + + /// + /// Xengine event wait handle. + /// + /// + /// This class exists becase XEngineScriptBase gets a reference to this wait handle. We need to make sure that + /// when scripts are running in different AppDomains the lease does not expire. + /// FIXME: Like LSL_Api, etc., this effectively leaks memory since the GC will never collect it. To avoid this, + /// proper remoting sponsorship needs to be implemented across the board. + /// + public class XEngineEventWaitHandle : EventWaitHandle + { + public XEngineEventWaitHandle(bool initialState, EventResetMode mode) : base(initialState, mode) {} + + public override Object InitializeLifetimeService() + { + return null; + } + } +} \ No newline at end of file From d06c85ea77f76f4d915081ed6b314d66d6d38fbf Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 13 Jul 2013 00:29:07 +0100 Subject: [PATCH 71/93] Reinsert PhysicsActor variable back into SOP.SubscribeForCollisionEvents() in order to avoid a race condition. A separate PhysicsActor variable is used in case some other thread removes the PhysicsActor whilst this code is executing. If this is now impossible please revert - just adding this now whilst I remember. Also makes method comment into proper method doc. --- .../Framework/Scenes/SceneObjectPart.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 830fe31319..eb3af42a13 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4272,10 +4272,14 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat("[SCENE OBJECT PART]: Updated PrimFlags on {0} {1} to {2}", Name, LocalId, Flags); } - // Subscribe for physics collision events if needed for scripts and sounds + /// + /// Subscribe for physics collision events if needed for scripts and sounds + /// public void SubscribeForCollisionEvents() { - if (PhysActor != null) + PhysicsActor pa = PhysActor; + + if (pa != null) { if ( ((AggregateScriptEvents & scriptEvents.collision) != 0) || @@ -4293,20 +4297,20 @@ namespace OpenSim.Region.Framework.Scenes (CollisionSound != UUID.Zero) ) { - if (!PhysActor.SubscribedEvents()) + if (!pa.SubscribedEvents()) { // If not already subscribed for event, set up for a collision event. - PhysActor.OnCollisionUpdate += PhysicsCollision; - PhysActor.SubscribeEvents(1000); + pa.OnCollisionUpdate += PhysicsCollision; + pa.SubscribeEvents(1000); } } else { // There is no need to be subscribed to collisions so, if subscribed, remove subscription - if (PhysActor.SubscribedEvents()) + if (pa.SubscribedEvents()) { - PhysActor.OnCollisionUpdate -= PhysicsCollision; - PhysActor.UnSubscribeEvents(); + pa.OnCollisionUpdate -= PhysicsCollision; + pa.UnSubscribeEvents(); } } } From cd64a70c793e746416a7f91e423d52dda4b05722 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 08:31:03 -0700 Subject: [PATCH 72/93] Added UploadBakedTexture/UploadBakedTextureServerConnector, so that this can eventually be served by a robust instance. NOT FINISHED YET. --- .../UploadBakedTextureServerConnector.cs | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs new file mode 100644 index 0000000000..10ea8eefe6 --- /dev/null +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs @@ -0,0 +1,76 @@ +/* + * 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 Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; +using OpenMetaverse; + +namespace OpenSim.Capabilities.Handlers +{ + public class UploadBakedTextureServerConnector : ServiceConnector + { + private IAssetService m_AssetService; + private string m_ConfigName = "CapsService"; + + public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + if (configName != String.Empty) + m_ConfigName = configName; + + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName)); + + string assetService = serverConfig.GetString("AssetService", String.Empty); + + if (assetService == String.Empty) + throw new Exception("No AssetService in config file"); + + Object[] args = new Object[] { config }; + m_AssetService = + ServerUtils.LoadPlugin(assetService, args); + + if (m_AssetService == null) + throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); + + // NEED TO FIX THIS + OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, ""); + server.AddStreamHandler(new RestStreamHandler( + "POST", + "/CAPS/UploadBakedTexture/", + new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture, + "UploadBakedTexture", + "Upload Baked Texture Capability")); + + } + } +} \ No newline at end of file From a412b1d6823141129bef3ab906c6590eb6a81c72 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 09:46:58 -0700 Subject: [PATCH 73/93] Moved SendInitialDataToMe to earlier in CompleteMovement. Moved TriggerOnMakeRootAgent to the end of CompleteMovement. Justin, if you read this, there's a long story here. Some time ago you placed SendInitialDataToMe at the very beginning of client creation (in LLUDPServer). That is problematic, as we discovered relatively recently: on TPs, as soon as the client starts getting data from child agents, it starts requesting resources back *from the simulator where its root agent is*. We found this to be the problem behind meshes missing on HG TPs (because the viewer was requesting the meshes of the receiving sim from the departing grid). But this affects much more than meshes and HG TPs. It may also explain cloud avatars after a local TP: baked textures are only stored in the simulator, so if a child agent receives a UUID of a baked texture in the destination sim and requests that texture from the departing sim where the root agent is, it will fail to get that texture. Bottom line: we need to delay sending the new simulator data to the viewer until we are absolutely sure that the viewer knows that its main agent is in a new sim. Hence, moving it to CompleteMovement. Now I am trying to tune the initial rez delay that we all experience in the CC. I think that when I fixed the issue described above, I may have moved SendInitialDataToMe to much later than it should be, so now I'm moving to earlier in CompleteMovement. --- .../ClientStack/Linden/UDP/LLUDPServer.cs | 2 +- .../Region/Framework/Scenes/ScenePresence.cs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 2aab4f9839..85270a6e2d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -1469,7 +1469,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); bool tp = (aCircuit.teleportFlags > 0); - // Let's delay this for TP agents, otherwise the viewer doesn't know where to get meshes from + // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from if (!tp) client.SceneAgent.SendInitialDataToMe(); } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 774546c693..bd4f68e018 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1010,7 +1010,9 @@ namespace OpenSim.Region.Framework.Scenes // recorded, which stops the input from being processed. MovementFlag = 0; - m_scene.EventManager.TriggerOnMakeRootAgent(this); + // DIVA NOTE: I moved TriggerOnMakeRootAgent out of here and into the end of + // CompleteMovement. We don't want modules doing heavy computation before CompleteMovement + // is over. } public int GetStateSource() @@ -1327,10 +1329,15 @@ namespace OpenSim.Region.Framework.Scenes bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); MakeRootAgent(AbsolutePosition, flying); ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); + // Remember in HandleUseCircuitCode, we delayed this to here + // This will also send the initial data to clients when TP to a neighboring region. + // Not ideal, but until we know we're TP-ing from a neighboring region, there's not much we can do + if (m_teleportFlags > 0) + SendInitialDataToMe(); // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); - if ((m_callbackURI != null) && !m_callbackURI.Equals("")) + if (!string.IsNullOrEmpty(m_callbackURI)) { // We cannot sleep here since this would hold up the inbound packet processing thread, as // CompleteMovement() is executed synchronously. However, it might be better to delay the release @@ -1358,9 +1365,6 @@ namespace OpenSim.Region.Framework.Scenes // Create child agents in neighbouring regions if (openChildAgents && !IsChildAgent) { - // Remember in HandleUseCircuitCode, we delayed this to here - SendInitialDataToMe(); - IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); if (m_agentTransfer != null) Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); @@ -1382,6 +1386,11 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); + + // DIVA NOTE: moved this here from MakeRoot. We don't want modules making heavy + // computations before CompleteMovement is over + m_scene.EventManager.TriggerOnMakeRootAgent(this); + } /// From ff4ad60207431427e26a365df1ff28aa380faf12 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 10:05:11 -0700 Subject: [PATCH 74/93] Same issue as previous commit. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bd4f68e018..fcb841a579 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2694,15 +2694,16 @@ namespace OpenSim.Region.Framework.Scenes // we created a new ScenePresence (a new child agent) in a fresh region. // Request info about all the (root) agents in this region // Note: This won't send data *to* other clients in that region (children don't send) - SendOtherAgentsAvatarDataToMe(); - SendOtherAgentsAppearanceToMe(); - EntityBase[] entities = Scene.Entities.GetEntities(); foreach(EntityBase e in entities) { if (e != null && e is SceneObjectGroup) ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); } + + SendOtherAgentsAvatarDataToMe(); + SendOtherAgentsAppearanceToMe(); + }); } From 3a26e366d2829c2f66a8aa22158bd0905f0894de Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 10:35:41 -0700 Subject: [PATCH 75/93] This commit effectively reverses the previous one, but it's just to log that we found the root of the rez delay: the priority scheme BestAvatarResponsiveness, which is currently the default, was the culprit. Changing it to FrontBack made the region rez be a lot more natural. BestAvatarResponsiveness introduces the region rez delay in cases where the region is full of avatars with lots of attachments, which is the case in CC load tests. In that case, the inworld prims are sent only after all avatar attachments are sent. Not recommended for regions with heavy avatar traffic! --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fcb841a579..9f8ada35a3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2694,16 +2694,16 @@ namespace OpenSim.Region.Framework.Scenes // we created a new ScenePresence (a new child agent) in a fresh region. // Request info about all the (root) agents in this region // Note: This won't send data *to* other clients in that region (children don't send) + SendOtherAgentsAvatarDataToMe(); + SendOtherAgentsAppearanceToMe(); + EntityBase[] entities = Scene.Entities.GetEntities(); - foreach(EntityBase e in entities) + foreach (EntityBase e in entities) { if (e != null && e is SceneObjectGroup) ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); } - SendOtherAgentsAvatarDataToMe(); - SendOtherAgentsAppearanceToMe(); - }); } From 682537738008746f0aca22954902f3a4dfbdc95f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 11:11:18 -0700 Subject: [PATCH 76/93] Trying to reduce CPU usage on logins and TPs: trying radical elimination of all FireAndForgets throughout CompleteMovement. There were 4. --- .../Avatar/UserProfiles/UserProfileModule.cs | 5 +- .../Region/Framework/Scenes/ScenePresence.cs | 60 ++++++++----------- 2 files changed, 27 insertions(+), 38 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index c04098c26d..e7216ed397 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -173,10 +173,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles if(obj.PresenceType == PresenceType.Npc) return; - Util.FireAndForget(delegate - { - GetImageAssets(((IScenePresence)obj).UUID); - }); + GetImageAssets(((IScenePresence)obj).UUID); } /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9f8ada35a3..4d796fead2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -958,14 +958,7 @@ namespace OpenSim.Region.Framework.Scenes // Viewers which have a current outfit folder will actually rez their own attachments. However, // viewers without (e.g. v1 viewers) will not, so we still need to make this call. if (Scene.AttachmentsModule != null) - Util.FireAndForget( - o => - { -// if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) -// System.Threading.Thread.Sleep(7000); - - Scene.AttachmentsModule.RezAttachments(this); - }); + Scene.AttachmentsModule.RezAttachments(this); } else { @@ -1362,18 +1355,6 @@ namespace OpenSim.Region.Framework.Scenes ValidateAndSendAppearanceAndAgentData(); - // Create child agents in neighbouring regions - if (openChildAgents && !IsChildAgent) - { - IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); - if (m_agentTransfer != null) - Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); - - IFriendsModule friendsModule = m_scene.RequestModuleInterface(); - if (friendsModule != null) - friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); - } - // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. // This may be due to viewer code or it may be something we're not doing properly simulator side. @@ -1383,6 +1364,19 @@ namespace OpenSim.Region.Framework.Scenes sog.ScheduleGroupForFullUpdate(); } + // Create child agents in neighbouring regions + if (openChildAgents && !IsChildAgent) + { + IFriendsModule friendsModule = m_scene.RequestModuleInterface(); + if (friendsModule != null) + friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); + + IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); + if (m_agentTransfer != null) + m_agentTransfer.EnableChildAgents(this); // this can take a while... several seconds + + } + // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); @@ -2689,22 +2683,20 @@ namespace OpenSim.Region.Framework.Scenes public void SendInitialDataToMe() { // Send all scene object to the new client - Util.FireAndForget(delegate + + // we created a new ScenePresence (a new child agent) in a fresh region. + // Request info about all the (root) agents in this region + // Note: This won't send data *to* other clients in that region (children don't send) + SendOtherAgentsAvatarDataToMe(); + SendOtherAgentsAppearanceToMe(); + + EntityBase[] entities = Scene.Entities.GetEntities(); + foreach (EntityBase e in entities) { - // we created a new ScenePresence (a new child agent) in a fresh region. - // Request info about all the (root) agents in this region - // Note: This won't send data *to* other clients in that region (children don't send) - SendOtherAgentsAvatarDataToMe(); - SendOtherAgentsAppearanceToMe(); + if (e != null && e is SceneObjectGroup) + ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); + } - EntityBase[] entities = Scene.Entities.GetEntities(); - foreach (EntityBase e in entities) - { - if (e != null && e is SceneObjectGroup) - ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); - } - - }); } /// From bc405a6a349f4d2be3f79afe7e8a88738339ef1f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 11:30:37 -0700 Subject: [PATCH 77/93] That didn't fix the problem. Revert "Trying to reduce CPU usage on logins and TPs: trying radical elimination of all FireAndForgets throughout CompleteMovement. There were 4." This reverts commit 682537738008746f0aca22954902f3a4dfbdc95f. --- .../Avatar/UserProfiles/UserProfileModule.cs | 5 +- .../Region/Framework/Scenes/ScenePresence.cs | 60 +++++++++++-------- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index e7216ed397..c04098c26d 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -173,7 +173,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles if(obj.PresenceType == PresenceType.Npc) return; - GetImageAssets(((IScenePresence)obj).UUID); + Util.FireAndForget(delegate + { + GetImageAssets(((IScenePresence)obj).UUID); + }); } /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4d796fead2..9f8ada35a3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -958,7 +958,14 @@ namespace OpenSim.Region.Framework.Scenes // Viewers which have a current outfit folder will actually rez their own attachments. However, // viewers without (e.g. v1 viewers) will not, so we still need to make this call. if (Scene.AttachmentsModule != null) - Scene.AttachmentsModule.RezAttachments(this); + Util.FireAndForget( + o => + { +// if (PresenceType != PresenceType.Npc && Util.FireAndForgetMethod != FireAndForgetMethod.None) +// System.Threading.Thread.Sleep(7000); + + Scene.AttachmentsModule.RezAttachments(this); + }); } else { @@ -1355,6 +1362,18 @@ namespace OpenSim.Region.Framework.Scenes ValidateAndSendAppearanceAndAgentData(); + // Create child agents in neighbouring regions + if (openChildAgents && !IsChildAgent) + { + IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); + if (m_agentTransfer != null) + Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); }); + + IFriendsModule friendsModule = m_scene.RequestModuleInterface(); + if (friendsModule != null) + friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); + } + // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. // This may be due to viewer code or it may be something we're not doing properly simulator side. @@ -1364,19 +1383,6 @@ namespace OpenSim.Region.Framework.Scenes sog.ScheduleGroupForFullUpdate(); } - // Create child agents in neighbouring regions - if (openChildAgents && !IsChildAgent) - { - IFriendsModule friendsModule = m_scene.RequestModuleInterface(); - if (friendsModule != null) - friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); - - IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); - if (m_agentTransfer != null) - m_agentTransfer.EnableChildAgents(this); // this can take a while... several seconds - - } - // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); @@ -2683,20 +2689,22 @@ namespace OpenSim.Region.Framework.Scenes public void SendInitialDataToMe() { // Send all scene object to the new client - - // we created a new ScenePresence (a new child agent) in a fresh region. - // Request info about all the (root) agents in this region - // Note: This won't send data *to* other clients in that region (children don't send) - SendOtherAgentsAvatarDataToMe(); - SendOtherAgentsAppearanceToMe(); - - EntityBase[] entities = Scene.Entities.GetEntities(); - foreach (EntityBase e in entities) + Util.FireAndForget(delegate { - if (e != null && e is SceneObjectGroup) - ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); - } + // we created a new ScenePresence (a new child agent) in a fresh region. + // Request info about all the (root) agents in this region + // Note: This won't send data *to* other clients in that region (children don't send) + SendOtherAgentsAvatarDataToMe(); + SendOtherAgentsAppearanceToMe(); + EntityBase[] entities = Scene.Entities.GetEntities(); + foreach (EntityBase e in entities) + { + if (e != null && e is SceneObjectGroup) + ((SceneObjectGroup)e).SendFullUpdateToClient(ControllingClient); + } + + }); } /// From 5a1d6727e15623af4700058d516cabf03fb910ac Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 11:39:17 -0700 Subject: [PATCH 78/93] Some more debug to see how many threads are available. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9f8ada35a3..11b15a74e5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1383,6 +1383,8 @@ namespace OpenSim.Region.Framework.Scenes sog.ScheduleGroupForFullUpdate(); } + m_log.DebugFormat("[SCENE PRESENCE]: ({0}) Available threads: {1}", Name, Util.FireAndForgetCount()); + // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); From 4d93870fe589ec4d184ee1e4165b7a1bbf18abc6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 17:52:05 -0700 Subject: [PATCH 79/93] Gatekeeper: stop bogus agents earlier, here at the Gatekeeper. No need to bother the sim. --- OpenSim/Services/HypergridService/GatekeeperService.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 0cf1c14daa..0a3e70b5d5 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -419,6 +419,12 @@ namespace OpenSim.Services.HypergridService if (!CheckAddress(aCircuit.ServiceSessionID)) return false; + if (string.IsNullOrEmpty(aCircuit.IPAddress)) + { + m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide a client IP address."); + return false; + } + string userURL = string.Empty; if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) userURL = aCircuit.ServiceURLs["HomeURI"].ToString(); From 931eb892d92bcd61194655ec02def6264d8b182e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 17:56:42 -0700 Subject: [PATCH 80/93] Deleted GET agent all around. Not used. --- .../Simulation/LocalSimulationConnector.cs | 20 ------ .../Simulation/RemoteSimulationConnector.cs | 18 ------ .../Handlers/Simulation/AgentHandlers.cs | 61 +------------------ .../Simulation/SimulationServiceConnector.cs | 35 ----------- .../Services/Interfaces/ISimulationService.cs | 2 - 5 files changed, 2 insertions(+), 134 deletions(-) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 942796171c..2dc3d2aeac 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -250,26 +250,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return true; } - public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) - { - agent = null; - - if (destination == null) - return false; - - if (m_scenes.ContainsKey(destination.RegionID)) - { -// m_log.DebugFormat( -// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", -// s.RegionInfo.RegionName, destination.RegionHandle); - - return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent); - } - - //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); - return false; - } - public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Communications failure"; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index d120e11c2c..4aa2d2a9f3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -212,24 +212,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return m_remoteConnector.UpdateAgent(destination, cAgentData); } - public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) - { - agent = null; - - if (destination == null) - return false; - - // Try local first - if (m_localBackend.RetrieveAgent(destination, id, out agent)) - return true; - - // else do the remote thing - if (!m_localBackend.IsLocalRegion(destination.RegionID)) - return m_remoteConnector.RetrieveAgent(destination, id, out agent); - - return false; - } - public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Communications failure"; diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 40a34c658a..17a8ef4e6d 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -90,12 +90,7 @@ namespace OpenSim.Server.Handlers.Simulation // Next, let's parse the verb string method = (string)request["http-method"]; - if (method.Equals("GET")) - { - DoAgentGet(request, responsedata, agentID, regionID); - return responsedata; - } - else if (method.Equals("DELETE")) + if (method.Equals("DELETE")) { DoAgentDelete(request, responsedata, agentID, action, regionID); return responsedata; @@ -107,7 +102,7 @@ namespace OpenSim.Server.Handlers.Simulation } else { - m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message (caller is {1})", method, Util.GetCallerIP(request)); + m_log.ErrorFormat("[AGENT HANDLER]: method {0} not supported in agent message {1} (caller is {2})", method, (string)request["uri"], Util.GetCallerIP(request)); responsedata["int_response_code"] = HttpStatusCode.MethodNotAllowed; responsedata["str_response_string"] = "Method not allowed"; @@ -156,58 +151,6 @@ namespace OpenSim.Server.Handlers.Simulation // Console.WriteLine("str_response_string [{0}]", responsedata["str_response_string"]); } - protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, UUID regionID) - { - if (m_SimulationService == null) - { - m_log.Debug("[AGENT HANDLER]: Agent GET called. Harmless but useless."); - responsedata["content_type"] = "application/json"; - responsedata["int_response_code"] = HttpStatusCode.NotImplemented; - responsedata["str_response_string"] = string.Empty; - - return; - } - - GridRegion destination = new GridRegion(); - destination.RegionID = regionID; - - IAgentData agent = null; - bool result = m_SimulationService.RetrieveAgent(destination, id, out agent); - OSDMap map = null; - if (result) - { - if (agent != null) // just to make sure - { - map = agent.Pack(); - string strBuffer = ""; - try - { - strBuffer = OSDParser.SerializeJsonString(map); - } - catch (Exception e) - { - m_log.WarnFormat("[AGENT HANDLER]: Exception thrown on serialization of DoAgentGet: {0}", e.Message); - responsedata["int_response_code"] = HttpStatusCode.InternalServerError; - // ignore. buffer will be empty, caller should check. - } - - responsedata["content_type"] = "application/json"; - responsedata["int_response_code"] = HttpStatusCode.OK; - responsedata["str_response_string"] = strBuffer; - } - else - { - responsedata["int_response_code"] = HttpStatusCode.InternalServerError; - responsedata["str_response_string"] = "Internal error"; - } - } - else - { - responsedata["int_response_code"] = HttpStatusCode.NotFound; - responsedata["str_response_string"] = "Not Found"; - } - } - protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID) { m_log.Debug(" >>> DoDelete action:" + action + "; RegionID:" + regionID); diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index f51c809413..7eb8c2419e 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -271,41 +271,6 @@ namespace OpenSim.Services.Connectors.Simulation return false; } - /// - /// Not sure what sequence causes this function to be invoked. The only calling - /// path is through the GET method - /// - public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) - { - // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: RetrieveAgent start"); - - agent = null; - - // Eventually, we want to use a caps url instead of the agentID - string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; - - try - { - OSDMap result = WebUtil.GetFromService(uri, 10000); - if (result["Success"].AsBoolean()) - { - // OSDMap args = Util.GetOSDMap(result["_RawResult"].AsString()); - OSDMap args = (OSDMap)result["_Result"]; - if (args != null) - { - agent = new CompleteAgentData(); - agent.Unpack(args, null); - return true; - } - } - } - catch (Exception e) - { - m_log.Warn("[REMOTE SIMULATION CONNECTOR]: UpdateAgent failed with exception: " + e.ToString()); - } - - return false; - } /// /// diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index b10a85c24e..c9cbd1a5fc 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -75,8 +75,6 @@ namespace OpenSim.Services.Interfaces /// bool UpdateAgent(GridRegion destination, AgentPosition data); - bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent); - bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason); /// From b4f1b9acf65f9e782d56602e60c58be6145c5cca Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 21:28:46 -0700 Subject: [PATCH 81/93] Guard against unauthorized agent deletes. --- .../EntityTransfer/EntityTransferModule.cs | 14 +++++----- .../Simulation/LocalSimulationConnector.cs | 4 +-- .../Simulation/RemoteSimulationConnector.cs | 6 ++--- OpenSim/Region/Framework/Scenes/Scene.cs | 26 +++++++++++++++---- .../Scenes/SceneCommunicationService.cs | 8 +++--- .../Region/Framework/Scenes/ScenePresence.cs | 6 ++++- .../Handlers/Simulation/AgentHandlers.cs | 16 ++++++++---- .../Simulation/SimulationServiceConnector.cs | 7 +++-- .../Services/Interfaces/ISimulationService.cs | 2 +- 9 files changed, 57 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 85d26f312a..ef2ed4f17e 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -817,7 +817,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established."); + Fail(sp, finalDestination, logout, Util.Md5Hash(currentAgentCircuit.Id0), "Connection between viewer and destination region could not be established."); return; } @@ -829,7 +829,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", sp.Name, finalDestination.RegionName, sp.Scene.Name); - CleanupFailedInterRegionTeleport(sp, finalDestination); + CleanupFailedInterRegionTeleport(sp, Util.Md5Hash(currentAgentCircuit.Id0), finalDestination); return; } @@ -873,7 +873,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); + Fail(sp, finalDestination, logout, Util.Md5Hash(currentAgentCircuit.Id0), "Destination region did not signal teleport completion."); return; } @@ -927,7 +927,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// - protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) + protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, string auth_token, GridRegion finalDestination) { m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); @@ -938,7 +938,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Finally, kill the agent we just created at the destination. // XXX: Possibly this should be done asynchronously. - Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); + Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token); } /// @@ -948,9 +948,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// /// Human readable reason for teleport failure. Will be sent to client. - protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) + protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string auth_code, string reason) { - CleanupFailedInterRegionTeleport(sp, finalDestination); + CleanupFailedInterRegionTeleport(sp, auth_code, finalDestination); m_interRegionTeleportFailures.Value++; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 2dc3d2aeac..6d5039b6fe 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -286,7 +286,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_token) { if (destination == null) return false; @@ -297,7 +297,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", // s.RegionInfo.RegionName, destination.RegionHandle); - m_scenes[destination.RegionID].IncomingCloseAgent(id, false); + m_scenes[destination.RegionID].IncomingCloseAgent(id, false, auth_token); return true; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 4aa2d2a9f3..8722b80ced 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -245,18 +245,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation } - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_token) { if (destination == null) return false; // Try local first - if (m_localBackend.CloseAgent(destination, id)) + if (m_localBackend.CloseAgent(destination, id, auth_token)) return true; // else do the remote thing if (!m_localBackend.IsLocalRegion(destination.RegionID)) - return m_remoteConnector.CloseAgent(destination, id); + return m_remoteConnector.CloseAgent(destination, id, auth_token); return false; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 54956ee3bf..becea1f07f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3452,7 +3452,7 @@ namespace OpenSim.Region.Framework.Scenes regions.Remove(RegionInfo.RegionHandle); // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours. - m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); + m_sceneGridService.SendCloseChildAgentConnections(agentID, Util.Md5Hash(acd.Id0), regions); } m_eventManager.TriggerClientClosed(agentID, this); @@ -4277,6 +4277,25 @@ namespace OpenSim.Region.Framework.Scenes return false; } + /// + /// Authenticated close (via network) + /// + /// + /// + /// + /// + public bool IncomingCloseAgent(UUID agentID, bool force, string auth_token) + { + //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token); + + // Check that the auth_token is valid + AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID); + if (acd != null && Util.Md5Hash(acd.Id0) == auth_token) + return IncomingCloseAgent(agentID, force); + else + m_log.ErrorFormat("[SCENE]: Request to close agent {0} with invalid authorization token {1}", agentID, auth_token); + return false; + } /// /// Tell a single agent to disconnect from the region. @@ -4292,12 +4311,9 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); if (presence != null) - { presence.ControllingClient.Close(force); - return true; - } - // Agent not here + // Agent not here return false; } diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 8238e23f9c..77889fadad 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -197,7 +197,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Closes a child agent on a given region /// - protected void SendCloseChildAgent(UUID agentID, ulong regionHandle) + protected void SendCloseChildAgent(UUID agentID, ulong regionHandle, string auth_token) { // let's do our best, but there's not much we can do if the neighbour doesn't accept. @@ -210,7 +210,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: Sending close agent ID {0} to {1}", agentID, destination.RegionName); - m_scene.SimulationService.CloseAgent(destination, agentID); + m_scene.SimulationService.CloseAgent(destination, agentID, auth_token); } /// @@ -219,14 +219,14 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public void SendCloseChildAgentConnections(UUID agentID, List regionslst) + public void SendCloseChildAgentConnections(UUID agentID, string auth_code, List regionslst) { foreach (ulong handle in regionslst) { // We must take a copy here since handle is acts like a reference when used in an iterator. // This leads to race conditions if directly passed to SendCloseChildAgent with more than one neighbour region. ulong handleCopy = handle; - Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy); }); + Util.FireAndForget((o) => { SendCloseChildAgent(agentID, handleCopy, auth_code); }); } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 11b15a74e5..5991a349c4 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3167,7 +3167,11 @@ namespace OpenSim.Region.Framework.Scenes { m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); - m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, byebyeRegions); + AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID); + string auth = string.Empty; + if (acd != null) + auth = Util.Md5Hash(acd.Id0); + m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions); } foreach (ulong handle in byebyeRegions) diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 17a8ef4e6d..cd172e4f04 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -27,11 +27,13 @@ using System; using System.Collections; +using System.Collections.Specialized; using System.IO; using System.IO.Compression; using System.Reflection; using System.Net; using System.Text; +using System.Web; using OpenSim.Server.Base; using OpenSim.Server.Handlers.Base; @@ -92,7 +94,11 @@ namespace OpenSim.Server.Handlers.Simulation string method = (string)request["http-method"]; if (method.Equals("DELETE")) { - DoAgentDelete(request, responsedata, agentID, action, regionID); + string auth_token = string.Empty; + if (request.ContainsKey("auth")) + auth_token = request["auth"].ToString(); + + DoAgentDelete(request, responsedata, agentID, action, regionID, auth_token); return responsedata; } else if (method.Equals("QUERYACCESS")) @@ -151,9 +157,9 @@ namespace OpenSim.Server.Handlers.Simulation // Console.WriteLine("str_response_string [{0}]", responsedata["str_response_string"]); } - protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID) + protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID, string auth_token) { - m_log.Debug(" >>> DoDelete action:" + action + "; RegionID:" + regionID); + m_log.DebugFormat("[AGENT HANDLER]: >>> DELETE action: {0}; RegionID: {1}; from: {2}; auth_code: {3}", action, regionID, Util.GetCallerIP(request), auth_token); GridRegion destination = new GridRegion(); destination.RegionID = regionID; @@ -161,12 +167,12 @@ namespace OpenSim.Server.Handlers.Simulation if (action.Equals("release")) ReleaseAgent(regionID, id); else - Util.FireAndForget(delegate { m_SimulationService.CloseAgent(destination, id); }); + Util.FireAndForget(delegate { m_SimulationService.CloseAgent(destination, id, auth_token); }); responsedata["int_response_code"] = HttpStatusCode.OK; responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); - m_log.DebugFormat("[AGENT HANDLER]: Agent {0} Released/Deleted from region {1}", id, regionID); + //m_log.DebugFormat("[AGENT HANDLER]: Agent {0} Released/Deleted from region {1}", id, regionID); } protected virtual void ReleaseAgent(UUID regionID, UUID id) diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 7eb8c2419e..aca414b82c 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -367,11 +367,10 @@ namespace OpenSim.Services.Connectors.Simulation /// /// - public bool CloseAgent(GridRegion destination, UUID id) + public bool CloseAgent(GridRegion destination, UUID id, string auth_code) { -// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent start"); - - string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; + string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/?auth=" + auth_code; + m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent {0}", uri); try { diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index c9cbd1a5fc..1c82b3e56c 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -93,7 +93,7 @@ namespace OpenSim.Services.Interfaces /// /// /// - bool CloseAgent(GridRegion destination, UUID id); + bool CloseAgent(GridRegion destination, UUID id, string auth_token); #endregion Agents From a2ee887c6d4cc0756b808353ad0183b1e7e29b74 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 22:32:52 -0700 Subject: [PATCH 82/93] Deleted a line too many --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index becea1f07f..264aaa8580 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4311,7 +4311,10 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); if (presence != null) + { presence.ControllingClient.Close(force); + return true; + } // Agent not here return false; From e4f741f0062dfe948e071a88f643f96931140f67 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 22:52:51 -0700 Subject: [PATCH 83/93] This should fix the failing test. --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 264aaa8580..155054aa1b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3452,7 +3452,7 @@ namespace OpenSim.Region.Framework.Scenes regions.Remove(RegionInfo.RegionHandle); // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours. - m_sceneGridService.SendCloseChildAgentConnections(agentID, Util.Md5Hash(acd.Id0), regions); + m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.Id0 != null ? Util.Md5Hash(acd.Id0) : string.Empty, regions); } m_eventManager.TriggerClientClosed(agentID, this); @@ -4308,7 +4308,6 @@ namespace OpenSim.Region.Framework.Scenes public bool IncomingCloseAgent(UUID agentID, bool force) { //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); - ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); if (presence != null) { From fcb0349d565154926be87144d374c7b6d6476eab Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 13 Jul 2013 23:01:41 -0700 Subject: [PATCH 84/93] And this fixes the other failing tests. Justin, the thread pool is not being initialized in the tests! --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5991a349c4..b7ce1731ab 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1383,8 +1383,6 @@ namespace OpenSim.Region.Framework.Scenes sog.ScheduleGroupForFullUpdate(); } - m_log.DebugFormat("[SCENE PRESENCE]: ({0}) Available threads: {1}", Name, Util.FireAndForgetCount()); - // m_log.DebugFormat( // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); From f3b3e21dea98b4ea974ae7649a63d00b69e6dfed Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 07:28:40 -0700 Subject: [PATCH 85/93] Change the auth token to be the user's sessionid. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 6 +++--- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | 5 ++++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ef2ed4f17e..344c8d7f46 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -817,7 +817,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout, Util.Md5Hash(currentAgentCircuit.Id0), "Connection between viewer and destination region could not be established."); + Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); return; } @@ -829,7 +829,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", sp.Name, finalDestination.RegionName, sp.Scene.Name); - CleanupFailedInterRegionTeleport(sp, Util.Md5Hash(currentAgentCircuit.Id0), finalDestination); + CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination); return; } @@ -873,7 +873,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - Fail(sp, finalDestination, logout, Util.Md5Hash(currentAgentCircuit.Id0), "Destination region did not signal teleport completion."); + Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion."); return; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 155054aa1b..ea7081ce25 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3452,7 +3452,7 @@ namespace OpenSim.Region.Framework.Scenes regions.Remove(RegionInfo.RegionHandle); // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours. - m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.Id0 != null ? Util.Md5Hash(acd.Id0) : string.Empty, regions); + m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions); } m_eventManager.TriggerClientClosed(agentID, this); @@ -4290,7 +4290,7 @@ namespace OpenSim.Region.Framework.Scenes // Check that the auth_token is valid AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID); - if (acd != null && Util.Md5Hash(acd.Id0) == auth_token) + if (acd != null && acd.SessionID.ToString() == auth_token) return IncomingCloseAgent(agentID, force); else m_log.ErrorFormat("[SCENE]: Request to close agent {0} with invalid authorization token {1}", agentID, auth_token); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b7ce1731ab..c5cca22c47 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3168,7 +3168,7 @@ namespace OpenSim.Region.Framework.Scenes AgentCircuitData acd = Scene.AuthenticateHandler.GetAgentCircuitData(UUID); string auth = string.Empty; if (acd != null) - auth = Util.Md5Hash(acd.Id0); + auth = acd.SessionID.ToString(); m_scene.SceneGridService.SendCloseChildAgentConnections(ControllingClient.AgentId, auth, byebyeRegions); } diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index cd172e4f04..4ac477f692 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -159,7 +159,10 @@ namespace OpenSim.Server.Handlers.Simulation protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID, string auth_token) { - m_log.DebugFormat("[AGENT HANDLER]: >>> DELETE action: {0}; RegionID: {1}; from: {2}; auth_code: {3}", action, regionID, Util.GetCallerIP(request), auth_token); + if (string.IsNullOrEmpty(action)) + m_log.DebugFormat("[AGENT HANDLER]: >>> DELETE <<< RegionID: {0}; from: {1}; auth_code: {2}", regionID, Util.GetCallerIP(request), auth_token); + else + m_log.DebugFormat("[AGENT HANDLER]: Release {0} to RegionID: {1}", id, regionID); GridRegion destination = new GridRegion(); destination.RegionID = regionID; From c61ff917ef99a00d4062f264ed10c2a662585e8a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 09:21:28 -0700 Subject: [PATCH 86/93] Authenticate ChildAgentUpdate too. --- OpenSim/Framework/ChildAgentDataUpdate.cs | 3 +- .../Framework/Tests/MundaneFrameworkTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 42 ++++++++++++------- .../Region/Framework/Scenes/ScenePresence.cs | 3 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index dfe60aaff1..9fc048bcc9 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -171,9 +171,10 @@ namespace OpenSim.Framework /// Soon to be decommissioned /// /// - public void CopyFrom(ChildAgentDataUpdate cAgent) + public void CopyFrom(ChildAgentDataUpdate cAgent, UUID sid) { AgentID = new UUID(cAgent.AgentID); + SessionID = sid; // next: ??? Size = new Vector3(); diff --git a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs index 1dc80533d8..3f0a031b33 100644 --- a/OpenSim/Framework/Tests/MundaneFrameworkTests.cs +++ b/OpenSim/Framework/Tests/MundaneFrameworkTests.cs @@ -100,7 +100,7 @@ namespace OpenSim.Framework.Tests cadu.AVHeight = Size1.Z; AgentPosition position2 = new AgentPosition(); - position2.CopyFrom(cadu); + position2.CopyFrom(cadu, position1.SessionID); Assert.IsTrue( position2.AgentID == position1.AgentID diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ea7081ce25..b07faa2138 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4202,10 +4202,18 @@ namespace OpenSim.Region.Framework.Scenes if (childAgentUpdate != null) { - childAgentUpdate.ChildAgentDataUpdate(cAgentData); - return true; + if (cAgentData.SessionID == childAgentUpdate.ControllingClient.SessionId) + { + childAgentUpdate.ChildAgentDataUpdate(cAgentData); + return true; + } + else + { + m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1}", childAgentUpdate.UUID, cAgentData.SessionID); + Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", + childAgentUpdate.UUID, childAgentUpdate.ControllingClient.SessionId, cAgentData.SessionID)); + } } - return false; } @@ -4221,20 +4229,24 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); if (childAgentUpdate != null) { - // I can't imagine *yet* why we would get an update if the agent is a root agent.. - // however to avoid a race condition crossing borders.. - if (childAgentUpdate.IsChildAgent) + if (childAgentUpdate.ControllingClient.SessionId == cAgentData.SessionID) { - uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); - uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); - uint tRegionX = RegionInfo.RegionLocX; - uint tRegionY = RegionInfo.RegionLocY; - //Send Data to ScenePresence - childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); - // Not Implemented: - //TODO: Do we need to pass the message on to one of our neighbors? + // I can't imagine *yet* why we would get an update if the agent is a root agent.. + // however to avoid a race condition crossing borders.. + if (childAgentUpdate.IsChildAgent) + { + uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); + uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); + uint tRegionX = RegionInfo.RegionLocX; + uint tRegionY = RegionInfo.RegionLocY; + //Send Data to ScenePresence + childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); + // Not Implemented: + //TODO: Do we need to pass the message on to one of our neighbors? + } } - + else + m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}", childAgentUpdate.UUID, cAgentData.SessionID); return true; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c5cca22c47..990ef6e20b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2927,7 +2927,7 @@ namespace OpenSim.Region.Framework.Scenes cadu.Velocity = Velocity; AgentPosition agentpos = new AgentPosition(); - agentpos.CopyFrom(cadu); + agentpos.CopyFrom(cadu, ControllingClient.SessionId); // Let's get this out of the update loop Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); }); @@ -3266,6 +3266,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.AgentID = UUID; cAgent.RegionID = Scene.RegionInfo.RegionID; + cAgent.SessionID = ControllingClient.SessionId; cAgent.Position = AbsolutePosition; cAgent.Velocity = m_velocity; From 98f59ffed59d33c3737787bff85a72fde545fc94 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 09:22:55 -0700 Subject: [PATCH 87/93] Fix broken tests -- the test setup was wrong... sigh. --- .../Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs | 1 + OpenSim/Tests/Common/Mock/TestClient.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs index 5a722398e2..5df9aba0f2 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCrossingTests.cs @@ -112,6 +112,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests //moveArgs.BodyRotation = Quaternion.CreateFromEulers(Vector3.Zero); moveArgs.BodyRotation = Quaternion.CreateFromEulers(new Vector3(0, 0, (float)-(Math.PI / 2))); moveArgs.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; + moveArgs.SessionID = acd.SessionID; originalSp.HandleAgentUpdate(originalSp.ControllingClient, moveArgs); diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index c660501dbe..2fc3f0b3c8 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -584,7 +584,7 @@ namespace OpenSim.Tests.Common.Mock { AgentCircuitData agentData = new AgentCircuitData(); agentData.AgentID = AgentId; - agentData.SessionID = UUID.Zero; + agentData.SessionID = SessionId; agentData.SecureSessionID = UUID.Zero; agentData.circuitcode = m_circuitCode; agentData.child = false; From c8dcb8474d0b0698168863328e61a6929bb0770f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 10:26:05 -0700 Subject: [PATCH 88/93] Let's go easy on authenticating ChildAgentUpdates, otherwise this will be chaotic while ppl are using different versions of opensim. Warning only, but no enforcement. --- OpenSim/Region/Framework/Scenes/Scene.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b07faa2138..9cfe869098 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4202,17 +4202,15 @@ namespace OpenSim.Region.Framework.Scenes if (childAgentUpdate != null) { - if (cAgentData.SessionID == childAgentUpdate.ControllingClient.SessionId) + if (cAgentData.SessionID != childAgentUpdate.ControllingClient.SessionId) { - childAgentUpdate.ChildAgentDataUpdate(cAgentData); - return true; - } - else - { - m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1}", childAgentUpdate.UUID, cAgentData.SessionID); + m_log.WarnFormat("[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", childAgentUpdate.UUID, cAgentData.SessionID); Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", childAgentUpdate.UUID, childAgentUpdate.ControllingClient.SessionId, cAgentData.SessionID)); } + + childAgentUpdate.ChildAgentDataUpdate(cAgentData); + return true; } return false; } From 593952903639e51df6faf6c8649a0410c9649184 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 14:29:10 -0700 Subject: [PATCH 89/93] Minor typo in log message --- .../Services/Connectors/GridUser/GridUserServicesConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs index 94bda82d14..1a62d2f1e7 100644 --- a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs +++ b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs @@ -214,7 +214,7 @@ namespace OpenSim.Services.Connectors } else - m_log.DebugFormat("[GRID USER CONNECTOR]: Loggedin received empty reply"); + m_log.DebugFormat("[GRID USER CONNECTOR]: Get received empty reply"); } catch (Exception e) { From e33ac50388b5b9d6d06c58c45e2ea6f17e9b987f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 14:31:20 -0700 Subject: [PATCH 90/93] HG UAS: Moved hg-session data from memory to DB storage. This makes it so that traveling info survives Robust resets. It should also eliminate the cause of empty IP addresses in agent circuit data that we saw in CC grid. MySQL only. --- OpenSim/Data/IHGTravelingData.cs | 58 +++++ OpenSim/Data/MySQL/MySQLHGTravelData.cs | 70 ++++++ .../MySQL/Resources/HGTravelStore.migrations | 17 ++ .../HypergridService/UserAgentService.cs | 205 ++++++++++-------- .../HypergridService/UserAgentServiceBase.cs | 84 +++++++ 5 files changed, 344 insertions(+), 90 deletions(-) create mode 100644 OpenSim/Data/IHGTravelingData.cs create mode 100644 OpenSim/Data/MySQL/MySQLHGTravelData.cs create mode 100644 OpenSim/Data/MySQL/Resources/HGTravelStore.migrations create mode 100644 OpenSim/Services/HypergridService/UserAgentServiceBase.cs diff --git a/OpenSim/Data/IHGTravelingData.cs b/OpenSim/Data/IHGTravelingData.cs new file mode 100644 index 0000000000..dd89935cd0 --- /dev/null +++ b/OpenSim/Data/IHGTravelingData.cs @@ -0,0 +1,58 @@ +/* + * 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; +using OpenSim.Framework; + +namespace OpenSim.Data +{ + // This MUST be a ref type! + public class HGTravelingData + { + public UUID SessionID; + public UUID UserID; + public Dictionary Data; + + public HGTravelingData() + { + Data = new Dictionary(); + } + } + + /// + /// An interface for connecting to the user grid datastore + /// + public interface IHGTravelingData + { + HGTravelingData Get(UUID sessionID); + HGTravelingData[] GetSessions(UUID userID); + bool Store(HGTravelingData data); + bool Delete(UUID sessionID); + } +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLHGTravelData.cs b/OpenSim/Data/MySQL/MySQLHGTravelData.cs new file mode 100644 index 0000000000..1efbfc3e40 --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLHGTravelData.cs @@ -0,0 +1,70 @@ +/* + * 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.Data; +using System.Reflection; +using System.Threading; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using MySql.Data.MySqlClient; + +namespace OpenSim.Data.MySQL +{ + /// + /// A MySQL Interface for user grid data + /// + public class MySQLHGTravelData : MySQLGenericTableHandler, IHGTravelingData + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public MySQLHGTravelData(string connectionString, string realm) : base(connectionString, realm, "HGTravelStore") { } + + public HGTravelingData Get(UUID sessionID) + { + HGTravelingData[] ret = Get("SessionID", sessionID.ToString()); + + if (ret.Length == 0) + return null; + + return ret[0]; + } + + public HGTravelingData[] GetSessions(UUID userID) + { + return base.Get("UserID", userID.ToString()); + } + + public bool Delete(UUID sessionID) + { + return Delete("SessionID", sessionID.ToString()); + } + + } +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations new file mode 100644 index 0000000000..a0c9ebe0d3 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations @@ -0,0 +1,17 @@ +:VERSION 1 # -------------------------- + +BEGIN; + +CREATE TABLE `hg_traveling_data` ( + `SessionID` VARCHAR(36) NOT NULL, + `UserID` VARCHAR(36) NOT NULL, + `GridExternalName` VARCHAR(255) NOT NULL DEFAULT '', + `ServiceToken` VARCHAR(255) NOT NULL DEFAULT '', + `ClientIPAddress` VARCHAR(16) NOT NULL DEFAULT '', + `MyIPAddress` VARCHAR(16) NOT NULL DEFAULT '', + PRIMARY KEY (`SessionID`), + KEY (`UserID`) +) ENGINE=InnoDB; + +COMMIT; + diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index 733993fb04..b597cb9690 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Net; using System.Reflection; +using OpenSim.Data; using OpenSim.Framework; using OpenSim.Services.Connectors.Friends; using OpenSim.Services.Connectors.Hypergrid; @@ -50,14 +51,14 @@ namespace OpenSim.Services.HypergridService /// needs to do it for them. /// Once we have better clients, this shouldn't be needed. /// - public class UserAgentService : IUserAgentService + public class UserAgentService : UserAgentServiceBase, IUserAgentService { private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); // This will need to go into a DB table - static Dictionary m_TravelingAgents = new Dictionary(); + //static Dictionary m_Database = new Dictionary(); static bool m_Initialized = false; @@ -86,6 +87,7 @@ namespace OpenSim.Services.HypergridService } public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector) + : base(config) { // Let's set this always, because we don't know the sequence // of instantiations @@ -260,7 +262,8 @@ namespace OpenSim.Services.HypergridService // Generate a new service session agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random(); - TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region); + TravelingAgentInfo old = null; + TravelingAgentInfo travel = CreateTravelInfo(agentCircuit, region, fromLogin, out old); bool success = false; string myExternalIP = string.Empty; @@ -282,23 +285,21 @@ namespace OpenSim.Services.HypergridService m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}", agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); - // restore the old travel info - lock (m_TravelingAgents) - { - if (old == null) - m_TravelingAgents.Remove(agentCircuit.SessionID); - else - m_TravelingAgents[agentCircuit.SessionID] = old; - } + if (old != null) + StoreTravelInfo(old); + else + m_Database.Delete(agentCircuit.SessionID); return false; } + // Everything is ok + + // Update the perceived IP Address of our grid m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP); - // else set the IP addresses associated with this client - if (fromLogin) - m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = agentCircuit.IPAddress; - m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP; + travel.MyIpAddress = myExternalIP; + + StoreTravelInfo(travel); return true; } @@ -309,57 +310,39 @@ namespace OpenSim.Services.HypergridService return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, false, out reason); } - private void SetClientIP(UUID sessionID, string ip) + TravelingAgentInfo CreateTravelInfo(AgentCircuitData agentCircuit, GridRegion region, bool fromLogin, out TravelingAgentInfo existing) { - if (m_TravelingAgents.ContainsKey(sessionID)) + HGTravelingData hgt = m_Database.Get(agentCircuit.SessionID); + existing = null; + + if (hgt != null) { - m_log.DebugFormat("[USER AGENT SERVICE]: Setting IP {0} for session {1}", ip, sessionID); - m_TravelingAgents[sessionID].ClientIPAddress = ip; + // Very important! Override whatever this agent comes with. + // UserAgentService always sets the IP for every new agent + // with the original IP address. + existing = new TravelingAgentInfo(hgt); + agentCircuit.IPAddress = existing.ClientIPAddress; } - } - TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region) - { - TravelingAgentInfo travel = new TravelingAgentInfo(); - TravelingAgentInfo old = null; - lock (m_TravelingAgents) - { - if (m_TravelingAgents.ContainsKey(agentCircuit.SessionID)) - { - // Very important! Override whatever this agent comes with. - // UserAgentService always sets the IP for every new agent - // with the original IP address. - agentCircuit.IPAddress = m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress; - - old = m_TravelingAgents[agentCircuit.SessionID]; - } - - m_TravelingAgents[agentCircuit.SessionID] = travel; - } + TravelingAgentInfo travel = new TravelingAgentInfo(existing); + travel.SessionID = agentCircuit.SessionID; travel.UserID = agentCircuit.AgentID; travel.GridExternalName = region.ServerURI; travel.ServiceToken = agentCircuit.ServiceSessionID; - if (old != null) - travel.ClientIPAddress = old.ClientIPAddress; - return old; + if (fromLogin) + travel.ClientIPAddress = agentCircuit.IPAddress; + + StoreTravelInfo(travel); + + return travel; } public void LogoutAgent(UUID userID, UUID sessionID) { m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID); - lock (m_TravelingAgents) - { - List travels = new List(); - foreach (KeyValuePair kvp in m_TravelingAgents) - if (kvp.Value == null) // do some clean up - travels.Add(kvp.Key); - else if (kvp.Value.UserID == userID) - travels.Add(kvp.Key); - foreach (UUID session in travels) - m_TravelingAgents.Remove(session); - } + m_Database.Delete(sessionID); GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString()); if (guinfo != null) @@ -369,10 +352,11 @@ namespace OpenSim.Services.HypergridService // We need to prevent foreign users with the same UUID as a local user public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName) { - if (!m_TravelingAgents.ContainsKey(sessionID)) + HGTravelingData hgt = m_Database.Get(sessionID); + if (hgt == null) return false; - TravelingAgentInfo travel = m_TravelingAgents[sessionID]; + TravelingAgentInfo travel = new TravelingAgentInfo(hgt); return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower(); } @@ -385,31 +369,32 @@ namespace OpenSim.Services.HypergridService m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.", sessionID, reportedIP); - if (m_TravelingAgents.ContainsKey(sessionID)) - { - bool result = m_TravelingAgents[sessionID].ClientIPAddress == reportedIP || - m_TravelingAgents[sessionID].MyIpAddress == reportedIP; // NATed + HGTravelingData hgt = m_Database.Get(sessionID); + if (hgt == null) + return false; - m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}", - reportedIP, m_TravelingAgents[sessionID].ClientIPAddress, m_TravelingAgents[sessionID].MyIpAddress, result); + TravelingAgentInfo travel = new TravelingAgentInfo(hgt); - return result; - } + bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP; // NATed - return false; + m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}", + reportedIP, travel.ClientIPAddress, travel.MyIpAddress, result); + + return result; } public bool VerifyAgent(UUID sessionID, string token) { - if (m_TravelingAgents.ContainsKey(sessionID)) + HGTravelingData hgt = m_Database.Get(sessionID); + if (hgt == null) { - m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, m_TravelingAgents[sessionID].ServiceToken); - return m_TravelingAgents[sessionID].ServiceToken == token; + m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID); + return false; } - m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID); - - return false; + TravelingAgentInfo travel = new TravelingAgentInfo(hgt); + m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, travel.ServiceToken); + return travel.ServiceToken == token; } [Obsolete] @@ -472,17 +457,17 @@ namespace OpenSim.Services.HypergridService } } - // Lastly, let's notify the rest who may be online somewhere else - foreach (string user in usersToBeNotified) - { - UUID id = new UUID(user); - if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName) - { - string url = m_TravelingAgents[id].GridExternalName; - // forward - m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); - } - } + //// Lastly, let's notify the rest who may be online somewhere else + //foreach (string user in usersToBeNotified) + //{ + // UUID id = new UUID(user); + // if (m_Database.ContainsKey(id) && m_Database[id].GridExternalName != m_GridName) + // { + // string url = m_Database[id].GridExternalName; + // // forward + // m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); + // } + //} // and finally, let's send the online friends if (online) @@ -609,16 +594,13 @@ namespace OpenSim.Services.HypergridService public string LocateUser(UUID userID) { - foreach (TravelingAgentInfo t in m_TravelingAgents.Values) - { - if (t == null) - { - m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis"); - continue; - } - if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName)) - return t.GridExternalName; - } + HGTravelingData[] hgts = m_Database.GetSessions(userID); + if (hgts == null) + return string.Empty; + + foreach (HGTravelingData t in hgts) + if (t.Data.ContainsKey("GridExternalName") && !m_GridName.Equals(t.Data["GridExternalName"])) + return t.Data["GridExternalName"]; return string.Empty; } @@ -689,17 +671,60 @@ namespace OpenSim.Services.HypergridService return exception; } + private void StoreTravelInfo(TravelingAgentInfo travel) + { + if (travel == null) + return; + + HGTravelingData hgt = new HGTravelingData(); + hgt.SessionID = travel.SessionID; + hgt.UserID = travel.UserID; + hgt.Data = new Dictionary(); + hgt.Data["GridExternalName"] = travel.GridExternalName; + hgt.Data["ServiceToken"] = travel.ServiceToken; + hgt.Data["ClientIPAddress"] = travel.ClientIPAddress; + hgt.Data["MyIPAddress"] = travel.MyIpAddress; + + m_Database.Store(hgt); + } #endregion } class TravelingAgentInfo { + public UUID SessionID; public UUID UserID; public string GridExternalName = string.Empty; public string ServiceToken = string.Empty; public string ClientIPAddress = string.Empty; // as seen from this user agent service public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper + + public TravelingAgentInfo(HGTravelingData t) + { + if (t.Data != null) + { + SessionID = new UUID(t.SessionID); + UserID = new UUID(t.UserID); + GridExternalName = t.Data["GridExternalName"]; + ServiceToken = t.Data["ServiceToken"]; + ClientIPAddress = t.Data["ClientIPAddress"]; + MyIpAddress = t.Data["MyIPAddress"]; + } + } + + public TravelingAgentInfo(TravelingAgentInfo old) + { + if (old != null) + { + SessionID = old.SessionID; + UserID = old.UserID; + GridExternalName = old.GridExternalName; + ServiceToken = old.ServiceToken; + ClientIPAddress = old.ClientIPAddress; + MyIpAddress = old.MyIpAddress; + } + } } } diff --git a/OpenSim/Services/HypergridService/UserAgentServiceBase.cs b/OpenSim/Services/HypergridService/UserAgentServiceBase.cs new file mode 100644 index 0000000000..a00e5a6a08 --- /dev/null +++ b/OpenSim/Services/HypergridService/UserAgentServiceBase.cs @@ -0,0 +1,84 @@ +/* + * 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.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Data; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Base; + +namespace OpenSim.Services.HypergridService +{ + public class UserAgentServiceBase : ServiceBase + { + protected IHGTravelingData m_Database = null; + + public UserAgentServiceBase(IConfigSource config) + : base(config) + { + string dllName = String.Empty; + string connString = String.Empty; + string realm = "hg_traveling_data"; + + // + // Try reading the [DatabaseService] section, if it exists + // + IConfig dbConfig = config.Configs["DatabaseService"]; + if (dbConfig != null) + { + if (dllName == String.Empty) + dllName = dbConfig.GetString("StorageProvider", String.Empty); + if (connString == String.Empty) + connString = dbConfig.GetString("ConnectionString", String.Empty); + } + + // + // [UserAgentService] section overrides [DatabaseService], if it exists + // + IConfig gridConfig = config.Configs["UserAgentService"]; + if (gridConfig != null) + { + dllName = gridConfig.GetString("StorageProvider", dllName); + connString = gridConfig.GetString("ConnectionString", connString); + realm = gridConfig.GetString("Realm", realm); + } + + // + // We tried, but this doesn't exist. We can't proceed. + // + if (dllName.Equals(String.Empty)) + throw new Exception("No StorageProvider configured"); + + m_Database = LoadPlugin(dllName, new Object[] { connString, realm }); + if (m_Database == null) + throw new Exception("Could not find a storage interface in the given module"); + + } + } +} From b0140383da21de03cb655160a2912d04c5b470e6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 15:47:54 -0700 Subject: [PATCH 91/93] Cleanup old hg sessions (older than 2 days) --- OpenSim/Data/IHGTravelingData.cs | 1 + OpenSim/Data/MySQL/MySQLHGTravelData.cs | 10 ++++++++++ OpenSim/Data/MySQL/Resources/HGTravelStore.migrations | 1 + .../Framework/EntityTransfer/HGEntityTransferModule.cs | 7 +++++-- OpenSim/Services/HypergridService/UserAgentService.cs | 3 +++ 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/OpenSim/Data/IHGTravelingData.cs b/OpenSim/Data/IHGTravelingData.cs index dd89935cd0..452af7bc50 100644 --- a/OpenSim/Data/IHGTravelingData.cs +++ b/OpenSim/Data/IHGTravelingData.cs @@ -54,5 +54,6 @@ namespace OpenSim.Data HGTravelingData[] GetSessions(UUID userID); bool Store(HGTravelingData data); bool Delete(UUID sessionID); + void DeleteOld(); } } \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLHGTravelData.cs b/OpenSim/Data/MySQL/MySQLHGTravelData.cs index 1efbfc3e40..e81b880c95 100644 --- a/OpenSim/Data/MySQL/MySQLHGTravelData.cs +++ b/OpenSim/Data/MySQL/MySQLHGTravelData.cs @@ -66,5 +66,15 @@ namespace OpenSim.Data.MySQL return Delete("SessionID", sessionID.ToString()); } + public void DeleteOld() + { + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 DAY", m_Realm); + + ExecuteNonQuery(cmd); + } + + } } } \ No newline at end of file diff --git a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations index a0c9ebe0d3..b4e4422871 100644 --- a/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations +++ b/OpenSim/Data/MySQL/Resources/HGTravelStore.migrations @@ -9,6 +9,7 @@ CREATE TABLE `hg_traveling_data` ( `ServiceToken` VARCHAR(255) NOT NULL DEFAULT '', `ClientIPAddress` VARCHAR(16) NOT NULL DEFAULT '', `MyIPAddress` VARCHAR(16) NOT NULL DEFAULT '', + `TMStamp` timestamp NOT NULL, PRIMARY KEY (`SessionID`), KEY (`UserID`) ) ENGINE=InnoDB; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 759155a799..76dbc72270 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -207,6 +207,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); m_UAS = scene.RequestModuleInterface(); + if (m_UAS == null) + m_UAS = new UserAgentServiceConnector(m_ThisHomeURI); + } } @@ -573,12 +576,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) { // local grid user + m_UAS.LogoutAgent(obj.AgentId, obj.SessionId); return; } AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); - - if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("HomeURI")) { string url = aCircuit.ServiceURLs["HomeURI"].ToString(); IUserAgentService security = new UserAgentServiceConnector(url); diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index b597cb9690..b414aca7fe 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -148,6 +148,9 @@ namespace OpenSim.Services.HypergridService if (!m_GridName.EndsWith("/")) m_GridName = m_GridName + "/"; + // Finally some cleanup + m_Database.DeleteOld(); + } } From af02231a7b334dde1e3dcbea03c93fe11bcc6037 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 16:03:46 -0700 Subject: [PATCH 92/93] Added SQLite version of hg travel data store. UNTESTED. Hope it works! --- .../SQLite/Resources/HGTravelStore.migrations | 18 ++++ OpenSim/Data/SQLite/SQLiteHGTravelData.cs | 82 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 OpenSim/Data/SQLite/Resources/HGTravelStore.migrations create mode 100644 OpenSim/Data/SQLite/SQLiteHGTravelData.cs diff --git a/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations b/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations new file mode 100644 index 0000000000..2e73caa9d2 --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/HGTravelStore.migrations @@ -0,0 +1,18 @@ +:VERSION 1 # -------------------------- + +BEGIN; + +CREATE TABLE hg_traveling_data ( + SessionID VARCHAR(36) NOT NULL, + UserID VARCHAR(36) NOT NULL, + GridExternalName VARCHAR(255) NOT NULL DEFAULT '', + ServiceToken VARCHAR(255) NOT NULL DEFAULT '', + ClientIPAddress VARCHAR(16) NOT NULL DEFAULT '', + MyIPAddress VARCHAR(16) NOT NULL DEFAULT '', + TMStamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`SessionID`), + KEY (`UserID`) +) ENGINE=InnoDB; + +COMMIT; + diff --git a/OpenSim/Data/SQLite/SQLiteHGTravelData.cs b/OpenSim/Data/SQLite/SQLiteHGTravelData.cs new file mode 100644 index 0000000000..db288b2486 --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteHGTravelData.cs @@ -0,0 +1,82 @@ +/* + * 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.Data; +using System.Reflection; +using System.Threading; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using Mono.Data.Sqlite; + +namespace OpenSim.Data.SQLite +{ + /// + /// A SQL Interface for user grid data + /// + public class SQLiteHGTravelData : SQLiteGenericTableHandler, IHGTravelingData + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public SQLiteHGTravelData(string connectionString, string realm) + : base(connectionString, realm, "HGTravelStore") {} + + public HGTravelingData Get(UUID sessionID) + { + HGTravelingData[] ret = Get("SessionID", sessionID.ToString()); + + if (ret.Length == 0) + return null; + + return ret[0]; + } + + public HGTravelingData[] GetSessions(UUID userID) + { + return base.Get("UserID", userID.ToString()); + } + + public bool Delete(UUID sessionID) + { + return Delete("SessionID", sessionID.ToString()); + } + + public void DeleteOld() + { + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.CommandText = String.Format("delete from {0} where TMStamp < datetime('now', '-2 day') ", m_Realm); + + DoQuery(cmd); + } + + } + + } +} \ No newline at end of file From d48946f9ef368ff72cec00c33bbfb53b6bd35696 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 14 Jul 2013 16:51:07 -0700 Subject: [PATCH 93/93] Document obscure Groups config related to the user level required for creating groups --- bin/OpenSim.ini.example | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 1c53935dff..4ddefba5f3 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -955,6 +955,10 @@ ;; Enables the groups module ; Enabled = false + ;# {LevelGroupCreate} {Enabled:true} {User level for creating groups} {} 0 + ;; Minimum user level required to create groups + ;LevelGroupCreate = 0 + ;# {Module} {Enabled:true} {Groups module to use? (Use GroupsModule to use Flotsam/Simian)} {Default "Groups Module V2"} Default ;; The default module can use a PHP XmlRpc server from the Flotsam project at ;; http://code.google.com/p/flotsam/