From 4cbadc3c4984b8bebc7098a720846309f645ad7b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 2 Sep 2013 17:27:45 +0100 Subject: Allow one to specify a DefaultHGRegion flag in [GridService] in order to allow different default regions for HG and direct grid logins. This requires a new GridService.GetDefaultHypergridRegions() so ROBUST services require updating but not simulators. This method still returns regions flagged with just DefaultRegion after any DefaultHGRegions, so if no DefaultHGRegions are specified then existing configured defaults will still work. Immediate use is for conference where we need to be able to specify different defaults However, this is also generally useful to send experienced HG users to one default location and local users whose specified region fails (e.g. no "home" or "last") to another. --- OpenSim/Data/IRegionData.cs | 1 + OpenSim/Data/MSSQL/MSSQLRegionData.cs | 5 +++ OpenSim/Data/MySQL/MySQLRegionData.cs | 5 +++ OpenSim/Data/Null/NullRegionData.cs | 5 +++ OpenSim/Framework/RegionFlags.cs | 3 +- .../Grid/LocalGridServiceConnector.cs | 5 +++ .../Grid/RemoteGridServiceConnector.cs | 20 +++++++++ .../Server/Handlers/Grid/GridServerPostHandler.cs | 33 ++++++++++++++ .../Connectors/Grid/GridServicesConnector.cs | 51 ++++++++++++++++++++++ .../SimianGrid/SimianGridServiceConnector.cs | 6 +++ OpenSim/Services/GridService/GridService.cs | 32 +++++++++++++- OpenSim/Services/GridService/HypergridLinker.cs | 2 +- .../Services/HypergridService/GatekeeperService.cs | 2 +- OpenSim/Services/Interfaces/IGridService.cs | 1 + 14 files changed, 166 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs index 70e1065..463c621 100644 --- a/OpenSim/Data/IRegionData.cs +++ b/OpenSim/Data/IRegionData.cs @@ -81,6 +81,7 @@ namespace OpenSim.Data bool Delete(UUID regionID); List GetDefaultRegions(UUID scopeID); + List GetDefaultHypergridRegions(UUID scopeID); List GetFallbackRegions(UUID scopeID, int x, int y); List GetHyperlinks(UUID scopeID); } diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index 0d89706..c0589df 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs @@ -315,6 +315,11 @@ namespace OpenSim.Data.MSSQL return Get((int)RegionFlags.DefaultRegion, scopeID); } + public List GetDefaultHypergridRegions(UUID scopeID) + { + return Get((int)RegionFlags.DefaultHGRegion, scopeID); + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { List regions = Get((int)RegionFlags.FallbackRegion, scopeID); diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index a2d4ae4..2ad7590 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -310,6 +310,11 @@ namespace OpenSim.Data.MySQL return Get((int)RegionFlags.DefaultRegion, scopeID); } + public List GetDefaultHypergridRegions(UUID scopeID) + { + return Get((int)RegionFlags.DefaultHGRegion, scopeID); + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { List regions = Get((int)RegionFlags.FallbackRegion, scopeID); diff --git a/OpenSim/Data/Null/NullRegionData.cs b/OpenSim/Data/Null/NullRegionData.cs index f707d98..d28cd99 100644 --- a/OpenSim/Data/Null/NullRegionData.cs +++ b/OpenSim/Data/Null/NullRegionData.cs @@ -239,6 +239,11 @@ namespace OpenSim.Data.Null return Get((int)RegionFlags.DefaultRegion, scopeID); } + public List GetDefaultHypergridRegions(UUID scopeID) + { + return Get((int)RegionFlags.DefaultHGRegion, scopeID); + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { List regions = Get((int)RegionFlags.FallbackRegion, scopeID); diff --git a/OpenSim/Framework/RegionFlags.cs b/OpenSim/Framework/RegionFlags.cs index a3089b0..7c6569e 100644 --- a/OpenSim/Framework/RegionFlags.cs +++ b/OpenSim/Framework/RegionFlags.cs @@ -48,6 +48,7 @@ namespace OpenSim.Framework NoMove = 64, // Don't allow moving this region Reservation = 128, // This is an inactive reservation Authenticate = 256, // Require authentication - Hyperlink = 512 // Record represents a HG link + Hyperlink = 512, // Record represents a HG link + DefaultHGRegion = 1024 // Record represents a default region for hypergrid teleports only. } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 3849a3f..31ef79b 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs @@ -235,6 +235,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid return m_GridService.GetDefaultRegions(scopeID); } + public List GetDefaultHypergridRegions(UUID scopeID) + { + return m_GridService.GetDefaultHypergridRegions(scopeID); + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { return m_GridService.GetFallbackRegions(scopeID, x, y); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs index b2646ba..6a57d1f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs @@ -277,6 +277,26 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid return rinfo; } + public List GetDefaultHypergridRegions(UUID scopeID) + { + List rinfo = m_LocalGridService.GetDefaultHypergridRegions(scopeID); + //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetDefaultHypergridRegions {0} found {1} regions", name, rinfo.Count); + List grinfo = m_RemoteGridService.GetDefaultHypergridRegions(scopeID); + + if (grinfo != null) + { + //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultHypergridRegions {0} found {1} regions", name, grinfo.Count); + foreach (GridRegion r in grinfo) + { + m_RegionInfoCache.Cache(r); + if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) + rinfo.Add(r); + } + } + + return rinfo; + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { List rinfo = m_LocalGridService.GetFallbackRegions(scopeID, x, y); diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index 89cba8a..c63b409 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -106,6 +106,9 @@ namespace OpenSim.Server.Handlers.Grid case "get_default_regions": return GetDefaultRegions(request); + case "get_default_hypergrid_regions": + return GetDefaultHypergridRegions(request); + case "get_fallback_regions": return GetFallbackRegions(request); @@ -444,6 +447,36 @@ namespace OpenSim.Server.Handlers.Grid return Util.UTF8NoBomEncoding.GetBytes(xmlString); } + byte[] GetDefaultHypergridRegions(Dictionary request) + { + //m_log.DebugFormat("[GRID HANDLER]: GetDefaultRegions"); + UUID scopeID = UUID.Zero; + if (request.ContainsKey("SCOPEID")) + UUID.TryParse(request["SCOPEID"].ToString(), out scopeID); + else + m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region range"); + + List rinfos = m_GridService.GetDefaultHypergridRegions(scopeID); + + Dictionary result = new Dictionary(); + if ((rinfos == null) || ((rinfos != null) && (rinfos.Count == 0))) + result["result"] = "null"; + else + { + int i = 0; + foreach (GridRegion rinfo in rinfos) + { + Dictionary rinfoDict = rinfo.ToKeyValuePairs(); + result["region" + i] = rinfoDict; + i++; + } + } + string xmlString = ServerUtils.BuildXmlResponse(result); + + //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); + } + byte[] GetFallbackRegions(Dictionary request) { //m_log.DebugFormat("[GRID HANDLER]: GetRegionRange"); diff --git a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs index 34ed0d7..0f5a613 100644 --- a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs +++ b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs @@ -515,6 +515,57 @@ namespace OpenSim.Services.Connectors return rinfos; } + public List GetDefaultHypergridRegions(UUID scopeID) + { + Dictionary sendData = new Dictionary(); + + sendData["SCOPEID"] = scopeID.ToString(); + + sendData["METHOD"] = "get_default_hypergrid_regions"; + + List rinfos = new List(); + string reply = string.Empty; + string uri = m_ServerURI + "/grid"; + try + { + reply = SynchronousRestFormsRequester.MakeRequest("POST", + uri, + ServerUtils.BuildQueryString(sendData)); + + //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); + } + catch (Exception e) + { + m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message); + return rinfos; + } + + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData != null) + { + Dictionary.ValueCollection rinfosList = replyData.Values; + foreach (object r in rinfosList) + { + if (r is Dictionary) + { + GridRegion rinfo = new GridRegion((Dictionary)r); + rinfos.Add(rinfo); + } + } + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultHypergridRegions {0} received null response", + scopeID); + } + else + m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultHypergridRegions received null reply"); + + return rinfos; + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { Dictionary sendData = new Dictionary(); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index bcc1e4a..816591b 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -330,6 +330,12 @@ namespace OpenSim.Services.Connectors.SimianGrid return new List(0); } + public List GetDefaultHypergridRegions(UUID scopeID) + { + // TODO: Allow specifying the default grid location + return GetDefaultRegions(scopeID); + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true); diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index a1485c8..e72b7f9 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -265,8 +265,9 @@ namespace OpenSim.Services.GridService m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); } - m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}", - regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY); + m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3} with flags {4}", + regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY, + (OpenSim.Framework.RegionFlags)flags); return String.Empty; } @@ -478,6 +479,33 @@ namespace OpenSim.Services.GridService return ret; } + public List GetDefaultHypergridRegions(UUID scopeID) + { + List ret = new List(); + + List regions = m_Database.GetDefaultHypergridRegions(scopeID); + + foreach (RegionData r in regions) + { + if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0) + ret.Add(RegionData2RegionInfo(r)); + } + + int hgDefaultRegionsFoundOnline = regions.Count; + + // For now, hypergrid default regions will always be given precedence but we will also return simple default + // regions in case no specific hypergrid regions are specified. + ret.AddRange(GetDefaultRegions(scopeID)); + + int normalDefaultRegionsFoundOnline = ret.Count - hgDefaultRegionsFoundOnline; + + m_log.DebugFormat( + "[GRID SERVICE]: GetDefaultHypergridRegions returning {0} hypergrid default and {1} normal default regions", + hgDefaultRegionsFoundOnline, normalDefaultRegionsFoundOnline); + + return ret; + } + public List GetFallbackRegions(UUID scopeID, int x, int y) { List ret = new List(); diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs index 8335724..4024295 100644 --- a/OpenSim/Services/GridService/HypergridLinker.cs +++ b/OpenSim/Services/GridService/HypergridLinker.cs @@ -79,7 +79,7 @@ namespace OpenSim.Services.GridService { if (m_DefaultRegion == null) { - List defs = m_GridService.GetDefaultRegions(m_ScopeID); + List defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID); if (defs != null && defs.Count > 0) m_DefaultRegion = defs[0]; else diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index e10c4cb..f6136b5 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -171,7 +171,7 @@ namespace OpenSim.Services.HypergridService m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName); if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty) { - List defs = m_GridService.GetDefaultRegions(m_ScopeID); + List defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID); if (defs != null && defs.Count > 0) { region = defs[0]; diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index 6ed681f..88ac5b3 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -97,6 +97,7 @@ namespace OpenSim.Services.Interfaces List GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax); List GetDefaultRegions(UUID scopeID); + List GetDefaultHypergridRegions(UUID scopeID); List GetFallbackRegions(UUID scopeID, int x, int y); List GetHyperlinks(UUID scopeID); -- cgit v1.1 From 5ce5ce6edb2217639cdcc375bf375452b81bb868 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 2 Sep 2013 17:45:38 +0100 Subject: Comment out warning about agent updating without valid session ID for now. This causes extreme console spam if a simulator running latest master and one running 0.7.5 have adjacent regions occupied by avatars. --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d547323..005c9b9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4346,10 +4346,10 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); if (childAgentUpdate != null) { - if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) - // Only warn for now - m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", - childAgentUpdate.UUID, cAgentData.SessionID); +// if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) +// // Only warn for now +// m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", +// childAgentUpdate.UUID, cAgentData.SessionID); // 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.. -- cgit v1.1 From 857f24a5e2b59072ad4d987d5e64318f5249c7e7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 2 Sep 2013 19:15:10 +0100 Subject: Fix bug where users teleporting to non-neighbour regions could continue to hear chat from their source region for some time after teleport completion. This occurs on v2 teleport since the source region now waits 15 secs before closing the old child agent, which could still receive chat. This commit introduces a ScenePresenceState.PreClose which is set before the wait, so that ChatModule can check for ScenePresenceState.Running. This was theoretically also an issue on v1 teleport but since the pause before close was only 2 secs there, it was not noticed. --- .../Caps/EventQueue/Tests/EventQueueTests.cs | 4 +- .../Region/CoreModules/Avatar/Chat/ChatModule.cs | 15 +++--- .../EntityTransfer/EntityTransferModule.cs | 7 +++ OpenSim/Region/Framework/Scenes/Scene.cs | 59 ++++++++++++++++++++-- .../Framework/Scenes/ScenePresenceStateMachine.cs | 15 +++++- 5 files changed, 85 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index 626932f..b3b0b8a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs @@ -76,7 +76,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests } [Test] - public void AddForClient() + public void TestAddForClient() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); @@ -88,7 +88,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests } [Test] - public void RemoveForClient() + public void TestRemoveForClient() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 58f747b..5229c08 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -326,15 +326,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, string message, ChatSourceType src, bool ignoreDistance) { - Vector3 fromRegionPos = fromPos + regionPos; - Vector3 toRegionPos = presence.AbsolutePosition + - new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, - presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); - - int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); + if (presence.LifecycleState != ScenePresenceState.Running) + return false; if (!ignoreDistance) { + Vector3 fromRegionPos = fromPos + regionPos; + Vector3 toRegionPos = presence.AbsolutePosition + + new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, + presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); + + int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); + if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || type == ChatTypeEnum.Say && dis > m_saydistance || type == ChatTypeEnum.Shout && dis > m_shoutdistance) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 8950516..4219254 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -920,6 +920,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) { + if (!sp.Scene.IncomingPreCloseAgent(sp)) + return; + // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before // they regard the new region as the current region after receiving the AgentMovementComplete // response. If close is sent before then, it will cause the viewer to quit instead. @@ -1082,6 +1085,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) { + if (!sp.Scene.IncomingPreCloseAgent(sp)) + return; + // RED ALERT!!!! // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion @@ -1095,6 +1101,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // then this will be handled in IncomingCloseAgent under lock conditions m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name); + sp.Scene.IncomingCloseAgent(sp.UUID, false); } else diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 005c9b9..2a21a4c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3695,10 +3695,13 @@ namespace OpenSim.Region.Framework.Scenes // We need to ensure that we are not already removing the scene presence before we ask it not to be // closed. - if (sp != null && sp.IsChildAgent && sp.LifecycleState == ScenePresenceState.Running) + if (sp != null && sp.IsChildAgent + && (sp.LifecycleState == ScenePresenceState.Running + || sp.LifecycleState == ScenePresenceState.PreRemove)) { m_log.DebugFormat( - "[SCENE]: Reusing existing child scene presence for {0} in {1}", sp.Name, Name); + "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}", + sp.Name, sp.LifecycleState, Name); // In the case where, for example, an A B C D region layout, an avatar may // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C @@ -3720,6 +3723,8 @@ namespace OpenSim.Region.Framework.Scenes // } // else if (EntityTransferModule.IsInTransit(sp.UUID)) + sp.LifecycleState = ScenePresenceState.Running; + if (EntityTransferModule.IsInTransit(sp.UUID)) { sp.DoNotCloseAfterTeleport = true; @@ -4441,6 +4446,50 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Tell a single agent to prepare to close. + /// + /// + /// This should only be called if we may close the agent but there will be some delay in so doing. Meant for + /// internal use - other callers should almost certainly called IncomingCloseAgent(). + /// + /// + /// true if pre-close state notification was successful. false if the agent + /// was not in a state where it could transition to pre-close. + public bool IncomingPreCloseAgent(ScenePresence sp) + { + lock (m_removeClientLock) + { + // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may + // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not + // want to obey this close since C may have renewed the child agent lease on B. + if (sp.DoNotCloseAfterTeleport) + { + m_log.DebugFormat( + "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection", + sp.IsChildAgent ? "child" : "root", sp.Name, Name); + + // Need to reset the flag so that a subsequent close after another teleport can succeed. + sp.DoNotCloseAfterTeleport = false; + + return false; + } + + if (sp.LifecycleState != ScenePresenceState.Running) + { + m_log.DebugFormat( + "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}", + sp.Name, Name, sp.LifecycleState); + + return false; + } + + sp.LifecycleState = ScenePresenceState.PreRemove; + + return true; + } + } + + /// /// Tell a single agent to disconnect from the region. /// /// @@ -4459,16 +4508,16 @@ namespace OpenSim.Region.Framework.Scenes if (sp == null) { m_log.DebugFormat( - "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in {1}", + "[SCENE]: Called IncomingCloseAgent() with agent ID {0} but no such presence is in {1}", agentID, Name); return false; } - if (sp.LifecycleState != ScenePresenceState.Running) + if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove) { m_log.DebugFormat( - "[SCENE]: Called RemoveClient() for {0} in {1} but presence is already in state {2}", + "[SCENE]: Called IncomingCloseAgent() for {0} in {1} but presence is already in state {2}", sp.Name, Name, sp.LifecycleState); return false; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs b/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs index dc3a212..cae7fe5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresenceStateMachine.cs @@ -37,7 +37,8 @@ namespace OpenSim.Region.Framework.Scenes /// This is a state machine. /// /// [Entry] => Running - /// Running => Removing + /// Running => PreRemove, Removing + /// PreRemove => Running, Removing /// Removing => Removed /// /// All other methods should only see the scene presence in running state - this is the normal operational state @@ -46,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes public enum ScenePresenceState { Running, // Normal operation state. The scene presence is available. + PreRemove, // The presence is due to be removed but can still be returning to running. Removing, // The presence is in the process of being removed from the scene via Scene.RemoveClient. Removed, // The presence has been removed from the scene and is effectively dead. // There is no exit from this state. @@ -80,8 +82,17 @@ namespace OpenSim.Region.Framework.Scenes lock (this) { - if (newState == ScenePresenceState.Removing && m_state == ScenePresenceState.Running) + if (newState == m_state) + return; + else if (newState == ScenePresenceState.Running && m_state == ScenePresenceState.PreRemove) transitionOkay = true; + else if (newState == ScenePresenceState.PreRemove && m_state == ScenePresenceState.Running) + transitionOkay = true; + else if (newState == ScenePresenceState.Removing) + { + if (m_state == ScenePresenceState.Running || m_state == ScenePresenceState.PreRemove) + transitionOkay = true; + } else if (newState == ScenePresenceState.Removed && m_state == ScenePresenceState.Removing) transitionOkay = true; } -- cgit v1.1 From 9643915093aad385163551655676adc943855330 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Mon, 2 Sep 2013 16:28:40 -0400 Subject: Remove test that gives issue on Windows, just let the try/catch do the work. --- OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index bf1cffb..56ff2bd 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -1212,7 +1212,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles json.Add("jsonrpc", OSD.FromString("2.0")); json.Add("id", OSD.FromString(jsonId)); json.Add("method", OSD.FromString(method)); - // Experiment + json.Add("params", OSD.SerializeMembers(parameters)); string jsonRequestData = OSDParser.SerializeJsonString(json); @@ -1240,8 +1240,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } Stream rstream = webResponse.GetResponseStream(); - if (rstream.Length < 1) - return false; OSDMap mret = new OSDMap(); try @@ -1318,8 +1316,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles } Stream rstream = webResponse.GetResponseStream(); - if (rstream.Length < 1) - return false; OSDMap response = new OSDMap(); try -- cgit v1.1 From 4035badd20c00c766a1262afd7fa730ea6c53e98 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 00:04:12 +0100 Subject: Add experimental "show grid users online" console command to show grid users online from a standalone/robust instance. This is not guaranteed to be accurate since users may be left "online" in certain situations. For example, if a simulator crashes and they never login/logout again. To counter this somewhat, only users continuously online for less than 5 days are shown. --- OpenSim/Framework/Util.cs | 8 ++--- .../Services/UserAccountService/GridUserService.cs | 39 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index f0e5bc1..52f5432 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -130,7 +130,7 @@ namespace OpenSim.Framework private static SmartThreadPool m_ThreadPool; // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. - private static readonly DateTime unixEpoch = + public static readonly DateTime UnixEpoch = DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime(); private static readonly string rawUUIDPattern @@ -521,19 +521,19 @@ namespace OpenSim.Framework public static int ToUnixTime(DateTime stamp) { - TimeSpan t = stamp.ToUniversalTime() - unixEpoch; + TimeSpan t = stamp.ToUniversalTime() - UnixEpoch; return (int) t.TotalSeconds; } public static DateTime ToDateTime(ulong seconds) { - DateTime epoch = unixEpoch; + DateTime epoch = UnixEpoch; return epoch.AddSeconds(seconds); } public static DateTime ToDateTime(int seconds) { - DateTime epoch = unixEpoch; + DateTime epoch = UnixEpoch; return epoch.AddSeconds(seconds); } diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs index b1cdd45..f9cfa12 100644 --- a/OpenSim/Services/UserAccountService/GridUserService.cs +++ b/OpenSim/Services/UserAccountService/GridUserService.cs @@ -47,6 +47,45 @@ namespace OpenSim.Services.UserAccountService public GridUserService(IConfigSource config) : base(config) { m_log.Debug("[GRID USER SERVICE]: Starting user grid service"); + + MainConsole.Instance.Commands.AddCommand( + "Users", false, + "show grid users online", + "show grid users online", + "Show number of grid users registered as online.", + "This number may not be accurate as a region may crash or not be cleanly shutdown and leave grid users shown as online\n." + + "For this reason, users online for more than 5 days are not currently counted", + HandleShowGridUsersOnline); + } + + protected void HandleShowGridUsersOnline(string module, string[] cmdparams) + { +// if (cmdparams.Length != 4) +// { +// MainConsole.Instance.Output("Usage: show grid users online"); +// return; +// } + +// int onlineCount; + int onlineRecentlyCount = 0; + + DateTime now = DateTime.UtcNow; + + foreach (GridUserData gu in m_Database.GetAll("")) + { + if (bool.Parse(gu.Data["Online"])) + { +// onlineCount++; + + int unixLoginTime = int.Parse(gu.Data["Login"]); + DateTime loginDateTime = Util.UnixEpoch.AddSeconds(unixLoginTime); + + if ((loginDateTime - now).Days < 5) + onlineRecentlyCount++; + } + } + + MainConsole.Instance.OutputFormat("Users online within last 5 days: {0}", onlineRecentlyCount); } public virtual GridUserInfo GetGridUserInfo(string userID) -- cgit v1.1 From 5f15ee95dc140ba775c4db801a72f6623e408b0f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 00:16:43 +0100 Subject: Fix logic errors in "show grid users online" console command which didn't actually filter out users shown continuously online for more than 5 days Remove confusion in command output. --- OpenSim/Services/UserAccountService/GridUserService.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs index f9cfa12..944411f 100644 --- a/OpenSim/Services/UserAccountService/GridUserService.cs +++ b/OpenSim/Services/UserAccountService/GridUserService.cs @@ -78,14 +78,13 @@ namespace OpenSim.Services.UserAccountService // onlineCount++; int unixLoginTime = int.Parse(gu.Data["Login"]); - DateTime loginDateTime = Util.UnixEpoch.AddSeconds(unixLoginTime); - if ((loginDateTime - now).Days < 5) + if ((now - Util.ToDateTime(unixLoginTime)).Days < 5) onlineRecentlyCount++; } } - MainConsole.Instance.OutputFormat("Users online within last 5 days: {0}", onlineRecentlyCount); + MainConsole.Instance.OutputFormat("Users online: {0}", onlineRecentlyCount); } public virtual GridUserInfo GetGridUserInfo(string userID) -- cgit v1.1 From 431156f6c48944c79e3f56c54d64e7f3bc748f7b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 00:17:50 +0100 Subject: minor simplification of some unix date functions in Util. No functional change. --- OpenSim/Framework/Util.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 52f5432..e8dfec1 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -522,19 +522,17 @@ namespace OpenSim.Framework public static int ToUnixTime(DateTime stamp) { TimeSpan t = stamp.ToUniversalTime() - UnixEpoch; - return (int) t.TotalSeconds; + return (int)t.TotalSeconds; } public static DateTime ToDateTime(ulong seconds) { - DateTime epoch = UnixEpoch; - return epoch.AddSeconds(seconds); + return UnixEpoch.AddSeconds(seconds); } public static DateTime ToDateTime(int seconds) { - DateTime epoch = UnixEpoch; - return epoch.AddSeconds(seconds); + return UnixEpoch.AddSeconds(seconds); } /// -- cgit v1.1 From 9c652079361f496c46640ed67e964ee6164ce06e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 17:07:57 +0100 Subject: Show behaviours of pCampbot bots in "show bots" and "show bot" console commands --- .../Tools/pCampBot/Behaviours/AbstractBehaviour.cs | 5 +++++ .../Tools/pCampBot/Behaviours/CrossBehaviour.cs | 6 +++++- .../Tools/pCampBot/Behaviours/GrabbingBehaviour.cs | 6 +++++- OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs | 6 +++++- .../Tools/pCampBot/Behaviours/PhysicsBehaviour.cs | 1 + .../Tools/pCampBot/Behaviours/TeleportBehaviour.cs | 6 +++++- OpenSim/Tools/pCampBot/BotManager.cs | 22 ++++++++++++++-------- OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs | 5 +++++ 8 files changed, 45 insertions(+), 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs index 9a9371d..66d5542 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs @@ -35,6 +35,11 @@ namespace pCampBot { public class AbstractBehaviour : IBehaviour { + /// + /// Abbreviated name of this behaviour. + /// + public string AbbreviatedName { get; protected set; } + public string Name { get; protected set; } public Bot Bot { get; protected set; } diff --git a/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs index 1e01c64..4d806fc 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/CrossBehaviour.cs @@ -47,7 +47,11 @@ namespace pCampBot public const int m_regionCrossingTimeout = 1000 * 60; - public CrossBehaviour() { Name = "Cross"; } + public CrossBehaviour() + { + AbbreviatedName = "c"; + Name = "Cross"; + } public override void Action() { diff --git a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs index 66a336a..6acc27d 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs @@ -41,7 +41,11 @@ namespace pCampBot /// public class GrabbingBehaviour : AbstractBehaviour { - public GrabbingBehaviour() { Name = "Grabbing"; } + public GrabbingBehaviour() + { + AbbreviatedName = "g"; + Name = "Grabbing"; + } public override void Action() { diff --git a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs index 9cf8a54..9a3075c 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/NoneBehaviour.cs @@ -38,6 +38,10 @@ namespace pCampBot /// public class NoneBehaviour : AbstractBehaviour { - public NoneBehaviour() { Name = "None"; } + public NoneBehaviour() + { + AbbreviatedName = "n"; + Name = "None"; + } } } \ No newline at end of file diff --git a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs index daa7485..47b4d46 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs @@ -46,6 +46,7 @@ namespace pCampBot public PhysicsBehaviour() { + AbbreviatedName = "p"; Name = "Physics"; talkarray = readexcuses(); } diff --git a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs index fbb4e96..5f7edda 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs @@ -42,7 +42,11 @@ namespace pCampBot { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public TeleportBehaviour() { Name = "Teleport"; } + public TeleportBehaviour() + { + AbbreviatedName = "t"; + Name = "Teleport"; + } public override void Action() { diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 5c3835b..35a24d1 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -572,10 +572,11 @@ namespace pCampBot private void HandleShowBotsStatus(string module, string[] cmd) { ConsoleDisplayTable cdt = new ConsoleDisplayTable(); - cdt.AddColumn("Name", 30); - cdt.AddColumn("Region", 30); - cdt.AddColumn("Status", 14); - cdt.AddColumn("Connections", 11); + cdt.AddColumn("Name", 24); + cdt.AddColumn("Region", 24); + cdt.AddColumn("Status", 13); + cdt.AddColumn("Conns", 5); + cdt.AddColumn("Behaviours", 20); Dictionary totals = new Dictionary(); foreach (object o in Enum.GetValues(typeof(ConnectionState))) @@ -583,13 +584,17 @@ namespace pCampBot lock (m_bots) { - foreach (Bot pb in m_bots) + foreach (Bot bot in m_bots) { - Simulator currentSim = pb.Client.Network.CurrentSim; - totals[pb.ConnectionState]++; + Simulator currentSim = bot.Client.Network.CurrentSim; + totals[bot.ConnectionState]++; cdt.AddRow( - pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState, pb.SimulatorsCount); + bot.Name, + currentSim != null ? currentSim.Name : "(none)", + bot.ConnectionState, + bot.SimulatorsCount, + string.Join(",", bot.Behaviours.ConvertAll(behaviour => behaviour.AbbreviatedName))); } } @@ -645,6 +650,7 @@ namespace pCampBot MainConsole.Instance.Output("Settings"); ConsoleDisplayList statusCdl = new ConsoleDisplayList(); + statusCdl.AddRow("Behaviours", string.Join(", ", bot.Behaviours.ConvertAll(b => b.Name))); GridClient botClient = bot.Client; statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES); diff --git a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs index 9c984be..f8a661b 100644 --- a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs @@ -32,6 +32,11 @@ namespace pCampBot.Interfaces public interface IBehaviour { /// + /// Abbreviated name of this behaviour. + /// + string AbbreviatedName { get; } + + /// /// Name of this behaviour. /// string Name { get; } -- cgit v1.1 From a89c56dcf1e2645554f8b81b6f1e517b829cc3a4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 17:53:29 +0100 Subject: Fix build break from last commit 9c65207. Mono 2.4 lacks string.join(string, List), or some auto casting is missing --- OpenSim/Tools/pCampBot/BotManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 35a24d1..7d4af13 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -594,7 +594,7 @@ namespace pCampBot currentSim != null ? currentSim.Name : "(none)", bot.ConnectionState, bot.SimulatorsCount, - string.Join(",", bot.Behaviours.ConvertAll(behaviour => behaviour.AbbreviatedName))); + string.Join(",", bot.Behaviours.ConvertAll(behaviour => behaviour.AbbreviatedName).ToArray())); } } -- cgit v1.1 From 01cb8033a42514728835a18a38f2a18349e83638 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 17:55:20 +0100 Subject: And fix break in "show bot" from commit 9c65207 --- OpenSim/Tools/pCampBot/BotManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 7d4af13..3e446af 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -650,7 +650,7 @@ namespace pCampBot MainConsole.Instance.Output("Settings"); ConsoleDisplayList statusCdl = new ConsoleDisplayList(); - statusCdl.AddRow("Behaviours", string.Join(", ", bot.Behaviours.ConvertAll(b => b.Name))); + statusCdl.AddRow("Behaviours", string.Join(", ", bot.Behaviours.ConvertAll(b => b.Name).ToArray())); GridClient botClient = bot.Client; statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES); -- cgit v1.1 From 9bd62715704685738c55c6de8127b16cc6695bdb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 18:51:55 +0100 Subject: Add ability to adjust pCampbot bot behaviours whilst running with "add behaviour " console commad --- OpenSim/Tools/pCampBot/Bot.cs | 51 ++++++++---- OpenSim/Tools/pCampBot/BotManager.cs | 147 ++++++++++++++++++++++++++++------- 2 files changed, 157 insertions(+), 41 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index d418288..6037516 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -72,9 +72,10 @@ namespace pCampBot /// Behaviours implemented by this bot. /// /// - /// Lock this list before manipulating it. + /// Indexed by abbreviated name. There can only be one instance of a particular behaviour. + /// Lock this structure before manipulating it. /// - public List Behaviours { get; private set; } + public Dictionary Behaviours { get; private set; } /// /// Objects that the bot has discovered. @@ -165,8 +166,6 @@ namespace pCampBot { ConnectionState = ConnectionState.Disconnected; - behaviours.ForEach(b => b.Initialize(this)); - Random = new Random(Environment.TickCount);// We do stuff randomly here FirstName = firstName; LastName = lastName; @@ -176,12 +175,31 @@ namespace pCampBot StartLocation = startLocation; Manager = bm; - Behaviours = behaviours; + + Behaviours = new Dictionary(); + foreach (IBehaviour behaviour in behaviours) + AddBehaviour(behaviour); // Only calling for use as a template. CreateLibOmvClient(); } + public bool AddBehaviour(IBehaviour behaviour) + { + lock (Behaviours) + { + if (!Behaviours.ContainsKey(behaviour.AbbreviatedName)) + { + behaviour.Initialize(this); + Behaviours.Add(behaviour.AbbreviatedName, behaviour); + + return true; + } + } + + return false; + } + private void CreateLibOmvClient() { GridClient newClient = new GridClient(); @@ -237,16 +255,21 @@ namespace pCampBot private void Action() { while (ConnectionState != ConnectionState.Disconnecting) + { lock (Behaviours) - Behaviours.ForEach( - b => - { - Thread.Sleep(Random.Next(3000, 10000)); - - // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); - b.Action(); - } - ); + { + foreach (IBehaviour behaviour in Behaviours.Values) + { + Thread.Sleep(Random.Next(3000, 10000)); + + // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); + behaviour.Action(); + } + } + + // XXX: This is a really shitty way of yielding so that behaviours can be added/removed + Thread.Sleep(100); + } } /// diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 3e446af..51c5ff4 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -140,7 +140,7 @@ namespace pCampBot /// /// Behaviour switches for bots. /// - private HashSet m_behaviourSwitches = new HashSet(); + private HashSet m_defaultBehaviourSwitches = new HashSet(); /// /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data @@ -195,6 +195,18 @@ namespace pCampBot HandleDisconnect); m_console.Commands.AddCommand( + "bot", false, "add behaviour", "add behaviour ", + "Add a behaviour to a bot", + "Can be performed on connected or disconnected bots.", + HandleAddBehaviour); + +// m_console.Commands.AddCommand( +// "bot", false, "remove behaviour", "remove behaviour ", +// "Remove a behaviour from a bot", +// "Can be performed on connected or disconnected bots.", +// HandleRemoveBehaviour); + + m_console.Commands.AddCommand( "bot", false, "sit", "sit", "Sit all bots on the ground.", HandleSit); @@ -235,7 +247,7 @@ namespace pCampBot m_startUri = ParseInputStartLocationToUri(startupConfig.GetString("start", "last")); Array.ForEach( - startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_behaviourSwitches.Add(b)); + startupConfig.GetString("behaviours", "p").Split(new char[] { ',' }), b => m_defaultBehaviourSwitches.Add(b)); for (int i = 0; i < botcount; i++) { @@ -243,28 +255,50 @@ namespace pCampBot { string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber); - // We must give each bot its own list of instantiated behaviours since they store state. - List behaviours = new List(); - - // Hard-coded for now - if (m_behaviourSwitches.Contains("c")) - behaviours.Add(new CrossBehaviour()); + CreateBot( + this, + CreateBehavioursFromAbbreviatedNames(m_defaultBehaviourSwitches), + m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting); + } + } + } + + private List CreateBehavioursFromAbbreviatedNames(HashSet abbreviatedNames) + { + // We must give each bot its own list of instantiated behaviours since they store state. + List behaviours = new List(); + + // Hard-coded for now + foreach (string abName in abbreviatedNames) + { + IBehaviour newBehaviour = null; + + if (abName == "c") + newBehaviour = new CrossBehaviour(); + + if (abName == "g") + newBehaviour = new GrabbingBehaviour(); - if (m_behaviourSwitches.Contains("g")) - behaviours.Add(new GrabbingBehaviour()); + if (abName == "n") + newBehaviour = new NoneBehaviour(); - if (m_behaviourSwitches.Contains("n")) - behaviours.Add(new NoneBehaviour()); + if (abName == "p") + newBehaviour = new PhysicsBehaviour(); - if (m_behaviourSwitches.Contains("p")) - behaviours.Add(new PhysicsBehaviour()); - - if (m_behaviourSwitches.Contains("t")) - behaviours.Add(new TeleportBehaviour()); + if (abName == "t") + newBehaviour = new TeleportBehaviour(); - CreateBot(this, behaviours, m_firstName, lastName, m_password, m_loginUri, m_startUri, m_wearSetting); + if (newBehaviour != null) + { + behaviours.Add(newBehaviour); + } + else + { + MainConsole.Instance.OutputFormat("No behaviour with abbreviated name {0} found", abName); } } + + return behaviours; } public void ConnectBots(int botcount) @@ -453,6 +487,44 @@ namespace pCampBot } } + private void HandleAddBehaviour(string module, string[] cmd) + { + if (cmd.Length != 4) + { + MainConsole.Instance.OutputFormat("Usage: add behaviour "); + return; + } + + string rawBehaviours = cmd[2]; + int botNumber; + + if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber)) + return; + + Bot bot = GetBotFromNumber(botNumber); + + if (bot == null) + { + MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); + return; + } + + HashSet rawAbbreviatedSwitchesToAdd = new HashSet(); + Array.ForEach(rawBehaviours.Split(new char[] { ',' }), b => rawAbbreviatedSwitchesToAdd.Add(b)); + + List behavioursAdded = new List(); + + foreach (IBehaviour behaviour in CreateBehavioursFromAbbreviatedNames(rawAbbreviatedSwitchesToAdd)) + { + if (bot.AddBehaviour(behaviour)) + behavioursAdded.Add(behaviour); + } + + MainConsole.Instance.OutputFormat( + "Added behaviours {0} to bot {1}", + string.Join(", ", behavioursAdded.ConvertAll(b => b.Name).ToArray()), bot.Name); + } + private void HandleDisconnect(string module, string[] cmd) { lock (m_bots) @@ -594,7 +666,7 @@ namespace pCampBot currentSim != null ? currentSim.Name : "(none)", bot.ConnectionState, bot.SimulatorsCount, - string.Join(",", bot.Behaviours.ConvertAll(behaviour => behaviour.AbbreviatedName).ToArray())); + string.Join(",", bot.Behaviours.Keys.ToArray())); } } @@ -621,16 +693,11 @@ namespace pCampBot if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, cmd[2], out botNumber)) return; - string name = string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber); - - Bot bot; - - lock (m_bots) - bot = m_bots.Find(b => b.Name == name); + Bot bot = GetBotFromNumber(botNumber); if (bot == null) { - MainConsole.Instance.Output("No bot found with name {0}", name); + MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); return; } @@ -650,13 +717,39 @@ namespace pCampBot MainConsole.Instance.Output("Settings"); ConsoleDisplayList statusCdl = new ConsoleDisplayList(); - statusCdl.AddRow("Behaviours", string.Join(", ", bot.Behaviours.ConvertAll(b => b.Name).ToArray())); + + statusCdl.AddRow( + "Behaviours", + string.Join(", ", bot.Behaviours.Values.ToList().ConvertAll(b => b.Name).ToArray())); + GridClient botClient = bot.Client; statusCdl.AddRow("SEND_AGENT_UPDATES", botClient.Settings.SEND_AGENT_UPDATES); MainConsole.Instance.Output(statusCdl.ToString()); } + /// + /// Get a specific bot from its number. + /// + /// null if no bot was found + /// + private Bot GetBotFromNumber(int botNumber) + { + string name = GenerateBotNameFromNumber(botNumber); + + Bot bot; + + lock (m_bots) + bot = m_bots.Find(b => b.Name == name); + + return bot; + } + + private string GenerateBotNameFromNumber(int botNumber) + { + return string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber); + } + internal void Grid_GridRegion(object o, GridRegionEventArgs args) { lock (RegionsKnown) -- cgit v1.1 From 1a2627031d8a80b1d5e21fd2d13e4dc2b123c0b4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 19:05:54 +0100 Subject: Add pCampbot "remove behaviour" console command for removing bot behaviours during operation. Doesn't currently work very well as stopping physics, for instance, can leave bot travelling in old direction --- OpenSim/Tools/pCampBot/Bot.cs | 12 ++++++++ OpenSim/Tools/pCampBot/BotManager.cs | 53 ++++++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index 6037516..0bd8151 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -184,6 +184,12 @@ namespace pCampBot CreateLibOmvClient(); } + public bool TryGetBehaviour(string abbreviatedName, out IBehaviour behaviour) + { + lock (Behaviours) + return Behaviours.TryGetValue(abbreviatedName, out behaviour); + } + public bool AddBehaviour(IBehaviour behaviour) { lock (Behaviours) @@ -200,6 +206,12 @@ namespace pCampBot return false; } + public bool RemoveBehaviour(string abbreviatedName) + { + lock (Behaviours) + return Behaviours.Remove(abbreviatedName); + } + private void CreateLibOmvClient() { GridClient newClient = new GridClient(); diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 51c5ff4..6433c2e 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -200,11 +200,11 @@ namespace pCampBot "Can be performed on connected or disconnected bots.", HandleAddBehaviour); -// m_console.Commands.AddCommand( -// "bot", false, "remove behaviour", "remove behaviour ", -// "Remove a behaviour from a bot", -// "Can be performed on connected or disconnected bots.", -// HandleRemoveBehaviour); + m_console.Commands.AddCommand( + "bot", false, "remove behaviour", "remove behaviour ", + "Remove a behaviour from a bot", + "Can be performed on connected or disconnected bots.", + HandleRemoveBehaviour); m_console.Commands.AddCommand( "bot", false, "sit", "sit", "Sit all bots on the ground.", @@ -525,6 +525,49 @@ namespace pCampBot string.Join(", ", behavioursAdded.ConvertAll(b => b.Name).ToArray()), bot.Name); } + private void HandleRemoveBehaviour(string module, string[] cmd) + { + if (cmd.Length != 4) + { + MainConsole.Instance.OutputFormat("Usage: remove behaviour "); + return; + } + + string rawBehaviours = cmd[2]; + int botNumber; + + if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber)) + return; + + Bot bot = GetBotFromNumber(botNumber); + + if (bot == null) + { + MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); + return; + } + + HashSet abbreviatedBehavioursToRemove = new HashSet(); + List behavioursRemoved = new List(); + + Array.ForEach(rawBehaviours.Split(new char[] { ',' }), b => abbreviatedBehavioursToRemove.Add(b)); + + foreach (string b in abbreviatedBehavioursToRemove) + { + IBehaviour behaviour; + + if (bot.TryGetBehaviour(b, out behaviour)) + { + bot.RemoveBehaviour(b); + behavioursRemoved.Add(behaviour); + } + } + + MainConsole.Instance.OutputFormat( + "Removed behaviours {0} to bot {1}", + string.Join(", ", behavioursRemoved.ConvertAll(b => b.Name).ToArray()), bot.Name); + } + private void HandleDisconnect(string module, string[] cmd) { lock (m_bots) -- cgit v1.1 From 3dbe7313d1c3fc28f0642531fbb6e238a98ac821 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 19:33:17 +0100 Subject: Add Close() method to IBehaviour to allow behaviours to cleanup when removed or bot it disconnected. In this case, it is used to turn off jump when physics testing behaviour is removed. --- OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs | 2 ++ OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs | 5 +++++ OpenSim/Tools/pCampBot/Bot.cs | 16 +++++++++++++++- OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs | 8 ++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs index 66d5542..9bc8512 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/AbstractBehaviour.cs @@ -50,5 +50,7 @@ namespace pCampBot { Bot = bot; } + + public virtual void Close() {} } } diff --git a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs index 47b4d46..65a7c90 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs @@ -78,6 +78,11 @@ namespace pCampBot Bot.Client.Self.Chat(randomf, 0, ChatType.Normal); } + public override void Close() + { + Bot.Client.Self.Jump(false); + } + private string[] readexcuses() { string allexcuses = ""; diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index 0bd8151..f871b77 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -209,7 +209,17 @@ namespace pCampBot public bool RemoveBehaviour(string abbreviatedName) { lock (Behaviours) - return Behaviours.Remove(abbreviatedName); + { + IBehaviour behaviour; + + if (!Behaviours.TryGetValue(abbreviatedName, out behaviour)) + return false; + + behaviour.Close(); + Behaviours.Remove(abbreviatedName); + + return true; + } } private void CreateLibOmvClient() @@ -282,6 +292,10 @@ namespace pCampBot // XXX: This is a really shitty way of yielding so that behaviours can be added/removed Thread.Sleep(100); } + + lock (Behaviours) + foreach (IBehaviour b in Behaviours.Values) + b.Close(); } /// diff --git a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs index f8a661b..0ed4825 100644 --- a/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Interfaces/IBehaviour.cs @@ -51,6 +51,14 @@ namespace pCampBot.Interfaces void Initialize(Bot bot); /// + /// Close down this behaviour. + /// + /// + /// This is triggered if a behaviour is removed via explicit command and when a bot is disconnected + /// + void Close(); + + /// /// Action to take when this behaviour is invoked. /// /// -- cgit v1.1 From 76bd2e2d727a15e5d3bc9045bdef6faaeca4a08f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 19:41:12 +0100 Subject: Consistently give responsibility for thread sleeping to behaviours rather than controlling from the main action loop This is to avoid excessive and inconsistent delays between behaviours that currently need to embed sleeps in other actions (e.g. physics) and other behaviours. Might need a more sophisticated approach in the long term. --- OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs | 3 +++ OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs | 3 +++ OpenSim/Tools/pCampBot/Bot.cs | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs index 6acc27d..59f6244 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/GrabbingBehaviour.cs @@ -29,6 +29,7 @@ using OpenMetaverse; using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using pCampBot.Interfaces; namespace pCampBot @@ -60,6 +61,8 @@ namespace pCampBot Bot.Client.Self.Grab(prim.LocalID); Bot.Client.Self.GrabUpdate(prim.ID, Vector3.Zero); Bot.Client.Self.DeGrab(prim.LocalID); + + Thread.Sleep(1000); } } } \ No newline at end of file diff --git a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs index 5f7edda..81f250d 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/TeleportBehaviour.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Threading; using log4net; using OpenMetaverse; using pCampBot.Interfaces; @@ -74,6 +75,8 @@ namespace pCampBot Bot.Name, sourceRegion.Name, Bot.Client.Self.SimPosition, destRegion.Name, destPosition); Bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition); + + Thread.Sleep(Bot.Random.Next(3000, 10000)); } } } \ No newline at end of file diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index f871b77..d0a4ef3 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -282,7 +282,7 @@ namespace pCampBot { foreach (IBehaviour behaviour in Behaviours.Values) { - Thread.Sleep(Random.Next(3000, 10000)); +// Thread.Sleep(Random.Next(3000, 10000)); // m_log.DebugFormat("[pCAMPBOT]: For {0} performing action {1}", Name, b.GetType()); behaviour.Action(); -- cgit v1.1 From 9c3c9b7f5f62a7ed892f691180b765a9190cbbcc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 19:57:34 +0100 Subject: Make pCampbot "add behaviour" and "remove behaviour" console commands work for all bots if no bot number is given --- OpenSim/Tools/pCampBot/BotManager.cs | 123 ++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 45 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 6433c2e..3c1b11e 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -195,15 +195,17 @@ namespace pCampBot HandleDisconnect); m_console.Commands.AddCommand( - "bot", false, "add behaviour", "add behaviour ", + "bot", false, "add behaviour", "add behaviour []", "Add a behaviour to a bot", - "Can be performed on connected or disconnected bots.", + "If no bot number is specified then behaviour is added to all bots.\n" + + "Can be performed on connected or disconnected bots.", HandleAddBehaviour); m_console.Commands.AddCommand( - "bot", false, "remove behaviour", "remove behaviour ", + "bot", false, "remove behaviour", "remove behaviour []", "Remove a behaviour from a bot", - "Can be performed on connected or disconnected bots.", + "If no bot number is specified then behaviour is added to all bots.\n" + + "Can be performed on connected or disconnected bots.", HandleRemoveBehaviour); m_console.Commands.AddCommand( @@ -224,7 +226,7 @@ namespace pCampBot "bot", false, "show bots", "show bots", "Shows the status of all bots", HandleShowBotsStatus); m_console.Commands.AddCommand( - "bot", false, "show bot", "show bot ", + "bot", false, "show bot", "show bot ", "Shows the detailed status and settings of a particular bot.", HandleShowBotStatus); m_bots = new List(); @@ -489,83 +491,114 @@ namespace pCampBot private void HandleAddBehaviour(string module, string[] cmd) { - if (cmd.Length != 4) + if (cmd.Length < 3 || cmd.Length > 4) { - MainConsole.Instance.OutputFormat("Usage: add behaviour "); + MainConsole.Instance.OutputFormat("Usage: add behaviour []"); return; } string rawBehaviours = cmd[2]; - int botNumber; - - if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber)) - return; - Bot bot = GetBotFromNumber(botNumber); + List botsToEffect = new List(); - if (bot == null) + if (cmd.Length == 3) { - MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); - return; + lock (m_bots) + botsToEffect.AddRange(m_bots); } + else + { + int botNumber; + if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber)) + return; + + Bot bot = GetBotFromNumber(botNumber); + + if (bot == null) + { + MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); + return; + } + + botsToEffect.Add(bot); + } + HashSet rawAbbreviatedSwitchesToAdd = new HashSet(); Array.ForEach(rawBehaviours.Split(new char[] { ',' }), b => rawAbbreviatedSwitchesToAdd.Add(b)); - List behavioursAdded = new List(); - - foreach (IBehaviour behaviour in CreateBehavioursFromAbbreviatedNames(rawAbbreviatedSwitchesToAdd)) + foreach (Bot bot in botsToEffect) { - if (bot.AddBehaviour(behaviour)) - behavioursAdded.Add(behaviour); - } + List behavioursAdded = new List(); - MainConsole.Instance.OutputFormat( - "Added behaviours {0} to bot {1}", - string.Join(", ", behavioursAdded.ConvertAll(b => b.Name).ToArray()), bot.Name); + foreach (IBehaviour behaviour in CreateBehavioursFromAbbreviatedNames(rawAbbreviatedSwitchesToAdd)) + { + if (bot.AddBehaviour(behaviour)) + behavioursAdded.Add(behaviour); + } + + MainConsole.Instance.OutputFormat( + "Added behaviours {0} to bot {1}", + string.Join(", ", behavioursAdded.ConvertAll(b => b.Name).ToArray()), bot.Name); + } } private void HandleRemoveBehaviour(string module, string[] cmd) { - if (cmd.Length != 4) + if (cmd.Length < 3 || cmd.Length > 4) { - MainConsole.Instance.OutputFormat("Usage: remove behaviour "); + MainConsole.Instance.OutputFormat("Usage: remove behaviour []"); return; } string rawBehaviours = cmd[2]; - int botNumber; - - if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber)) - return; - Bot bot = GetBotFromNumber(botNumber); + List botsToEffect = new List(); - if (bot == null) + if (cmd.Length == 3) { - MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); - return; + lock (m_bots) + botsToEffect.AddRange(m_bots); } + else + { + int botNumber; + if (!ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, cmd[3], out botNumber)) + return; - HashSet abbreviatedBehavioursToRemove = new HashSet(); - List behavioursRemoved = new List(); + Bot bot = GetBotFromNumber(botNumber); + + if (bot == null) + { + MainConsole.Instance.OutputFormat("Error: No bot found with number {0}", botNumber); + return; + } + botsToEffect.Add(bot); + } + + HashSet abbreviatedBehavioursToRemove = new HashSet(); Array.ForEach(rawBehaviours.Split(new char[] { ',' }), b => abbreviatedBehavioursToRemove.Add(b)); - foreach (string b in abbreviatedBehavioursToRemove) + foreach (Bot bot in botsToEffect) { - IBehaviour behaviour; + List behavioursRemoved = new List(); - if (bot.TryGetBehaviour(b, out behaviour)) + foreach (string b in abbreviatedBehavioursToRemove) { - bot.RemoveBehaviour(b); - behavioursRemoved.Add(behaviour); + IBehaviour behaviour; + + if (bot.TryGetBehaviour(b, out behaviour)) + { + bot.RemoveBehaviour(b); + behavioursRemoved.Add(behaviour); + } } - } - MainConsole.Instance.OutputFormat( - "Removed behaviours {0} to bot {1}", - string.Join(", ", behavioursRemoved.ConvertAll(b => b.Name).ToArray()), bot.Name); + MainConsole.Instance.OutputFormat( + "Removed behaviours {0} to bot {1}", + string.Join(", ", behavioursRemoved.ConvertAll(b => b.Name).ToArray()), bot.Name); + } } private void HandleDisconnect(string module, string[] cmd) -- cgit v1.1 From b781a23c445bea0fd199eb756ebf6143959256a6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 3 Sep 2013 19:58:27 +0100 Subject: In pCampbot PhysicsBehaviour.Close(), only cancel jumping if bot is connected --- OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs index 65a7c90..6fd2b7c 100644 --- a/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs +++ b/OpenSim/Tools/pCampBot/Behaviours/PhysicsBehaviour.cs @@ -80,7 +80,8 @@ namespace pCampBot public override void Close() { - Bot.Client.Self.Jump(false); + if (Bot.ConnectionState == ConnectionState.Connected) + Bot.Client.Self.Jump(false); } private string[] readexcuses() -- cgit v1.1 From 5f0d54c209249e0640bc27b3d74a92e7c9d82428 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 26 Aug 2013 20:04:07 +0100 Subject: For a Hypergrid user, delay estate access checks until NewUserConnection() so that they work. This is necessary because the hypergrid groups checks (as referenced by estates) require an agent circuit to be present to construct the hypergrid ID. However, this is not around until Scene.NewUserConnection(), as called by CreateAgent() in EntityTransferModule. Therefore, if we're dealing with a hypergrid user, delay the check until NewUserConnection()/CreateAgent() The entity transfer impact should be minimal since CreateAgent() is the next significant call after NewUserConnection() However, to preserve the accuracy of query access we will only relax the check for HG users. --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2a21a4c..8754024 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5788,9 +5788,13 @@ namespace OpenSim.Region.Framework.Scenes try { - if (!AuthorizeUser(aCircuit, false, out reason)) + // If this is a hypergrid user, then we can't perform a successful groups access check here since this + // currently relies on a circuit being present in the AuthenticateHandler to construct a Hypergrid ID. + // This is only present in NewUserConnection() which entity transfer calls very soon after QueryAccess(). + // Therefore, we'll defer to the check in NewUserConnection() instead. + if (!AuthorizeUser(aCircuit, !UserManagementModule.IsLocalGridUser(agentID), out reason)) { - // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); + //m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); return false; } } -- cgit v1.1 From c7ded0618c303f8c24a91c83c2129292beebe466 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 27 Aug 2013 00:35:33 +0100 Subject: Also check user authorization if looking to upgrade from a child to a root agent. Relevant if a child agent has been allowed into the region which should not be upgraded to a root agent. --- OpenSim/Region/Framework/Scenes/Scene.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8754024..3eaa8fd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3860,6 +3860,19 @@ namespace OpenSim.Region.Framework.Scenes // Let the SP know how we got here. This has a lot of interesting // uses down the line. sp.TeleportFlags = (TPFlags)teleportFlags; + + // We must carry out a further authorization check if there's an + // attempt to make a child agent into a root agent, since SeeIntoRegion may have allowed a child + // agent to login to a region where a full avatar would not be allowed. + // + // We determine whether this is a CreateAgent for a future non-child agent by inspecting + // TeleportFlags, which will be default for a child connection. This relies on input from the source + // region. + if (sp.TeleportFlags != TPFlags.Default) + { + if (!AuthorizeUser(acd, false, out reason)) + return false; + } if (sp.IsChildAgent) { -- cgit v1.1 From dc74a50225a901e969ea83008555170f5742ca7a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 4 Sep 2013 23:48:24 +0100 Subject: Stop "show client stats" from throwing an exception if somehow Scene.m_clientManager still retains a reference to a dead client. Instead, "show client stats" now prints "Off!" so that exception is not thrown and we know which entries in ClientManager are in this state. There's a race condition which could trigger this, but the window is extremely short and exceptions would not be thrown consistently (which is the behaviour observed). It should otherwise be impossible for this condition to occur, so there may be a weakness in client manager IClientAPI removal. --- .../OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs index 15dea17..1eb0a6b 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs @@ -624,9 +624,16 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden 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); + string childAgentStatus; + + if (llClient.SceneAgent != null) + childAgentStatus = llClient.SceneAgent.IsChildAgent ? "N" : "Y"; + else + childAgentStatus = "Off!"; + m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", scene.RegionInfo.RegionName, llClient.Name, - llClient.SceneAgent.IsChildAgent ? "N" : "Y", + childAgentStatus, (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs, string.Format( -- cgit v1.1 From 04619a9b139ac67c92b5b8be9607544be2621d7e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 5 Sep 2013 07:44:27 -0700 Subject: Restore group membership check for HG users in QueryAccess. --- .../Groups/Hypergrid/GroupsServiceHGConnectorModule.cs | 9 ++++++--- .../Framework/UserManagement/UserManagementModule.cs | 14 ++++++++++---- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +----- 3 files changed, 17 insertions(+), 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs index 4642b2a..7d48516 100644 --- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs +++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs @@ -623,10 +623,13 @@ namespace OpenSim.Groups if (agent != null) break; } - if (agent == null) // oops - return AgentID.ToString(); + if (agent != null) + return Util.ProduceUserUniversalIdentifier(agent); + + // we don't know anything about this foreign user + // try asking the user management module, which may know more + return m_UserManagement.GetUserUUI(AgentID); - return Util.ProduceUserUniversalIdentifier(agent); } private string AgentUUIForOutside(string AgentIDStr) diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 7adb203..8c983e6 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -481,14 +481,20 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public string GetUserUUI(UUID userID) { - UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID); - if (account != null) - return userID.ToString(); - UserData ud; lock (m_UserCache) m_UserCache.TryGetValue(userID, out ud); + if (ud == null) // It's not in the cache + { + string[] names = new string[2]; + // This will pull the data from either UserAccounts or GridUser + // and stick it into the cache + TryGetUserNamesFromServices(userID, names); + lock (m_UserCache) + m_UserCache.TryGetValue(userID, out ud); + } + if (ud != null) { string homeURL = ud.HomeURL; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3eaa8fd..e00206f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5801,11 +5801,7 @@ namespace OpenSim.Region.Framework.Scenes try { - // If this is a hypergrid user, then we can't perform a successful groups access check here since this - // currently relies on a circuit being present in the AuthenticateHandler to construct a Hypergrid ID. - // This is only present in NewUserConnection() which entity transfer calls very soon after QueryAccess(). - // Therefore, we'll defer to the check in NewUserConnection() instead. - if (!AuthorizeUser(aCircuit, !UserManagementModule.IsLocalGridUser(agentID), out reason)) + if (!AuthorizeUser(aCircuit, false, out reason)) { //m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); return false; -- cgit v1.1