diff --git a/OpenSim/Framework/FriendListItem.cs b/OpenSim/Framework/FriendListItem.cs index 349ee974e0..f090ab1c4b 100644 --- a/OpenSim/Framework/FriendListItem.cs +++ b/OpenSim/Framework/FriendListItem.cs @@ -34,6 +34,7 @@ namespace OpenSim.Framework { public class FriendListItem { + public LLUUID FriendListOwner; public LLUUID Friend; diff --git a/OpenSim/Grid/MessagingServer/MessageService.cs b/OpenSim/Grid/MessagingServer/MessageService.cs index a4362c79b9..d8221dce3f 100644 --- a/OpenSim/Grid/MessagingServer/MessageService.cs +++ b/OpenSim/Grid/MessagingServer/MessageService.cs @@ -30,13 +30,14 @@ using System.Net; using System.Net.Sockets; using System.Collections; using System.Collections.Generic; -using System.Xml; +//using System.Xml; using libsecondlife; using Nwc.XmlRpc; using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Framework.Data; using OpenSim.Framework.Servers; +using FriendRights = libsecondlife.FriendRights; namespace OpenSim.Grid.MessagingServer { @@ -44,9 +45,16 @@ namespace OpenSim.Grid.MessagingServer { private LogBase m_log; private MessageServerConfig m_cfg; + + //A hashtable of all current presences this server knows about private Hashtable m_presences = new Hashtable(); + + //a hashtable of all current regions this server knows about private Hashtable m_regionInfoCache = new Hashtable(); + //A hashtable containing lists of UUIDs keyed by UUID for fast backreferencing + private Hashtable m_presence_BackReferences = new Hashtable(); + public MessageService(LogBase log, MessageServerConfig cfg) { m_log = log; @@ -80,13 +88,104 @@ namespace OpenSim.Grid.MessagingServer } ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); + + UserPresenceData up = new UserPresenceData(); + up.agentData = agentData; + List flData = GetUserFriendList(agentData.AgentID); + up.friendData = flData; + RegionInfo riData = GetRegionInfo(regionHandle); + up.regionData = riData; - m_presences.Add(regionHandle, agentData); + ProcessFriendListSubscriptions(up); return new XmlRpcResponse(); } + #region FriendList Methods + #region FriendListProcessing + + public void ProcessFriendListSubscriptions(UserPresenceData userpresence) + { + List uFriendList = userpresence.friendData; + for (int i = 0; i < uFriendList.Count; i++) + { + if (m_presences.Contains(uFriendList[i].Friend)) + { + UserPresenceData friendup = (UserPresenceData)m_presences[uFriendList[i]]; + SubscribeToPresenceUpdates(userpresence, friendup, uFriendList[i],i); + } + } + + m_presences.Add(userpresence.agentData.AgentID, userpresence); + } + + public void SubscribeToPresenceUpdates(UserPresenceData userpresence, UserPresenceData friendpresence, + FriendListItem uFriendListItem, int uFriendListIndex) + { + + if ((uFriendListItem.FriendListOwnerPerms & (uint)FriendRights.CanSeeOnline) != 0) + { + // Subscribe and Send Out updates + // Add backreference + m_presence_BackReferences.Add(userpresence.agentData.AgentID, friendpresence.agentData.AgentID); + } + + + + + } + + /// + /// Adds a backreference so presence specific data doesn't have to be + /// enumerated for each logged in user every time someone logs on or off. + /// + /// + /// + public void addBackReference(LLUUID agentID, LLUUID friendID) + { + if (m_presence_BackReferences.Contains(agentID)) + { + List presenseBackReferences = (List)m_presence_BackReferences[agentID]; + if (!presenseBackReferences.Contains(friendID)) + { + presenseBackReferences.Add(friendID); + } + m_presence_BackReferences[agentID] = presenseBackReferences; + } + else + { + List presenceBackReferences = new List(); + presenceBackReferences.Add(friendID); + m_presence_BackReferences[agentID] = presenceBackReferences; + } + } + + /// + /// Removes a backreference to free up some memory + /// + /// + /// + public void removeBackReference(LLUUID agentID, LLUUID friendID) + { + if (m_presence_BackReferences.Contains(agentID)) + { + List presenseBackReferences = (List)m_presence_BackReferences[agentID]; + if (presenseBackReferences.Contains(friendID)) + { + presenseBackReferences.Remove(friendID); + } + + // If there are no more backreferences for this agent, + // remove it to free up memory. + if (presenseBackReferences.Count == 0) + { + m_presence_BackReferences.Remove(agentID); + } + } + } + + #endregion #region FriendList Gathering @@ -147,6 +246,8 @@ namespace OpenSim.Grid.MessagingServer } #endregion + #endregion + #region regioninfo gathering /// diff --git a/OpenSim/Grid/MessagingServer/UserPresenceData.cs b/OpenSim/Grid/MessagingServer/UserPresenceData.cs index 88007ae031..13914605ca 100644 --- a/OpenSim/Grid/MessagingServer/UserPresenceData.cs +++ b/OpenSim/Grid/MessagingServer/UserPresenceData.cs @@ -38,6 +38,7 @@ namespace OpenSim.Grid.MessagingServer public AgentCircuitData agentData = new AgentCircuitData(); public RegionInfo regionData = new RegionInfo(); public List friendData = new List (); + public List subscriptionData = new List(); public UserPresenceData() {