public List <GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID) { string url = string.Empty, gname = string.Empty; if (IsLocal(GroupID, out url, out gname)) { string agentID = AgentUUI(RequestingAgentID); return(m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID)); } else if (!string.IsNullOrEmpty(url)) { ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID); string accessToken = string.Empty; if (membership != null) { accessToken = membership.AccessToken; } else { return(null); } GroupsServiceHGConnector c = GetConnector(url); if (c != null) { return(m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate { return c.GetGroupMembers(AgentUUIForOutside(RequestingAgentID), GroupID, accessToken); })); } } return(new List <GroupMembersData>()); }
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID) { string url = string.Empty, gname = string.Empty; if (IsLocal(groupID, out url, out gname)) { if (m_LocalGroupsConnector.AddGroupNotice(AgentUUI(RequestingAgentID), groupID, noticeID, fromName, subject, message, hasAttachment, attType, attName, attItemID, AgentUUI(attOwnerID))) { // then send the notice to every grid for which there are members in this group List <GroupMembersData> members = m_LocalGroupsConnector.GetGroupMembers(AgentUUI(RequestingAgentID), groupID); List <string> urls = new List <string>(); foreach (GroupMembersData m in members) { if (!m_UserManagement.IsLocalGridUser(m.AgentID)) { string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI"); if (!urls.Contains(gURL)) { urls.Add(gURL); } } } // so we have the list of urls to send the notice to // this may take a long time... Util.RunThreadNoTimeout(delegate { foreach (string u in urls) { GroupsServiceHGConnector c = GetConnector(u); if (c != null) { c.AddNotice(AgentUUIForOutside(RequestingAgentID), groupID, noticeID, fromName, subject, message, hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID)); } } }, "AddGroupNotice", null); return(true); } return(false); } else { return(false); } }
public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { if (m_debugEnabled) { m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); } foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) { 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); } } }
public void SendMessageToGroup(GridInstantMessage im, UUID groupID) { if (m_debugEnabled) { m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); } // 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; foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Parse(msg.fromAgentID.ToString()), groupID)) { 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; } msg.toAgentID = member.AgentID.Guid; if (m_debugEnabled) { m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0}", member.AgentID); } m_msgTransferModule.SendInstantMessage(msg); } }
public List <GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID) { if (m_log.IsDebugEnabled) { m_log.DebugFormat("{0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); } string url = string.Empty, gname = string.Empty; if (IsLocal(GroupID, out url, out gname)) { string agentID = AgentUUI(RequestingAgentID); return(m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID)); } else if (!string.IsNullOrEmpty(url)) { ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID); string accessToken = string.Empty; if (membership != null) { accessToken = membership.AccessToken; } else { return(null); } GroupsServiceHGConnector c = GetConnector(url); if (c != null) { return(m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate { return c.GetGroupMembers(AgentUUIForOutside(RequestingAgentID), GroupID, accessToken); })); } } return(new List <GroupMembersData>()); }
public void EnsureGroupChatIsStarted(UUID groupID) { ChatSession session = m_groupData.GetSession(groupID); if (session == null) { GroupRecord record = m_groupData.GetGroupRecord(UUID.Zero, groupID, ""); UUID ownerID = record.FounderID; //Requires that the founder is still in the group List <ChatSessionMember> members = (from gmd in m_groupData.GetGroupMembers(ownerID, groupID) where (gmd.AgentPowers & (ulong)GroupPowers.JoinChat) == (ulong)GroupPowers.JoinChat select new ChatSessionMember { AvatarKey = gmd.AgentID }).ToList(); m_groupData.CreateSession(new ChatSession { Members = members, Name = record.GroupName, SessionID = groupID }); } }
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); } }
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 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); } }