diff --git a/OpenSim/Framework/IRegionCommsListener.cs b/OpenSim/Framework/IRegionCommsListener.cs deleted file mode 100644 index cd59c63db6..0000000000 --- a/OpenSim/Framework/IRegionCommsListener.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.Collections.Generic; -using OpenMetaverse; - -namespace OpenSim.Framework -{ - public delegate void ExpectUserDelegate(AgentCircuitData agent); - - - public delegate void UpdateNeighbours(List neighbours); - - public delegate void AgentCrossing(UUID agentID, Vector3 position, bool isFlying); - - public delegate void PrimCrossing(UUID primID, Vector3 position, bool isPhysical); - - public delegate void AcknowledgeAgentCross(UUID agentID); - - public delegate void AcknowledgePrimCross(UUID PrimID); - - public delegate bool CloseAgentConnection(UUID agentID); - - public delegate bool ChildAgentUpdate(ChildAgentDataUpdate cAgentData); - - public delegate void LogOffUser(UUID agentID, UUID regionSecret, string message); - - public delegate LandData GetLandData(uint x, uint y); - - public interface IRegionCommsListener - { - event ExpectUserDelegate OnExpectUser; - event GenericCall2 OnExpectChildAgent; - event AgentCrossing OnAvatarCrossingIntoRegion; - event PrimCrossing OnPrimCrossingIntoRegion; - event AcknowledgeAgentCross OnAcknowledgeAgentCrossed; - event AcknowledgePrimCross OnAcknowledgePrimCrossed; - event UpdateNeighbours OnNeighboursUpdate; - event CloseAgentConnection OnCloseAgentConnection; - event ChildAgentUpdate OnChildAgentUpdate; - event LogOffUser OnLogOffUser; - event GetLandData OnGetLandData; - } -} diff --git a/OpenSim/Framework/RegionCommsListener.cs b/OpenSim/Framework/RegionCommsListener.cs deleted file mode 100644 index 3e0955d073..0000000000 --- a/OpenSim/Framework/RegionCommsListener.cs +++ /dev/null @@ -1,204 +0,0 @@ -/* - * 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; - -namespace OpenSim.Framework -{ - /// - /// Sandbox mode region comms listener. There is one of these per region - /// - public class RegionCommsListener : IRegionCommsListener - { - public string debugRegionName = String.Empty; - private AcknowledgeAgentCross handlerAcknowledgeAgentCrossed = null; // OnAcknowledgeAgentCrossed; - private AcknowledgePrimCross handlerAcknowledgePrimCrossed = null; // OnAcknowledgePrimCrossed; - private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion; - private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate; - private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection; - private GenericCall2 handlerExpectChildAgent = null; // OnExpectChildAgent; - private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser - private UpdateNeighbours handlerNeighboursUpdate = null; // OnNeighboursUpdate; -// private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; - private LogOffUser handlerLogOffUser = null; - private GetLandData handlerGetLandData = null; - - #region IRegionCommsListener Members - - public event ExpectUserDelegate OnExpectUser; - public event GenericCall2 OnExpectChildAgent; - public event AgentCrossing OnAvatarCrossingIntoRegion; - public event PrimCrossing OnPrimCrossingIntoRegion; - public event UpdateNeighbours OnNeighboursUpdate; - public event AcknowledgeAgentCross OnAcknowledgeAgentCrossed; - public event AcknowledgePrimCross OnAcknowledgePrimCrossed; - public event CloseAgentConnection OnCloseAgentConnection; - public event ChildAgentUpdate OnChildAgentUpdate; - public event LogOffUser OnLogOffUser; - public event GetLandData OnGetLandData; - - #endregion - - /// - /// - /// - /// - /// - public virtual bool TriggerExpectUser(AgentCircuitData agent) - { - handlerExpectUser = OnExpectUser; - if (handlerExpectUser != null) - { - handlerExpectUser(agent); - return true; - } - - return false; - } - - // From User Server - public virtual void TriggerLogOffUser(UUID agentID, UUID RegionSecret, string message) - { - handlerLogOffUser = OnLogOffUser; - if (handlerLogOffUser != null) - { - handlerLogOffUser(agentID, RegionSecret, message); - } - - } - - public virtual bool TriggerChildAgentUpdate(ChildAgentDataUpdate cAgentData) - { - handlerChildAgentUpdate = OnChildAgentUpdate; - if (handlerChildAgentUpdate != null) - { - handlerChildAgentUpdate(cAgentData); - return true; - } - return false; - } - - public virtual bool TriggerExpectAvatarCrossing(UUID agentID, Vector3 position, bool isFlying) - { - handlerAvatarCrossingIntoRegion = OnAvatarCrossingIntoRegion; - if (handlerAvatarCrossingIntoRegion != null) - { - handlerAvatarCrossingIntoRegion(agentID, position, isFlying); - return true; - } - return false; - } - - public virtual bool TriggerAcknowledgeAgentCrossed(UUID agentID) - { - handlerAcknowledgeAgentCrossed = OnAcknowledgeAgentCrossed; - if (handlerAcknowledgeAgentCrossed != null) - { - handlerAcknowledgeAgentCrossed(agentID); - return true; - } - return false; - } - - public virtual bool TriggerAcknowledgePrimCrossed(UUID primID) - { - handlerAcknowledgePrimCrossed = OnAcknowledgePrimCrossed; - if (handlerAcknowledgePrimCrossed != null) - { - handlerAcknowledgePrimCrossed(primID); - return true; - } - return false; - } - - public virtual bool TriggerCloseAgentConnection(UUID agentID) - { - handlerCloseAgentConnection = OnCloseAgentConnection; - if (handlerCloseAgentConnection != null) - { - handlerCloseAgentConnection(agentID); - return true; - } - return false; - } - - /// - /// - /// - /// TODO: Doesnt take any args?? - /// - public virtual bool TriggerExpectChildAgent() - { - handlerExpectChildAgent = OnExpectChildAgent; - if (handlerExpectChildAgent != null) - { - handlerExpectChildAgent(); - return true; - } - - return false; - } - - /// - /// - /// - /// Added to avoid a unused compiler warning on OnNeighboursUpdate, TODO: Check me - /// - /// - public virtual bool TriggerOnNeighboursUpdate(List neighbours) - { - handlerNeighboursUpdate = OnNeighboursUpdate; - if (handlerNeighboursUpdate != null) - { - handlerNeighboursUpdate(neighbours); - return true; - } - - return false; - } - - public bool TriggerTellRegionToCloseChildConnection(UUID agentID) - { - handlerCloseAgentConnection = OnCloseAgentConnection; - if (handlerCloseAgentConnection != null) - return handlerCloseAgentConnection(agentID); - - return false; - } - - public LandData TriggerGetLandData(uint x, uint y) - { - handlerGetLandData = OnGetLandData; - if (handlerGetLandData != null) - return handlerGetLandData(x, y); - - return null; - } - } -} diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 66d0813b1d..3551d5db9a 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -243,17 +243,32 @@ namespace OpenSim.Framework.Servers /// protected string GetThreadsReport() { + // This should be a constant field. + string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}"; + StringBuilder sb = new StringBuilder(); Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreads(); sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine); + + int timeNow = Util.EnvironmentTickCount(); + + sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE"); + sb.Append(Environment.NewLine); + foreach (Watchdog.ThreadWatchdogInfo twi in threads) { Thread t = twi.Thread; - sb.Append( - "ID: " + t.ManagedThreadId + ", Name: " + t.Name + ", TimeRunning: " - + "Pri: " + t.Priority + ", State: " + t.ThreadState); + sb.AppendFormat( + reportFormat, + t.ManagedThreadId, + t.Name, + timeNow - twi.LastTick, + timeNow - twi.FirstTick, + t.Priority, + t.ThreadState); + sb.Append(Environment.NewLine); } diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs index 16e56d2060..5e171f00f8 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceWorkerThread.cs @@ -69,6 +69,9 @@ namespace OpenSim.Framework.Servers.HttpServer while (m_running) { PollServiceHttpRequest req = m_request.Dequeue(); + + Watchdog.UpdateThread(); + try { if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index 4847675b68..fa94109af1 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs @@ -48,6 +48,18 @@ namespace OpenSim.Framework public class ThreadWatchdogInfo { public Thread Thread { get; private set; } + + /// + /// Approximate tick when this thread was started. + /// + /// + /// Not terribly good since this quickly wraps around. + /// + public int FirstTick { get; private set; } + + /// + /// First time this heartbeat update was invoked + /// public int LastTick { get; set; } /// @@ -64,7 +76,8 @@ namespace OpenSim.Framework { Thread = thread; Timeout = timeout; - LastTick = Environment.TickCount & Int32.MaxValue; + FirstTick = Environment.TickCount & Int32.MaxValue; + LastTick = FirstTick; } } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 0c81bb2882..5d94ff7e1c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Threading; using log4net; using Nini.Config; using Nwc.XmlRpc; @@ -79,10 +80,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected IFriendsService m_FriendsService = null; protected FriendsSimConnector m_FriendsSimConnector; - protected Dictionary m_Friends = - new Dictionary(); + /// + /// Cache friends lists for users. + /// + /// + /// This is a complex and error-prone thing to do. At the moment, we assume that the efficiency gained in + /// permissions checks outweighs the disadvantages of that complexity. + /// + protected Dictionary m_Friends = new Dictionary(); - protected HashSet m_NeedsListOfFriends = new HashSet(); + /// + /// Maintain a record of viewers that need to be sent notifications for friends that are online. This only + /// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism. + /// + protected HashSet m_NeedsListOfOnlineFriends = new HashSet(); protected IPresenceService PresenceService { @@ -189,6 +200,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { if (!m_Enabled) return; + m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); m_Scenes.Add(scene); @@ -241,16 +253,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends client.OnInstantMessage += OnInstantMessage; client.OnApproveFriendRequest += OnApproveFriendRequest; client.OnDenyFriendRequest += OnDenyFriendRequest; - client.OnTerminateFriendship += OnTerminateFriendship; + client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID); client.OnGrantUserRights += OnGrantUserRights; - Util.FireAndForget(delegate { FetchFriendslist(client); }); + // Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and + // return misleading results from the still empty friends cache. + // If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls + // to GetFriends() will wait until CacheFriends() completes. Locks are insufficient. + CacheFriends(client); } - /// Fetch the friends list or increment the refcount for the existing - /// friends list + /// + /// Cache the friends list or increment the refcount for the existing friends list. + /// + /// + /// + /// /// Returns true if the list was fetched, false if it wasn't - protected virtual bool FetchFriendslist(IClientAPI client) + /// + protected virtual bool CacheFriends(IClientAPI client) { UUID agentID = client.AgentId; lock (m_Friends) @@ -297,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void OnMakeRootAgent(ScenePresence sp) { - RefetchFriends(sp.ControllingClient); + RecacheFriends(sp.ControllingClient); } private void OnClientLogin(IClientAPI client) @@ -309,8 +330,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends StatusChange(agentID, true); // Register that we need to send the list of online friends to this user - lock (m_NeedsListOfFriends) - m_NeedsListOfFriends.Add(agentID); + lock (m_NeedsListOfOnlineFriends) + m_NeedsListOfOnlineFriends.Add(agentID); } public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client) @@ -318,9 +339,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends UUID agentID = client.AgentId; // Check if the online friends list is needed - lock (m_NeedsListOfFriends) + lock (m_NeedsListOfOnlineFriends) { - if (!m_NeedsListOfFriends.Remove(agentID)) + if (!m_NeedsListOfOnlineFriends.Remove(agentID)) return false; } @@ -328,7 +349,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends List online = GetOnlineFriends(agentID); if (online.Count > 0) { - m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count); + m_log.DebugFormat( + "[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", + client.Name, client.Scene.RegionInfo.RegionName, online.Count); + client.SendAgentOnline(online.ToArray()); } @@ -586,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } // Update the local cache - RefetchFriends(client); + RecacheFriends(client); // // Notify the friend @@ -641,14 +665,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } } - - private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) + + public void RemoveFriendship(IClientAPI client, UUID exfriendID) { - if (!DeleteFriendship(agentID, exfriendID)) + if (!DeleteFriendship(client.AgentId, exfriendID)) client.SendAlertMessage("Unable to terminate friendship on this sim."); // Update local cache - RefetchFriends(client); + RecacheFriends(client); client.SendTerminateFriend(exfriendID); @@ -667,9 +691,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (friendSession != null) { GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID); + m_FriendsSimConnector.FriendshipTerminated(region, client.AgentId, exfriendID); } - } + } } private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) @@ -769,7 +793,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // Update the local cache - RefetchFriends(friendClient); + RecacheFriends(friendClient); // we're done return true; @@ -802,7 +826,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // the friend in this sim as root agent friendClient.SendTerminateFriend(exfriendID); // update local cache - RefetchFriends(friendClient); + RecacheFriends(friendClient); // we're done return true; } @@ -819,16 +843,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (onlineBitChanged) { if ((rights & (int)FriendRights.CanSeeOnline) == 1) - friendClient.SendAgentOnline(new UUID[] { new UUID(userID) }); + friendClient.SendAgentOnline(new UUID[] { userID }); else - friendClient.SendAgentOffline(new UUID[] { new UUID(userID) }); + friendClient.SendAgentOffline(new UUID[] { userID }); } else { bool canEditObjectsChanged = ((rights ^ userFlags) & (int)FriendRights.CanModifyObjects) != 0; if (canEditObjectsChanged) friendClient.SendChangeUserRights(userID, friendID, rights); - } // Update local cache @@ -847,7 +870,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends IClientAPI friendClient = LocateClientObject(friendID); if (friendClient != null) { - // the friend in this sim as root agent + // the friend in this sim as root agent if (online) friendClient.SendAgentOnline(new UUID[] { userID }); else @@ -902,8 +925,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return FriendsService.GetFriends(client.AgentId); } - private void RefetchFriends(IClientAPI client) + private void RecacheFriends(IClientAPI client) { + // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event + // is on the critical path for transferring an avatar from one region to another. UUID agentID = client.AgentId; lock (m_Friends) { diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 02b417f946..9a97925bfc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -30,7 +30,6 @@ using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Threading; - using log4net; using Nini.Config; using Nwc.XmlRpc; @@ -84,9 +83,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends #endregion - protected override bool FetchFriendslist(IClientAPI client) + protected override bool CacheFriends(IClientAPI client) { - if (base.FetchFriendslist(client)) +// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name); + + if (base.CacheFriends(client)) { UUID agentID = client.AgentId; // we do this only for the root agent @@ -110,14 +111,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } } + +// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting CacheFriends for {0} since detected root agent", client.Name); return true; } } + +// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting CacheFriends for {0} since detected not root agent", client.Name); return false; } public override bool SendFriendsOnlineIfNeeded(IClientAPI client) { +// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering SendFriendsOnlineIfNeeded for {0}", client.Name); + if (base.SendFriendsOnlineIfNeeded(client)) { AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId); @@ -134,11 +141,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } } + +// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting SendFriendsOnlineIfNeeded for {0}", client.Name); return false; } protected override void GetOnlineFriends(UUID userID, List friendList, /*collector*/ List online) { +// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetOnlineFriends for {0}", userID); + List fList = new List(); foreach (string s in friendList) { @@ -157,6 +168,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (UUID.TryParse(pi.UserID, out presenceID)) online.Add(presenceID); } + +// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID); } //protected override void GetOnlineFriends(UUID userID, List friendList, /*collector*/ List online) @@ -246,6 +259,8 @@ 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); + // First, let's divide the friends on a per-domain basis Dictionary> friendsPerDomain = new Dictionary>(); foreach (FriendInfo friend in friendList) @@ -298,6 +313,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } } + +// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID); } protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) @@ -351,6 +368,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected override FriendInfo[] GetFriendsFromService(IClientAPI client) { +// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name); + UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); if (account1 != null) return base.GetFriendsFromService(client); @@ -365,6 +384,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends finfos = FriendsService.GetFriends(agentUUI); m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); } + +// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name); + return finfos; } @@ -401,7 +423,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } return false; - } protected override void StoreBackwards(UUID friendID, UUID agentID) @@ -627,4 +648,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs index c945dcf12c..682fbab142 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs @@ -71,12 +71,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId); - Assert.That(((TestClient)sp.ControllingClient).OfflineNotificationsReceived.Count, Is.EqualTo(0)); - Assert.That(((TestClient)sp.ControllingClient).OnlineNotificationsReceived.Count, Is.EqualTo(0)); + Assert.That(((TestClient)sp.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0)); + Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0)); } [Test] - public void TestAddFriendWhileOnline() + public void TestAddFriendshipWhileOnline() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); @@ -91,8 +91,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests // notification. m_fm.AddFriendship(sp.ControllingClient, user2Id); - Assert.That(((TestClient)sp.ControllingClient).OfflineNotificationsReceived.Count, Is.EqualTo(0)); - Assert.That(((TestClient)sp.ControllingClient).OnlineNotificationsReceived.Count, Is.EqualTo(1)); + Assert.That(((TestClient)sp.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0)); + Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1)); + } + + [Test] + public void TestRemoveFriendshipWhileOnline() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UUID user1Id = TestHelpers.ParseTail(0x1); + UUID user2Id = TestHelpers.ParseTail(0x2); + + ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, user1Id); + SceneHelpers.AddScenePresence(m_scene, user2Id); + + m_fm.AddFriendship(sp.ControllingClient, user2Id); + m_fm.RemoveFriendship(sp.ControllingClient, user2Id); + + TestClient user1Client = sp.ControllingClient as TestClient; + Assert.That(user1Client.ReceivedFriendshipTerminations.Count, Is.EqualTo(1)); + Assert.That(user1Client.ReceivedFriendshipTerminations[0], Is.EqualTo(user2Id)); } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index bef0d69697..a40a6a4822 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -31,7 +31,6 @@ using System.Reflection; using OpenSim.Framework; using OpenSim.Framework.Console; - using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -44,13 +43,13 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.UserManagement { - struct UserData + class UserData { - public UUID Id; - public string FirstName; - public string LastName; - public string HomeURL; - public Dictionary ServerURLs; + public UUID Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string HomeURL { get; set; } + public Dictionary ServerURLs { get; set; } } public class UserManagementModule : ISharedRegionModule, IUserManagement @@ -130,7 +129,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public void Close() { m_Scenes.Clear(); - m_UserCache.Clear(); + + lock (m_UserCache) + m_UserCache.Clear(); } #endregion ISharedRegionModule @@ -188,11 +189,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement { string[] returnstring = new string[2]; - if (m_UserCache.ContainsKey(uuid)) + lock (m_UserCache) { - returnstring[0] = m_UserCache[uuid].FirstName; - returnstring[1] = m_UserCache[uuid].LastName; - return returnstring; + if (m_UserCache.ContainsKey(uuid)) + { + returnstring[0] = m_UserCache[uuid].FirstName; + returnstring[1] = m_UserCache[uuid].LastName; + return returnstring; + } } UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); @@ -237,22 +241,36 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public string GetUserHomeURL(UUID userID) { - if (m_UserCache.ContainsKey(userID)) - return m_UserCache[userID].HomeURL; + lock (m_UserCache) + { + if (m_UserCache.ContainsKey(userID)) + return m_UserCache[userID].HomeURL; + } return string.Empty; } public string GetUserServerURL(UUID userID, string serverType) { - if (m_UserCache.ContainsKey(userID)) - { - UserData userdata = m_UserCache[userID]; - if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) - return userdata.ServerURLs[serverType].ToString(); + UserData userdata; + lock (m_UserCache) + m_UserCache.TryGetValue(userID, out userdata); - if (userdata.HomeURL != string.Empty) + if (userdata != null) + { +// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Requested url type {0} for {1}", serverType, userID); + + if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) { + return userdata.ServerURLs[serverType].ToString(); + } + + if (userdata.HomeURL != null && userdata.HomeURL != string.Empty) + { + m_log.DebugFormat( + "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}", + serverType, userdata.HomeURL, userID); + UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); userdata.ServerURLs = uConn.GetServerURLs(userID); if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) @@ -269,9 +287,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement if (account != null) return userID.ToString(); - if (m_UserCache.ContainsKey(userID)) + UserData ud; + lock (m_UserCache) + m_UserCache.TryGetValue(userID, out ud); + + if (ud != null) { - UserData ud = m_UserCache[userID]; string homeURL = ud.HomeURL; string first = ud.FirstName, last = ud.LastName; if (ud.LastName.StartsWith("@")) @@ -291,8 +312,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public void AddUser(UUID uuid, string first, string last) { - if (m_UserCache.ContainsKey(uuid)) - return; + lock (m_UserCache) + { + if (m_UserCache.ContainsKey(uuid)) + return; + } UserData user = new UserData(); user.Id = uuid; @@ -310,8 +334,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement public void AddUser(UUID id, string creatorData) { - if (m_UserCache.ContainsKey(id)) - return; + lock (m_UserCache) + { + if (m_UserCache.ContainsKey(id)) + return; + } // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData); @@ -402,22 +429,24 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement private void HandleShowUsers(string module, string[] cmd) { - if (m_UserCache.Count == 0) + lock (m_UserCache) { - MainConsole.Instance.Output("No users not found"); + if (m_UserCache.Count == 0) + { + MainConsole.Instance.Output("No users not found"); + return; + } + + MainConsole.Instance.Output("UUID User Name"); + MainConsole.Instance.Output("-----------------------------------------------------------------------------"); + foreach (KeyValuePair kvp in m_UserCache) + { + MainConsole.Instance.Output(String.Format("{0} {1} {2}", + kvp.Key, kvp.Value.FirstName, kvp.Value.LastName)); + } + return; } - - MainConsole.Instance.Output("UUID User Name"); - MainConsole.Instance.Output("-----------------------------------------------------------------------------"); - foreach (KeyValuePair kvp in m_UserCache) - { - MainConsole.Instance.Output(String.Format("{0} {1} {2}", - kvp.Key, kvp.Value.FirstName, kvp.Value.LastName)); - } - return; } - - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 2e877f0437..3963474a58 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -479,8 +479,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions } protected bool IsFriendWithPerms(UUID user,UUID objectOwner) - { - + { if (user == UUID.Zero) return false; diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index b49f23c589..ba4ddc14a0 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -65,7 +65,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private OpenSim.Framework.BlockingQueue requests = new OpenSim.Framework.BlockingQueue(); - //private IConfig m_config; protected Scene m_scene; private List cachedMapBlocks = new List(); private int cachedTime = 0; @@ -348,7 +347,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // m_log.Debug("[WORLD MAP]: Starting remote MapItem request thread"); - Watchdog.StartThread(process, "MapItemRequestThread", ThreadPriority.BelowNormal, true); + Watchdog.StartThread( + process, + string.Format("MapItemRequestThread ({0})", m_scene.RegionInfo.RegionName), + ThreadPriority.BelowNormal, + true); } /// @@ -357,7 +360,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private void StopThread() { MapRequestState st = new MapRequestState(); - st.agentID=STOP_UUID; + st.agentID = STOP_UUID; st.EstateID=0; st.flags=0; st.godlike=false; diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs index fdede340fc..061799e394 100644 --- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs @@ -44,6 +44,17 @@ namespace OpenSim.Region.Framework.Interfaces /// void AddFriendship(IClientAPI client, UUID friendID); + /// + /// Remove a friendship between two users. + /// + /// + /// Ultimately, it would be more useful to take in a user account here rather than having to have a user + /// present in the scene. + /// + /// + /// + void RemoveFriendship(IClientAPI client, UUID exFriendID); + uint GetFriendPerms(UUID PrincipalID, UUID FriendID); bool SendFriendsOnlineIfNeeded(IClientAPI client); } diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs index 664be01dbb..741f53b0bf 100644 --- a/OpenSim/Region/Framework/Scenes/EntityBase.cs +++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs @@ -103,7 +103,11 @@ namespace OpenSim.Region.Framework.Scenes public virtual uint LocalId { get { return m_localId; } - set { m_localId = value; } + set + { + m_localId = value; +// m_log.DebugFormat("[ENTITY BASE]: Set part {0} to local id {1}", Name, m_localId); + } } /// diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index 1812bd2983..b788a3ca08 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs @@ -79,7 +79,7 @@ namespace OpenSim.Region.Framework.Scenes { List tmp = new List(); - m_entities.ForEach( + ForEach( delegate(EntityBase entity) { if (entity is T) @@ -93,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes public EntityBase[] GetEntities() { List tmp = new List(m_entities.Count); - m_entities.ForEach(delegate(EntityBase entity) { tmp.Add(entity); }); + ForEach(delegate(EntityBase entity) { tmp.Add(entity); }); return tmp.ToArray(); } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 65c6a29cca..0049384b46 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -77,8 +77,10 @@ namespace OpenSim.Region.Framework.Scenes /// public event OnNewClientDelegate OnNewClient; - public delegate void OnClientLoginDelegate(IClientAPI client); - public event OnClientLoginDelegate OnClientLogin; + /// + /// Fired if the client entering this sim is doing so as a new login + /// + public event Action OnClientLogin; public delegate void OnNewPresenceDelegate(ScenePresence presence); @@ -214,10 +216,15 @@ namespace OpenSim.Region.Framework.Scenes public delegate void OnMakeChildAgentDelegate(ScenePresence presence); public event OnMakeChildAgentDelegate OnMakeChildAgent; - public delegate void OnMakeRootAgentDelegate(ScenePresence presence); public delegate void OnSaveNewWindlightProfileDelegate(); public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionLightShareData wl, UUID user); - public event OnMakeRootAgentDelegate OnMakeRootAgent; + + /// + /// This event is on the critical path for transferring an avatar from one region to another. Try and do + /// as little work on this event as possible, or do work asynchronously. + /// + public event Action OnMakeRootAgent; + public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted; public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile; @@ -655,10 +662,10 @@ namespace OpenSim.Region.Framework.Scenes public void TriggerOnClientLogin(IClientAPI client) { - OnClientLoginDelegate handlerClientLogin = OnClientLogin; + Action handlerClientLogin = OnClientLogin; if (handlerClientLogin != null) { - foreach (OnClientLoginDelegate d in handlerClientLogin.GetInvocationList()) + foreach (Action d in handlerClientLogin.GetInvocationList()) { try { @@ -1344,10 +1351,10 @@ namespace OpenSim.Region.Framework.Scenes public void TriggerOnMakeRootAgent(ScenePresence presence) { - OnMakeRootAgentDelegate handlerMakeRootAgent = OnMakeRootAgent; + Action handlerMakeRootAgent = OnMakeRootAgent; if (handlerMakeRootAgent != null) { - foreach (OnMakeRootAgentDelegate d in handlerMakeRootAgent.GetInvocationList()) + foreach (Action d in handlerMakeRootAgent.GetInvocationList()) { try { diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 876dfb2813..b6067eae6c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1148,8 +1148,8 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGraph.Close(); - // De-register with region communications (events cleanup) - UnRegisterRegionWithComms(); + if (!GridService.DeregisterRegion(m_regInfo.RegionID)) + m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName); // call the base class Close method. base.Close(); @@ -1177,7 +1177,9 @@ namespace OpenSim.Region.Framework.Scenes } m_lastUpdate = Util.EnvironmentTickCount(); - HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false); + HeartbeatThread + = Watchdog.StartThread( + Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false); } /// @@ -1663,8 +1665,6 @@ namespace OpenSim.Region.Framework.Scenes /// Thrown if registration of the region itself fails. public void RegisterRegionWithGrid() { - RegisterCommsEvents(); - m_sceneGridService.SetScene(this); GridRegion region = new GridRegion(RegionInfo); @@ -2665,11 +2665,12 @@ namespace OpenSim.Region.Framework.Scenes // Send all scene object to the new client Util.FireAndForget(delegate { - Entities.ForEach(delegate(EntityBase e) + EntityBase[] entities = Entities.GetEntities(); + foreach(EntityBase e in entities) { if (e != null && e is SceneObjectGroup) ((SceneObjectGroup)e).SendFullUpdateToClient(client); - }); + } }); } @@ -3331,40 +3332,6 @@ namespace OpenSim.Region.Framework.Scenes #region RegionComms - /// - /// Register the methods that should be invoked when this scene receives various incoming events - /// - public void RegisterCommsEvents() - { - m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing; - m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent; - //m_eventManager.OnRegionUp += OtherRegionUp; - //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; - //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; - m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; - m_sceneGridService.OnGetLandData += GetLandData; - } - - /// - /// Deregister this scene from receiving incoming region events - /// - public void UnRegisterRegionWithComms() - { - m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; - //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; - //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; - //m_eventManager.OnRegionUp -= OtherRegionUp; - m_sceneGridService.OnAvatarCrossingIntoRegion -= AgentCrossing; - m_sceneGridService.OnCloseAgentConnection -= IncomingCloseAgent; - m_sceneGridService.OnGetLandData -= GetLandData; - - // this does nothing; should be removed - m_sceneGridService.Close(); - - if (!GridService.DeregisterRegion(m_regInfo.RegionID)) - m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", m_regInfo.RegionName); - } - /// /// Do the work necessary to initiate a new user connection for a particular scene. /// At the moment, this consists of setting up the caps infrastructure diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index fe9fe31962..12058c88af 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -56,88 +56,12 @@ namespace OpenSim.Region.Framework.Scenes protected RegionInfo m_regionInfo; protected Scene m_scene; - protected RegionCommsListener regionCommsHost; - - protected List m_agentsInTransit; - - /// - /// An agent is crossing into this region - /// - public event AgentCrossing OnAvatarCrossingIntoRegion; - - /// - /// A user will arrive shortly, set up appropriate credentials so it can connect - /// -// public event ExpectUserDelegate OnExpectUser; - - /// - /// A Prim will arrive shortly - /// - public event CloseAgentConnection OnCloseAgentConnection; - - /// - /// A new prim has arrived - /// -// public event PrimCrossing OnPrimCrossingIntoRegion; - - ///// - ///// A New Region is up and available - ///// - //public event RegionUp OnRegionUp; - - /// - /// We have a child agent for this avatar and we're getting a status update about it - /// -// public event ChildAgentUpdate OnChildAgentUpdate; - //public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar; - - /// - /// Time to log one of our users off. Grid Service sends this mostly - /// - public event LogOffUser OnLogOffUser; - - /// - /// A region wants land data from us! - /// - public event GetLandData OnGetLandData; - -// private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion; -// private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser; -// private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection; -// private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; - //private RegionUp handlerRegionUp = null; // OnRegionUp; -// private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate; - //private RemoveKnownRegionsFromAvatarList handlerRemoveKnownRegionFromAvatar = null; // OnRemoveKnownRegionFromAvatar; -// private LogOffUser handlerLogOffUser = null; -// private GetLandData handlerGetLandData = null; // OnGetLandData - - public SceneCommunicationService() - { - } - public void SetScene(Scene s) { m_scene = s; m_regionInfo = s.RegionInfo; } - /// - /// Register a region with the grid - /// - /// - /// Thrown if region registration fails. - public void RegisterRegion(IInterregionCommsOut comms_out, RegionInfo regionInfos) - { - } - - /// - /// This region is shutting down, de-register all events! - /// De-Register region from Grid! - /// - public void Close() - { - } - public delegate void InformNeighbourThatRegionUpDelegate(INeighbourService nService, RegionInfo region, ulong regionhandle); private void InformNeighborsThatRegionisUpCompleted(IAsyncResult iar) @@ -173,7 +97,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void InformNeighborsThatRegionisUp(INeighbourService neighbourService, RegionInfo region) { //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName); @@ -190,7 +113,6 @@ namespace OpenSim.Region.Framework.Scenes } public delegate void SendChildAgentDataUpdateDelegate(AgentPosition cAgentData, UUID scopeID, GridRegion dest); - /// /// This informs all neighboring regions about the settings of it's child agent. @@ -295,6 +217,5 @@ namespace OpenSim.Region.Framework.Scenes { return m_scene.GridService.GetRegionsByName(UUID.Zero, name, maxNumber); } - } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 45ca0b75ac..e214f5788d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -533,7 +533,11 @@ namespace OpenSim.Region.Framework.Scenes public uint LocalId { get { return m_localId; } - set { m_localId = value; } + set + { + m_localId = value; +// m_log.DebugFormat("[SCENE OBJECT PART]: Set part {0} to local id {1}", Name, m_localId); + } } public virtual string Name diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 839259ffaf..d89c1c0157 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -757,7 +757,7 @@ namespace OpenSim.Region.Framework.Scenes m_name = String.Format("{0} {1}", Firstname, Lastname); m_scene = world; m_uuid = client.AgentId; - m_localId = m_scene.AllocateLocalId(); + LocalId = m_scene.AllocateLocalId(); UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); if (account != null) @@ -860,9 +860,15 @@ namespace OpenSim.Region.Framework.Scenes #region Status Methods /// - /// This turns a child agent, into a root agent - /// This is called when an agent teleports into a region, or if an - /// agent crosses into this region from a neighbor over the border + /// Turns a child agent into a root agent. + /// + /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the + /// avatar is actual in the sim. They can perform all actions. + /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, + /// teleporting in or on initial login. + /// + /// This method is on the critical path for transferring an avatar from one region to another. Delay here + /// delays that crossing. /// public void MakeRootAgent(Vector3 pos, bool isFlying) { diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 49f60f8d5e..798a0a42d9 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -25,8 +25,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using log4net; using System; using System.Collections.Generic; +using System.Reflection; using OpenSim.Framework; using OpenMetaverse; @@ -46,10 +48,10 @@ namespace OpenSim.Region.Physics.Manager public enum PIDHoverType { - Ground - , GroundAndWater - , Water - , Absolute + Ground, + GroundAndWater, + Water, + Absolute } public struct ContactPoint @@ -114,6 +116,8 @@ namespace OpenSim.Region.Physics.Manager public abstract class PhysicsActor { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public delegate void RequestTerseUpdate(); public delegate void CollisionUpdate(EventArgs e); public delegate void OutOfBounds(Vector3 pos); @@ -197,10 +201,10 @@ namespace OpenSim.Region.Physics.Manager { CollisionUpdate handler = OnCollisionUpdate; +// m_log.DebugFormat("[PHYSICS ACTOR]: Sending collision for {0}", LocalID); + if (handler != null) - { handler(e); - } } public virtual void SetMaterial (int material) diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 363051062f..c37d588730 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -108,7 +108,6 @@ namespace OpenSim.Region.Physics.OdePlugin /// private Vector3 m_taintForce; - internal uint m_localID = 0; // taints and their non-tainted counterparts private bool m_isPhysical = false; // the current physical status private bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing) @@ -231,11 +230,6 @@ namespace OpenSim.Region.Physics.OdePlugin set { m_alwaysRun = value; } } - public override uint LocalID - { - set { m_localID = value; } - } - public override bool Grabbed { set { return; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index ffd6dc06b8..f07cf46f94 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -142,8 +142,6 @@ namespace OpenSim.Region.Physics.OdePlugin public bool m_taintselected { get; private set; } public bool m_taintCollidesWater { get; private set; } - public uint m_localID { get; private set; } - private bool m_taintforce = false; private bool m_taintaddangularforce = false; private Vector3 m_force; @@ -290,13 +288,6 @@ namespace OpenSim.Region.Physics.OdePlugin set { return; } } - public override uint LocalID - { - set { - //m_log.Info("[PHYSICS]: Setting TrackerID: " + value); - m_localID = value; } - } - public override bool Grabbed { set { return; } @@ -1058,7 +1049,7 @@ Console.WriteLine("ZProcessTaints for " + Name); private void AddChildPrim(OdePrim prim) { //Console.WriteLine("AddChildPrim " + Name); - if (this.m_localID != prim.m_localID) + if (LocalID != prim.LocalID) { if (Body == IntPtr.Zero) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs index 9d7aa94c8c..7e3ec63d23 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs @@ -378,12 +378,13 @@ namespace OpenSim.Region.Physics.OdePlugin // Loop over contacts, build results. for (int i = 0; i < count; i++) { - if (p1 != null) { + if (p1 != null) + { if (p1 is OdePrim) { ContactResult collisionresult = new ContactResult(); - collisionresult.ConsumerID = ((OdePrim)p1).m_localID; + collisionresult.ConsumerID = p1.LocalID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, @@ -399,7 +400,7 @@ namespace OpenSim.Region.Physics.OdePlugin { ContactResult collisionresult = new ContactResult(); - collisionresult.ConsumerID = ((OdePrim)p2).m_localID; + collisionresult.ConsumerID = p2.LocalID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index c3279c6911..43d852b05e 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs @@ -219,9 +219,14 @@ namespace OpenSim.Region.Physics.OdePlugin private readonly List _perloopContact = new List(); /// - /// A list of actors that should receive collision events. + /// A dictionary of actors that should receive collision events. /// - private readonly List _collisionEventPrim = new List(); + private readonly Dictionary _collisionEventPrim = new Dictionary(); + + /// + /// A dictionary of collision event changes that are waiting to be processed. + /// + private readonly Dictionary _collisionEventPrimChanges = new Dictionary(); private readonly HashSet _badCharacter = new HashSet(); public Dictionary geom_name_map = new Dictionary(); @@ -1301,8 +1306,8 @@ namespace OpenSim.Region.Physics.OdePlugin { case ActorTypes.Agent: cc1 = (OdeCharacter)p1; - obj2LocalID = cc1.m_localID; - cc1.AddCollisionEvent(cc2.m_localID, contact); + obj2LocalID = cc1.LocalID; + cc1.AddCollisionEvent(cc2.LocalID, contact); //ctype = (int)CollisionCategories.Character; //if (cc1.CollidingObj) @@ -1317,8 +1322,8 @@ namespace OpenSim.Region.Physics.OdePlugin if (p1 is OdePrim) { cp1 = (OdePrim) p1; - obj2LocalID = cp1.m_localID; - cp1.AddCollisionEvent(cc2.m_localID, contact); + obj2LocalID = cp1.LocalID; + cp1.AddCollisionEvent(cc2.LocalID, contact); } //ctype = (int)CollisionCategories.Geom; @@ -1354,8 +1359,8 @@ namespace OpenSim.Region.Physics.OdePlugin if (p1 is OdeCharacter) { cc1 = (OdeCharacter) p1; - obj2LocalID = cc1.m_localID; - cc1.AddCollisionEvent(cp2.m_localID, contact); + obj2LocalID = cc1.LocalID; + cc1.AddCollisionEvent(cp2.LocalID, contact); //ctype = (int)CollisionCategories.Character; //if (cc1.CollidingObj) @@ -1370,8 +1375,8 @@ namespace OpenSim.Region.Physics.OdePlugin if (p1 is OdePrim) { cp1 = (OdePrim) p1; - obj2LocalID = cp1.m_localID; - cp1.AddCollisionEvent(cp2.m_localID, contact); + obj2LocalID = cp1.LocalID; + cp1.AddCollisionEvent(cp2.LocalID, contact); //ctype = (int)CollisionCategories.Geom; //if (cp1.CollidingObj) @@ -1633,13 +1638,10 @@ namespace OpenSim.Region.Physics.OdePlugin /// internal void AddCollisionEventReporting(PhysicsActor obj) { -// m_log.DebugFormat("[PHYSICS]: Adding {0} to collision event reporting", obj.SOPName); +// m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID); - lock (_collisionEventPrim) - { - if (!_collisionEventPrim.Contains(obj)) - _collisionEventPrim.Add(obj); - } + lock (_collisionEventPrimChanges) + _collisionEventPrimChanges[obj.LocalID] = obj; } /// @@ -1648,10 +1650,10 @@ namespace OpenSim.Region.Physics.OdePlugin /// internal void RemoveCollisionEventReporting(PhysicsActor obj) { -// m_log.DebugFormat("[PHYSICS]: Removing {0} from collision event reporting", obj.SOPName); +// m_log.DebugFormat("[PHYSICS]: Removing {0} {1} from collision event reporting", obj.SOPName, obj.LocalID); - lock (_collisionEventPrim) - _collisionEventPrim.Remove(obj); + lock (_collisionEventPrimChanges) + _collisionEventPrimChanges[obj.LocalID] = null; } #region Add/Remove Entities @@ -1752,9 +1754,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, Vector3 size, Quaternion rotation, bool isPhysical, uint localid) { -#if SPAM - m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); -#endif +// m_log.DebugFormat("[ODE SCENE]: Adding physics actor to {0} {1}", primName, localid); return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); } @@ -2663,6 +2663,22 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); // m_physicsiterations = 10; // } + // We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential + // deadlock if the collision event tries to lock something else later on which is already locked by a + // caller that is adding or removing the collision event. + lock (_collisionEventPrimChanges) + { + foreach (KeyValuePair kvp in _collisionEventPrimChanges) + { + if (kvp.Value == null) + _collisionEventPrim.Remove(kvp.Key); + else + _collisionEventPrim[kvp.Key] = kvp.Value; + } + + _collisionEventPrimChanges.Clear(); + } + if (SupportsNINJAJoints) { DeleteRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks @@ -2790,25 +2806,22 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); collision_optimized(); - lock (_collisionEventPrim) + foreach (PhysicsActor obj in _collisionEventPrim.Values) { - foreach (PhysicsActor obj in _collisionEventPrim) +// m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID); + + switch ((ActorTypes)obj.PhysicsActorType) { -// m_log.DebugFormat("[PHYSICS]: Assessing {0} for collision events", obj.SOPName); + case ActorTypes.Agent: + OdeCharacter cobj = (OdeCharacter)obj; + cobj.AddCollisionFrameTime(100); + cobj.SendCollisions(); + break; - switch ((ActorTypes)obj.PhysicsActorType) - { - case ActorTypes.Agent: - OdeCharacter cobj = (OdeCharacter)obj; - cobj.AddCollisionFrameTime(100); - cobj.SendCollisions(); - break; - - case ActorTypes.Prim: - OdePrim pobj = (OdePrim)obj; - pobj.SendCollisions(); - break; - } + case ActorTypes.Prim: + OdePrim pobj = (OdePrim)obj; + pobj.SendCollisions(); + break; } } @@ -3731,7 +3744,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); { if (prm.CollisionScore > 0) { - returncolliders.Add(prm.m_localID, prm.CollisionScore); + returncolliders.Add(prm.LocalID, prm.CollisionScore); cnt++; prm.CollisionScore = 0f; if (cnt > 25) diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs index 2ea810f997..cbc6b95844 100644 --- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs +++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs @@ -104,7 +104,7 @@ namespace OpenSim.Region.Physics.OdePlugin.Tests m_log.Info("TargetSpace: " + oprim.m_targetSpace + " - SceneMainSpace: " + pscene.space); Assert.That(!oprim.m_taintadd); - m_log.Info("Prim Position (" + oprim.m_localID + "): " + prim.Position.ToString()); + m_log.Info("Prim Position (" + oprim.LocalID + "): " + prim.Position); // Make sure we're above the ground //Assert.That(prim.Position.Z > 20f); diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs index c5ae0c056e..41361ab6e4 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs @@ -67,7 +67,7 @@ namespace OpenSim.Services.Connectors.Friends IConfig gridConfig = source.Configs["FriendsService"]; if (gridConfig == null) { - m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini"); + m_log.Error("[FRIENDS SERVICE CONNECTOR]: FriendsService missing from OpenSim.ini"); throw new Exception("Friends connector init error"); } @@ -76,7 +76,7 @@ namespace OpenSim.Services.Connectors.Friends if (serviceURI == String.Empty) { - m_log.Error("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService"); + m_log.Error("[FRIENDS SERVICE CONNECTOR]: No Server URI named in section FriendsService"); throw new Exception("Friends connector init error"); } m_ServerURI = serviceURI; @@ -127,7 +127,7 @@ namespace OpenSim.Services.Connectors.Friends List finfos = new List(); Dictionary.ValueCollection finfosList = replyData.Values; - //m_log.DebugFormat("[FRIENDS CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count); + //m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count); foreach (object f in finfosList) { if (f is Dictionary) @@ -136,7 +136,7 @@ namespace OpenSim.Services.Connectors.Friends finfos.Add(finfo); } else - m_log.DebugFormat("[FRIENDS CONNECTOR]: GetFriends {0} received invalid response type {1}", + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: GetFriends {0} received invalid response type {1}", PrincipalID, f.GetType()); } @@ -145,14 +145,14 @@ namespace OpenSim.Services.Connectors.Friends } else - m_log.DebugFormat("[FRIENDS CONNECTOR]: GetFriends {0} received null response", + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: GetFriends {0} received null response", PrincipalID); } } catch (Exception e) { - m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message); + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server: {0}", e.Message); } return new FriendInfo[0]; @@ -175,7 +175,7 @@ namespace OpenSim.Services.Connectors.Friends } catch (Exception e) { - m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message); + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server: {0}", e.Message); return false; } @@ -190,11 +190,11 @@ namespace OpenSim.Services.Connectors.Friends return success; } else - m_log.DebugFormat("[FRIENDS CONNECTOR]: StoreFriend {0} {1} received null response", + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: StoreFriend {0} {1} received null response", PrincipalID, Friend); } else - m_log.DebugFormat("[FRIENDS CONNECTOR]: StoreFriend received null reply"); + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: StoreFriend received null reply"); return false; @@ -231,7 +231,7 @@ namespace OpenSim.Services.Connectors.Friends } catch (Exception e) { - m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message); + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: Exception when contacting friends server: {0}", e.Message); return false; } @@ -246,11 +246,11 @@ namespace OpenSim.Services.Connectors.Friends return success; } else - m_log.DebugFormat("[FRIENDS CONNECTOR]: DeleteFriend {0} {1} received null response", + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: DeleteFriend {0} {1} received null response", PrincipalID, Friend); } else - m_log.DebugFormat("[FRIENDS CONNECTOR]: DeleteFriend received null reply"); + m_log.DebugFormat("[FRIENDS SERVICE CONNECTOR]: DeleteFriend received null reply"); return false; } diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs index 4ffa68c381..d0a20fc989 100644 --- a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs +++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs @@ -134,11 +134,11 @@ namespace OpenSim.Services.Connectors.Friends private bool Call(GridRegion region, Dictionary sendData) { string reqString = ServerUtils.BuildQueryString(sendData); - //m_log.DebugFormat("[FRIENDS CONNECTOR]: queryString = {0}", reqString); + //m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: queryString = {0}", reqString); if (region == null) return false; - m_log.DebugFormat("[FRIENDS CONNECTOR]: region: {0}", region.ExternalHostName + ":" + region.HttpPort); + m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: region: {0}", region.ExternalHostName + ":" + region.HttpPort); try { string url = "http://" + region.ExternalHostName + ":" + region.HttpPort; @@ -157,15 +157,15 @@ namespace OpenSim.Services.Connectors.Friends return false; } else - m_log.DebugFormat("[FRIENDS CONNECTOR]: reply data does not contain result field"); + m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: reply data does not contain result field"); } else - m_log.DebugFormat("[FRIENDS CONNECTOR]: received empty reply"); + m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: received empty reply"); } catch (Exception e) { - m_log.DebugFormat("[FRIENDS CONNECTOR]: Exception when contacting remote sim: {0}", e.ToString()); + m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: Exception when contacting remote sim: {0}", e.ToString()); } return false; diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index 9385b8df74..e26383f0ff 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -335,22 +335,21 @@ namespace OpenSim.Services.HypergridService } if (userURL == m_ExternalName) + { return m_UserAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID); + } else { -// Object[] args = new Object[] { userURL }; IUserAgentService userAgentService = new UserAgentServiceConnector(userURL); - if (userAgentService != null) + + try { - try - { - return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID); - } - catch - { - m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL); - return false; - } + return userAgentService.VerifyAgent(aCircuit.SessionID, aCircuit.ServiceSessionID); + } + catch + { + m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to contact authentication service at {0}", userURL); + return false; } } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 5fe1985d55..cedd6c7432 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -57,8 +57,9 @@ namespace OpenSim.Tests.Common.Mock private IScene m_scene; // Properties so that we can get at received data for test purposes - public List OfflineNotificationsReceived { get; private set; } - public List OnlineNotificationsReceived { get; private set; } + public List ReceivedOfflineNotifications { get; private set; } + public List ReceivedOnlineNotifications { get; private set; } + public List ReceivedFriendshipTerminations { get; private set; } // disable warning: public events, part of the public API #pragma warning disable 67 @@ -445,8 +446,9 @@ namespace OpenSim.Tests.Common.Mock m_scene = scene; CapsSeedUrl = agentData.CapsPath; - OfflineNotificationsReceived = new List(); - OnlineNotificationsReceived = new List(); + ReceivedOfflineNotifications = new List(); + ReceivedOnlineNotifications = new List(); + ReceivedFriendshipTerminations = new List(); } /// @@ -834,12 +836,12 @@ namespace OpenSim.Tests.Common.Mock public void SendAgentOffline(UUID[] agentIDs) { - OfflineNotificationsReceived.AddRange(agentIDs); + ReceivedOfflineNotifications.AddRange(agentIDs); } public void SendAgentOnline(UUID[] agentIDs) { - OnlineNotificationsReceived.AddRange(agentIDs); + ReceivedOnlineNotifications.AddRange(agentIDs); } public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, @@ -1113,6 +1115,7 @@ namespace OpenSim.Tests.Common.Mock public void SendTerminateFriend(UUID exFriendID) { + ReceivedFriendshipTerminations.Add(exFriendID); } public bool AddGenericPacketHandler(string MethodName, GenericMessage handler) diff --git a/prebuild.xml b/prebuild.xml index d1a1cf826a..56e7904cb7 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1724,7 +1724,6 @@ -