예제 #1
0
        public bool HasGroupAccess(UUID avatar)
        {
            if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
            {
                ScenePresence sp;
                if (!m_scene.TryGetScenePresence(avatar, out sp))
                {
                    bool isMember;
                    if (m_groupMemberCache.TryGetValue(avatar, out isMember))
                    {
                        m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout);
                        return(isMember);
                    }

                    IGroupsModule groupsModule = m_scene.RequestModuleInterface <IGroupsModule>();
                    if (groupsModule == null)
                    {
                        return(false);
                    }

                    GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar);
                    if (membership == null || membership.Length == 0)
                    {
                        m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
                        return(false);
                    }

                    foreach (GroupMembershipData d in membership)
                    {
                        if (d.GroupID == LandData.GroupID)
                        {
                            m_groupMemberCache.Add(avatar, true, m_groupMemberCacheTimeout);
                            return(true);
                        }
                    }
                    m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
                    return(false);
                }

                return(sp.ControllingClient.IsGroupMember(LandData.GroupID));
            }
            return(false);
        }
예제 #2
0
        void OnIncomingInstantMessage(GridInstantMessage im)
        {
            if (im.dialog == (byte)InstantMessageDialog.RequestTeleport ||
                im.dialog == (byte)InstantMessageDialog.GodLikeRequestTeleport)
            {
                UUID sessionID = new UUID(im.imSessionID);

                try
                {
                    m_PendingLures.Add(sessionID, im, 7200); // 2 hours
                    m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
                }
                catch (ArgumentException)
                {
                }

                // Forward. We do this, because the IM module explicitly rejects
                // IMs of this type
                if (m_TransferModule != null)
                {
                    m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
                }
            }
        }
 // Add this agent in this region as a banned person
 public void Add(ulong pRegionHandle, UUID pAgentID)
 {
     m_idCache = m_bannedRegions.GetOrAdd(pAgentID, delegate()
     { 
         return new ThreadedClasses.ExpiringCache<ulong, DateTime>(30);
     }, TimeSpan.FromSeconds(45));
     m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
 }
예제 #4
0
        public void SendMessageToGroup(
            GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition)
        {
            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.
            string[] t1 = groupMembers.ConvertAll <string>(gmd => gmd.AgentID.ToString()).ToArray();

            // 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))
            {
                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());

            int requestStartTick = Environment.TickCount;

            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);
            }
        }
        public void SendMessageToGroup(
            GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func <GroupMembersData, bool> sendCondition)
        {
            List <GroupMembersData> groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, 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 (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;

                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, client);
                }
            }

            // 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);
            }
        }