From 134f86e8d5c414409631b25b8c6f0ee45fbd8631 Mon Sep 17 00:00:00 2001
From: David Walter Seikel
Date: Thu, 3 Nov 2016 21:44:39 +1000
Subject: Initial update to OpenSim 0.8.2.1 source code.
---
.../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 289 ++++++++++++++-------
.../Avatar/XmlRpcGroups/GroupsModule.cs | 272 ++++++++++++-------
.../SimianGroupsServicesConnectorModule.cs | 6 +-
.../Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs | 214 ++++++++++++++-
.../XmlRpcGroupsServicesConnectorModule.cs | 71 +++--
5 files changed, 621 insertions(+), 231 deletions(-)
(limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups')
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
index 2802e2f..e1b6abb 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
@@ -55,8 +55,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
private IGroupsServicesConnector m_groupData = null;
// Config Options
- private bool m_groupMessagingEnabled = false;
- private bool m_debugEnabled = true;
+ private bool m_groupMessagingEnabled;
+ private bool m_debugEnabled;
///
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
@@ -113,7 +113,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
if (m_messageOnlineAgentsOnly)
m_usersOnlineCache = new ExpiringCache();
- m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
+ m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled);
}
m_log.InfoFormat(
@@ -127,6 +127,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
return;
scene.RegisterModuleInterface(this);
+
+ scene.AddCommand(
+ "Debug",
+ this,
+ "debug groups messaging verbose",
+ "debug groups messaging verbose ",
+ "This setting turns on very verbose groups messaging debugging",
+ HandleDebugGroupsMessagingVerbose);
}
public void RegionLoaded(Scene scene)
@@ -218,6 +226,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
#endregion
+ private void HandleDebugGroupsMessagingVerbose(object modules, string[] args)
+ {
+ if (args.Length < 5)
+ {
+ MainConsole.Instance.Output("Usage: debug groups messaging verbose ");
+ return;
+ }
+
+ bool verbose = false;
+ if (!bool.TryParse(args[4], out verbose))
+ {
+ MainConsole.Instance.Output("Usage: debug groups messaging verbose ");
+ return;
+ }
+
+ m_debugEnabled = verbose;
+
+ MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
+ }
+
///
/// Not really needed, but does confirm that the group exists.
///
@@ -237,11 +265,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
return false;
}
}
-
+
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
{
- List groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID), groupID);
+ SendMessageToGroup(im, groupID, new UUID(im.fromAgentID), null);
+ }
+
+ public void SendMessageToGroup(
+ GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func sendCondition)
+ {
+ int requestStartTick = Environment.TickCount;
+
+ List groupMembers = m_groupData.GetGroupMembers(sendingAgentForGroupCalls, groupID);
int groupMembersCount = groupMembers.Count;
+ HashSet attemptDeliveryUuidSet = null;
if (m_messageOnlineAgentsOnly)
{
@@ -257,10 +294,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
}
- HashSet onlineAgentsUuidSet = new HashSet();
- Array.ForEach(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
+ attemptDeliveryUuidSet
+ = new HashSet(Array.ConvertAll(onlineAgents, pi => pi.UserID));
+
+ //Array.ForEach(onlineAgents, pi => attemptDeliveryUuidSet.Add(pi.UserID));
- groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
+ //groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
// if (m_debugEnabled)
// m_log.DebugFormat(
@@ -269,26 +308,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
}
else
{
+ attemptDeliveryUuidSet
+ = new HashSet(groupMembers.ConvertAll(gmd => gmd.AgentID.ToString()));
+
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))
+ 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;
}
// Copy Message
GridInstantMessage msg = new GridInstantMessage();
- msg.imSessionID = groupID.Guid;
+ msg.imSessionID = im.imSessionID;
msg.fromAgentName = im.fromAgentName;
msg.message = im.message;
msg.dialog = im.dialog;
@@ -304,26 +359,51 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
msg.toAgentID = member.AgentID.Guid;
- IClientAPI client = GetActiveClient(member.AgentID);
- if (client == null)
+ if (attemptDeliveryUuidSet.Contains(member.AgentID.ToString()))
{
- // 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) { });
+ 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
{
- // Deliver locally, directly
- if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
- ProcessMessageFromGroupSession(msg);
+ 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);
}
}
- // Temporary for assessing how long it still takes to send messages to large online groups.
- if (m_messageOnlineAgentsOnly)
+ 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);
+ "[GROUPS-MESSAGING]: Total SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3} ms",
+ groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick);
}
#region SimGridEventHandlers
@@ -348,7 +428,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,13 +441,35 @@ 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);
+ if (m_debugEnabled)
+ m_log.DebugFormat(
+ "[GROUPS-MESSAGING]: Session message from {0} going to agent {1}, sessionID {2}, type {3}",
+ msg.fromAgentName, msg.toAgentID, msg.imSessionID, (InstantMessageDialog)msg.dialog);
UUID AgentID = new UUID(msg.fromAgentID);
UUID GroupID = new UUID(msg.imSessionID);
@@ -392,74 +493,62 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// Add them to the session for now, and Invite them
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");
-
- // 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)
- );
-
- eq.ChatterBoxSessionAgentListUpdates(
- new UUID(GroupID)
- , new UUID(msg.fromAgentID)
- , new UUID(msg.toAgentID)
- , false //canVoiceChat
- , false //isModerator
- , false //text mute
- );
- }
+ 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 = 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
+ );
}
+
+ 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;;
}
}
#endregion
-
#region ClientEvents
private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
{
@@ -548,15 +637,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// Don't log any normal IMs (privacy!)
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: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False");
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", (InstantMessageDialog)im.dialog);
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID);
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName);
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID);
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message);
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline);
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID);
+ m_log.DebugFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
}
}
@@ -567,7 +656,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
///
private IClientAPI GetActiveClient(UUID agentID)
{
- if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID);
+ if (m_debugEnabled)
+ m_log.DebugFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID);
IClientAPI child = null;
@@ -579,12 +669,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
{
if (!sp.IsChildAgent)
{
- if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name);
+ if (m_debugEnabled)
+ m_log.DebugFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name);
+
return sp.ControllingClient;
}
else
{
- if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name);
+ if (m_debugEnabled)
+ m_log.DebugFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name);
+
child = sp.ControllingClient;
}
}
@@ -593,12 +687,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// If we didn't find a root, then just return whichever child we found, or null if none
if (child == null)
{
- if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID);
+ if (m_debugEnabled)
+ m_log.DebugFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID);
}
else
{
- if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name);
+ if (m_debugEnabled)
+ m_log.DebugFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name);
}
+
return child;
}
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 29f9591..1565da9 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -35,10 +35,10 @@ using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
-using OpenSim.Framework.Communications;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
+using System.Text;
using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
@@ -76,9 +76,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;
@@ -184,10 +186,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);
@@ -250,7 +261,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
- client.OnDirFindQuery += OnDirFindQuery;
client.OnRequestAvatarProperties += OnRequestAvatarProperties;
// Used for Notices and Group Invites/Accept/Reject
@@ -303,21 +313,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
}
*/
- void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
- {
- if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
- {
- if (m_debugEnabled)
- m_log.DebugFormat(
- "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
- System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
-
- // TODO: This currently ignores pretty much all the query flags including Mature and sort order
- remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray());
- }
-
- }
-
private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
{
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -361,7 +356,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
{
- if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+ if (m_debugEnabled)
+ m_log.DebugFormat(
+ "[GROUPS]: {0} called for {1}, message type {2}",
+ System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog);
// Group invitations
if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline))
@@ -437,81 +435,160 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
string Subject = im.message.Substring(0, im.message.IndexOf('|'));
string Message = im.message.Substring(Subject.Length + 1);
+ InventoryItemBase item = null;
+ bool hasAttachment = false;
+ UUID itemID = UUID.Zero; //Assignment to quiet compiler
+ UUID ownerID = UUID.Zero; //Assignment to quiet compiler
byte[] bucket;
- if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0))
- {
- bucket = new byte[19];
- bucket[0] = 0; //dunno
- bucket[1] = 0; //dunno
- GroupID.ToBytes(bucket, 2);
- bucket[18] = 0; //dunno
- }
- else
+ if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
{
string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
binBucket = binBucket.Remove(0, 14).Trim();
- if (m_debugEnabled)
+
+ OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
+ if (binBucketOSD is OSD)
{
- m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket);
+ OSDMap binBucketMap = (OSDMap)binBucketOSD;
+
+ itemID = binBucketMap["item_id"].AsUUID();
+ ownerID = binBucketMap["owner_id"].AsUUID();
+
+ //Attempt to get the details of the attached item.
+ //If sender doesn't own the attachment, the item
+ //variable will be set to null and attachment will
+ //not be included with the group notice.
+ Scene scene = (Scene)remoteClient.Scene;
+ item = new InventoryItemBase(itemID, ownerID);
+ item = scene.InventoryService.GetItem(item);
- OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
-
- foreach (string key in binBucketOSD.Keys)
+ if (item != null)
{
- if (binBucketOSD.ContainsKey(key))
- {
- m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString());
- }
+ //Got item details so include the attachment.
+ hasAttachment = true;
}
}
-
- // treat as if no attachment
+ else
+ {
+ m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType());
+ }
+ }
+
+ if (hasAttachment)
+ {
+ //Bucket contains information about attachment.
+ //
+ //Byte offset and description of bucket data:
+ //0: 1 byte indicating if attachment is present
+ //1: 1 byte indicating the type of attachment
+ //2: 16 bytes - Group UUID
+ //18: 16 bytes - UUID of the attachment owner
+ //34: 16 bytes - UUID of the attachment
+ //50: variable - Name of the attachment
+ //??: NUL byte to terminate the attachment name
+ byte[] name = Encoding.UTF8.GetBytes(item.Name);
+ bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name
+ bucket[0] = 1; //Has attachment flag
+ bucket[1] = (byte)item.InvType; //Type of Attachment
+ GroupID.ToBytes(bucket, 2);
+ ownerID.ToBytes(bucket, 18);
+ itemID.ToBytes(bucket, 34);
+ name.CopyTo(bucket, 50);
+ }
+ else
+ {
bucket = new byte[19];
- bucket[0] = 0; //dunno
- bucket[1] = 0; //dunno
+ bucket[0] = 0; //Has attachment flag
+ bucket[1] = 0; //Type of attachment
GroupID.ToBytes(bucket, 2);
- bucket[18] = 0; //dunno
+ bucket[18] = 0; //NUL terminate name of attachment
}
-
m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
if (OnNewGroupNotice != null)
{
OnNewGroupNotice(GroupID, NoticeID);
}
- // 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 (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);
+ }
}
}
+ }
- if (member.AcceptNotices)
- {
- // Build notice IIM
- GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
+ GridInstantMessage msg
+ = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
- msg.toAgentID = member.AgentID.Guid;
- OutgoingInstantMessage(msg, member.AgentID);
- }
+ if (m_groupsMessagingModule != null)
+ m_groupsMessagingModule.SendMessageToGroup(
+ msg, GroupID, remoteClient.AgentId, gmd => gmd.AcceptNotices);
+ }
+ }
+
+ if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted)
+ {
+ //Is bucket large enough to hold UUID of the attachment?
+ if (im.binaryBucket.Length < 16)
+ return;
+
+ UUID noticeID = new UUID(im.imSessionID);
+
+ if (m_debugEnabled)
+ m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId);
+
+ GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID);
+ if (notice != null)
+ {
+ UUID giver = new UUID(notice.BinaryBucket, 18);
+ UUID attachmentUUID = new UUID(notice.BinaryBucket, 34);
+
+ if (m_debugEnabled)
+ m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
+
+ string message;
+ InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
+ giver, attachmentUUID, out message);
+
+ if (itemCopy == null)
+ {
+ remoteClient.SendAgentAlertMessage(message, false);
+ return;
}
+
+ remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
+ }
+ else
+ {
+ if (m_debugEnabled)
+ m_log.DebugFormat(
+ "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
+ noticeID, remoteClient.AgentId);
}
}
-
+
// Interop, received special 210 code for ejecting a group member
// this only works within the comms servers domain, and won't work hypergrid
- // TODO:FIXME: Use a presense server of some kind to find out where the
+ // TODO:FIXME: Use a presence server of some kind to find out where the
// client actually is, and try contacting that region directly to notify them,
// or provide the notification via xmlrpc update queue
if ((im.dialog == 210))
@@ -764,7 +841,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group.");
return UUID.Zero;
}
- money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation");
+ money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate);
}
UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient));
@@ -889,26 +966,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
if (data != null)
{
- GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null);
-
- GridInstantMessage msg = new GridInstantMessage();
- msg.imSessionID = UUID.Zero.Guid;
- msg.fromAgentID = data.GroupID.Guid;
- msg.toAgentID = GetRequestingAgentID(remoteClient).Guid;
- msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
- msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName;
- msg.message = data.noticeData.Subject + "|" + data.Message;
- msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested;
- msg.fromGroup = true;
- msg.offline = (byte)0;
- msg.ParentEstateID = 0;
- msg.Position = Vector3.Zero;
- msg.RegionID = UUID.Zero.Guid;
- msg.binaryBucket = data.BinaryBucket;
+ GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
}
-
}
public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog)
@@ -916,10 +977,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
GridInstantMessage msg = new GridInstantMessage();
- msg.imSessionID = UUID.Zero.Guid;
+ byte[] bucket;
+
+ msg.imSessionID = groupNoticeID.Guid;
msg.toAgentID = agentID.Guid;
msg.dialog = dialog;
- // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice;
msg.fromGroup = true;
msg.offline = (byte)0;
msg.ParentEstateID = 0;
@@ -933,13 +995,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
msg.timestamp = info.noticeData.Timestamp;
msg.fromAgentName = info.noticeData.FromName;
msg.message = info.noticeData.Subject + "|" + info.Message;
- msg.binaryBucket = info.BinaryBucket;
+
+ if (info.BinaryBucket[0] > 0)
+ {
+ //32 is due to not needing space for two of the UUIDs.
+ //(Don't need UUID of attachment or its owner in IM)
+ //50 offset gets us to start of attachment name.
+ //We are skipping the attachment flag, type, and
+ //the three UUID fields at the start of the bucket.
+ bucket = new byte[info.BinaryBucket.Length-32];
+ bucket[0] = 1; //Has attachment
+ bucket[1] = info.BinaryBucket[1];
+ Array.Copy(info.BinaryBucket, 50,
+ bucket, 18, info.BinaryBucket.Length-50);
+ }
+ else
+ {
+ bucket = new byte[19];
+ bucket[0] = 0; //No attachment
+ bucket[1] = 0; //Attachment type
+ bucket[18] = 0; //NUL terminate name
+ }
+
+ info.GroupID.ToBytes(bucket, 2);
+ msg.binaryBucket = bucket;
}
else
{
- if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID);
+ if (m_debugEnabled)
+ m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID);
+
msg.fromAgentID = UUID.Zero.Guid;
- msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ;
+ msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
msg.fromAgentName = string.Empty;
msg.message = string.Empty;
msg.binaryBucket = new byte[0];
@@ -1063,7 +1150,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// Message to ejector
// Interop, received special 210 code for ejecting a group member
// this only works within the comms servers domain, and won't work hypergrid
- // TODO:FIXME: Use a presense server of some kind to find out where the
+ // TODO:FIXME: Use a presence server of some kind to find out where the
// client actually is, and try contacting that region directly to notify them,
// or provide the notification via xmlrpc update queue
@@ -1178,6 +1265,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
}
}
+ public List FindGroups(IClientAPI remoteClient, string query)
+ {
+ return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query);
+ }
+
+
#endregion
#region Client/Update Tools
@@ -1222,7 +1315,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
AgentData.Add(AgentDataMap);
-
OSDArray GroupData = new OSDArray(data.Length);
OSDArray NewGroupData = new OSDArray(data.Length);
@@ -1288,7 +1380,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
presence.Grouptitle = Title;
if (! presence.IsChildAgent)
- presence.SendAvatarDataToAllAgents();
+ presence.SendAvatarDataToAllClients();
}
}
}
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
index 7bae8f7..1cb4747 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
@@ -42,7 +42,6 @@ using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
-using OpenSim.Framework.Communications;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Services.Interfaces;
@@ -212,8 +211,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name);
m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty);
- if ((m_groupsServerURI == null) ||
- (m_groupsServerURI == string.Empty))
+ if (string.IsNullOrEmpty(m_groupsServerURI))
{
m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]");
m_connectorEnabled = false;
@@ -438,7 +436,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
return null;
}
}
- else if ((groupName != null) && (groupName != string.Empty))
+ else if (!string.IsNullOrEmpty(groupName))
{
if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap))
{
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
index c1bdacb..9a42bac 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
@@ -26,15 +26,25 @@
*/
using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Net;
using System.Reflection;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
+using OpenMetaverse.Messages.Linden;
+using OpenMetaverse.Packets;
+using OpenMetaverse.StructuredData;
using OpenSim.Framework;
-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;
using OpenSim.Tests.Common;
-using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
{
@@ -44,11 +54,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
[TestFixture]
public class GroupsModuleTests : OpenSimTestCase
{
+ [SetUp]
+ public override void SetUp()
+ {
+ base.SetUp();
+
+ uint port = 9999;
+ uint sslPort = 9998;
+
+ // This is an unfortunate bit of clean up we have to do because MainServer manages things through static
+ // variables and the VM is not restarted between tests.
+ MainServer.RemoveHttpServer(port);
+
+ BaseHttpServer server = new BaseHttpServer(port, false, sslPort, "");
+ MainServer.AddHttpServer(server);
+ MainServer.Instance = server;
+ }
+
[Test]
- public void TestBasic()
+ public void TestSendAgentGroupDataUpdate()
{
TestHelpers.InMethod();
-// log4net.Config.XmlConfigurator.Configure();
+// TestHelpers.EnableLogging();
TestScene scene = new SceneHelpers().SetupScene();
IConfigSource configSource = new IniConfigSource();
@@ -56,8 +83,185 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
config.Set("Enabled", true);
config.Set("Module", "GroupsModule");
config.Set("DebugEnabled", true);
+
+ GroupsModule gm = new GroupsModule();
+ EventQueueGetModule eqgm = new EventQueueGetModule();
+
+ // We need a capabilities module active so that adding the scene presence creates an event queue in the
+ // EventQueueGetModule
SceneHelpers.SetupSceneModules(
- scene, configSource, new object[] { new MockGroupsServicesConnector() });
+ scene, configSource, gm, new MockGroupsServicesConnector(), new CapabilitiesModule(), eqgm);
+
+ ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseStem("1"));
+
+ gm.SendAgentGroupDataUpdate(sp.ControllingClient);
+
+ Hashtable eventsResponse = eqgm.GetEvents(UUID.Zero, sp.UUID);
+
+ Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK));
+
+// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]);
+
+ OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]);
+ OSDArray eventsOsd = (OSDArray)rawOsd["events"];
+
+ bool foundUpdate = false;
+ foreach (OSD osd in eventsOsd)
+ {
+ OSDMap eventOsd = (OSDMap)osd;
+
+ if (eventOsd["message"] == "AgentGroupDataUpdate")
+ foundUpdate = true;
+ }
+
+ Assert.That(foundUpdate, Is.True, "Did not find AgentGroupDataUpdate in response");
+
+ // TODO: More checking of more actual event data.
+ }
+
+ [Test]
+ public void TestSendGroupNotice()
+ {
+ TestHelpers.InMethod();
+// TestHelpers.EnableLogging();
+
+ TestScene scene = new SceneHelpers().SetupScene();
+
+ MessageTransferModule mtm = new MessageTransferModule();
+ GroupsModule gm = new GroupsModule();
+ GroupsMessagingModule gmm = new GroupsMessagingModule();
+ MockGroupsServicesConnector mgsc = 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, mgsc, mtm, gm, gmm);
+
+ UUID userId = TestHelpers.ParseTail(0x1);
+ string subjectText = "newman";
+ string messageText = "Hello";
+ string combinedSubjectMessage = string.Format("{0}|{1}", subjectText, messageText);
+
+ ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
+ TestClient tc = (TestClient)sp.ControllingClient;
+
+ UUID groupID = gm.CreateGroup(tc, "group1", null, true, UUID.Zero, 0, true, true, true);
+ gm.JoinGroupRequest(tc, groupID);
+
+ // Create a second user who doesn't want to receive notices
+ ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x2));
+ TestClient tc2 = (TestClient)sp2.ControllingClient;
+ gm.JoinGroupRequest(tc2, groupID);
+ gm.SetGroupAcceptNotices(tc2, groupID, false, true);
+
+ List spReceivedMessages = new List();
+ tc.OnReceivedInstantMessage += im => spReceivedMessages.Add(im);
+
+ List sp2ReceivedMessages = new List();
+ tc2.OnReceivedInstantMessage += im => sp2ReceivedMessages.Add(im);
+
+ GridInstantMessage noticeIm = new GridInstantMessage();
+ noticeIm.fromAgentID = userId.Guid;
+ noticeIm.toAgentID = groupID.Guid;
+ noticeIm.message = combinedSubjectMessage;
+ noticeIm.dialog = (byte)InstantMessageDialog.GroupNotice;
+
+ tc.HandleImprovedInstantMessage(noticeIm);
+
+ Assert.That(spReceivedMessages.Count, Is.EqualTo(1));
+ Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage));
+
+ List notices = mgsc.GetGroupNotices(UUID.Zero, groupID);
+ Assert.AreEqual(1, notices.Count);
+
+ // OpenSimulator (possibly also SL) transport the notice ID as the session ID!
+ Assert.AreEqual(notices[0].NoticeID.Guid, spReceivedMessages[0].imSessionID);
+
+ Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0));
+ }
+
+ ///
+ /// Run test with the MessageOnlineUsersOnly flag set.
+ ///
+ [Test]
+ public void TestSendGroupNoticeOnlineOnly()
+ {
+ TestHelpers.InMethod();
+ // TestHelpers.EnableLogging();
+
+ TestScene scene = new SceneHelpers().SetupScene();
+
+ MessageTransferModule mtm = new MessageTransferModule();
+ GroupsModule gm = new GroupsModule();
+ GroupsMessagingModule gmm = new GroupsMessagingModule();
+
+ 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);
+ config.Set("MessageOnlineUsersOnly", true);
+ }
+
+ SceneHelpers.SetupSceneModules(scene, configSource, new MockGroupsServicesConnector(), mtm, gm, gmm);
+
+ UUID userId = TestHelpers.ParseTail(0x1);
+ string subjectText = "newman";
+ string messageText = "Hello";
+ string combinedSubjectMessage = string.Format("{0}|{1}", subjectText, messageText);
+
+ ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
+ TestClient tc = (TestClient)sp.ControllingClient;
+
+ UUID groupID = gm.CreateGroup(tc, "group1", null, true, UUID.Zero, 0, true, true, true);
+ gm.JoinGroupRequest(tc, groupID);
+
+ // Create a second user who doesn't want to receive notices
+ ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x2));
+ TestClient tc2 = (TestClient)sp2.ControllingClient;
+ gm.JoinGroupRequest(tc2, groupID);
+ gm.SetGroupAcceptNotices(tc2, groupID, false, true);
+
+ List spReceivedMessages = new List();
+ tc.OnReceivedInstantMessage += im => spReceivedMessages.Add(im);
+
+ List sp2ReceivedMessages = new List();
+ tc2.OnReceivedInstantMessage += im => sp2ReceivedMessages.Add(im);
+
+ GridInstantMessage noticeIm = new GridInstantMessage();
+ noticeIm.fromAgentID = userId.Guid;
+ noticeIm.toAgentID = groupID.Guid;
+ noticeIm.message = combinedSubjectMessage;
+ noticeIm.dialog = (byte)InstantMessageDialog.GroupNotice;
+
+ tc.HandleImprovedInstantMessage(noticeIm);
+
+ Assert.That(spReceivedMessages.Count, Is.EqualTo(1));
+ Assert.That(spReceivedMessages[0].message, Is.EqualTo(combinedSubjectMessage));
+
+ Assert.That(sp2ReceivedMessages.Count, Is.EqualTo(0));
}
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
index 1101851..20555e4 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
@@ -41,7 +41,6 @@ using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
-using OpenSim.Framework.Communications;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Services.Interfaces;
@@ -168,8 +167,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name);
m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty);
- if ((m_groupsServerURI == null) ||
- (m_groupsServerURI == string.Empty))
+ if (string.IsNullOrEmpty(m_groupsServerURI))
{
m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]");
m_connectorEnabled = false;
@@ -354,7 +352,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
{
param["GroupID"] = GroupID.ToString();
}
- if ((GroupName != null) && (GroupName != string.Empty))
+ if (!string.IsNullOrEmpty(GroupName))
{
param["Name"] = GroupName.ToString();
}
@@ -1013,7 +1011,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
Hashtable respData = (Hashtable)resp.Value;
if (respData.Contains("error") && !respData.Contains("succeed"))
{
- LogRespDataToConsoleError(respData);
+ LogRespDataToConsoleError(requestingAgentID, function, param, respData);
}
return respData;
@@ -1041,20 +1039,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
return error;
}
- private void LogRespDataToConsoleError(Hashtable respData)
+ private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData)
{
- m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:");
-
- foreach (string key in respData.Keys)
- {
- m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key);
-
- string[] lines = respData[key].ToString().Split(new char[] { '\n' });
- foreach (string line in lines)
- {
- m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line);
- }
- }
+ m_log.ErrorFormat(
+ "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}",
+ function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData));
}
///
@@ -1146,28 +1135,38 @@ namespace Nwc.XmlRpc
request.AllowWriteStreamBuffering = true;
request.KeepAlive = !_disableKeepAlive;
- Stream stream = request.GetRequestStream();
- XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII);
- _serializer.Serialize(xml, this);
- xml.Flush();
- xml.Close();
-
- HttpWebResponse response = (HttpWebResponse)request.GetResponse();
- StreamReader input = new StreamReader(response.GetResponseStream());
-
- string inputXml = input.ReadToEnd();
- XmlRpcResponse resp;
- try
+ using (Stream stream = request.GetRequestStream())
{
- resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml);
+ using (XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII))
+ {
+ _serializer.Serialize(xml, this);
+ xml.Flush();
+ }
}
- catch (Exception e)
+
+ XmlRpcResponse resp;
+
+ using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
- RequestResponse = inputXml;
- throw e;
+ using (Stream s = response.GetResponseStream())
+ {
+ using (StreamReader input = new StreamReader(s))
+ {
+ string inputXml = input.ReadToEnd();
+
+ try
+ {
+ resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml);
+ }
+ catch (Exception e)
+ {
+ RequestResponse = inputXml;
+ throw e;
+ }
+ }
+ }
}
- input.Close();
- response.Close();
+
return resp;
}
}
--
cgit v1.1