From 2e1269e4cac8542dbf74854ec4d3196f4e0cd372 Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Thu, 10 Jun 2010 21:59:12 -0700
Subject: Bug fix on friends notifications. OnClientClose and OnLogout ordering
are unpredictable; when OnClientClosed happened first, it was removing the
friends list, which would prevent OnLogout notifications to go out.
---
.../CoreModules/Avatar/Friends/FriendsModule.cs | 41 +++++++++++++++++-----
1 file changed, 33 insertions(+), 8 deletions(-)
(limited to 'OpenSim/Region/CoreModules/Avatar/Friends')
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 3590f27..4f0487b 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -245,11 +245,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnClientClosed(UUID agentID, Scene scene)
{
+ ScenePresence sp = scene.GetScenePresence(agentID);
lock (m_Friends)
if (m_Friends.ContainsKey(agentID))
{
if (m_Friends[agentID].Refcount == 1)
- m_Friends.Remove(agentID);
+ {
+ if (sp != null && sp.IsChildAgent)
+ // we do this only for child agents
+ // Root agents' closing = logout; that's
+ // processed with OnLogout
+ {
+ m_Friends.Remove(agentID);
+ }
+ }
else
m_Friends[agentID].Refcount--;
}
@@ -267,11 +276,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (m_Friends.ContainsKey(agentID))
{
- if (m_Friends[agentID].RegionID == UUID.Zero)
- {
- m_Friends[agentID].Friends =
+ // This is probably an overkill, but just
+ // to make sure we have the latest and greatest
+ // friends list -- always pull OnMakeRoot
+ m_Friends[agentID].Friends =
m_FriendsService.GetFriends(agentID);
- }
+
m_Friends[agentID].RegionID =
sp.ControllingClient.Scene.RegionInfo.RegionID;
}
@@ -437,8 +447,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
///
private void StatusChange(UUID agentID, bool online)
{
+ //m_log.DebugFormat("[FRIENDS]: StatusChange {0}", online);
if (m_Friends.ContainsKey(agentID))
{
+ //m_log.DebugFormat("[FRIENDS]: # of friends: {0}", m_Friends[agentID].Friends.Length);
List friendList = new List();
foreach (FriendInfo fi in m_Friends[agentID].Friends)
{
@@ -447,10 +459,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
foreach (FriendInfo fi in friendList)
{
+ //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
// Notify about this user status
StatusNotify(fi, agentID, online);
}
}
+ else
+ m_log.WarnFormat("[FRIENDS]: {0} not found in cache", agentID);
}
private void StatusNotify(FriendInfo friend, UUID userID, bool online)
@@ -462,21 +477,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Try local
if (LocalStatusNotification(userID, friendID, online))
return;
-
+
// The friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0)
{
- PresenceInfo friendSession = friendSessions[0];
+ PresenceInfo friendSession = null;
+ foreach (PresenceInfo pinfo in friendSessions)
+ if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
+ {
+ friendSession = pinfo;
+ break;
+ }
+
if (friendSession != null)
{
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
+ //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
}
}
// Friend is not online. Ignore.
}
+ else
+ m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
}
private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
@@ -763,7 +788,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
IClientAPI friendClient = LocateClientObject(friendID);
if (friendClient != null)
{
- //m_log.DebugFormat("[FRIENDS]: Notify {0} that user {1} is {2}", friend.Friend, userID, online);
+ //m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
// the friend in this sim as root agent
if (online)
friendClient.SendAgentOnline(new UUID[] { userID });
--
cgit v1.1
From 7f349d61cb8251a1c13811f5ff7bd95b2311706c Mon Sep 17 00:00:00 2001
From: Diva Canto
Date: Fri, 11 Jun 2010 06:32:24 -0700
Subject: Better friends notification: get rid of OnLogout and use
OnClientClose for sending notifications. This takes care of crashed sessions.
Also, made the notifications themselves asynchronous.
---
.../CoreModules/Avatar/Friends/FriendsModule.cs | 37 ++++++++--------------
1 file changed, 14 insertions(+), 23 deletions(-)
(limited to 'OpenSim/Region/CoreModules/Avatar/Friends')
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 4f0487b..80982fd 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -220,8 +220,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.OnGrantUserRights += OnGrantUserRights;
- client.OnLogout += OnLogout;
-
lock (m_Friends)
{
if (m_Friends.ContainsKey(client.AgentId))
@@ -240,36 +238,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_Friends.Add(client.AgentId, newFriends);
}
- //StatusChange(client.AgentId, true);
}
private void OnClientClosed(UUID agentID, Scene scene)
{
ScenePresence sp = scene.GetScenePresence(agentID);
+ if (sp != null && !sp.IsChildAgent)
+ // do this for root agents closing out
+ StatusChange(agentID, false);
+
lock (m_Friends)
if (m_Friends.ContainsKey(agentID))
{
if (m_Friends[agentID].Refcount == 1)
- {
- if (sp != null && sp.IsChildAgent)
- // we do this only for child agents
- // Root agents' closing = logout; that's
- // processed with OnLogout
- {
- m_Friends.Remove(agentID);
- }
- }
+ m_Friends.Remove(agentID);
else
m_Friends[agentID].Refcount--;
}
}
- private void OnLogout(IClientAPI client)
- {
- StatusChange(client.AgentId, false);
- m_Friends.Remove(client.AgentId);
- }
-
private void OnMakeRootAgent(ScenePresence sp)
{
UUID agentID = sp.ControllingClient.AgentId;
@@ -457,12 +444,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1))
friendList.Add(fi);
}
- foreach (FriendInfo fi in friendList)
+
+ Util.FireAndForget(delegate
{
- //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
- // Notify about this user status
- StatusNotify(fi, agentID, online);
- }
+ foreach (FriendInfo fi in friendList)
+ {
+ //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
+ // Notify about this user status
+ StatusNotify(fi, agentID, online);
+ }
+ });
}
else
m_log.WarnFormat("[FRIENDS]: {0} not found in cache", agentID);
--
cgit v1.1