From fbd61106cb5bcbd5edf54d49d5d299988b971f1c Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 30 Mar 2012 01:05:29 +0100 Subject: [PATCH] refactor: Move "friends show cache" console command out into separate FriendsCommandsModule. Expose required methods on IFriendsModule. Rename GetFriends() -> GetFriendsFromCache() for self-documentation --- .../Avatar/Friends/FriendsModule.cs | 110 +++--------- .../Avatar/Friends/HGFriendsModule.cs | 12 +- .../Framework/Interfaces/IFriendsModule.cs | 25 ++- .../Avatar/Friends/FriendsCommandsModule.cs | 165 ++++++++++++++++++ 4 files changed, 217 insertions(+), 95 deletions(-) create mode 100644 OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index ae551532e7..99d1c2a692 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -213,14 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends scene.EventManager.OnClientLogin += OnClientLogin; } - public void RegionLoaded(Scene scene) - { - scene.AddCommand( - "Friends", this, "friends show cache", - "friends show cache [ ]", - "Show the friends cache for the given user", - HandleFriendsShowCacheCommand); - } + public virtual void RegionLoaded(Scene scene) {} public void RemoveRegion(Scene scene) { @@ -244,7 +237,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID) { - FriendInfo[] friends = GetFriends(principalID); + FriendInfo[] friends = GetFriendsFromCache(principalID); FriendInfo finfo = GetFriend(friends, friendID); if (finfo != null) { @@ -362,7 +355,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // Send outstanding friendship offers List outstanding = new List(); - FriendInfo[] friends = GetFriends(agentID); + FriendInfo[] friends = GetFriendsFromCache(agentID); foreach (FriendInfo fi in friends) { if (fi.TheirFlags == -1) @@ -419,7 +412,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { List friendList = new List(); - FriendInfo[] friends = GetFriends(userID); + FriendInfo[] friends = GetFriendsFromCache(userID); foreach (FriendInfo fi in friends) { if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1)) @@ -492,7 +485,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends /// private void StatusChange(UUID agentID, bool online) { - FriendInfo[] friends = GetFriends(agentID); + FriendInfo[] friends = GetFriendsFromCache(agentID); if (friends.Length > 0) { List friendList = new List(); @@ -561,7 +554,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends UUID principalID = new UUID(im.fromAgentID); UUID friendID = new UUID(im.toAgentID); - m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID); + m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName); + + // Check that the friendship doesn't exist yet + FriendInfo[] finfos = GetFriendsFromCache(principalID); + if (finfos != null) + { + FriendInfo f = GetFriend(finfos, friendID); + if (f != null) + { + client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false); + return; + } + } // This user wants to be friends with the other user. // Let's add the relation backwards, in case the other is not online @@ -715,7 +720,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends "[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, friendID); - FriendInfo[] friends = GetFriends(requester); + FriendInfo[] friends = GetFriendsFromCache(requester); if (friends.Length == 0) { return; @@ -901,20 +906,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends #endregion #region Get / Set friends in several flavours - /// - /// Get friends from local cache only - /// - /// - /// - /// An empty array if the user has no friends or friends have not been cached. - /// - protected FriendInfo[] GetFriends(UUID agentID) + + public FriendInfo[] GetFriendsFromCache(UUID userID) { UserFriendData friendsData; lock (m_Friends) { - if (m_Friends.TryGetValue(agentID, out friendsData)) + if (m_Friends.TryGetValue(userID, out friendsData)) return friendsData.Friends; } @@ -932,7 +931,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // Update local cache lock (m_Friends) { - FriendInfo[] friends = GetFriends(friendID); + FriendInfo[] friends = GetFriendsFromCache(friendID); FriendInfo finfo = GetFriend(friends, userID); finfo.TheirFlags = rights; } @@ -956,12 +955,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } } - /// - /// Are friends cached on this simulator for a particular user? - /// - /// - /// - protected bool AreFriendsCached(UUID userID) + public bool AreFriendsCached(UUID userID) { lock (m_Friends) return m_Friends.ContainsKey(userID); @@ -992,61 +986,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } #endregion - - protected void HandleFriendsShowCacheCommand(string module, string[] cmd) - { - if (cmd.Length != 5) - { - MainConsole.Instance.OutputFormat("Usage: friends show cache [ ]"); - return; - } - - string firstName = cmd[3]; - string lastName = cmd[4]; - - IUserManagement umModule = m_Scenes[0].RequestModuleInterface(); - UUID userId = umModule.GetUserIdByName(firstName, lastName); - -// UserAccount ua -// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName); - - if (userId == UUID.Zero) - { - MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName); - return; - } - - if (!AreFriendsCached(userId)) - { - MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName); - return; - } - - MainConsole.Instance.OutputFormat("Cached friends for {0} {1}:", firstName, lastName); - - MainConsole.Instance.OutputFormat("UUID\n"); - - FriendInfo[] friends = GetFriends(userId); - - foreach (FriendInfo friend in friends) - { -// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString()); - -// string friendFirstName, friendLastName; -// -// UserAccount friendUa -// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID); - - UUID friendId; - string friendName; - - if (UUID.TryParse(friend.Friend, out friendId)) - friendName = umModule.GetUserName(friendId); - else - friendName = friend.Friend; - - MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags); - } - } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index f83b15c827..539e656992 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); if (account == null) // foreign { - FriendInfo[] friends = GetFriends(client.AgentId); + FriendInfo[] friends = GetFriendsFromCache(client.AgentId); foreach (FriendInfo f in friends) { client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); @@ -430,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (agentIsLocal) // agent is local, friend is foreigner { - FriendInfo[] finfos = GetFriends(agentID); + FriendInfo[] finfos = GetFriendsFromCache(agentID); FriendInfo finfo = GetFriend(finfos, friendID); if (finfo != null) { @@ -527,10 +527,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { // This may happen when the agent returned home, in which case the friend is not there // We need to look for its information in the friends list itself + FriendInfo[] finfos = null; bool confirming = false; if (friendUUI == string.Empty) { - FriendInfo[] finfos = GetFriends(agentID); + finfos = GetFriendsFromCache(agentID); + foreach (FriendInfo finfo in finfos) { if (finfo.TheirFlags == -1) @@ -614,7 +616,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (agentIsLocal) // agent is local, 'friend' is foreigner { // We need to look for its information in the friends list itself - FriendInfo[] finfos = GetFriends(agentID); + FriendInfo[] finfos = GetFriendsFromCache(agentID); FriendInfo finfo = GetFriend(finfos, exfriendID); if (finfo != null) { @@ -658,7 +660,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private string GetUUI(UUID localUser, UUID foreignUser) { // Let's see if the user is here by any chance - FriendInfo[] finfos = GetFriends(localUser); + FriendInfo[] finfos = GetFriendsFromCache(localUser); if (finfos != EMPTY_FRIENDS) // friend is here, cool { FriendInfo finfo = GetFriend(finfos, foreignUser); diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs index 10bef1e2dc..7e87006706 100644 --- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs @@ -25,14 +25,31 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; -using System.Collections.Generic; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; namespace OpenSim.Region.Framework.Interfaces { public interface IFriendsModule { + /// + /// Are friends cached on this simulator for a particular user? + /// + /// + /// + bool AreFriendsCached(UUID userID); + + /// + /// Get friends from local cache only + /// + /// + /// + /// An empty array if the user has no friends or friends have not been cached. + /// + FriendInfo[] GetFriendsFromCache(UUID userID); + /// /// Add a friendship between two users. /// @@ -58,10 +75,10 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Get permissions granted by a friend. /// - /// The user. - /// The friend that granted. + /// The user. + /// The friend that granted. /// The permissions. These come from the FriendRights enum. - int GetRightsGrantedByFriend(UUID PrincipalID, UUID FriendID); + int GetRightsGrantedByFriend(UUID userID, UUID friendID); /// /// Grant permissions for a friend. diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs new file mode 100644 index 0000000000..2bcb8a736c --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs @@ -0,0 +1,165 @@ +/* + * 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 System.Linq; +using System.Reflection; +using System.Text; +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; +using OpenSim.Region.ClientStack.LindenUDP; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; + +namespace OpenSim.Region.OptionalModules.Avatar.Friends +{ + /// + /// A module that just holds commands for inspecting avatar appearance. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FriendsCommandModule")] + public class FriendsCommandsModule : ISharedRegionModule + { +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene; + private IFriendsModule m_friendsModule; + private IUserManagement m_userManagementModule; + +// private IAvatarFactoryModule m_avatarFactory; + + public string Name { get { return "Appearance Information Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[FRIENDS COMMANDO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + + if (m_scene == null) + m_scene = scene; + + m_friendsModule = m_scene.RequestModuleInterface(); + m_userManagementModule = m_scene.RequestModuleInterface(); + + if (m_friendsModule != null && m_userManagementModule != null) + { + m_scene.AddCommand( + "Friends", this, "friends show cache", + "friends show cache [ ]", + "Show the friends cache for the given user", + HandleFriendsShowCacheCommand); + } + } + + protected void HandleFriendsShowCacheCommand(string module, string[] cmd) + { + if (cmd.Length != 5) + { + MainConsole.Instance.OutputFormat("Usage: friends show cache [ ]"); + return; + } + + string firstName = cmd[3]; + string lastName = cmd[4]; + + UUID userId = m_userManagementModule.GetUserIdByName(firstName, lastName); + +// UserAccount ua +// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName); + + if (userId == UUID.Zero) + { + MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName); + return; + } + + if (m_friendsModule.AreFriendsCached(userId)) + { + MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName); + return; + } + + MainConsole.Instance.OutputFormat("Cached friends for {0} {1}:", firstName, lastName); + + MainConsole.Instance.OutputFormat("UUID\n"); + + FriendInfo[] friends = m_friendsModule.GetFriendsFromCache(userId); + + foreach (FriendInfo friend in friends) + { +// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString()); + +// string friendFirstName, friendLastName; +// +// UserAccount friendUa +// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID); + + UUID friendId; + string friendName; + + if (UUID.TryParse(friend.Friend, out friendId)) + friendName = m_userManagementModule.GetUserName(friendId); + else + friendName = friend.Friend; + + MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags); + } + } + } +} \ No newline at end of file