aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs220
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs18
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs67
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs226
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs65
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs5
9 files changed, 491 insertions, 123 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs
index 5a37fad..b5d9fda 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs
@@ -461,7 +461,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
461 461
462 string result = instr; 462 string result = instr;
463 463
464 if (result == null || result.Length == 0) 464 if (string.IsNullOrEmpty(result))
465 return result; 465 return result;
466 466
467 // Repeatedly scan the string until all possible 467 // Repeatedly scan the string until all possible
diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
index 018357a..c48e585 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
@@ -375,11 +375,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
375 scene.GetRootAgentCount(), scene.RegionInfo.RegionName, 375 scene.GetRootAgentCount(), scene.RegionInfo.RegionName,
376 scene.RegionInfo.RegionID, 376 scene.RegionInfo.RegionID,
377 DateTime.UtcNow.ToString("s"))); 377 DateTime.UtcNow.ToString("s")));
378
378 scene.ForEachRootScenePresence(delegate(ScenePresence sp) 379 scene.ForEachRootScenePresence(delegate(ScenePresence sp)
379 { 380 {
380 list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID)); 381 list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID));
381 list.Append("</avatars>");
382 }); 382 });
383
384 list.Append("</avatars>");
383 string payload = list.ToString(); 385 string payload = list.ToString();
384 386
385 // post via REST to broker 387 // post via REST to broker
diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs
new file mode 100644
index 0000000..5a6b284
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs
@@ -0,0 +1,220 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33using System.Text.RegularExpressions;
34using log4net;
35using Mono.Addins;
36using NDesk.Options;
37using Nini.Config;
38using OpenMetaverse;
39using OpenSim.Framework;
40using OpenSim.Framework.Console;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43
44namespace OpenSim.Region.OptionalModules.Avatar.SitStand
45{
46 /// <summary>
47 /// A module that just holds commands for changing avatar sitting and standing states.
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AnimationsCommandModule")]
50 public class SitStandCommandModule : INonSharedRegionModule
51 {
52// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private Scene m_scene;
55
56 public string Name { get { return "SitStand Command Module"; } }
57
58 public Type ReplaceableInterface { get { return null; } }
59
60 public void Initialise(IConfigSource source)
61 {
62// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE");
63 }
64
65 public void PostInitialise()
66 {
67// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE");
68 }
69
70 public void Close()
71 {
72// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE");
73 }
74
75 public void AddRegion(Scene scene)
76 {
77// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
78 }
79
80 public void RemoveRegion(Scene scene)
81 {
82// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
83 }
84
85 public void RegionLoaded(Scene scene)
86 {
87// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
88
89 m_scene = scene;
90
91 scene.AddCommand(
92 "Users", this, "sit user name",
93 "sit user name [--regex] <first-name> <last-name>",
94 "Sit the named user on an unoccupied object with a sit target.",
95 "If there are no such objects then nothing happens.\n"
96 + "If --regex is specified then the names are treated as regular expressions.",
97 HandleSitUserNameCommand);
98
99 scene.AddCommand(
100 "Users", this, "stand user name",
101 "stand user name [--regex] <first-name> <last-name>",
102 "Stand the named user.",
103 "If --regex is specified then the names are treated as regular expressions.",
104 HandleStandUserNameCommand);
105 }
106
107 private void HandleSitUserNameCommand(string module, string[] cmd)
108 {
109 if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null)
110 return;
111
112 if (cmd.Length < 5)
113 {
114 MainConsole.Instance.Output("Usage: sit user name [--regex] <first-name> <last-name>");
115 return;
116 }
117
118 List<ScenePresence> scenePresences = GetScenePresences(cmd);
119
120 foreach (ScenePresence sp in scenePresences)
121 {
122 if (sp.SitGround || sp.IsSatOnObject)
123 continue;
124
125 SceneObjectPart sitPart = null;
126 List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups();
127
128 foreach (SceneObjectGroup sceneObject in sceneObjects)
129 {
130 if (sceneObject.IsAttachment)
131 continue;
132
133 foreach (SceneObjectPart part in sceneObject.Parts)
134 {
135 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
136 {
137 sitPart = part;
138 break;
139 }
140 }
141 }
142
143 if (sitPart != null)
144 {
145 MainConsole.Instance.OutputFormat(
146 "Sitting {0} on {1} {2} in {3}",
147 sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name);
148
149 sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero);
150 sp.HandleAgentSit(sp.ControllingClient, sp.UUID);
151 }
152 else
153 {
154 MainConsole.Instance.OutputFormat(
155 "Could not find any unoccupied set seat on which to sit {0} in {1}. Aborting",
156 sp.Name, m_scene.Name);
157
158 break;
159 }
160 }
161 }
162
163 private void HandleStandUserNameCommand(string module, string[] cmd)
164 {
165 if (MainConsole.Instance.ConsoleScene != m_scene && MainConsole.Instance.ConsoleScene != null)
166 return;
167
168 if (cmd.Length < 5)
169 {
170 MainConsole.Instance.Output("Usage: stand user name [--regex] <first-name> <last-name>");
171 return;
172 }
173
174 List<ScenePresence> scenePresences = GetScenePresences(cmd);
175
176 foreach (ScenePresence sp in scenePresences)
177 {
178 if (sp.SitGround || sp.IsSatOnObject)
179 {
180 MainConsole.Instance.OutputFormat("Standing {0} in {1}", sp.Name, m_scene.Name);
181 sp.StandUp();
182 }
183 }
184 }
185
186 private List<ScenePresence> GetScenePresences(string[] cmdParams)
187 {
188 bool useRegex = false;
189 OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
190
191 List<string> mainParams = options.Parse(cmdParams);
192
193 string firstName = mainParams[3];
194 string lastName = mainParams[4];
195
196 List<ScenePresence> scenePresencesMatched = new List<ScenePresence>();
197
198 if (useRegex)
199 {
200 Regex nameRegex = new Regex(string.Format("{0} {1}", firstName, lastName));
201 List<ScenePresence> scenePresences = m_scene.GetScenePresences();
202
203 foreach (ScenePresence sp in scenePresences)
204 {
205 if (!sp.IsChildAgent && nameRegex.IsMatch(sp.Name))
206 scenePresencesMatched.Add(sp);
207 }
208 }
209 else
210 {
211 ScenePresence sp = m_scene.GetScenePresence(firstName, lastName);
212
213 if (sp != null && !sp.IsChildAgent)
214 scenePresencesMatched.Add(sp);
215 }
216
217 return scenePresencesMatched;
218 }
219 }
220} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 0cec959..2b33084 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -326,15 +326,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
326 "ParcelVoiceInfoRequest", 326 "ParcelVoiceInfoRequest",
327 agentID.ToString())); 327 agentID.ToString()));
328 328
329 caps.RegisterHandler( 329 //caps.RegisterHandler(
330 "ChatSessionRequest", 330 // "ChatSessionRequest",
331 new RestStreamHandler( 331 // new RestStreamHandler(
332 "POST", 332 // "POST",
333 capsBase + m_chatSessionRequestPath, 333 // capsBase + m_chatSessionRequestPath,
334 (request, path, param, httpRequest, httpResponse) 334 // (request, path, param, httpRequest, httpResponse)
335 => ChatSessionRequest(scene, request, path, param, agentID, caps), 335 // => ChatSessionRequest(scene, request, path, param, agentID, caps),
336 "ChatSessionRequest", 336 // "ChatSessionRequest",
337 agentID.ToString())); 337 // agentID.ToString()));
338 } 338 }
339 339
340 /// <summary> 340 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
index 9e6cc1a..38ba54d 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -117,6 +117,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
117 117
118 private IConfig m_config; 118 private IConfig m_config;
119 119
120 private object m_Lock;
121
120 public void Initialise(IConfigSource config) 122 public void Initialise(IConfigSource config)
121 { 123 {
122 124
@@ -128,6 +130,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
128 if (!m_config.GetBoolean("enabled", false)) 130 if (!m_config.GetBoolean("enabled", false))
129 return; 131 return;
130 132
133 m_Lock = new object();
134
131 try 135 try
132 { 136 {
133 // retrieve configuration variables 137 // retrieve configuration variables
@@ -429,15 +433,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
429 "ParcelVoiceInfoRequest", 433 "ParcelVoiceInfoRequest",
430 agentID.ToString())); 434 agentID.ToString()));
431 435
432 caps.RegisterHandler( 436 //caps.RegisterHandler(
433 "ChatSessionRequest", 437 // "ChatSessionRequest",
434 new RestStreamHandler( 438 // new RestStreamHandler(
435 "POST", 439 // "POST",
436 capsBase + m_chatSessionRequestPath, 440 // capsBase + m_chatSessionRequestPath,
437 (request, path, param, httpRequest, httpResponse) 441 // (request, path, param, httpRequest, httpResponse)
438 => ChatSessionRequest(scene, request, path, param, agentID, caps), 442 // => ChatSessionRequest(scene, request, path, param, agentID, caps),
439 "ChatSessionRequest", 443 // "ChatSessionRequest",
440 agentID.ToString())); 444 // agentID.ToString()));
441 } 445 }
442 446
443 /// <summary> 447 /// <summary>
@@ -823,11 +827,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
823 { 827 {
824 string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", channelId, m_authToken); 828 string requrl = String.Format(m_vivoxChannelPath, m_vivoxServer, "create", channelId, m_authToken);
825 829
826 if (parent != null && parent != String.Empty) 830 if (!string.IsNullOrEmpty(parent))
827 { 831 {
828 requrl = String.Format("{0}&chan_parent={1}", requrl, parent); 832 requrl = String.Format("{0}&chan_parent={1}", requrl, parent);
829 } 833 }
830 if (description != null && description != String.Empty) 834 if (!string.IsNullOrEmpty(description))
831 { 835 {
832 requrl = String.Format("{0}&chan_desc={1}", requrl, description); 836 requrl = String.Format("{0}&chan_desc={1}", requrl, description);
833 } 837 }
@@ -837,7 +841,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
837 requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff); 841 requrl = String.Format("{0}&chan_roll_off={1}", requrl, m_vivoxChannelRollOff);
838 requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel); 842 requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel);
839 requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange); 843 requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange);
840 requrl = String.Format("{0}&chan_ckamping_distance={1}", requrl, m_vivoxChannelClampingDistance); 844 requrl = String.Format("{0}&chan_clamping_distance={1}", requrl, m_vivoxChannelClampingDistance);
841 845
842 XmlElement resp = VivoxCall(requrl, true); 846 XmlElement resp = VivoxCall(requrl, true);
843 if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri)) 847 if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri))
@@ -863,7 +867,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
863 // requrl = String.Format("{0}&chan_parent={1}", requrl, parent); 867 // requrl = String.Format("{0}&chan_parent={1}", requrl, parent);
864 // } 868 // }
865 869
866 if (description != null && description != String.Empty) 870 if (!string.IsNullOrEmpty(description))
867 { 871 {
868 requrl = String.Format("{0}&chan_desc={1}", requrl, description); 872 requrl = String.Format("{0}&chan_desc={1}", requrl, description);
869 } 873 }
@@ -1049,7 +1053,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1049 private XmlElement VivoxDeleteChannel(string parent, string channelid) 1053 private XmlElement VivoxDeleteChannel(string parent, string channelid)
1050 { 1054 {
1051 string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken); 1055 string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken);
1052 if (parent != null && parent != String.Empty) 1056 if (!string.IsNullOrEmpty(parent))
1053 { 1057 {
1054 requrl = String.Format("{0}&chan_parent={1}", requrl, parent); 1058 requrl = String.Format("{0}&chan_parent={1}", requrl, parent);
1055 } 1059 }
@@ -1118,25 +1122,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1118 1122
1119 doc = new XmlDocument(); 1123 doc = new XmlDocument();
1120 1124
1121 try 1125 // Let's serialize all calls to Vivox. Most of these are driven by
1126 // the clients (CAPs), when the user arrives at the region. We don't
1127 // want to issue many simultaneous http requests to Vivox, because mono
1128 // doesn't like that
1129 lock (m_Lock)
1122 { 1130 {
1123 // Otherwise prepare the request 1131 try
1124// m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); 1132 {
1133 // Otherwise prepare the request
1134 //m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl);
1125 1135
1126 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); 1136 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl);
1127 1137
1128 // We are sending just parameters, no content 1138 // We are sending just parameters, no content
1129 req.ContentLength = 0; 1139 req.ContentLength = 0;
1130 1140
1131 // Send request and retrieve the response 1141 // Send request and retrieve the response
1132 using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) 1142 using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse())
1133 using (Stream s = rsp.GetResponseStream()) 1143 using (Stream s = rsp.GetResponseStream())
1134 using (XmlTextReader rdr = new XmlTextReader(s)) 1144 using (XmlTextReader rdr = new XmlTextReader(s))
1135 doc.Load(rdr); 1145 doc.Load(rdr);
1136 } 1146 }
1137 catch (Exception e) 1147 catch (Exception e)
1138 { 1148 {
1139 m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message); 1149 m_log.ErrorFormat("[VivoxVoice] Error in admin call : {0}", e.Message);
1150 }
1140 } 1151 }
1141 1152
1142 // If we're debugging server responses, dump the whole 1153 // If we're debugging server responses, dump the whole
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index d0a5989..2764465 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -39,6 +39,7 @@ using OpenSim.Framework.Communications;
39using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
42using System.Text;
42using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; 43using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
43 44
44namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups 45namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
@@ -194,6 +195,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
194 } 195 }
195 196
196 scene.EventManager.OnNewClient += OnNewClient; 197 scene.EventManager.OnNewClient += OnNewClient;
198 scene.EventManager.OnMakeRootAgent += OnMakeRoot;
199 scene.EventManager.OnMakeChildAgent += OnMakeChild;
197 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 200 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
198 // The InstantMessageModule itself doesn't do this, 201 // The InstantMessageModule itself doesn't do this,
199 // so lets see if things explode if we don't do it 202 // so lets see if things explode if we don't do it
@@ -244,20 +247,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
244 #endregion 247 #endregion
245 248
246 #region EventHandlers 249 #region EventHandlers
250
251 private void OnMakeRoot(ScenePresence sp)
252 {
253 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
254
255 sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
256 // Used for Notices and Group Invites/Accept/Reject
257 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
258 // Send client their groups information.
259// SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
260 // only send data viwer will ask rest later
261 OnAgentDataUpdateRequest(sp.ControllingClient, sp.UUID, sp.UUID);
262 }
263
264 private void OnMakeChild(ScenePresence sp)
265 {
266 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
267
268 sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
269 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
270 }
271
247 private void OnNewClient(IClientAPI client) 272 private void OnNewClient(IClientAPI client)
248 { 273 {
249 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 274 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
250 275
251 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
252 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 276 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
253 client.OnDirFindQuery += OnDirFindQuery;
254 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 277 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
255
256 // Used for Notices and Group Invites/Accept/Reject
257 client.OnInstantMessage += OnInstantMessage;
258
259 // Send client their groups information.
260 SendAgentGroupDataUpdate(client, client.AgentId);
261 } 278 }
262 279
263 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 280 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
@@ -303,21 +320,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
303 } 320 }
304 */ 321 */
305 322
306 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
307 {
308 if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
309 {
310 if (m_debugEnabled)
311 m_log.DebugFormat(
312 "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
313 System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
314
315 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
316 remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray());
317 }
318
319 }
320
321 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) 323 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
322 { 324 {
323 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 325 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -437,44 +439,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
437 string Subject = im.message.Substring(0, im.message.IndexOf('|')); 439 string Subject = im.message.Substring(0, im.message.IndexOf('|'));
438 string Message = im.message.Substring(Subject.Length + 1); 440 string Message = im.message.Substring(Subject.Length + 1);
439 441
442 InventoryItemBase item = null;
443 bool hasAttachment = false;
444 UUID itemID = UUID.Zero; //Assignment to quiet compiler
445 UUID ownerID = UUID.Zero; //Assignment to quiet compiler
440 byte[] bucket; 446 byte[] bucket;
441 447
442 if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) 448 if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
443 {
444 bucket = new byte[19];
445 bucket[0] = 0; //dunno
446 bucket[1] = 0; //dunno
447 GroupID.ToBytes(bucket, 2);
448 bucket[18] = 0; //dunno
449 }
450 else
451 { 449 {
452 string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); 450 string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
453 binBucket = binBucket.Remove(0, 14).Trim(); 451 binBucket = binBucket.Remove(0, 14).Trim();
454 if (m_debugEnabled) 452
453 OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
454 if (binBucketOSD is OSD)
455 { 455 {
456 m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); 456 OSDMap binBucketMap = (OSDMap)binBucketOSD;
457
458 itemID = binBucketMap["item_id"].AsUUID();
459 ownerID = binBucketMap["owner_id"].AsUUID();
457 460
458 OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); 461 //Attempt to get the details of the attached item.
459 462 //If sender doesn't own the attachment, the item
460 foreach (string key in binBucketOSD.Keys) 463 //variable will be set to null and attachment will
464 //not be included with the group notice.
465 Scene scene = (Scene)remoteClient.Scene;
466 item = new InventoryItemBase(itemID, ownerID);
467 item = scene.InventoryService.GetItem(item);
468
469 if (item != null)
461 { 470 {
462 if (binBucketOSD.ContainsKey(key)) 471 //Got item details so include the attachment.
463 { 472 hasAttachment = true;
464 m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString());
465 }
466 } 473 }
467 } 474 }
468 475 else
469 // treat as if no attachment 476 {
477 m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType());
478 }
479 }
480
481 if (hasAttachment)
482 {
483 //Bucket contains information about attachment.
484 //
485 //Byte offset and description of bucket data:
486 //0: 1 byte indicating if attachment is present
487 //1: 1 byte indicating the type of attachment
488 //2: 16 bytes - Group UUID
489 //18: 16 bytes - UUID of the attachment owner
490 //34: 16 bytes - UUID of the attachment
491 //50: variable - Name of the attachment
492 //??: NUL byte to terminate the attachment name
493 byte[] name = Encoding.UTF8.GetBytes(item.Name);
494 bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name
495 bucket[0] = 1; //Has attachment flag
496 bucket[1] = (byte)item.InvType; //Type of Attachment
497 GroupID.ToBytes(bucket, 2);
498 ownerID.ToBytes(bucket, 18);
499 itemID.ToBytes(bucket, 34);
500 name.CopyTo(bucket, 50);
501 }
502 else
503 {
470 bucket = new byte[19]; 504 bucket = new byte[19];
471 bucket[0] = 0; //dunno 505 bucket[0] = 0; //Has attachment flag
472 bucket[1] = 0; //dunno 506 bucket[1] = 0; //Type of attachment
473 GroupID.ToBytes(bucket, 2); 507 GroupID.ToBytes(bucket, 2);
474 bucket[18] = 0; //dunno 508 bucket[18] = 0; //NUL terminate name of attachment
475 } 509 }
476 510
477
478 m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); 511 m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
479 if (OnNewGroupNotice != null) 512 if (OnNewGroupNotice != null)
480 { 513 {
@@ -499,7 +532,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
499 532
500 if (member.AcceptNotices) 533 if (member.AcceptNotices)
501 { 534 {
502 // Build notice IIM 535 // Build notice IM
503 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); 536 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
504 537
505 msg.toAgentID = member.AgentID.Guid; 538 msg.toAgentID = member.AgentID.Guid;
@@ -508,10 +541,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
508 } 541 }
509 } 542 }
510 } 543 }
511 544
545 if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted)
546 {
547 //Is bucket large enough to hold UUID of the attachment?
548 if (im.binaryBucket.Length < 16)
549 return;
550
551 UUID noticeID = new UUID(im.imSessionID);
552
553 GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID);
554 if (notice != null)
555 {
556 UUID giver = new UUID(notice.BinaryBucket, 18);
557 UUID attachmentUUID = new UUID(notice.BinaryBucket, 34);
558
559 if (m_debugEnabled)
560 m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
561
562 InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
563 giver, attachmentUUID);
564
565 if (itemCopy == null)
566 {
567 remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
568 return;
569 }
570
571 remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
572 }
573 }
574
512 // Interop, received special 210 code for ejecting a group member 575 // Interop, received special 210 code for ejecting a group member
513 // this only works within the comms servers domain, and won't work hypergrid 576 // this only works within the comms servers domain, and won't work hypergrid
514 // TODO:FIXME: Use a presense server of some kind to find out where the 577 // TODO:FIXME: Use a presence server of some kind to find out where the
515 // client actually is, and try contacting that region directly to notify them, 578 // client actually is, and try contacting that region directly to notify them,
516 // or provide the notification via xmlrpc update queue 579 // or provide the notification via xmlrpc update queue
517 if ((im.dialog == 210)) 580 if ((im.dialog == 210))
@@ -889,26 +952,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
889 952
890 if (data != null) 953 if (data != null)
891 { 954 {
892 GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); 955 GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
893
894 GridInstantMessage msg = new GridInstantMessage();
895 msg.imSessionID = UUID.Zero.Guid;
896 msg.fromAgentID = data.GroupID.Guid;
897 msg.toAgentID = GetRequestingAgentID(remoteClient).Guid;
898 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
899 msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName;
900 msg.message = data.noticeData.Subject + "|" + data.Message;
901 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested;
902 msg.fromGroup = true;
903 msg.offline = (byte)0;
904 msg.ParentEstateID = 0;
905 msg.Position = Vector3.Zero;
906 msg.RegionID = UUID.Zero.Guid;
907 msg.binaryBucket = data.BinaryBucket;
908 956
909 OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); 957 OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
910 } 958 }
911
912 } 959 }
913 960
914 public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) 961 public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog)
@@ -916,10 +963,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
916 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 963 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
917 964
918 GridInstantMessage msg = new GridInstantMessage(); 965 GridInstantMessage msg = new GridInstantMessage();
919 msg.imSessionID = UUID.Zero.Guid; 966 byte[] bucket;
967
968 msg.imSessionID = groupNoticeID.Guid;
920 msg.toAgentID = agentID.Guid; 969 msg.toAgentID = agentID.Guid;
921 msg.dialog = dialog; 970 msg.dialog = dialog;
922 // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice;
923 msg.fromGroup = true; 971 msg.fromGroup = true;
924 msg.offline = (byte)1; // Allow this message to be stored for offline use 972 msg.offline = (byte)1; // Allow this message to be stored for offline use
925 msg.ParentEstateID = 0; 973 msg.ParentEstateID = 0;
@@ -933,13 +981,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
933 msg.timestamp = info.noticeData.Timestamp; 981 msg.timestamp = info.noticeData.Timestamp;
934 msg.fromAgentName = info.noticeData.FromName; 982 msg.fromAgentName = info.noticeData.FromName;
935 msg.message = info.noticeData.Subject + "|" + info.Message; 983 msg.message = info.noticeData.Subject + "|" + info.Message;
936 msg.binaryBucket = info.BinaryBucket; 984
985 if (info.BinaryBucket[0] > 0)
986 {
987 //32 is due to not needing space for two of the UUIDs.
988 //(Don't need UUID of attachment or its owner in IM)
989 //50 offset gets us to start of attachment name.
990 //We are skipping the attachment flag, type, and
991 //the three UUID fields at the start of the bucket.
992 bucket = new byte[info.BinaryBucket.Length-32];
993 bucket[0] = 1; //Has attachment
994 bucket[1] = info.BinaryBucket[1];
995 Array.Copy(info.BinaryBucket, 50,
996 bucket, 18, info.BinaryBucket.Length-50);
997 }
998 else
999 {
1000 bucket = new byte[19];
1001 bucket[0] = 0; //No attachment
1002 bucket[1] = 0; //Attachment type
1003 bucket[18] = 0; //NUL terminate name
1004 }
1005
1006 info.GroupID.ToBytes(bucket, 2);
1007 msg.binaryBucket = bucket;
937 } 1008 }
938 else 1009 else
939 { 1010 {
940 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); 1011 if (m_debugEnabled)
1012 m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID);
1013
941 msg.fromAgentID = UUID.Zero.Guid; 1014 msg.fromAgentID = UUID.Zero.Guid;
942 msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; 1015 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
943 msg.fromAgentName = string.Empty; 1016 msg.fromAgentName = string.Empty;
944 msg.message = string.Empty; 1017 msg.message = string.Empty;
945 msg.binaryBucket = new byte[0]; 1018 msg.binaryBucket = new byte[0];
@@ -1063,7 +1136,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1063 // Message to ejector 1136 // Message to ejector
1064 // Interop, received special 210 code for ejecting a group member 1137 // Interop, received special 210 code for ejecting a group member
1065 // this only works within the comms servers domain, and won't work hypergrid 1138 // this only works within the comms servers domain, and won't work hypergrid
1066 // TODO:FIXME: Use a presense server of some kind to find out where the 1139 // TODO:FIXME: Use a presence server of some kind to find out where the
1067 // client actually is, and try contacting that region directly to notify them, 1140 // client actually is, and try contacting that region directly to notify them,
1068 // or provide the notification via xmlrpc update queue 1141 // or provide the notification via xmlrpc update queue
1069 1142
@@ -1178,6 +1251,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1178 } 1251 }
1179 } 1252 }
1180 1253
1254 public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
1255 {
1256 return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query);
1257 }
1258
1259
1181 #endregion 1260 #endregion
1182 1261
1183 #region Client/Update Tools 1262 #region Client/Update Tools
@@ -1222,7 +1301,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1222 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); 1301 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
1223 AgentData.Add(AgentDataMap); 1302 AgentData.Add(AgentDataMap);
1224 1303
1225
1226 OSDArray GroupData = new OSDArray(data.Length); 1304 OSDArray GroupData = new OSDArray(data.Length);
1227 OSDArray NewGroupData = new OSDArray(data.Length); 1305 OSDArray NewGroupData = new OSDArray(data.Length);
1228 1306
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
index 7bae8f7..8095b28 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
@@ -212,8 +212,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
212 m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name); 212 m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name);
213 213
214 m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); 214 m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty);
215 if ((m_groupsServerURI == null) || 215 if (string.IsNullOrEmpty(m_groupsServerURI))
216 (m_groupsServerURI == string.Empty))
217 { 216 {
218 m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); 217 m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]");
219 m_connectorEnabled = false; 218 m_connectorEnabled = false;
@@ -438,7 +437,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
438 return null; 437 return null;
439 } 438 }
440 } 439 }
441 else if ((groupName != null) && (groupName != string.Empty)) 440 else if (!string.IsNullOrEmpty(groupName))
442 { 441 {
443 if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) 442 if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap))
444 { 443 {
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
index c1bdacb..26d2597 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
@@ -26,13 +26,23 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
30using System.Net;
29using System.Reflection; 31using System.Reflection;
30using Nini.Config; 32using Nini.Config;
31using NUnit.Framework; 33using NUnit.Framework;
32using OpenMetaverse; 34using OpenMetaverse;
35using OpenMetaverse.Messages.Linden;
36using OpenMetaverse.Packets;
37using OpenMetaverse.StructuredData;
33using OpenSim.Framework; 38using OpenSim.Framework;
34using OpenSim.Framework.Communications; 39using OpenSim.Framework.Communications;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.ClientStack.Linden;
43using OpenSim.Region.CoreModules.Framework;
35using OpenSim.Region.Framework.Scenes; 44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups;
36using OpenSim.Tests.Common; 46using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock; 47using OpenSim.Tests.Common.Mock;
38 48
@@ -44,11 +54,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
44 [TestFixture] 54 [TestFixture]
45 public class GroupsModuleTests : OpenSimTestCase 55 public class GroupsModuleTests : OpenSimTestCase
46 { 56 {
57 [SetUp]
58 public override void SetUp()
59 {
60 base.SetUp();
61
62 uint port = 9999;
63 uint sslPort = 9998;
64
65 // This is an unfortunate bit of clean up we have to do because MainServer manages things through static
66 // variables and the VM is not restarted between tests.
67 MainServer.RemoveHttpServer(port);
68
69 BaseHttpServer server = new BaseHttpServer(port, false, sslPort, "");
70 MainServer.AddHttpServer(server);
71 MainServer.Instance = server;
72 }
73
47 [Test] 74 [Test]
48 public void TestBasic() 75 public void TestSendAgentGroupDataUpdate()
49 { 76 {
50 TestHelpers.InMethod(); 77 TestHelpers.InMethod();
51// log4net.Config.XmlConfigurator.Configure(); 78// TestHelpers.EnableLogging();
52 79
53 TestScene scene = new SceneHelpers().SetupScene(); 80 TestScene scene = new SceneHelpers().SetupScene();
54 IConfigSource configSource = new IniConfigSource(); 81 IConfigSource configSource = new IniConfigSource();
@@ -56,8 +83,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
56 config.Set("Enabled", true); 83 config.Set("Enabled", true);
57 config.Set("Module", "GroupsModule"); 84 config.Set("Module", "GroupsModule");
58 config.Set("DebugEnabled", true); 85 config.Set("DebugEnabled", true);
86
87 GroupsModule gm = new GroupsModule();
88 EventQueueGetModule eqgm = new EventQueueGetModule();
89
90 // We need a capabilities module active so that adding the scene presence creates an event queue in the
91 // EventQueueGetModule
59 SceneHelpers.SetupSceneModules( 92 SceneHelpers.SetupSceneModules(
60 scene, configSource, new object[] { new MockGroupsServicesConnector() }); 93 scene, configSource, gm, new MockGroupsServicesConnector(), new CapabilitiesModule(), eqgm);
94
95 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseStem("1"));
96
97 gm.SendAgentGroupDataUpdate(sp.ControllingClient);
98
99 Hashtable eventsResponse = eqgm.GetEvents(UUID.Zero, sp.UUID);
100
101 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK));
102
103// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]);
104
105 OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]);
106 OSDArray eventsOsd = (OSDArray)rawOsd["events"];
107
108 bool foundUpdate = false;
109 foreach (OSD osd in eventsOsd)
110 {
111 OSDMap eventOsd = (OSDMap)osd;
112
113 if (eventOsd["message"] == "AgentGroupDataUpdate")
114 foundUpdate = true;
115 }
116
117 Assert.That(foundUpdate, Is.True, "Did not find AgentGroupDataUpdate in response");
118
119 // TODO: More checking of more actual event data.
61 } 120 }
62 } 121 }
63} \ No newline at end of file 122} \ 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 71b24ac..e28d0c2 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
@@ -168,8 +168,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
168 m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); 168 m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name);
169 169
170 m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); 170 m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty);
171 if ((m_groupsServerURI == null) || 171 if (string.IsNullOrEmpty(m_groupsServerURI))
172 (m_groupsServerURI == string.Empty))
173 { 172 {
174 m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); 173 m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]");
175 m_connectorEnabled = false; 174 m_connectorEnabled = false;
@@ -354,7 +353,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
354 { 353 {
355 param["GroupID"] = GroupID.ToString(); 354 param["GroupID"] = GroupID.ToString();
356 } 355 }
357 if ((GroupName != null) && (GroupName != string.Empty)) 356 if (!string.IsNullOrEmpty(GroupName))
358 { 357 {
359 param["Name"] = GroupName.ToString(); 358 param["Name"] = GroupName.ToString();
360 } 359 }