Over a dozen thread safety fixes in FriendsModule
parent
972ef92590
commit
8415b98806
|
@ -54,7 +54,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
public UUID PrincipalID;
|
public UUID PrincipalID;
|
||||||
public FriendInfo[] Friends;
|
public FriendInfo[] Friends;
|
||||||
public int Refcount;
|
public int Refcount;
|
||||||
public UUID RegionID;
|
|
||||||
|
|
||||||
public bool IsFriend(string friend)
|
public bool IsFriend(string friend)
|
||||||
{
|
{
|
||||||
|
@ -68,6 +67,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected List<Scene> m_Scenes = new List<Scene>();
|
protected List<Scene> m_Scenes = new List<Scene>();
|
||||||
|
@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
protected Dictionary<UUID, UserFriendData> m_Friends =
|
protected Dictionary<UUID, UserFriendData> m_Friends =
|
||||||
new Dictionary<UUID, UserFriendData>();
|
new Dictionary<UUID, UserFriendData>();
|
||||||
|
|
||||||
protected List<UUID> m_NeedsListOfFriends = new List<UUID>();
|
protected HashSet<UUID> m_NeedsListOfFriends = new HashSet<UUID>();
|
||||||
|
|
||||||
protected IPresenceService PresenceService
|
protected IPresenceService PresenceService
|
||||||
{
|
{
|
||||||
|
@ -146,7 +146,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
// Instantiate the request handler
|
// Instantiate the request handler
|
||||||
IHttpServer server = MainServer.GetHttpServer((uint)mPort);
|
IHttpServer server = MainServer.GetHttpServer((uint)mPort);
|
||||||
server.AddStreamHandler(new FriendsRequestHandler(this));
|
server.AddStreamHandler(new FriendsRequestHandler(this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_FriendsService == null)
|
if (m_FriendsService == null)
|
||||||
|
@ -173,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
scene.EventManager.OnNewClient += OnNewClient;
|
scene.EventManager.OnNewClient += OnNewClient;
|
||||||
scene.EventManager.OnClientClosed += OnClientClosed;
|
scene.EventManager.OnClientClosed += OnClientClosed;
|
||||||
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
|
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
|
||||||
scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
|
|
||||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
scene.EventManager.OnClientLogin += OnClientLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,16 +196,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
public uint GetFriendPerms(UUID principalID, UUID friendID)
|
public uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||||
{
|
{
|
||||||
if (!m_Friends.ContainsKey(principalID))
|
FriendInfo[] friends = GetFriends(principalID);
|
||||||
return 0;
|
foreach (FriendInfo fi in friends)
|
||||||
|
|
||||||
UserFriendData data = m_Friends[principalID];
|
|
||||||
|
|
||||||
foreach (FriendInfo fi in data.Friends)
|
|
||||||
{
|
{
|
||||||
if (fi.Friend == friendID.ToString())
|
if (fi.Friend == friendID.ToString())
|
||||||
return (uint)fi.TheirFlags;
|
return (uint)fi.TheirFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,73 +212,59 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
||||||
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
||||||
client.OnTerminateFriendship += OnTerminateFriendship;
|
client.OnTerminateFriendship += OnTerminateFriendship;
|
||||||
|
|
||||||
client.OnGrantUserRights += OnGrantUserRights;
|
client.OnGrantUserRights += OnGrantUserRights;
|
||||||
|
|
||||||
lock (m_Friends)
|
// Asynchronously fetch the friends list or increment the refcount for the existing
|
||||||
{
|
// friends list
|
||||||
if (m_Friends.ContainsKey(client.AgentId))
|
Util.FireAndForget(
|
||||||
|
delegate(object o)
|
||||||
{
|
{
|
||||||
m_Friends[client.AgentId].Refcount++;
|
lock (m_Friends)
|
||||||
return;
|
{
|
||||||
|
UserFriendData friendsData;
|
||||||
|
if (m_Friends.TryGetValue(client.AgentId, out friendsData))
|
||||||
|
{
|
||||||
|
friendsData.Refcount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
friendsData = new UserFriendData();
|
||||||
|
friendsData.PrincipalID = client.AgentId;
|
||||||
|
friendsData.Friends = FriendsService.GetFriends(client.AgentId);
|
||||||
|
friendsData.Refcount = 1;
|
||||||
|
|
||||||
|
m_Friends[client.AgentId] = friendsData;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
);
|
||||||
UserFriendData newFriends = new UserFriendData();
|
|
||||||
|
|
||||||
newFriends.PrincipalID = client.AgentId;
|
|
||||||
newFriends.Friends = m_FriendsService.GetFriends(client.AgentId);
|
|
||||||
newFriends.Refcount = 1;
|
|
||||||
newFriends.RegionID = UUID.Zero;
|
|
||||||
|
|
||||||
m_Friends.Add(client.AgentId, newFriends);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientClosed(UUID agentID, Scene scene)
|
private void OnClientClosed(UUID agentID, Scene scene)
|
||||||
{
|
{
|
||||||
ScenePresence sp = scene.GetScenePresence(agentID);
|
ScenePresence sp = scene.GetScenePresence(agentID);
|
||||||
if (sp != null && !sp.IsChildAgent)
|
if (sp != null && !sp.IsChildAgent)
|
||||||
|
{
|
||||||
// do this for root agents closing out
|
// do this for root agents closing out
|
||||||
StatusChange(agentID, false);
|
StatusChange(agentID, false);
|
||||||
|
}
|
||||||
|
|
||||||
lock (m_Friends)
|
lock (m_Friends)
|
||||||
if (m_Friends.ContainsKey(agentID))
|
{
|
||||||
|
UserFriendData friendsData;
|
||||||
|
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||||
{
|
{
|
||||||
if (m_Friends[agentID].Refcount == 1)
|
friendsData.Refcount--;
|
||||||
|
if (friendsData.Refcount <= 0)
|
||||||
m_Friends.Remove(agentID);
|
m_Friends.Remove(agentID);
|
||||||
else
|
|
||||||
m_Friends[agentID].Refcount--;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMakeRootAgent(ScenePresence sp)
|
private void OnMakeRootAgent(ScenePresence sp)
|
||||||
{
|
{
|
||||||
UUID agentID = sp.ControllingClient.AgentId;
|
UUID agentID = sp.ControllingClient.AgentId;
|
||||||
|
UpdateFriendsCache(agentID);
|
||||||
if (m_Friends.ContainsKey(agentID))
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void OnMakeChildAgent(ScenePresence sp)
|
|
||||||
{
|
|
||||||
UUID agentID = sp.ControllingClient.AgentId;
|
|
||||||
|
|
||||||
if (m_Friends.ContainsKey(agentID))
|
|
||||||
{
|
|
||||||
if (m_Friends[agentID].RegionID == sp.ControllingClient.Scene.RegionInfo.RegionID)
|
|
||||||
m_Friends[agentID].RegionID = UUID.Zero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientLogin(IClientAPI client)
|
private void OnClientLogin(IClientAPI client)
|
||||||
|
@ -295,72 +276,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
// Register that we need to send the list of online friends to this user
|
// Register that we need to send the list of online friends to this user
|
||||||
lock (m_NeedsListOfFriends)
|
lock (m_NeedsListOfFriends)
|
||||||
if (!m_NeedsListOfFriends.Contains(agentID))
|
m_NeedsListOfFriends.Add(agentID);
|
||||||
{
|
|
||||||
m_NeedsListOfFriends.Add(agentID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendFriendsOnlineIfNeeded(IClientAPI client)
|
public void SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||||
{
|
{
|
||||||
UUID agentID = client.AgentId;
|
UUID agentID = client.AgentId;
|
||||||
if (m_NeedsListOfFriends.Contains(agentID))
|
|
||||||
|
// Check if the online friends list is needed
|
||||||
|
lock (m_NeedsListOfFriends)
|
||||||
{
|
{
|
||||||
if (!m_Friends.ContainsKey(agentID))
|
if (!m_NeedsListOfFriends.Remove(agentID))
|
||||||
{
|
|
||||||
m_log.DebugFormat("[FRIENDS MODULE]: agent {0} not found in local cache", agentID);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Send the friends online
|
||||||
// Send the friends online
|
List<UUID> online = GetOnlineFriends(agentID);
|
||||||
//
|
if (online.Count > 0)
|
||||||
List<UUID> 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);
|
||||||
{
|
client.SendAgentOnline(online.ToArray());
|
||||||
m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count);
|
}
|
||||||
client.SendAgentOnline(online.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
// Send outstanding friendship offers
|
||||||
// Send outstanding friendship offers
|
List<string> outstanding = new List<string>();
|
||||||
//
|
FriendInfo[] friends = GetFriends(agentID);
|
||||||
if (m_Friends.ContainsKey(agentID))
|
foreach (FriendInfo fi in friends)
|
||||||
{
|
{
|
||||||
List<string> outstanding = new List<string>();
|
if (fi.TheirFlags == -1)
|
||||||
|
outstanding.Add(fi.Friend);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (FriendInfo fi in m_Friends[agentID].Friends)
|
GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, String.Empty, agentID, (byte)InstantMessageDialog.FriendshipOffered,
|
||||||
if (fi.TheirFlags == -1)
|
"Will you be my friend?", true, Vector3.Zero);
|
||||||
outstanding.Add(fi.Friend);
|
|
||||||
|
|
||||||
GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, "", agentID, (byte)InstantMessageDialog.FriendshipOffered, "Will you be my friend?", true, Vector3.Zero);
|
foreach (string fid in outstanding)
|
||||||
foreach (string fid in outstanding)
|
{
|
||||||
{
|
UUID fromAgentID;
|
||||||
try
|
if (!UUID.TryParse(fid, out fromAgentID))
|
||||||
{
|
continue;
|
||||||
im.fromAgentID = new Guid(fid);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, new UUID(im.fromAgentID));
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
|
||||||
im.fromAgentName = account.FirstName + " " + account.LastName;
|
PresenceInfo presence = PresenceService.GetAgent(fromAgentID);
|
||||||
|
|
||||||
PresenceInfo presence = PresenceService.GetAgent(new UUID(im.fromAgentID));
|
im.fromAgentID = fromAgentID.Guid;
|
||||||
if (presence != null)
|
im.fromAgentName = account.FirstName + " " + account.LastName;
|
||||||
im.offline = 0;
|
im.offline = (byte)((presence == null) ? 1 : 0);
|
||||||
|
im.imSessionID = im.fromAgentID;
|
||||||
|
|
||||||
im.imSessionID = im.fromAgentID;
|
// Finally
|
||||||
|
LocalFriendshipOffered(agentID, im);
|
||||||
// Finally
|
|
||||||
LocalFriendshipOffered(agentID, im);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (m_NeedsListOfFriends)
|
|
||||||
m_NeedsListOfFriends.Remove(agentID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,44 +334,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
List<string> friendList = new List<string>();
|
List<string> friendList = new List<string>();
|
||||||
List<UUID> online = new List<UUID>();
|
List<UUID> online = new List<UUID>();
|
||||||
|
|
||||||
foreach (FriendInfo fi in m_Friends[userID].Friends)
|
FriendInfo[] friends = GetFriends(userID);
|
||||||
|
foreach (FriendInfo fi in friends)
|
||||||
{
|
{
|
||||||
if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
|
if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
|
||||||
friendList.Add(fi.Friend);
|
friendList.Add(fi.Friend);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (friendList.Count == 0)
|
if (friendList.Count > 0)
|
||||||
// no friends whatsoever
|
{
|
||||||
return online;
|
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||||
|
foreach (PresenceInfo pi in presence)
|
||||||
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
{
|
||||||
|
UUID presenceID;
|
||||||
foreach (PresenceInfo pi in presence)
|
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||||
online.Add(new UUID(pi.UserID));
|
online.Add(presenceID);
|
||||||
//m_log.DebugFormat("[XXX] {0} friend online {1}", userID, pi.UserID);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return online;
|
return online;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// <summary>
|
||||||
// Find the client for a ID
|
/// Find the client for a ID
|
||||||
//
|
/// </summary>
|
||||||
public IClientAPI LocateClientObject(UUID agentID)
|
public IClientAPI LocateClientObject(UUID agentID)
|
||||||
{
|
{
|
||||||
Scene scene = GetClientScene(agentID);
|
Scene scene = GetClientScene(agentID);
|
||||||
if (scene == null)
|
if (scene != null)
|
||||||
return null;
|
{
|
||||||
|
ScenePresence presence = scene.GetScenePresence(agentID);
|
||||||
|
if (presence != null)
|
||||||
|
return presence.ControllingClient;
|
||||||
|
}
|
||||||
|
|
||||||
ScenePresence presence = scene.GetScenePresence(agentID);
|
return null;
|
||||||
if (presence == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return presence.ControllingClient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// <summary>
|
||||||
// Find the scene for an agent
|
/// Find the scene for an agent
|
||||||
//
|
/// </summary>
|
||||||
private Scene GetClientScene(UUID agentId)
|
private Scene GetClientScene(UUID agentId)
|
||||||
{
|
{
|
||||||
lock (m_Scenes)
|
lock (m_Scenes)
|
||||||
|
@ -414,13 +381,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
foreach (Scene scene in m_Scenes)
|
foreach (Scene scene in m_Scenes)
|
||||||
{
|
{
|
||||||
ScenePresence presence = scene.GetScenePresence(agentId);
|
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||||
if (presence != null)
|
if (presence != null && !presence.IsChildAgent)
|
||||||
{
|
return scene;
|
||||||
if (!presence.IsChildAgent)
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,35 +396,33 @@ 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);
|
FriendInfo[] friends = GetFriends(agentID);
|
||||||
if (m_Friends.ContainsKey(agentID))
|
if (friends.Length > 0)
|
||||||
{
|
{
|
||||||
//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 friends)
|
||||||
{
|
{
|
||||||
if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1))
|
if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1))
|
||||||
friendList.Add(fi);
|
friendList.Add(fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
Util.FireAndForget(delegate
|
Util.FireAndForget(
|
||||||
{
|
delegate
|
||||||
foreach (FriendInfo fi in friendList)
|
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
|
foreach (FriendInfo fi in friendList)
|
||||||
// Notify about this user status
|
{
|
||||||
StatusNotify(fi, agentID, online);
|
//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)
|
private void StatusNotify(FriendInfo friend, UUID userID, bool online)
|
||||||
{
|
{
|
||||||
UUID friendID = UUID.Zero;
|
UUID friendID;
|
||||||
|
|
||||||
if (UUID.TryParse(friend.Friend, out friendID))
|
if (UUID.TryParse(friend.Friend, out friendID))
|
||||||
{
|
{
|
||||||
// Try local
|
// Try local
|
||||||
|
@ -476,12 +439,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
|
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)
|
||||||
{
|
{
|
||||||
if (im.dialog == (byte)OpenMetaverse.InstantMessageDialog.FriendshipOffered)
|
if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered)
|
||||||
{
|
{
|
||||||
// we got a friendship offer
|
// we got a friendship offer
|
||||||
UUID principalID = new UUID(im.fromAgentID);
|
UUID principalID = new UUID(im.fromAgentID);
|
||||||
|
@ -527,9 +492,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
FriendsService.StoreFriend(agentID, friendID.ToString(), 1);
|
FriendsService.StoreFriend(agentID, friendID.ToString(), 1);
|
||||||
FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
|
FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
|
||||||
// update the local cache
|
|
||||||
m_Friends[agentID].Friends = FriendsService.GetFriends(agentID);
|
|
||||||
|
|
||||||
|
// Update the local cache
|
||||||
|
UpdateFriendsCache(agentID);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Notify the friend
|
// Notify the friend
|
||||||
|
@ -584,7 +549,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
FriendsService.Delete(exfriendID, agentID.ToString());
|
FriendsService.Delete(exfriendID, agentID.ToString());
|
||||||
|
|
||||||
// Update local cache
|
// Update local cache
|
||||||
m_Friends[agentID].Friends = FriendsService.GetFriends(agentID);
|
UpdateFriendsCache(agentID);
|
||||||
|
|
||||||
client.SendTerminateFriend(exfriendID);
|
client.SendTerminateFriend(exfriendID);
|
||||||
|
|
||||||
|
@ -606,16 +571,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
||||||
{
|
{
|
||||||
if (!m_Friends.ContainsKey(remoteClient.AgentId))
|
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
||||||
|
if (friends.Length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
||||||
// Let's find the friend in this user's friend list
|
// Let's find the friend in this user's friend list
|
||||||
UserFriendData fd = m_Friends[remoteClient.AgentId];
|
|
||||||
FriendInfo friend = null;
|
FriendInfo friend = null;
|
||||||
foreach (FriendInfo fi in fd.Friends)
|
foreach (FriendInfo fi in friends)
|
||||||
|
{
|
||||||
if (fi.Friend == target.ToString())
|
if (fi.Friend == target.ToString())
|
||||||
friend = fi;
|
friend = fi;
|
||||||
|
}
|
||||||
|
|
||||||
if (friend != null) // Found it
|
if (friend != null) // Found it
|
||||||
{
|
{
|
||||||
|
@ -672,8 +639,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID,
|
GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID,
|
||||||
(byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
|
(byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
|
||||||
friendClient.SendInstantMessage(im);
|
friendClient.SendInstantMessage(im);
|
||||||
// update the local cache
|
|
||||||
m_Friends[friendID].Friends = FriendsService.GetFriends(friendID);
|
// Update the local cache
|
||||||
|
UpdateFriendsCache(friendID);
|
||||||
|
|
||||||
// we're done
|
// we're done
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -687,7 +656,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
if (friendClient != null)
|
if (friendClient != null)
|
||||||
{
|
{
|
||||||
// the prospective friend in this sim as root agent
|
// the prospective friend in this sim as root agent
|
||||||
|
|
||||||
GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID,
|
GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID,
|
||||||
(byte)OpenMetaverse.InstantMessageDialog.FriendshipDeclined, userID.ToString(), false, Vector3.Zero);
|
(byte)OpenMetaverse.InstantMessageDialog.FriendshipDeclined, userID.ToString(), false, Vector3.Zero);
|
||||||
friendClient.SendInstantMessage(im);
|
friendClient.SendInstantMessage(im);
|
||||||
|
@ -706,7 +674,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
// the friend in this sim as root agent
|
// the friend in this sim as root agent
|
||||||
friendClient.SendTerminateFriend(exfriendID);
|
friendClient.SendTerminateFriend(exfriendID);
|
||||||
// update local cache
|
// update local cache
|
||||||
m_Friends[exfriendID].Friends = FriendsService.GetFriends(exfriendID);
|
UpdateFriendsCache(exfriendID);
|
||||||
// we're done
|
// we're done
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -735,11 +703,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update local cache
|
// Update local cache
|
||||||
//m_Friends[friendID].Friends = m_FriendsService.GetFriends(friendID);
|
lock (m_Friends)
|
||||||
foreach (FriendInfo finfo in m_Friends[friendID].Friends)
|
{
|
||||||
if (finfo.Friend == userID.ToString())
|
FriendInfo[] friends = GetFriends(friendID);
|
||||||
finfo.TheirFlags = rights;
|
foreach (FriendInfo finfo in friends)
|
||||||
|
{
|
||||||
|
if (finfo.Friend == userID.ToString())
|
||||||
|
finfo.TheirFlags = rights;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -765,7 +738,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private FriendInfo[] GetFriends(UUID agentID)
|
||||||
|
{
|
||||||
|
UserFriendData friendsData;
|
||||||
|
|
||||||
|
lock (m_Friends)
|
||||||
|
{
|
||||||
|
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||||
|
return friendsData.Friends;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EMPTY_FRIENDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateFriendsCache(UUID agentID)
|
||||||
|
{
|
||||||
|
lock (m_Friends)
|
||||||
|
{
|
||||||
|
UserFriendData friendsData;
|
||||||
|
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||||
|
friendsData.Friends = FriendsService.GetFriends(agentID);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue