diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs index be59c6258c..f701e48c06 100644 --- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs +++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs @@ -172,10 +172,8 @@ namespace OpenSim.Groups return; } - if (m_presenceService == null) m_presenceService = scene.PresenceService; - } public void RemoveRegion(Scene scene) @@ -222,7 +220,6 @@ namespace OpenSim.Groups #endregion - /// /// Not really needed, but does confirm that the group exists. /// @@ -242,8 +239,13 @@ namespace OpenSim.Groups return false; } } - + public void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + SendMessageToGroup(im, groupID, null); + } + + public void SendMessageToGroup(GridInstantMessage im, UUID groupID, Func sendCondition) { UUID fromAgentID = new UUID(im.fromAgentID); List groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID); @@ -299,12 +301,27 @@ namespace OpenSim.Groups if (clientsAlreadySent.Contains(member.AgentID)) continue; + clientsAlreadySent.Add(member.AgentID); - if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) + 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); + if (m_debugEnabled) + m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID); + continue; } diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index b0493faaf5..7f453dbf8c 100644 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -45,9 +45,6 @@ namespace OpenSim.Groups [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")] public class GroupsModule : ISharedRegionModule, IGroupsModule { - /// - /// - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -466,6 +463,7 @@ namespace OpenSim.Groups OnNewGroupNotice(GroupID, NoticeID); } + // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID)) { diff --git a/OpenSim/Region/Framework/Interfaces/IGroupsMessagingModule.cs b/OpenSim/Region/Framework/Interfaces/IGroupsMessagingModule.cs index f15823659b..61bd153ae0 100644 --- a/OpenSim/Region/Framework/Interfaces/IGroupsMessagingModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IGroupsMessagingModule.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using OpenMetaverse; using OpenSim.Framework; @@ -57,7 +58,7 @@ namespace OpenSim.Region.Framework.Interfaces bool StartGroupChatSession(UUID agentID, UUID groupID); /// - /// Send a message to an entire group. + /// Send a message to each member of a group whose chat session is active. /// /// /// The message itself. The fields that must be populated are @@ -69,5 +70,23 @@ namespace OpenSim.Region.Framework.Interfaces /// /// void SendMessageToGroup(GridInstantMessage im, UUID groupID); + + /// + /// Send a message to all the members of a group that fulfill a condition. + /// + /// + /// The message itself. The fields that must be populated are + /// + /// imSessionID - Populate this with the group ID (session ID and group ID are currently identical) + /// fromAgentName - Populate this with whatever arbitrary name you want to show up in the chat dialog + /// message - The message itself + /// dialog - This must be (byte)InstantMessageDialog.SessionSend + /// + /// + /// + /// The condition that must be met by a member for the message to be sent. If null then the message is sent + /// if the chat session is active. + /// + void SendMessageToGroup(GridInstantMessage im, UUID groupID, Func sendCondition); } } \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 2802e2fb7f..741a98f69a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -237,8 +237,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return false; } } + public void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + SendMessageToGroup(im, groupID, null); + } + + public void SendMessageToGroup(GridInstantMessage im, UUID groupID, Func sendCondition) { List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID); int groupMembersCount = groupMembers.Count; @@ -279,10 +285,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembersData member in groupMembers) { - if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) + 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); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + continue; } @@ -315,7 +336,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { // Deliver locally, directly if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); + ProcessMessageFromGroupSession(msg, client); } } @@ -348,7 +369,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Any other message type will not be delivered to a client by the // Instant Message Module - if (m_debugEnabled) { m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -362,11 +382,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) || (msg.dialog == (byte)InstantMessageDialog.SessionDrop))) { - ProcessMessageFromGroupSession(msg); + IClientAPI client = null; + + if (msg.dialog == (byte)InstantMessageDialog.SessionSend) + { + client = GetActiveClient(new UUID(msg.toAgentID)); + + if (client != null) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name); + } + else + { + m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); + + return; + } + } + + ProcessMessageFromGroupSession(msg, client); } } - private void ProcessMessageFromGroupSession(GridInstantMessage msg) + private void ProcessMessageFromGroupSession(GridInstantMessage msg, IClientAPI client) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); @@ -393,67 +432,58 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); UUID toAgentID = new UUID(msg.toAgentID); - IClientAPI activeClient = GetActiveClient(toAgentID); - if (activeClient != null) + + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + if (groupInfo != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); - if (groupInfo != null) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); - // Force? open the group session dialog??? - // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); - IEventQueue eq = activeClient.Scene.RequestModuleInterface(); - eq.ChatterboxInvitation( - GroupID - , groupInfo.GroupName - , new UUID(msg.fromAgentID) - , msg.message - , new UUID(msg.toAgentID) - , msg.fromAgentName - , msg.dialog - , msg.timestamp - , msg.offline == 1 - , (int)msg.ParentEstateID - , msg.Position - , 1 - , new UUID(msg.imSessionID) - , msg.fromGroup - , Utils.StringToBytes(groupInfo.GroupName) - ); + // Force? open the group session dialog??? + // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); + IEventQueue eq = client.Scene.RequestModuleInterface(); + eq.ChatterboxInvitation( + GroupID + , groupInfo.GroupName + , new UUID(msg.fromAgentID) + , msg.message + , new UUID(msg.toAgentID) + , msg.fromAgentName + , msg.dialog + , msg.timestamp + , msg.offline == 1 + , (int)msg.ParentEstateID + , msg.Position + , 1 + , new UUID(msg.imSessionID) + , msg.fromGroup + , Utils.StringToBytes(groupInfo.GroupName) + ); - eq.ChatterBoxSessionAgentListUpdates( - new UUID(GroupID) - , new UUID(msg.fromAgentID) - , new UUID(msg.toAgentID) - , false //canVoiceChat - , false //isModerator - , false //text mute - ); - } + eq.ChatterBoxSessionAgentListUpdates( + new UUID(GroupID) + , new UUID(msg.fromAgentID) + , new UUID(msg.toAgentID) + , false //canVoiceChat + , false //isModerator + , false //text mute + ); } + + break; } else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) { // User hasn't dropped, so they're in the session, // maybe we should deliver it. - IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); - if (client != null) - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name); - client.SendInstantMessage(msg); - } - else - { - m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); - } + client.SendInstantMessage(msg); } + break; default: - m_log.WarnFormat("[GROUPS-MESSAGING]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); - break; + client.SendInstantMessage(msg); + + break;; } } @@ -549,13 +579,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent) { m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False"); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline.ToString()); - m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID.ToString()); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", (InstantMessageDialog)im.dialog); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline); + m_log.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID); m_log.WarnFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 62020ee621..d4f70a75ca 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -77,9 +77,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private List m_sceneList = new List(); - private IMessageTransferModule m_msgTransferModule = null; + private IMessageTransferModule m_msgTransferModule; + + private IGroupsMessagingModule m_groupsMessagingModule; - private IGroupsServicesConnector m_groupData = null; + private IGroupsServicesConnector m_groupData; // Configuration settings private bool m_groupsEnabled = false; @@ -185,10 +187,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_msgTransferModule == null) { m_groupsEnabled = false; - m_log.Warn("[GROUPS]: Could not get MessageTransferModule"); + m_log.Warn("[GROUPS]: Could not get IMessageTransferModule"); } } + if (m_groupsMessagingModule == null) + { + m_groupsMessagingModule = scene.RequestModuleInterface(); + + // No message transfer module, no notices, group invites, rejects, ejects, etc + if (m_groupsMessagingModule == null) + m_log.Warn("[GROUPS]: Could not get IGroupsMessagingModule"); + } + lock (m_sceneList) { m_sceneList.Add(scene); @@ -497,32 +508,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OnNewGroupNotice(GroupID, NoticeID); } - /*** We would insert call code here ***/ - // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) + if (m_debugEnabled) { - if (m_debugEnabled) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) { - UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); - if (targetUser != null) + if (m_debugEnabled) { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); - } - else - { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, member.AgentID, member.AcceptNotices); - } - } + UserAccount targetUser + = m_sceneList[0].UserAccountService.GetUserAccount( + remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); - if (member.AcceptNotices) - { - // Build notice IM - GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); - - msg.toAgentID = member.AgentID.Guid; - OutgoingInstantMessage(msg, member.AgentID); + if (targetUser != null) + { + m_log.DebugFormat( + "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", + NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); + } + else + { + m_log.DebugFormat( + "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", + NoticeID, member.AgentID, member.AcceptNotices); + } + } } } + + GridInstantMessage msg + = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); + + if (m_groupsMessagingModule != null) + m_groupsMessagingModule.SendMessageToGroup(msg, GroupID, gmd => gmd.AcceptNotices); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs index 08a93b8dea..71f10986f2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs @@ -41,6 +41,7 @@ using OpenSim.Framework.Communications; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.ClientStack.Linden; +using OpenSim.Region.CoreModules.Avatar.InstantMessage; using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups; @@ -127,15 +128,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests // TestHelpers.EnableLogging(); TestScene scene = new SceneHelpers().SetupScene(); - IConfigSource configSource = new IniConfigSource(); - IConfig config = configSource.AddConfig("Groups"); - config.Set("Enabled", true); - config.Set("Module", "GroupsModule"); - config.Set("DebugEnabled", true); + MessageTransferModule mtm = new MessageTransferModule(); GroupsModule gm = new GroupsModule(); + GroupsMessagingModule gmm = new GroupsMessagingModule(); - SceneHelpers.SetupSceneModules(scene, configSource, gm, new MockGroupsServicesConnector()); + IConfigSource configSource = new IniConfigSource(); + + { + IConfig config = configSource.AddConfig("Messaging"); + config.Set("MessageTransferModule", mtm.Name); + } + + { + IConfig config = configSource.AddConfig("Groups"); + config.Set("Enabled", true); + config.Set("Module", gm.Name); + config.Set("DebugEnabled", true); + config.Set("MessagingModule", gmm.Name); + config.Set("MessagingEnabled", true); + } + + SceneHelpers.SetupSceneModules(scene, configSource, new MockGroupsServicesConnector(), mtm, gm, gmm); UUID userId = TestHelpers.ParseTail(0x1); string subjectText = "newman";