Beispiel #1
0
        public List <UUID> GetOnlineFriends(UUID foreignUserID, List <string> friends)
        {
            List <UUID> online = new List <UUID>();

            if (m_FriendsService == null || m_PresenceService == null)
            {
                m_log.WarnFormat("[USER AGENT SERVICE]: Unable to get online friends because friends or presence services are missing");
                return(online);
            }

            m_log.DebugFormat("[USER AGENT SERVICE]: Foreign user {0} wants to know status of {1} local friends", foreignUserID, friends.Count);

            // First, let's double check that the reported friends are, indeed, friends of that user
            // And let's check that the secret matches and the rights
            List <string> usersToBeNotified = new List <string>();

            foreach (string uui in friends)
            {
                UUID   localUserID;
                string secret = string.Empty, tmp = string.Empty;
                if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
                {
                    FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
                    foreach (FriendInfo finfo in friendInfos)
                    {
                        if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret) &&
                            (finfo.TheirFlags & (int)FriendRights.CanSeeOnline) != 0 && (finfo.TheirFlags != -1))
                        {
                            // great!
                            usersToBeNotified.Add(localUserID.ToString());
                        }
                    }
                }
            }

            // Now, let's find out their status
            m_log.DebugFormat("[USER AGENT SERVICE]: GetOnlineFriends: user has {0} local friends with status rights", usersToBeNotified.Count);

            // First, let's send notifications to local users who are online in the home grid
            PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
            if (friendSessions != null && friendSessions.Length > 0)
            {
                foreach (PresenceInfo pi in friendSessions)
                {
                    UUID presenceID;
                    if (UUID.TryParse(pi.UserID, out presenceID))
                    {
                        online.Add(presenceID);
                    }
                }
            }

            return(online);
        }
        public PresenceInfo[] GetAgents(string[] userIDs)
        {
            // Don't bother potentially making a useless network call if we not going to ask for any users anyway.
            if (userIDs.Length == 0)
            {
                return(new PresenceInfo[0]);
            }

            return(m_PresenceService.GetAgents(userIDs));
        }
Beispiel #3
0
        byte[] GetAgents(Dictionary <string, object> request)
        {
            string[] userIDs;

            if (!request.ContainsKey("uuids"))
            {
                m_log.DebugFormat("[PRESENCE HANDLER]: GetAgents called without required uuids argument");
                return(FailureResult());
            }

            if (!(request["uuids"] is List <string>))
            {
                m_log.DebugFormat("[PRESENCE HANDLER]: GetAgents input argument was of unexpected type {0}", request["uuids"].GetType().ToString());
                return(FailureResult());
            }

            userIDs = ((List <string>)request["uuids"]).ToArray();

            PresenceInfo[] pinfos = m_PresenceService.GetAgents(userIDs);

            Dictionary <string, object> result = new Dictionary <string, object>();

            if ((pinfos == null) || ((pinfos != null) && (pinfos.Length == 0)))
            {
                result["result"] = "null";
            }
            else
            {
                int i = 0;
                foreach (PresenceInfo pinfo in pinfos)
                {
                    Dictionary <string, object> rinfoDict = pinfo.ToKeyValuePairs();
                    result["presence" + i] = rinfoDict;
                    i++;
                }
            }

            string xmlString = ServerUtils.BuildXmlResponse(result);
            //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString);
            UTF8Encoding encoding = new UTF8Encoding();

            return(encoding.GetBytes(xmlString));
        }
Beispiel #4
0
        public void AddFriendship(IClientAPI client, UUID friendID)
        {
            StoreFriendships(client.AgentId, friendID);

            ICallingCardModule ccm = client.Scene.RequestModuleInterface <ICallingCardModule>();

            if (ccm != null)
            {
                ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero);
            }

            // Update the local cache.
            RecacheFriends(client);

            //
            // Notify the friend
            //

            // Try Local
            if (LocalFriendshipApproved(client.AgentId, client.Name, friendID))
            {
                client.SendAgentOnline(new UUID[] { friendID });
                return;
            }

            // The friend is not here
            PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
            if (friendSessions != null && friendSessions.Length > 0)
            {
                PresenceInfo friendSession = friendSessions[0];
                if (friendSession != null)
                {
                    GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
                    m_FriendsSimConnector.FriendshipApproved(region, client.AgentId, client.Name, friendID);
                    client.SendAgentOnline(new UUID[] { friendID });
                }
            }
        }
        public void SendMessageToGroup(
            GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition)
        {
            int requestStartTick = Environment.TickCount;

            UUID fromAgentID = new UUID(im.fromAgentID);

            // Unlike current XmlRpcGroups, Groups V2 can accept UUID.Zero when a perms check for the requesting agent
            // is not necessary.
            List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);

            int groupMembersCount = groupMembers.Count;

            PresenceInfo[] onlineAgents = null;

            // In V2 we always only send to online members.
            // Sending to offline members is not an option.

            // We cache in order not to overwhelm the presence service on large grids with many groups.  This does
            // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
            // (assuming this is the same across all grid simulators).
            if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
            {
                string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray();
                onlineAgents = m_presenceService.GetAgents(t1);
                m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
            }

            HashSet <string> onlineAgentsUuidSet = new HashSet <string>();

            Array.ForEach <PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));

            groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();

//            if (m_debugEnabled)
//                    m_log.DebugFormat(
//                        "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
//                        groupID, groupMembersCount, groupMembers.Count());

            im.imSessionID = groupID.Guid;
            im.fromGroup   = true;
            IClientAPI thisClient = GetActiveClient(fromAgentID);

            if (thisClient != null)
            {
                im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
            }

            if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0)))
            {
                ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), groupID, null);
                if (groupInfo != null)
                {
                    im.binaryBucket = Util.StringToBytes256(groupInfo.GroupName);
                }
            }

            // Send to self first of all
            im.toAgentID = im.fromAgentID;
            im.fromGroup = true;
            ProcessMessageFromGroupSession(im);

            List <UUID> regions            = new List <UUID>();
            List <UUID> clientsAlreadySent = new List <UUID>();

            // Then send to everybody else
            foreach (GroupMembersData member in groupMembers)
            {
                if (member.AgentID.Guid == im.fromAgentID)
                {
                    continue;
                }

                if (clientsAlreadySent.Contains(member.AgentID))
                {
                    continue;
                }

                clientsAlreadySent.Add(member.AgentID);

                if (sendCondition != null)
                {
                    if (!sendCondition(member))
                    {
                        if (m_debugEnabled)
                        {
                            m_log.DebugFormat(
                                "[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
                                member.AgentID);
                        }

                        continue;
                    }
                }
                else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
                {
                    // Don't deliver messages to people who have dropped this session
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
                    }

                    continue;
                }

                im.toAgentID = member.AgentID.Guid;

                IClientAPI client = GetActiveClient(member.AgentID);
                if (client == null)
                {
                    // If they're not local, forward across the grid
                    // BUT do it only once per region, please! Sim would be even better!
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
                    }

                    bool reallySend = true;
                    if (onlineAgents != null)
                    {
                        PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
                        if (regions.Contains(presence.RegionID))
                        {
                            reallySend = false;
                        }
                        else
                        {
                            regions.Add(presence.RegionID);
                        }
                    }

                    if (reallySend)
                    {
                        // We have to create a new IM structure because the transfer module
                        // uses async send
                        GridInstantMessage msg = new GridInstantMessage(im, true);
                        m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
                    }
                }
                else
                {
                    // Deliver locally, directly
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
                    }

                    ProcessMessageFromGroupSession(im);
                }
            }

            if (m_debugEnabled)
            {
                m_log.DebugFormat(
                    "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
                    groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
            }
        }
        protected void HandleFriendsShowCommand(string module, string[] cmd)
        {
            Dictionary <string, object> options = new Dictionary <string, object>();
            OptionSet optionSet = new OptionSet().Add("c|cache", delegate(string v) { options["cache"] = v != null; });

            List <string> mainParams = optionSet.Parse(cmd);

            if (mainParams.Count != 4)
            {
                MainConsole.Instance.Output("Usage: friends show [--cache] <first-name> <last-name>");
                return;
            }

            string firstName = mainParams[2];
            string lastName  = mainParams[3];

            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.Output("No such user as {0} {1}", firstName, lastName);
                return;
            }

            FriendInfo[] friends;

            if (options.ContainsKey("cache"))
            {
                if (!m_friendsModule.AreFriendsCached(userId))
                {
                    MainConsole.Instance.Output("No friends cached on this simulator for {0} {1}", firstName, lastName);
                    return;
                }
                else
                {
                    friends = m_friendsModule.GetFriendsFromCache(userId);
                }
            }
            else
            {
                // FIXME: We're forced to do this right now because IFriendsService has no region connectors.  We can't
                // just expose FriendsModule.GetFriendsFromService() because it forces an IClientAPI requirement that
                // can't currently be changed because of HGFriendsModule code that takes the scene from the client.
                friends = ((FriendsModule)m_friendsModule).FriendsService.GetFriends(userId);
            }

            MainConsole.Instance.Output("Friends for {0} {1} {2}:", firstName, lastName, userId);

            MainConsole.Instance.Output(
                "{0,-36}  {1,-36}  {2,-7}  {3,7}  {4,10}", "UUID", "Name", "Status", "MyFlags", "TheirFlags");

            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;
                string onlineText;

                if (UUID.TryParse(friend.Friend, out friendId))
                {
                    friendName = m_userManagementModule.GetUserName(friendId);
                }
                else
                {
                    friendName = friend.Friend;
                }

                OpenSim.Services.Interfaces.PresenceInfo[] pi = m_presenceService.GetAgents(new string[] { friend.Friend });
                if (pi.Length > 0)
                {
                    onlineText = "online";
                }
                else
                {
                    onlineText = "offline";
                }

                MainConsole.Instance.Output(
                    "{0,-36}  {1,-36}  {2,-7}  {3,-7}  {4,-10}",
                    friend.Friend, friendName, onlineText, friend.MyFlags, friend.TheirFlags);
            }
        }
        protected bool TrySendInstantMessage(GridInstantMessage im, object previousLocation, bool firstTime, bool foreigner)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            PresenceInfo upd = null;
            string       url = string.Empty;

            bool lookupAgent = false;

            lock (m_UserLocationMap)
            {
                if (m_UserLocationMap.ContainsKey(toAgentID))
                {
                    object o = m_UserLocationMap[toAgentID];
                    if (o is PresenceInfo)
                    {
                        upd = (PresenceInfo)o;
                    }
                    else if (o is string)
                    {
                        url = (string)o;
                    }

                    // We need to compare the current location with the previous
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (!firstTime)
                    {
                        lookupAgent = true;
                        upd         = null;
                    }
                }
                else
                {
                    lookupAgent = true;
                }
            }

            //m_log.DebugFormat("[XXX] Neeed lookup ? {0}", (lookupAgent ? "yes" : "no"));

            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                // Non-cached user agent lookup.
                PresenceInfo[] presences = m_PresenceService.GetAgents(new string[] { toAgentID.ToString() });
                if (presences != null && presences.Length > 0)
                {
                    foreach (PresenceInfo p in presences)
                    {
                        if (p.RegionID != UUID.Zero)
                        {
                            //m_log.DebugFormat("[XXX]: Found presence in {0}", p.RegionID);
                            upd = p;
                            break;
                        }
                    }
                }

                if (upd == null && !foreigner)
                {
                    // Let's check with the UAS if the user is elsewhere
                    m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service");
                    try
                    {
                        url = m_UserAgentService.LocateUser(toAgentID);
                    }
                    catch (Exception e)
                    {
                        m_log.Warn("[HG IM SERVICE]: LocateUser call failed ", e);
                        url = string.Empty;
                    }
                }

                // check if we've tried this before..
                // This is one way to end the recursive loop
                //
                if (!firstTime && ((previousLocation is PresenceInfo && upd != null && upd.RegionID == ((PresenceInfo)previousLocation).RegionID) ||
                                   (previousLocation is string && upd == null && previousLocation.Equals(url))))
                {
                    // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    m_log.DebugFormat("[HG IM SERVICE]: Fail 2 {0} {1}", previousLocation, url);

                    return(false);
                }
            }

            if (upd != null)
            {
                // ok, the user is around somewhere. Let's send back the reply with "success"
                // even though the IM may still fail. Just don't keep the caller waiting for
                // the entire time we're trying to deliver the IM
                return(SendIMToRegion(upd, im, toAgentID, foreigner));
            }
            else if (url != string.Empty)
            {
                // ok, the user is around somewhere. Let's send back the reply with "success"
                // even though the IM may still fail. Just don't keep the caller waiting for
                // the entire time we're trying to deliver the IM
                return(ForwardIMToGrid(url, im, toAgentID, foreigner));
            }
            else if (firstTime && previousLocation is string && (string)previousLocation != string.Empty)
            {
                return(ForwardIMToGrid((string)previousLocation, im, toAgentID, foreigner));
            }
            else
            {
                m_log.DebugFormat("[HG IM SERVICE]: Unable to locate user {0}", toAgentID);
            }
            return(false);
        }
Beispiel #8
0
        public List <UUID> StatusNotification(List <string> friends, UUID foreignUserID, bool online)
        {
            if (m_FriendsService == null || m_PresenceService == null)
            {
                m_log.WarnFormat("[USER AGENT SERVICE]: Unable to perform status notifications because friends or presence services are missing");
                return(new List <UUID>());
            }

            List <UUID> localFriendsOnline = new List <UUID>();

            m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: foreign user {0} wants to notify {1} local friends", foreignUserID, friends.Count);

            // First, let's double check that the reported friends are, indeed, friends of that user
            // And let's check that the secret matches
            List <string> usersToBeNotified = new List <string>();

            foreach (string uui in friends)
            {
                UUID   localUserID;
                string secret = string.Empty, tmp = string.Empty;
                if (Util.ParseUniversalUserIdentifier(uui, out localUserID, out tmp, out tmp, out tmp, out secret))
                {
                    FriendInfo[] friendInfos = m_FriendsService.GetFriends(localUserID);
                    foreach (FriendInfo finfo in friendInfos)
                    {
                        if (finfo.Friend.StartsWith(foreignUserID.ToString()) && finfo.Friend.EndsWith(secret))
                        {
                            // great!
                            usersToBeNotified.Add(localUserID.ToString());
                        }
                    }
                }
            }

            // Now, let's send the notifications
            m_log.DebugFormat("[USER AGENT SERVICE]: Status notification: user has {0} local friends", usersToBeNotified.Count);

            // First, let's send notifications to local users who are online in the home grid
            PresenceInfo[] friendSessions = m_PresenceService.GetAgents(usersToBeNotified.ToArray());
            if (friendSessions != null && friendSessions.Length > 0)
            {
                PresenceInfo friendSession = null;
                foreach (PresenceInfo pinfo in friendSessions)
                {
                    if (pinfo.RegionID != UUID.Zero) // let's guard against traveling agents
                    {
                        friendSession = pinfo;
                        break;
                    }
                }

                if (friendSession != null)
                {
                    ForwardStatusNotificationToSim(friendSession.RegionID, foreignUserID, friendSession.UserID, online);
                    usersToBeNotified.Remove(friendSession.UserID.ToString());
                    UUID id;
                    if (UUID.TryParse(friendSession.UserID, out id))
                    {
                        localFriendsOnline.Add(id);
                    }
                }
            }

            //// Lastly, let's notify the rest who may be online somewhere else
            //foreach (string user in usersToBeNotified)
            //{
            //    UUID id = new UUID(user);
            //    if (m_Database.ContainsKey(id) && m_Database[id].GridExternalName != m_GridName)
            //    {
            //        string url = m_Database[id].GridExternalName;
            //        // forward
            //        m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
            //    }
            //}

            // and finally, let's send the online friends
            if (online)
            {
                return(localFriendsOnline);
            }
            else
            {
                return(new List <UUID>());
            }
        }
        public void SendMessageToGroup(
            GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition)
        {
            int requestStartTick = Environment.TickCount;

            List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, groupID);
            int groupMembersCount = groupMembers.Count;
            HashSet <string> attemptDeliveryUuidSet = null;

            if (m_messageOnlineAgentsOnly)
            {
                string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray();

                // We cache in order not to overwhlem the presence service on large grids with many groups.  This does
                // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
                // (assuming this is the same across all grid simulators).
                PresenceInfo[] onlineAgents;
                if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
                {
                    onlineAgents = m_presenceService.GetAgents(t1);
                    m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
                }

                attemptDeliveryUuidSet
                    = new HashSet <string>(Array.ConvertAll <PresenceInfo, string>(onlineAgents, pi => pi.UserID));
            }
            else
            {
                attemptDeliveryUuidSet
                    = new HashSet <string>(groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()));

                if (m_debugEnabled)
                {
                    m_log.DebugFormat(
                        "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
                        groupID, groupMembers.Count);
                }
            }

            foreach (GroupMembersData member in groupMembers)
            {
                if (sendCondition != null)
                {
                    if (!sendCondition(member))
                    {
                        if (m_debugEnabled)
                        {
                            m_log.DebugFormat(
                                "[GROUPS-MESSAGING]: Not sending to {0} as they do not fulfill send condition",
                                member.AgentID);
                        }

                        continue;
                    }
                }
                else if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID))
                {
                    // Don't deliver messages to people who have dropped this session
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat(
                            "[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID);
                    }

                    continue;
                }

                // Copy Message
                GridInstantMessage msg = new GridInstantMessage();
                msg.imSessionID    = im.imSessionID;
                msg.fromAgentName  = im.fromAgentName;
                msg.message        = im.message;
                msg.dialog         = im.dialog;
                msg.offline        = im.offline;
                msg.ParentEstateID = im.ParentEstateID;
                msg.Position       = im.Position;
                msg.RegionID       = im.RegionID;
                msg.binaryBucket   = im.binaryBucket;
                msg.timestamp      = (uint)Util.UnixTimeSinceEpoch();

                msg.fromAgentID = im.fromAgentID;
                msg.fromGroup   = true;

                msg.toAgentID = member.AgentID.Guid;

                if (attemptDeliveryUuidSet.Contains(member.AgentID.ToString()))
                {
                    IClientAPI client = GetActiveClient(member.AgentID);
                    if (client == null)
                    {
                        int startTick = Environment.TickCount;

                        // If they're not local, forward across the grid
                        m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });

                        if (m_debugEnabled)
                        {
                            m_log.DebugFormat(
                                "[GROUPS-MESSAGING]: Delivering to {0} via grid took {1} ms",
                                member.AgentID, Environment.TickCount - startTick);
                        }
                    }
                    else
                    {
                        int startTick = Environment.TickCount;

                        ProcessMessageFromGroupSession(msg, client);

                        // Deliver locally, directly
                        if (m_debugEnabled)
                        {
                            m_log.DebugFormat(
                                "[GROUPS-MESSAGING]: Delivering to {0} locally took {1} ms",
                                member.AgentID, Environment.TickCount - startTick);
                        }
                    }
                }
                else if (im.dialog != (byte)InstantMessageDialog.SessionAdd &&
                         im.dialog != (byte)InstantMessageDialog.SessionDrop)
                {
                    int startTick = Environment.TickCount;

                    m_msgTransferModule.HandleUndeliverableMessage(msg, delegate(bool success) { });

                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat(
                            "[GROUPS-MESSAGING]: Handling undeliverable message for {0} took {1} ms",
                            member.AgentID, Environment.TickCount - startTick);
                    }
                }
            }

            if (m_debugEnabled)
            {
                m_log.DebugFormat(
                    "[GROUPS-MESSAGING]: Total SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3} ms",
                    groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick);
            }
        }
 public PresenceInfo[] GetAgents(string[] userIDs)
 {
     return(m_PresenceService.GetAgents(userIDs));
 }
 public PresenceInfo[] GetAgents(string[] userIDs)
 {
     return(m_RemoteConnector.GetAgents(userIDs));
 }
Beispiel #12
0
        public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
        {
            List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID);
            int groupMembersCount = groupMembers.Count;

            if (m_messageOnlineAgentsOnly)
            {
                string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray();

                // We cache in order not to overwhlem the presence service on large grids with many groups.  This does
                // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
                // (assuming this is the same across all grid simulators).
                PresenceInfo[] onlineAgents;
                if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
                {
                    onlineAgents = m_presenceService.GetAgents(t1);
                    m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
                }

                HashSet <string> onlineAgentsUuidSet = new HashSet <string>();
                Array.ForEach <PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));

                groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();

                //            if (m_debugEnabled)
//                    m_log.DebugFormat(
//                        "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
//                        groupID, groupMembersCount, groupMembers.Count());
            }
            else
            {
                if (m_debugEnabled)
                {
                    m_log.DebugFormat(
                        "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
                        groupID, groupMembers.Count);
                }
            }

            int requestStartTick = Environment.TickCount;

            foreach (GroupMembersData member in groupMembers)
            {
                if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID))
                {
                    // Don't deliver messages to people who have dropped this session
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID);
                    }
                    continue;
                }

                // Copy Message
                GridInstantMessage msg = new GridInstantMessage();
                msg.imSessionID    = groupID.Guid;
                msg.fromAgentName  = im.fromAgentName;
                msg.message        = im.message;
                msg.dialog         = im.dialog;
                msg.offline        = im.offline;
                msg.ParentEstateID = im.ParentEstateID;
                msg.Position       = im.Position;
                msg.RegionID       = im.RegionID;
                msg.binaryBucket   = im.binaryBucket;
                msg.timestamp      = (uint)Util.UnixTimeSinceEpoch();

                msg.fromAgentID = im.fromAgentID;
                msg.fromGroup   = true;

                msg.toAgentID = member.AgentID.Guid;

                IClientAPI client = GetActiveClient(member.AgentID);
                if (client == null)
                {
                    // If they're not local, forward across the grid
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID);
                    }
                    m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
                }
                else
                {
                    // Deliver locally, directly
                    if (m_debugEnabled)
                    {
                        m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
                    }
                    ProcessMessageFromGroupSession(msg);
                }
            }

            // Temporary for assessing how long it still takes to send messages to large online groups.
            if (m_messageOnlineAgentsOnly)
            {
                m_log.DebugFormat(
                    "[GROUPS-MESSAGING]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
                    groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
            }
        }