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