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.

soprefactor
Diva Canto 2010-06-10 21:59:12 -07:00
parent b2b6799f1c
commit 2e1269e4ca
1 changed files with 33 additions and 8 deletions

View File

@ -245,11 +245,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnClientClosed(UUID agentID, Scene scene) private void OnClientClosed(UUID agentID, Scene scene)
{ {
ScenePresence sp = scene.GetScenePresence(agentID);
lock (m_Friends) lock (m_Friends)
if (m_Friends.ContainsKey(agentID)) if (m_Friends.ContainsKey(agentID))
{ {
if (m_Friends[agentID].Refcount == 1) 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 else
m_Friends[agentID].Refcount--; m_Friends[agentID].Refcount--;
} }
@ -267,11 +276,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (m_Friends.ContainsKey(agentID)) if (m_Friends.ContainsKey(agentID))
{ {
if (m_Friends[agentID].RegionID == UUID.Zero) // This is probably an overkill, but just
{ // to make sure we have the latest and greatest
m_Friends[agentID].Friends = // friends list -- always pull OnMakeRoot
m_Friends[agentID].Friends =
m_FriendsService.GetFriends(agentID); m_FriendsService.GetFriends(agentID);
}
m_Friends[agentID].RegionID = m_Friends[agentID].RegionID =
sp.ControllingClient.Scene.RegionInfo.RegionID; sp.ControllingClient.Scene.RegionInfo.RegionID;
} }
@ -437,8 +447,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
/// <param name="online"></param> /// <param name="online"></param>
private void StatusChange(UUID agentID, bool online) private void StatusChange(UUID agentID, bool online)
{ {
//m_log.DebugFormat("[FRIENDS]: StatusChange {0}", online);
if (m_Friends.ContainsKey(agentID)) if (m_Friends.ContainsKey(agentID))
{ {
//m_log.DebugFormat("[FRIENDS]: # of friends: {0}", m_Friends[agentID].Friends.Length);
List<FriendInfo> friendList = new List<FriendInfo>(); List<FriendInfo> friendList = new List<FriendInfo>();
foreach (FriendInfo fi in m_Friends[agentID].Friends) foreach (FriendInfo fi in m_Friends[agentID].Friends)
{ {
@ -447,10 +459,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
foreach (FriendInfo fi in friendList) foreach (FriendInfo fi in friendList)
{ {
//m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
// Notify about this user status // Notify about this user status
StatusNotify(fi, agentID, online); StatusNotify(fi, agentID, online);
} }
} }
else
m_log.WarnFormat("[FRIENDS]: {0} not found in cache", agentID);
} }
private void StatusNotify(FriendInfo friend, UUID userID, bool online) private void StatusNotify(FriendInfo friend, UUID userID, bool online)
@ -467,16 +482,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0) 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) if (friendSession != null)
{ {
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 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); m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
} }
} }
// Friend is not online. Ignore. // Friend is not online. Ignore.
} }
else
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
} }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
@ -763,7 +788,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
IClientAPI friendClient = LocateClientObject(friendID); IClientAPI friendClient = LocateClientObject(friendID);
if (friendClient != null) 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 // the friend in this sim as root agent
if (online) if (online)
friendClient.SendAgentOnline(new UUID[] { userID }); friendClient.SendAgentOnline(new UUID[] { userID });