aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs85
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs1017
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs423
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs1039
-rw-r--r--OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml14
-rw-r--r--bin/OpenSim.ini.example24
-rw-r--r--prebuild.xml4
7 files changed, 2605 insertions, 1 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs
new file mode 100644
index 0000000..6e9105d
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupDataProvider.cs
@@ -0,0 +1,85 @@
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 OpenSim 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;
30
31using OpenMetaverse;
32
33using OpenSim.Framework;
34
35namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
36{
37 interface IGroupDataProvider
38 {
39 UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID);
40 void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish);
41 GroupRecord GetGroupRecord(UUID GroupID, string GroupName);
42 List<DirGroupsReplyData> FindGroups(string search);
43 List<GroupMembersData> GetGroupMembers(UUID GroupID);
44
45 void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers);
46 void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers);
47 void RemoveGroupRole(UUID groupID, UUID roleID);
48 List<GroupRolesData> GetGroupRoles(UUID GroupID);
49 List<GroupRoleMembersData> GetGroupRoleMembers(UUID GroupID);
50
51 void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID);
52 void RemoveAgentFromGroup(UUID AgentID, UUID GroupID);
53
54 void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID);
55 GroupInviteInfo GetAgentToGroupInvite(UUID inviteID);
56 void RemoveAgentToGroupInvite(UUID inviteID);
57
58
59 void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID);
60 void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID);
61 List<GroupRolesData> GetAgentGroupRoles(UUID AgentID, UUID GroupID);
62
63 void SetAgentActiveGroup(UUID AgentID, UUID GroupID);
64 GroupMembershipData GetAgentActiveMembership(UUID AgentID);
65
66 void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID);
67 void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile);
68
69 GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID);
70 List<GroupMembershipData> GetAgentGroupMemberships(UUID AgentID);
71
72 void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket);
73 GroupNoticeInfo GetGroupNotice(UUID noticeID);
74 List<GroupNoticeData> GetGroupNotices(UUID GroupID);
75 }
76
77 public class GroupInviteInfo
78 {
79 public UUID GroupID = UUID.Zero;
80 public UUID RoleID = UUID.Zero;
81 public UUID AgentID = UUID.Zero;
82 public UUID InviteID = UUID.Zero;
83 }
84
85}
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs
new file mode 100644
index 0000000..343bd6d
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs
@@ -0,0 +1,1017 @@
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 OpenSim 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;
30using System.Collections.Generic;
31using System.Reflection;
32//using System.Text;
33
34using Nwc.XmlRpc;
35
36using log4net;
37// using Nini.Config;
38
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41
42using OpenSim.Framework;
43//using OpenSim.Region.Framework.Interfaces;
44
45namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
46{
47
48 public class XmlRpcGroupDataProvider : IGroupDataProvider
49 {
50 private static readonly ILog m_log =
51 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private string m_serviceURL = "http://osflotsam.org/xmlrpc.php";
54
55 public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | GroupPowers.JoinChat | GroupPowers.AllowVoiceChat | GroupPowers.ReceiveNotices | GroupPowers.StartProposal | GroupPowers.VoteOnProposal;
56
57 public XmlRpcGroupDataProvider(string serviceURL)
58 {
59 m_serviceURL = serviceURL;
60 }
61
62 /// <summary>
63 /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role.
64 /// </summary>
65 public UUID CreateGroup(string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID)
66 {
67 UUID GroupID = UUID.Random();
68 UUID OwnerRoleID = UUID.Random();
69
70 Hashtable param = new Hashtable();
71 param["GroupID"] = GroupID.ToString();
72 param["Name"] = name;
73 param["Charter"] = charter;
74 param["ShowInList"] = showInList == true ? 1 : 0;
75 param["InsigniaID"] = insigniaID.ToString();
76 param["MembershipFee"] = 0;
77 param["OpenEnrollment"] = openEnrollment == true ? 1 : 0;
78 param["AllowPublish"] = allowPublish == true ? 1 : 0;
79 param["MaturePublish"] = maturePublish == true ? 1 : 0;
80 param["FounderID"] = founderID.ToString();
81 param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString();
82 param["OwnerRoleID"] = OwnerRoleID.ToString();
83
84 // Would this be cleaner as (GroupPowers)ulong.MaxValue;
85 GroupPowers OwnerPowers = GroupPowers.Accountable
86 | GroupPowers.AllowEditLand
87 | GroupPowers.AllowFly
88 | GroupPowers.AllowLandmark
89 | GroupPowers.AllowRez
90 | GroupPowers.AllowSetHome
91 | GroupPowers.AllowVoiceChat
92 | GroupPowers.AssignMember
93 | GroupPowers.AssignMemberLimited
94 | GroupPowers.ChangeActions
95 | GroupPowers.ChangeIdentity
96 | GroupPowers.ChangeMedia
97 | GroupPowers.ChangeOptions
98 | GroupPowers.CreateRole
99 | GroupPowers.DeedObject
100 | GroupPowers.DeleteRole
101 | GroupPowers.Eject
102 | GroupPowers.FindPlaces
103 | GroupPowers.Invite
104 | GroupPowers.JoinChat
105 | GroupPowers.LandChangeIdentity
106 | GroupPowers.LandDeed
107 | GroupPowers.LandDivideJoin
108 | GroupPowers.LandEdit
109 | GroupPowers.LandEjectAndFreeze
110 | GroupPowers.LandGardening
111 | GroupPowers.LandManageAllowed
112 | GroupPowers.LandManageBanned
113 | GroupPowers.LandManagePasses
114 | GroupPowers.LandOptions
115 | GroupPowers.LandRelease
116 | GroupPowers.LandSetSale
117 | GroupPowers.ModerateChat
118 | GroupPowers.ObjectManipulate
119 | GroupPowers.ObjectSetForSale
120 | GroupPowers.ReceiveNotices
121 | GroupPowers.RemoveMember
122 | GroupPowers.ReturnGroupOwned
123 | GroupPowers.ReturnGroupSet
124 | GroupPowers.ReturnNonGroup
125 | GroupPowers.RoleProperties
126 | GroupPowers.SendNotices
127 | GroupPowers.SetLandingPoint
128 | GroupPowers.StartProposal
129 | GroupPowers.VoteOnProposal;
130 param["OwnersPowers"] = ((ulong)OwnerPowers).ToString();
131
132
133
134 IList parameters = new ArrayList();
135 parameters.Add(param);
136 XmlRpcRequest req = new XmlRpcRequest("groups.createGroup", parameters);
137 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
138 Hashtable respData = (Hashtable)resp.Value;
139
140 if (respData.Contains("error"))
141 {
142 LogRespDataToConsoleError(respData);
143 }
144
145 return UUID.Parse((string)respData["GroupID"]);
146 }
147
148 public void UpdateGroup(UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
149 {
150 Hashtable param = new Hashtable();
151 param["GroupID"] = groupID.ToString();
152 param["Charter"] = charter;
153 param["ShowInList"] = showInList == true ? 1 : 0;
154 param["InsigniaID"] = insigniaID.ToString();
155 param["MembershipFee"] = membershipFee;
156 param["OpenEnrollment"] = openEnrollment == true ? 1 : 0;
157 param["AllowPublish"] = allowPublish == true ? 1 : 0;
158 param["MaturePublish"] = maturePublish == true ? 1 : 0;
159
160 IList parameters = new ArrayList();
161 parameters.Add(param);
162 XmlRpcRequest req = new XmlRpcRequest("groups.updateGroup", parameters);
163 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
164 Hashtable respData = (Hashtable)resp.Value;
165
166 if (respData.Contains("error"))
167 {
168 LogRespDataToConsoleError(respData);
169 }
170 }
171
172 public void AddGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
173 {
174 Hashtable param = new Hashtable();
175 param["GroupID"] = groupID.ToString();
176 param["RoleID"] = roleID.ToString();
177 param["Name"] = name;
178 param["Description"] = description;
179 param["Title"] = title;
180 param["Powers"] = powers.ToString();
181
182 IList parameters = new ArrayList();
183 parameters.Add(param);
184 XmlRpcRequest req = new XmlRpcRequest("groups.addRoleToGroup", parameters);
185 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
186 Hashtable respData = (Hashtable)resp.Value;
187
188 if (respData.Contains("error"))
189 {
190 LogRespDataToConsoleError(respData);
191 }
192 }
193
194 public void RemoveGroupRole(UUID groupID, UUID roleID)
195 {
196 Hashtable param = new Hashtable();
197 param["GroupID"] = groupID.ToString();
198 param["RoleID"] = roleID.ToString();
199
200 IList parameters = new ArrayList();
201 parameters.Add(param);
202 XmlRpcRequest req = new XmlRpcRequest("groups.removeRoleFromGroup", parameters);
203 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
204 Hashtable respData = (Hashtable)resp.Value;
205
206 if (respData.Contains("error"))
207 {
208 LogRespDataToConsoleError(respData);
209 }
210 }
211
212 public void UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
213 {
214 Hashtable param = new Hashtable();
215 param["GroupID"] = groupID.ToString();
216 param["RoleID"] = roleID.ToString();
217 if (name != null)
218 {
219 param["Name"] = name;
220 }
221 if (description != null)
222 {
223 param["Description"] = description;
224 }
225 if (title != null)
226 {
227 param["Title"] = title;
228 }
229 param["Powers"] = powers.ToString();
230
231 IList parameters = new ArrayList();
232 parameters.Add(param);
233 XmlRpcRequest req = new XmlRpcRequest("groups.updateGroupRole", parameters);
234 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
235 Hashtable respData = (Hashtable)resp.Value;
236
237 if (respData.Contains("error"))
238 {
239 LogRespDataToConsoleError(respData);
240 }
241 }
242
243 public GroupRecord GetGroupRecord(UUID GroupID, string GroupName)
244 {
245 Hashtable param = new Hashtable();
246 if ((GroupID != null) && (GroupID != UUID.Zero))
247 {
248 param["GroupID"] = GroupID.ToString();
249 }
250 if ((GroupName != null) && (GroupName != string.Empty))
251 {
252 param["Name"] = GroupName.ToString();
253 }
254
255
256 IList parameters = new ArrayList();
257 parameters.Add(param);
258 XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters);
259 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
260 Hashtable respData = (Hashtable)resp.Value;
261
262 if (respData.Contains("error"))
263 {
264 if ((string)respData["error"] != "Group Not Found")
265 {
266 LogRespDataToConsoleError(respData);
267 }
268 return null;
269 }
270
271 return GroupProfileHashtableToGroupRecord(respData);
272
273 }
274
275 public GroupProfileData GetMemberGroupProfile(UUID GroupID, UUID AgentID)
276 {
277 Hashtable param = new Hashtable();
278 param["GroupID"] = GroupID.ToString();
279
280
281 IList parameters = new ArrayList();
282 parameters.Add(param);
283 XmlRpcRequest req = new XmlRpcRequest("groups.getGroup", parameters);
284 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
285 Hashtable respData = (Hashtable)resp.Value;
286
287 if (respData.Contains("error"))
288 {
289 if ((string)respData["error"] != "Group Not Found")
290 {
291 LogRespDataToConsoleError(respData);
292 }
293 return new GroupProfileData();
294 }
295
296 GroupMembershipData MemberInfo = GetAgentGroupMembership(AgentID, GroupID);
297 GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData);
298
299 MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle;
300 MemberGroupProfile.PowersMask = MemberInfo.GroupPowers;
301
302 return MemberGroupProfile;
303
304 }
305
306 private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile)
307 {
308 GroupProfileData group = new GroupProfileData();
309 group.GroupID = UUID.Parse((string)groupProfile["GroupID"]);
310 group.Name = (string)groupProfile["Name"];
311
312 if (groupProfile["Charter"] != null)
313 {
314 group.Charter = (string)groupProfile["Charter"];
315 }
316
317 group.ShowInList = ((string)groupProfile["ShowInList"]) == "1";
318 group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]);
319 group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]);
320 group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1";
321 group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1";
322 group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1";
323 group.FounderID = UUID.Parse((string)groupProfile["FounderID"]);
324 group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]);
325
326 group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]);
327 group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]);
328
329 return group;
330 }
331
332 private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile)
333 {
334
335 GroupRecord group = new GroupRecord();
336 m_log.Debug("GroupID");
337 group.GroupID = UUID.Parse((string)groupProfile["GroupID"]);
338
339 m_log.Debug("Name");
340 group.GroupName = groupProfile["Name"].ToString();
341
342 m_log.Debug("Charter");
343 if (groupProfile["Charter"] != null)
344 {
345 group.Charter = (string)groupProfile["Charter"];
346 }
347
348 m_log.Debug("ShowInList");
349 group.ShowInList = ((string)groupProfile["ShowInList"]) == "1";
350
351 m_log.Debug("InsigniaID");
352 group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]);
353
354 m_log.Debug("MembershipFee");
355 group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]);
356
357 m_log.Debug("OpenEnrollment");
358 group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1";
359
360 m_log.Debug("AllowPublish");
361 group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1";
362
363 m_log.Debug("MaturePublish");
364 group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1";
365
366 m_log.Debug("FounderID");
367 group.FounderID = UUID.Parse((string)groupProfile["FounderID"]);
368
369 m_log.Debug("OwnerRoleID");
370 group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]);
371
372 return group;
373 }
374
375
376 public void SetAgentActiveGroup(UUID AgentID, UUID GroupID)
377 {
378 Hashtable param = new Hashtable();
379 param["AgentID"] = AgentID.ToString();
380 param["GroupID"] = GroupID.ToString();
381
382 IList parameters = new ArrayList();
383 parameters.Add(param);
384 XmlRpcRequest req = new XmlRpcRequest("groups.setAgentActiveGroup", parameters);
385 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
386 Hashtable respData = (Hashtable)resp.Value;
387
388 if (respData.Contains("error"))
389 {
390 LogRespDataToConsoleError(respData);
391 }
392
393 }
394
395 public void SetAgentActiveGroupRole(UUID AgentID, UUID GroupID, UUID RoleID)
396 {
397 Hashtable param = new Hashtable();
398 param["AgentID"] = AgentID.ToString();
399 param["GroupID"] = GroupID.ToString();
400 param["SelectedRoleID"] = RoleID.ToString();
401
402 IList parameters = new ArrayList();
403 parameters.Add(param);
404 XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters);
405 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
406 Hashtable respData = (Hashtable)resp.Value;
407
408 if (respData.Contains("error"))
409 {
410 LogRespDataToConsoleError(respData);
411 }
412
413 }
414
415 public void SetAgentGroupInfo(UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
416 {
417 Hashtable param = new Hashtable();
418 param["AgentID"] = AgentID.ToString();
419 param["GroupID"] = GroupID.ToString();
420 param["AcceptNotices"] = AcceptNotices ? "1" : "0";
421 param["ListInProfile"] = ListInProfile ? "1" : "0";
422
423 IList parameters = new ArrayList();
424 parameters.Add(param);
425 XmlRpcRequest req = new XmlRpcRequest("groups.setAgentGroupInfo", parameters);
426 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
427 Hashtable respData = (Hashtable)resp.Value;
428
429 if (respData.Contains("error"))
430 {
431 LogRespDataToConsoleError(respData);
432 }
433 }
434
435 public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID)
436 {
437 Hashtable param = new Hashtable();
438 param["InviteID"] = inviteID.ToString();
439 param["AgentID"] = agentID.ToString();
440 param["RoleID"] = roleID.ToString();
441 param["GroupID"] = groupID.ToString();
442
443 IList parameters = new ArrayList();
444 parameters.Add(param);
445 XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupInvite", parameters);
446 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
447 Hashtable respData = (Hashtable)resp.Value;
448
449 if (respData.Contains("error"))
450 {
451 if (respData["error"] != "Duplicate group invite requested")
452 {
453 LogRespDataToConsoleError(respData);
454 }
455 }
456
457
458 }
459
460 public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID)
461 {
462 Hashtable param = new Hashtable();
463 param["InviteID"] = inviteID.ToString();
464
465 IList parameters = new ArrayList();
466 parameters.Add(param);
467 XmlRpcRequest req = new XmlRpcRequest("groups.getAgentToGroupInvite", parameters);
468 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
469 Hashtable respData = (Hashtable)resp.Value;
470
471
472 if (respData.Contains("error"))
473 {
474 LogRespDataToConsoleError(respData);
475
476 return null;
477 }
478
479 GroupInviteInfo inviteInfo = new GroupInviteInfo();
480 inviteInfo.InviteID = inviteID;
481 inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]);
482 inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]);
483 inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]);
484
485 return inviteInfo;
486 }
487
488 public void RemoveAgentToGroupInvite(UUID inviteID)
489 {
490 Hashtable param = new Hashtable();
491 param["InviteID"] = inviteID.ToString();
492
493 IList parameters = new ArrayList();
494 parameters.Add(param);
495 XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentToGroupInvite", parameters);
496 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
497 Hashtable respData = (Hashtable)resp.Value;
498
499 if (respData.Contains("error"))
500 {
501 LogRespDataToConsoleError(respData);
502 }
503 }
504
505 public void AddAgentToGroup(UUID AgentID, UUID GroupID, UUID RoleID)
506 {
507 Hashtable param = new Hashtable();
508 param["AgentID"] = AgentID.ToString();
509 param["GroupID"] = GroupID.ToString();
510 param["RoleID"] = RoleID.ToString();
511
512 IList parameters = new ArrayList();
513 parameters.Add(param);
514 XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroup", parameters);
515 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
516 Hashtable respData = (Hashtable)resp.Value;
517
518 if (respData.Contains("error"))
519 {
520 LogRespDataToConsoleError(respData);
521 }
522 }
523
524 public void RemoveAgentFromGroup(UUID AgentID, UUID GroupID)
525 {
526 Hashtable param = new Hashtable();
527 param["AgentID"] = AgentID.ToString();
528 param["GroupID"] = GroupID.ToString();
529
530 IList parameters = new ArrayList();
531 parameters.Add(param);
532 XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroup", parameters);
533 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
534 Hashtable respData = (Hashtable)resp.Value;
535
536 if (respData.Contains("error"))
537 {
538 LogRespDataToConsoleError(respData);
539 }
540 }
541
542 public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID)
543 {
544 Hashtable param = new Hashtable();
545 param["AgentID"] = AgentID.ToString();
546 param["GroupID"] = GroupID.ToString();
547 param["RoleID"] = RoleID.ToString();
548
549 IList parameters = new ArrayList();
550 parameters.Add(param);
551 XmlRpcRequest req = new XmlRpcRequest("groups.addAgentToGroupRole", parameters);
552 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
553 Hashtable respData = (Hashtable)resp.Value;
554
555 if (respData.Contains("error"))
556 {
557 LogRespDataToConsoleError(respData);
558 }
559 }
560
561 public void RemoveAgentFromGroupRole(UUID AgentID, UUID GroupID, UUID RoleID)
562 {
563 Hashtable param = new Hashtable();
564 param["AgentID"] = AgentID.ToString();
565 param["GroupID"] = GroupID.ToString();
566 param["RoleID"] = RoleID.ToString();
567
568 IList parameters = new ArrayList();
569 parameters.Add(param);
570 XmlRpcRequest req = new XmlRpcRequest("groups.removeAgentFromGroupRole", parameters);
571 XmlRpcResponse resp = req.Send(m_serviceURL, 3000);
572 Hashtable respData = (Hashtable)resp.Value;
573
574 if (respData.Contains("error"))
575 {
576 LogRespDataToConsoleError(respData);
577 }
578 }
579
580
581 public List<DirGroupsReplyData> FindGroups(string search)
582 {
583 Hashtable param = new Hashtable();
584 param["Search"] = search;
585
586 IList parameters = new ArrayList();
587 parameters.Add(param);
588 XmlRpcRequest req = new XmlRpcRequest("groups.findGroups", parameters);
589 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
590 Hashtable respData = (Hashtable)resp.Value;
591
592 List<DirGroupsReplyData> findings = new List<DirGroupsReplyData>();
593
594 if (respData.Contains("error"))
595 {
596 if (respData["error"].ToString() != "No groups found.")
597 {
598 LogRespDataToConsoleError(respData);
599 }
600 }
601 else
602 {
603 Hashtable results = (Hashtable)respData["results"];
604 foreach (Hashtable groupFind in results.Values)
605 {
606 DirGroupsReplyData data = new DirGroupsReplyData();
607 data.groupID = new UUID((string)groupFind["GroupID"]); ;
608 data.groupName = (string)groupFind["Name"];
609 data.members = int.Parse((string)groupFind["Members"]);
610 // data.searchOrder = order;
611
612 findings.Add(data);
613 }
614 }
615
616 return findings;
617 }
618
619 public GroupMembershipData GetAgentGroupMembership(UUID AgentID, UUID GroupID)
620 {
621 Hashtable param = new Hashtable();
622 param["AgentID"] = AgentID.ToString();
623 param["GroupID"] = GroupID.ToString();
624
625 IList parameters = new ArrayList();
626 parameters.Add(param);
627 XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMembership", parameters);
628 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
629 Hashtable respData = (Hashtable)resp.Value;
630
631 if (respData.Contains("error"))
632 {
633 if ((string)respData["error"] != "None Found")
634 {
635 LogRespDataToConsoleError(respData);
636 }
637 return null;
638 }
639
640 GroupMembershipData data = HashTableToGroupMembershipData(respData);
641
642 return data;
643 }
644
645 public GroupMembershipData GetAgentActiveMembership(UUID AgentID)
646 {
647 Hashtable param = new Hashtable();
648 param["AgentID"] = AgentID.ToString();
649
650 IList parameters = new ArrayList();
651 parameters.Add(param);
652 XmlRpcRequest req = new XmlRpcRequest("groups.getAgentActiveMembership", parameters);
653 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
654 Hashtable respData = (Hashtable)resp.Value;
655
656 if (respData.Contains("error"))
657 {
658 if (respData["error"].ToString() == "No Active Group Specified")
659 {
660 return null;
661 }
662 LogRespDataToConsoleError(respData);
663 return null;
664 }
665
666 try
667 {
668 GroupMembershipData data = HashTableToGroupMembershipData(respData);
669 return data;
670 }
671 catch (System.Exception e)
672 {
673 LogRespDataToConsoleError(respData);
674 throw e;
675 }
676 }
677
678 private void LogRespDataToConsoleError(Hashtable respData)
679 {
680 m_log.Error("[GROUPDATA] Error:");
681
682 foreach (string key in respData.Keys)
683 {
684 m_log.ErrorFormat("[GROUPDATA] Key: {0}", key);
685
686 object o = respData[key];
687
688 string[] lines = respData[key].ToString().Split(new char[] { '\n' });
689 foreach (string line in lines)
690 {
691 m_log.ErrorFormat("[GROUPDATA] {0}", line);
692 }
693
694 }
695 }
696
697 public List<GroupMembershipData> GetAgentGroupMemberships(UUID AgentID)
698 {
699 Hashtable param = new Hashtable();
700 param["AgentID"] = AgentID.ToString();
701
702 IList parameters = new ArrayList();
703 parameters.Add(param);
704 XmlRpcRequest req = new XmlRpcRequest("groups.getAgentGroupMemberships", parameters);
705 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
706 Hashtable respData = (Hashtable)resp.Value;
707
708 List<GroupMembershipData> memberships = new List<GroupMembershipData>();
709
710 if (respData.Contains("error"))
711 {
712 if (respData["error"].ToString() != "No Memberships")
713 {
714 LogRespDataToConsoleError(respData);
715 }
716 }
717 else
718 {
719 foreach (object membership in respData.Values)
720 {
721 memberships.Add(HashTableToGroupMembershipData((Hashtable)membership));
722 }
723 }
724 return memberships;
725 }
726
727 public List<GroupRolesData> GetAgentGroupRoles(UUID AgentID, UUID GroupID)
728 {
729 Hashtable param = new Hashtable();
730 param["AgentID"] = AgentID.ToString();
731 param["GroupID"] = GroupID.ToString();
732
733 IList parameters = new ArrayList();
734 parameters.Add(param);
735 XmlRpcRequest req = new XmlRpcRequest("groups.getAgentRoles", parameters);
736 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
737 Hashtable respData = (Hashtable)resp.Value;
738
739 List<GroupRolesData> Roles = new List<GroupRolesData>();
740
741 if (respData.Contains("error"))
742 {
743 if ((string)respData["error"] != "None found")
744 {
745 LogRespDataToConsoleError(respData);
746 }
747 return Roles;
748 }
749
750 foreach (Hashtable role in respData.Values)
751 {
752 GroupRolesData data = new GroupRolesData();
753 data.RoleID = new UUID((string)role["RoleID"]);
754 data.Name = (string)role["Name"];
755 data.Description = (string)role["Description"];
756 data.Powers = ulong.Parse((string)role["Powers"]);
757 data.Title = (string)role["Title"];
758
759 Roles.Add(data);
760 }
761
762 return Roles;
763
764
765 }
766
767 public List<GroupRolesData> GetGroupRoles(UUID GroupID)
768 {
769 Hashtable param = new Hashtable();
770 param["GroupID"] = GroupID.ToString();
771
772 IList parameters = new ArrayList();
773 parameters.Add(param);
774 XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoles", parameters);
775 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
776 Hashtable respData = (Hashtable)resp.Value;
777
778 if (respData.Contains("error"))
779 {
780 LogRespDataToConsoleError(respData);
781 return null;
782 }
783
784 List<GroupRolesData> Roles = new List<GroupRolesData>();
785 foreach (Hashtable role in respData.Values)
786 {
787 GroupRolesData data = new GroupRolesData();
788 data.Description = (string)role["Description"];
789 data.Members = int.Parse((string)role["Members"]);
790 data.Name = (string)role["Name"];
791 data.Powers = ulong.Parse((string)role["Powers"]);
792 data.RoleID = new UUID((string)role["RoleID"]);
793 data.Title = (string)role["Title"];
794
795 Roles.Add(data);
796 }
797
798 return Roles;
799
800 }
801
802 private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData)
803 {
804 GroupMembershipData data = new GroupMembershipData();
805 data.AcceptNotices = ((string)respData["AcceptNotices"] == "1");
806 data.Contribution = int.Parse((string)respData["Contribution"]);
807 data.ListInProfile = ((string)respData["ListInProfile"] == "1");
808
809 data.ActiveRole = new UUID((string)respData["SelectedRoleID"]);
810 data.GroupTitle = (string)respData["Title"];
811
812 data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]);
813
814 // Is this group the agent's active group
815
816 data.GroupID = new UUID((string)respData["GroupID"]);
817
818 UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]);
819 data.Active = data.GroupID.Equals(ActiveGroup);
820
821 data.AllowPublish = ((string)respData["AllowPublish"] == "1");
822 data.Charter = (string)respData["Charter"];
823 data.FounderID = new UUID((string)respData["FounderID"]);
824 data.GroupID = new UUID((string)respData["GroupID"]);
825 data.GroupName = (string)respData["GroupName"];
826 data.GroupPicture = new UUID((string)respData["InsigniaID"]);
827 data.MaturePublish = ((string)respData["MaturePublish"] == "1");
828 data.MembershipFee = int.Parse((string)respData["MembershipFee"]);
829 data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1");
830 data.ShowInList = ((string)respData["ShowInList"] == "1");
831 return data;
832 }
833
834 public List<GroupMembersData> GetGroupMembers(UUID GroupID)
835 {
836 Hashtable param = new Hashtable();
837 param["GroupID"] = GroupID.ToString();
838
839 IList parameters = new ArrayList();
840 parameters.Add(param);
841 XmlRpcRequest req = new XmlRpcRequest("groups.getGroupMembers", parameters);
842 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
843 Hashtable respData = (Hashtable)resp.Value;
844
845 if (respData.Contains("error"))
846 {
847 LogRespDataToConsoleError(respData);
848 return null;
849 }
850
851 List<GroupMembersData> members = new List<GroupMembersData>();
852 foreach (Hashtable membership in respData.Values)
853 {
854 GroupMembersData data = new GroupMembersData();
855
856 data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1";
857 data.AgentID = new UUID((string)membership["AgentID"]);
858 data.Contribution = int.Parse((string)membership["Contribution"]);
859 data.IsOwner = ((string)membership["IsOwner"]) == "1";
860 data.ListInProfile = ((string)membership["ListInProfile"]) == "1";
861 data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]);
862 data.Title = (string)membership["Title"];
863
864 members.Add(data);
865 }
866
867 return members;
868
869 }
870
871 public List<GroupRoleMembersData> GetGroupRoleMembers(UUID GroupID)
872 {
873 Hashtable param = new Hashtable();
874 param["GroupID"] = GroupID.ToString();
875
876 IList parameters = new ArrayList();
877 parameters.Add(param);
878 XmlRpcRequest req = new XmlRpcRequest("groups.getGroupRoleMembers", parameters);
879 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
880 Hashtable respData = (Hashtable)resp.Value;
881
882 if (respData.Contains("error"))
883 {
884 LogRespDataToConsoleError(respData);
885 return null;
886 }
887
888 List<GroupRoleMembersData> members = new List<GroupRoleMembersData>();
889 foreach (Hashtable membership in respData.Values)
890 {
891 GroupRoleMembersData data = new GroupRoleMembersData();
892
893 data.MemberID = new UUID((string)membership["AgentID"]);
894 data.RoleID = new UUID((string)membership["RoleID"]);
895
896 members.Add(data);
897 }
898
899 return members;
900 }
901
902 public List<GroupNoticeData> GetGroupNotices(UUID GroupID)
903 {
904 Hashtable param = new Hashtable();
905 param["GroupID"] = GroupID.ToString();
906
907 IList parameters = new ArrayList();
908 parameters.Add(param);
909 XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotices", parameters);
910 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
911 Hashtable respData = (Hashtable)resp.Value;
912
913 List<GroupNoticeData> values = new List<GroupNoticeData>();
914
915 if (respData.Contains("error"))
916 {
917 if ((string)respData["error"] != "No Notices")
918 {
919 LogRespDataToConsoleError(respData);
920 }
921 }
922 else
923 {
924 foreach (Hashtable value in respData.Values)
925 {
926 GroupNoticeData data = new GroupNoticeData();
927 data.NoticeID = UUID.Parse((string)value["NoticeID"]);
928 data.Timestamp = uint.Parse((string)value["Timestamp"]);
929 data.FromName = (string)value["FromName"];
930 data.Subject = (string)value["Subject"];
931 data.HasAttachment = false;
932 data.AssetType = 0;
933
934 values.Add(data);
935 }
936 }
937 return values;
938
939 }
940 public GroupNoticeInfo GetGroupNotice(UUID noticeID)
941 {
942 Hashtable param = new Hashtable();
943 param["NoticeID"] = noticeID.ToString();
944
945 IList parameters = new ArrayList();
946 parameters.Add(param);
947 XmlRpcRequest req = new XmlRpcRequest("groups.getGroupNotice", parameters);
948 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
949 Hashtable respData = (Hashtable)resp.Value;
950
951
952
953 if (respData.Contains("error"))
954 {
955 if ((string)respData["error"] != "Group Notice Not Found")
956 {
957 LogRespDataToConsoleError(respData);
958 return null;
959 }
960 }
961
962 GroupNoticeInfo data = new GroupNoticeInfo();
963 data.GroupID = UUID.Parse((string)respData["GroupID"]);
964 data.Message = (string)respData["Message"];
965 data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true);
966 data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]);
967 data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]);
968 data.noticeData.FromName = (string)respData["FromName"];
969 data.noticeData.Subject = (string)respData["Subject"];
970 data.noticeData.HasAttachment = false;
971 data.noticeData.AssetType = 0;
972
973 if (data.Message == null)
974 {
975 data.Message = string.Empty;
976 }
977
978 return data;
979 }
980 public void AddGroupNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket)
981 {
982 string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, "");
983
984 Hashtable param = new Hashtable();
985 param["GroupID"] = groupID.ToString();
986 param["NoticeID"] = noticeID.ToString();
987 param["FromName"] = fromName;
988 param["Subject"] = subject;
989 param["Message"] = message;
990 param["BinaryBucket"] = binBucket;
991 param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString();
992
993 IList parameters = new ArrayList();
994 parameters.Add(param);
995 XmlRpcRequest req = new XmlRpcRequest("groups.addGroupNotice", parameters);
996 XmlRpcResponse resp = req.Send(m_serviceURL, 10000);
997 Hashtable respData = (Hashtable)resp.Value;
998
999 List<GroupNoticeData> values = new List<GroupNoticeData>();
1000
1001 if (respData.Contains("error"))
1002 {
1003 LogRespDataToConsoleError(respData);
1004 }
1005 }
1006
1007
1008 }
1009
1010 public class GroupNoticeInfo
1011 {
1012 public GroupNoticeData noticeData = new GroupNoticeData();
1013 public UUID GroupID = UUID.Zero;
1014 public string Message = string.Empty;
1015 public byte[] BinaryBucket = new byte[0];
1016 }
1017}
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
new file mode 100644
index 0000000..d14d135
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs
@@ -0,0 +1,423 @@
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 OpenSim 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;
29//using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32
33
34using log4net;
35using Nini.Config;
36
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39
40using OpenSim.Framework;
41using OpenSim.Region.CoreModules.Framework.EventQueue;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44
45
46using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
47
48namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
49{
50 public class XmlRpcGroupsMessaging : INonSharedRegionModule
51 {
52
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private List<Scene> m_SceneList = new List<Scene>();
56
57 // must be NonShared for this to work, otherewise we may actually get multiple active clients
58 private Dictionary<Guid, IClientAPI> m_ActiveClients = new Dictionary<Guid, IClientAPI>();
59
60 private IMessageTransferModule m_MsgTransferModule = null;
61
62 private IGroupsModule m_GroupsModule = null;
63
64 // Config Options
65 private bool m_GroupMessagingEnabled = true;
66 private bool m_debugEnabled = true;
67
68 #region IRegionModule Members
69
70 public void Initialise(IConfigSource config)
71 {
72 IConfig groupsConfig = config.Configs["Groups"];
73
74 m_log.Info("[GROUPS-MESSAGING]: Initializing XmlRpcGroupsMessaging");
75
76 if (groupsConfig == null)
77 {
78 // Do not run this module by default.
79 m_log.Info("[GROUPS-MESSAGING]: No config found in OpenSim.ini -- not enabling XmlRpcGroupsMessaging");
80 return;
81 }
82 else
83 {
84 if (!groupsConfig.GetBoolean("Enabled", false))
85 {
86 m_log.Info("[GROUPS-MESSAGING]: Groups disabled in configuration");
87 return;
88 }
89
90 if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups")
91 {
92 m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups");
93
94 return;
95 }
96
97 m_GroupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true);
98
99 if (!m_GroupMessagingEnabled)
100 {
101 m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled.");
102 return;
103 }
104
105 m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true);
106
107 }
108
109 m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroupsMessaging starting up");
110
111 }
112
113 public void AddRegion(Scene scene)
114 {
115 }
116 public void RegionLoaded(Scene scene)
117 {
118 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
119
120 if (!m_GroupMessagingEnabled)
121 return;
122
123
124 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
125
126 // No groups module, no groups messaging
127 if (m_GroupsModule == null)
128 {
129 m_GroupMessagingEnabled = false;
130 m_log.Info("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled.");
131 Close();
132 return;
133 }
134
135 m_MsgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
136
137 // No message transfer module, no groups messaging
138 if (m_MsgTransferModule == null)
139 {
140 m_GroupMessagingEnabled = false;
141 m_log.Info("[GROUPS-MESSAGING]: Could not get MessageTransferModule");
142 Close();
143 return;
144 }
145
146
147 m_SceneList.Add(scene);
148
149 scene.EventManager.OnNewClient += OnNewClient;
150 scene.EventManager.OnClientClosed += OnClientClosed;
151 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
152
153 }
154
155 public void RemoveRegion(Scene scene)
156 {
157 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
158
159 m_SceneList.Remove(scene);
160 }
161
162
163 public void Close()
164 {
165 m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module.");
166
167
168 foreach (Scene scene in m_SceneList)
169 {
170 scene.EventManager.OnNewClient -= OnNewClient;
171 scene.EventManager.OnClientClosed -= OnClientClosed;
172 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
173 }
174
175 m_SceneList.Clear();
176
177 m_GroupsModule = null;
178 m_MsgTransferModule = null;
179 }
180
181 public string Name
182 {
183 get { return "XmlRpcGroupsMessaging"; }
184 }
185
186 #endregion
187
188 #region SimGridEventHandlers
189
190 private void OnNewClient(IClientAPI client)
191 {
192 RegisterClientAgent(client);
193 }
194 private void OnClientClosed(UUID AgentId)
195 {
196 UnregisterClientAgent(AgentId);
197 }
198
199 private void OnGridInstantMessage(GridInstantMessage msg)
200 {
201 m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
202
203 DebugGridInstantMessage(msg);
204
205 // Incoming message from a group
206 if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true))
207 {
208 if (m_ActiveClients.ContainsKey(msg.toAgentID))
209 {
210 UUID GroupID = new UUID(msg.fromAgentID);
211 // SendMessageToGroup(im);
212
213 GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID);
214 if (GroupInfo != null)
215 {
216
217 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message");
218
219 // Force? open the group session dialog???
220 IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface<IEventQueue>();
221 eq.ChatterboxInvitation(
222 GroupID
223 , GroupInfo.GroupName
224 , new UUID(msg.fromAgentID)
225 , msg.message, new UUID(msg.toAgentID)
226 , msg.fromAgentName
227 , msg.dialog
228 , msg.timestamp
229 , msg.offline==1
230 , (int)msg.ParentEstateID
231 , msg.Position
232 , 1
233 , new UUID(msg.imSessionID)
234 , msg.fromGroup
235 , Utils.StringToBytes(GroupInfo.GroupName)
236 );
237
238 eq.ChatterBoxSessionAgentListUpdates(
239 new UUID(GroupID)
240 , new UUID(msg.fromAgentID)
241 , new UUID(msg.toAgentID)
242 , false //canVoiceChat
243 , false //isModerator
244 , false //text mute
245 );
246
247 }
248 }
249 }
250
251 }
252
253 #endregion
254
255 #region ClientEvents
256 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
257 {
258 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
259
260 DebugGridInstantMessage(im);
261
262 // Start group IM session
263 if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart))
264 {
265 UUID GroupID = new UUID(im.toAgentID);
266
267 GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID);
268 if (GroupInfo != null)
269 {
270 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Start Group Session for {0}", GroupInfo.GroupName);
271
272 // remoteClient.SendInstantMessage(new GridInstantMessage(remoteClient.Scene, GroupID, GroupProfile.Name, remoteClient.AgentId, (byte)OpenMetaverse.InstantMessageDialog.SessionSend, true, "Welcome", GroupID, false, new Vector3(), new byte[0]));
273
274 ChatterBoxSessionStartReplyViaCaps(remoteClient, GroupInfo.GroupName, GroupID);
275
276 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
277 queue.ChatterBoxSessionAgentListUpdates(
278 new UUID(GroupID)
279 , new UUID(im.fromAgentID)
280 , new UUID(im.toAgentID)
281 , false //canVoiceChat
282 , false //isModerator
283 , false //text mute
284 );
285 }
286 }
287
288 // Send a message to a group
289 if ((im.dialog == (byte)InstantMessageDialog.SessionSend))
290 {
291 UUID GroupID = new UUID(im.toAgentID);
292
293 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Send message to session for group {0}", GroupID);
294
295 SendMessageToGroup(im, GroupID);
296 }
297
298 // Incoming message from a group
299 if ((im.dialog == (byte)InstantMessageDialog.SessionSend) && (im.fromGroup == true))
300 {
301 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Message from group session {0} going to agent {1}", im.fromAgentID, im.toAgentID);
302 }
303 }
304 #endregion
305
306 private void RegisterClientAgent(IClientAPI client)
307 {
308 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
309
310 lock (m_ActiveClients)
311 {
312 if (!m_ActiveClients.ContainsKey(client.AgentId.Guid))
313 {
314 client.OnInstantMessage += OnInstantMessage;
315
316 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name);
317
318 m_ActiveClients.Add(client.AgentId.Guid, client);
319 }
320 else
321 {
322 // Remove old client connection for this agent
323 UnregisterClientAgent(client.AgentId);
324
325 // Add new client connection
326 RegisterClientAgent(client);
327 }
328 }
329 }
330 private void UnregisterClientAgent(UUID agentID)
331 {
332 lock (m_ActiveClients)
333 {
334 if (m_ActiveClients.ContainsKey(agentID.Guid))
335 {
336 IClientAPI client = m_ActiveClients[agentID.Guid];
337 client.OnInstantMessage -= OnInstantMessage;
338
339 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage unregistered for {0}", client.Name);
340
341 m_ActiveClients.Remove(agentID.Guid);
342 }
343 else
344 {
345 m_log.InfoFormat("[GROUPS-MESSAGING] Client closed that wasn't registered here.");
346 }
347 }
348 }
349
350 private void SendMessageToGroup(GridInstantMessage im, UUID groupID)
351 {
352 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
353
354 GridInstantMessage msg = new GridInstantMessage();
355 msg.imSessionID = im.imSessionID;
356 msg.fromAgentID = im.imSessionID; // GroupID
357 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
358 msg.fromAgentName = im.fromAgentName;
359 msg.message = im.message;
360 msg.dialog = im.dialog;
361 msg.fromGroup = true;
362 msg.offline = (byte)0;
363 msg.ParentEstateID = im.ParentEstateID;
364 msg.Position = im.Position;
365 msg.RegionID = im.RegionID;
366 msg.binaryBucket = new byte[1] { 0 };
367
368 foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID))
369 {
370 msg.toAgentID = member.AgentID.Guid;
371 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
372 }
373 }
374
375 void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID)
376 {
377 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
378
379 OSDMap moderatedMap = new OSDMap(4);
380 moderatedMap.Add("voice", OSD.FromBoolean(false));
381
382 OSDMap sessionMap = new OSDMap(4);
383 sessionMap.Add("moderated_mode", moderatedMap);
384 sessionMap.Add("session_name", OSD.FromString(groupName));
385 sessionMap.Add("type", OSD.FromInteger(0));
386 sessionMap.Add("voice_enabled", OSD.FromBoolean(false));
387
388
389 OSDMap bodyMap = new OSDMap(4);
390 bodyMap.Add("session_id", OSD.FromUUID(groupID));
391 bodyMap.Add("temp_session_id", OSD.FromUUID(groupID));
392 bodyMap.Add("success", OSD.FromBoolean(true));
393 bodyMap.Add("session_info", sessionMap);
394
395
396 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
397
398 if (queue != null)
399 {
400 queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
401 }
402
403 }
404
405
406 private void DebugGridInstantMessage(GridInstantMessage im)
407 {
408 if (m_debugEnabled)
409 {
410 m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromGroup({0})", im.fromGroup ? "True" : "False");
411 m_log.WarnFormat("[GROUPS-MESSAGING] IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString());
412 m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentID({0})", im.fromAgentID.ToString());
413 m_log.WarnFormat("[GROUPS-MESSAGING] IM: fromAgentName({0})", im.fromAgentName.ToString());
414 m_log.WarnFormat("[GROUPS-MESSAGING] IM: imSessionID({0})", im.imSessionID.ToString());
415 m_log.WarnFormat("[GROUPS-MESSAGING] IM: message({0})", im.message.ToString());
416 m_log.WarnFormat("[GROUPS-MESSAGING] IM: offline({0})", im.offline.ToString());
417 m_log.WarnFormat("[GROUPS-MESSAGING] IM: toAgentID({0})", im.toAgentID.ToString());
418 m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
419 }
420 }
421
422 }
423}
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs
new file mode 100644
index 0000000..ca08fe2
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs
@@ -0,0 +1,1039 @@
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 OpenSim 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.Reflection;
31
32using System.Collections;
33//using Nwc.XmlRpc;
34
35using log4net;
36using Nini.Config;
37
38using OpenMetaverse;
39using OpenMetaverse.StructuredData;
40
41using OpenSim.Framework;
42using OpenSim.Region.CoreModules.Framework.EventQueue;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45
46using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
47using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
48
49
50
51namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
52{
53 public class XmlRpcGroupsModule : INonSharedRegionModule, IGroupsModule
54 {
55 /// <summary>
56 /// To use this module, you must specify the following in your OpenSim.ini
57 /// [GROUPS]
58 /// Enabled = true
59 /// Module = XmlRpcGroups
60 /// XmlRpcMessagingEnabled = true
61 /// XmlRpcNoticesEnabled = true
62 /// XmlRpcDebugEnabled = true
63 ///
64 /// </summary>
65
66 private static readonly ILog m_log =
67 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
68
69 private List<Scene> m_SceneList = new List<Scene>();
70
71 // This only works when running as non-Shared, in shared, there may be multiple IClientAPIs for a single client
72 private Dictionary<UUID, IClientAPI> m_ActiveClients = new Dictionary<UUID, IClientAPI>();
73
74 private IMessageTransferModule m_MsgTransferModule = null;
75
76 private IGroupDataProvider m_groupData = null;
77
78 // Configuration settings
79 private const string m_defaultXmlRpcServiceURL = "http://osflotsam.org/xmlrpc.php";
80 private bool m_GroupsEnabled = false;
81 private bool m_GroupNoticesEnabled = true;
82 private bool m_debugEnabled = true;
83
84 #region IRegionModule Members
85
86 public void Initialise(IConfigSource config)
87 {
88 IConfig groupsConfig = config.Configs["Groups"];
89
90 m_log.Info("[GROUPS]: Initializing XmlRpcGroups");
91
92 if (groupsConfig == null)
93 {
94 // Do not run this module by default.
95 m_log.Info("[GROUPS]: No config found in OpenSim.ini -- not enabling XmlRpcGroups");
96 return;
97 }
98 else
99 {
100 m_GroupsEnabled = groupsConfig.GetBoolean("Enabled", false);
101 if (!m_GroupsEnabled)
102 {
103 m_log.Info("[GROUPS]: Groups disabled in configuration");
104 return;
105 }
106
107 if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups")
108 {
109 m_log.Info("[GROUPS]: Config Groups Module not set to XmlRpcGroups");
110
111 return;
112 }
113
114 string ServiceURL = groupsConfig.GetString("XmlRpcServiceURL", m_defaultXmlRpcServiceURL);
115 m_groupData = new XmlRpcGroupDataProvider(ServiceURL);
116 m_log.InfoFormat("[GROUPS]: XmlRpc Service URL set to: {0}", ServiceURL);
117
118 m_GroupNoticesEnabled = groupsConfig.GetBoolean("XmlRpcNoticesEnabled", true);
119 m_debugEnabled = groupsConfig.GetBoolean("XmlRpcDebugEnabled", true);
120
121 }
122 }
123
124 public void AddRegion(Scene scene)
125 {
126 scene.RegisterModuleInterface<IGroupsModule>(this);
127 }
128 public void RegionLoaded(Scene scene)
129 {
130 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
131
132 if (!m_GroupsEnabled)
133 return;
134
135
136 m_MsgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
137
138 // No message transfer module, no notices, group invites, rejects, ejects, etc
139 if (m_MsgTransferModule == null)
140 {
141 m_GroupsEnabled = false;
142 m_log.Info("[GROUPS]: Could not get MessageTransferModule");
143 Close();
144 return;
145 }
146
147
148 m_SceneList.Add(scene);
149
150 scene.EventManager.OnNewClient += OnNewClient;
151 scene.EventManager.OnClientClosed += OnClientClosed;
152 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
153
154 }
155
156 public void RemoveRegion(Scene scene)
157 {
158 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
159
160 m_SceneList.Remove(scene);
161 }
162
163 public void Close()
164 {
165 m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module.");
166 }
167
168 public string Name
169 {
170 get { return "XmlRpcGroupsModule"; }
171 }
172
173 #endregion
174
175 private void UpdateAllClientsWithGroupInfo()
176 {
177 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
178 foreach (IClientAPI client in m_ActiveClients.Values)
179 {
180 UpdateClientWithGroupInfo(client);
181 }
182 }
183
184 private void UpdateClientWithGroupInfo(IClientAPI client)
185 {
186 m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name);
187 OnAgentDataUpdateRequest(client, client.AgentId, UUID.Zero);
188
189
190 // Need to send a group membership update to the client
191 // UDP version doesn't seem to behave nicely
192 // client.SendGroupMembership(GetMembershipData(client.AgentId));
193
194 GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(client.AgentId).ToArray();
195
196 SendGroupMembershipInfoViaCaps(client, membershipData);
197 client.SendAvatarGroupsReply(client.AgentId, membershipData);
198
199 }
200
201 #region EventHandlers
202 private void OnNewClient(IClientAPI client)
203 {
204 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
205
206
207 lock (m_ActiveClients)
208 {
209 if (!m_ActiveClients.ContainsKey(client.AgentId))
210 {
211 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
212 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
213 client.OnDirFindQuery += OnDirFindQuery;
214 client.OnInstantMessage += OnInstantMessage;
215
216 m_ActiveClients.Add(client.AgentId, client);
217 }
218 }
219
220 UpdateClientWithGroupInfo(client);
221 }
222 private void OnClientClosed(UUID AgentId)
223 {
224 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
225
226 lock (m_ActiveClients)
227 {
228 if (m_ActiveClients.ContainsKey(AgentId))
229 {
230 IClientAPI client = m_ActiveClients[AgentId];
231 client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
232 client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest;
233 client.OnDirFindQuery -= OnDirFindQuery;
234 client.OnInstantMessage -= OnInstantMessage;
235
236 m_ActiveClients.Remove(AgentId);
237 }
238 else
239 {
240 m_log.InfoFormat("[GROUPS] Client closed that wasn't registered here.");
241 }
242
243
244 }
245
246 }
247
248
249 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
250 {
251 if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
252 {
253 m_log.InfoFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
254
255 remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray());
256 }
257
258 }
259
260 private void OnAgentDataUpdateRequest(IClientAPI remoteClient,
261 UUID AgentID, UUID SessionID)
262 {
263 m_log.InfoFormat("[GROUPS] {0} called with SessionID :: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, SessionID);
264
265
266 UUID ActiveGroupID = UUID.Zero;
267 string ActiveGroupTitle = string.Empty;
268 string ActiveGroupName = string.Empty;
269 ulong ActiveGroupPowers = (ulong)GroupPowers.None;
270
271 GroupMembershipData membership = m_groupData.GetAgentActiveMembership(AgentID);
272 if (membership != null)
273 {
274 ActiveGroupID = membership.GroupID;
275 ActiveGroupTitle = membership.GroupTitle;
276 ActiveGroupPowers = membership.GroupPowers;
277 }
278
279 string firstname, lastname;
280 IClientAPI agent;
281 if( m_ActiveClients.TryGetValue(AgentID, out agent) )
282 {
283 firstname = agent.FirstName;
284 lastname = agent.LastName;
285 } else {
286 firstname = "Unknown";
287 lastname = "Unknown";
288 }
289
290 UpdateScenePresenceWithTitle(AgentID, ActiveGroupTitle);
291
292 remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname,
293 lastname, ActiveGroupPowers, ActiveGroupName,
294 ActiveGroupTitle);
295 }
296
297 private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client)
298 {
299 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
300
301 string GroupName;
302
303 GroupRecord group = m_groupData.GetGroupRecord(GroupID, null);
304 if (group != null)
305 {
306 GroupName = group.GroupName;
307 }
308 else
309 {
310 GroupName = "Unknown";
311 }
312
313
314 remote_client.SendGroupNameReply(GroupID, GroupName);
315 }
316
317
318 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
319 {
320 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
321
322
323 // Group invitations
324 if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline))
325 {
326 m_log.WarnFormat("[GROUPS] Received an IIM for {0}.", ((InstantMessageDialog)im.dialog).ToString());
327
328
329 UUID inviteID = new UUID(im.imSessionID);
330 GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID);
331
332 m_log.WarnFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID);
333
334 UUID fromAgentID = new UUID(im.fromAgentID);
335 if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID))
336 {
337
338 // Accept
339 if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept)
340 {
341 m_log.WarnFormat("[GROUPS] Received an accept invite notice.");
342
343 // and the sessionid is the role
344 m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID);
345
346 if (m_MsgTransferModule != null)
347 {
348 GridInstantMessage msg = new GridInstantMessage();
349 msg.imSessionID = UUID.Zero.Guid;
350 msg.fromAgentID = UUID.Zero.Guid;
351 msg.toAgentID = inviteInfo.AgentID.Guid;
352 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
353 msg.fromAgentName = "Groups";
354 msg.message = string.Format("You have been added to the group.");
355 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox;
356 msg.fromGroup = false;
357 msg.offline = (byte)0;
358 msg.ParentEstateID = 0;
359 msg.Position = Vector3.Zero;
360 msg.RegionID = UUID.Zero.Guid;
361 msg.binaryBucket = new byte[0];
362
363 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
364 }
365
366 UpdateAllClientsWithGroupInfo();
367
368 m_groupData.RemoveAgentToGroupInvite(inviteID);
369 }
370
371 // Reject
372 if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)
373 {
374 m_log.WarnFormat("[GROUPS] Received a reject invite notice.");
375 m_groupData.RemoveAgentToGroupInvite(inviteID);
376
377 }
378
379
380 }
381 }
382
383 // Group notices
384 if ((im.dialog == (byte)InstantMessageDialog.GroupNotice))
385 {
386 if (!m_GroupNoticesEnabled)
387 {
388 return;
389 }
390
391 UUID GroupID = new UUID(im.toAgentID);
392 if( m_groupData.GetGroupRecord(GroupID, null) != null)
393 {
394 UUID NoticeID = UUID.Random();
395 string Subject = im.message.Substring(0, im.message.IndexOf('|'));
396 string Message = im.message.Substring(Subject.Length + 1);
397
398 byte[] bucket;
399
400 if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0))
401 {
402 bucket = new byte[19];
403 bucket[0] = 0; //dunno
404 bucket[1] = 0; //dunno
405 GroupID.ToBytes(bucket, 2);
406 bucket[18] = 0; //dunno
407 }
408 else
409 {
410 string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
411 binBucket = binBucket.Remove(0, 14).Trim();
412 m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket);
413
414 OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket);
415
416 foreach (string key in binBucketOSD.Keys)
417 {
418 m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString());
419 }
420
421 // treat as if no attachment
422 bucket = new byte[19];
423 bucket[0] = 0; //dunno
424 bucket[1] = 0; //dunno
425 GroupID.ToBytes(bucket, 2);
426 bucket[18] = 0; //dunno
427 }
428
429
430 m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket);
431 if (OnNewGroupNotice != null)
432 {
433 OnNewGroupNotice(GroupID, NoticeID);
434 }
435
436 // Build notice IIM
437 GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
438
439 // Send notice out to everyone that wants notices
440 foreach( GroupMembersData member in m_groupData.GetGroupMembers(GroupID) )
441 {
442 if( member.AcceptNotices )
443 {
444 msg.toAgentID = member.AgentID.Guid;
445 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
446
447 }
448 }
449
450
451
452 }
453 }
454
455 // Interop, received special 210 code for ejecting a group member
456 // this only works within the comms servers domain, and won't work hypergrid
457 // TODO:FIXME: Use a presense server of some kind to find out where the
458 // client actually is, and try contacting that region directly to notify them,
459 // or provide the notification via xmlrpc update queue
460 if ((im.dialog == 210))
461 {
462 // This is sent from the region that the ejectee was ejected from
463 // if it's being delivered here, then the ejectee is here
464 // so we need to send local updates to the agent.
465
466
467 if (m_MsgTransferModule != null)
468 {
469 im.dialog = (byte)InstantMessageDialog.MessageFromAgent;
470 m_MsgTransferModule.SendInstantMessage(im, delegate(bool success) { });
471 }
472
473 UUID ejecteeID = new UUID(im.toAgentID);
474 UUID groupID = new UUID(im.toAgentID);
475 if (m_ActiveClients.ContainsKey(ejecteeID))
476 {
477 m_ActiveClients[ejecteeID].SendAgentDropGroup(groupID);
478 }
479
480 }
481
482
483
484 }
485
486 private void OnGridInstantMessage(GridInstantMessage msg)
487 {
488 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
489
490 // Trigger the above event handler
491 OnInstantMessage(null, msg);
492 }
493
494
495 #endregion
496
497
498 private void UpdateScenePresenceWithTitle(UUID AgentID, string Title)
499 {
500 m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", AgentID, Title);
501 ScenePresence presence = null;
502 lock (m_SceneList)
503 {
504 foreach (Scene scene in m_SceneList)
505 {
506 presence = scene.GetScenePresence(AgentID);
507 if (presence != null)
508 {
509 presence.Grouptitle = Title;
510
511 // FixMe: Ter suggests a "Schedule" method that I can't find.
512 presence.SendFullUpdateToAllClients();
513 }
514 }
515 }
516 }
517
518
519 #region IGroupsModule Members
520
521 public event NewGroupNotice OnNewGroupNotice;
522
523 public GroupRecord GetGroupRecord(UUID GroupID)
524 {
525 return m_groupData.GetGroupRecord(GroupID, null);
526 }
527
528 public void ActivateGroup(IClientAPI remoteClient, UUID groupID)
529 {
530 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
531
532 m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID);
533
534 // UpdateClientWithGroupInfo(remoteClient);
535 UpdateAllClientsWithGroupInfo();
536 }
537
538 /// <summary>
539 /// Get the Role Titles for an Agent, for a specific group
540 /// </summary>
541 public List<GroupTitlesData> GroupTitlesRequest(IClientAPI remoteClient, UUID groupID)
542 {
543 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
544
545 List<GroupRolesData> agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID);
546 GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID);
547
548 List<GroupTitlesData> titles = new List<GroupTitlesData>();
549 foreach (GroupRolesData role in agentRoles)
550 {
551 GroupTitlesData title = new GroupTitlesData();
552 title.Name = role.Name;
553 title.Selected = agentMembership.ActiveRole == role.RoleID;
554 title.UUID = role.RoleID;
555 }
556
557 return titles;
558 }
559
560 public List<GroupMembersData> GroupMembersRequest(IClientAPI remoteClient, UUID groupID)
561 {
562 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
563
564 List<GroupMembersData> data = m_groupData.GetGroupMembers(groupID);
565
566 foreach (GroupMembersData member in data)
567 {
568 m_log.InfoFormat("[GROUPS] {0} {1}", member.AgentID, member.Title);
569 }
570
571 return data;
572
573 }
574
575 public List<GroupRolesData> GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID)
576 {
577 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
578
579 List<GroupRolesData> data = m_groupData.GetGroupRoles(groupID);
580
581 foreach (GroupRolesData member in data)
582 {
583 m_log.InfoFormat("[GROUPS] {0} {1}", member.Title, member.Members);
584 }
585
586 return data;
587
588 }
589
590 public List<GroupRoleMembersData> GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID)
591 {
592 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
593
594 List<GroupRoleMembersData> data = m_groupData.GetGroupRoleMembers(groupID);
595
596 foreach (GroupRoleMembersData member in data)
597 {
598 m_log.InfoFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID);
599 }
600
601 return data;
602
603
604 }
605
606 public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID)
607 {
608 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
609
610 GroupProfileData profile = new GroupProfileData();
611
612 GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null);
613 if (groupInfo != null)
614 {
615 profile.AllowPublish = groupInfo.AllowPublish;
616 profile.Charter = groupInfo.Charter;
617 profile.FounderID = groupInfo.FounderID;
618 profile.GroupID = groupID;
619 profile.GroupMembershipCount = m_groupData.GetGroupMembers(groupID).Count;
620 profile.GroupRolesCount = m_groupData.GetGroupRoles(groupID).Count;
621 profile.InsigniaID = groupInfo.GroupPicture;
622 profile.MaturePublish = groupInfo.MaturePublish;
623 profile.MembershipFee = groupInfo.MembershipFee;
624 profile.Money = 0; // TODO: Get this from the currency server?
625 profile.Name = groupInfo.GroupName;
626 profile.OpenEnrollment = groupInfo.OpenEnrollment;
627 profile.OwnerRole = groupInfo.OwnerRoleID;
628 profile.ShowInList = groupInfo.ShowInList;
629 }
630
631 GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID);
632 if (memberInfo != null)
633 {
634 profile.MemberTitle = memberInfo.GroupTitle;
635 profile.PowersMask = memberInfo.GroupPowers;
636 }
637
638 return profile;
639 }
640
641 public GroupMembershipData[] GetMembershipData(UUID UserID)
642 {
643 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
644
645 return m_groupData.GetAgentGroupMemberships(UserID).ToArray();
646 }
647
648 public GroupMembershipData GetMembershipData(UUID GroupID, UUID UserID)
649 {
650 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
651
652 return m_groupData.GetAgentGroupMembership(UserID, GroupID);
653 }
654
655 public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
656 {
657 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
658
659 // TODO: Security Check?
660
661 m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
662 }
663
664 public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile)
665 {
666 // TODO: Security Check?
667 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
668
669 m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile);
670 }
671
672 public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
673 {
674 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
675
676 if( m_groupData.GetGroupRecord(UUID.Zero, name) != null )
677 {
678 remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists.");
679 return UUID.Zero;
680 }
681
682 UUID GroupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId);
683
684 remoteClient.SendCreateGroupReply(GroupID, true, "Group created successfullly");
685
686 UpdateClientWithGroupInfo(remoteClient);
687
688 return GroupID;
689 }
690
691 public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID GroupID)
692 {
693 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
694
695 // ToDo: check if agent is a member of group and is allowed to see notices?
696
697 return m_groupData.GetGroupNotices(GroupID).ToArray();
698 }
699
700 /// <summary>
701 /// Get the title of the agent's current role.
702 /// </summary>
703 public string GetGroupTitle(UUID avatarID)
704 {
705 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
706
707 GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID);
708 if (membership != null)
709 {
710 return membership.GroupTitle;
711 }
712 return string.Empty;
713 }
714
715 /// <summary>
716 /// Change the current Active Group Role for Agent
717 /// </summary>
718 public void GroupTitleUpdate(IClientAPI remoteClient, UUID GroupID, UUID TitleRoleID)
719 {
720 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
721
722 m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, GroupID, TitleRoleID);
723
724 UpdateAllClientsWithGroupInfo();
725 }
726
727
728 public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType)
729 {
730 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
731
732 // TODO: Security Checks?
733
734 switch ((OpenMetaverse.GroupRoleUpdate)updateType)
735 {
736 case OpenMetaverse.GroupRoleUpdate.Create:
737 m_groupData.AddGroupRole(groupID, UUID.Random(), name, description, title, powers);
738 break;
739
740 case OpenMetaverse.GroupRoleUpdate.Delete:
741 m_groupData.RemoveGroupRole(groupID, roleID);
742 break;
743
744 case OpenMetaverse.GroupRoleUpdate.UpdateAll:
745 case OpenMetaverse.GroupRoleUpdate.UpdateData:
746 case OpenMetaverse.GroupRoleUpdate.UpdatePowers:
747 m_groupData.UpdateGroupRole(groupID, roleID, name, description, title, powers);
748 break;
749
750 case OpenMetaverse.GroupRoleUpdate.NoUpdate:
751 default:
752 // No Op
753 break;
754
755 }
756
757 UpdateClientWithGroupInfo(remoteClient);
758 }
759
760 public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes)
761 {
762 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
763 // Todo: Security check
764
765 switch (changes)
766 {
767 case 0:
768 // Add
769 m_groupData.AddAgentToGroupRole(memberID, groupID, roleID);
770
771 break;
772 case 1:
773 // Remove
774 m_groupData.RemoveAgentFromGroupRole(memberID, groupID, roleID);
775
776 break;
777 default:
778 m_log.ErrorFormat("[GROUPS] {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes);
779 break;
780 }
781 UpdateClientWithGroupInfo(remoteClient);
782 }
783
784 public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID)
785 {
786 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
787
788
789 GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID);
790
791 if (data != null)
792 {
793 if (m_MsgTransferModule != null)
794 {
795 GridInstantMessage msg = new GridInstantMessage();
796 msg.imSessionID = UUID.Zero.Guid;
797 msg.fromAgentID = data.GroupID.Guid;
798 msg.toAgentID = remoteClient.AgentId.Guid;
799 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
800 msg.fromAgentName = "Group Notice From";
801 msg.message = data.noticeData.Subject + "|" + data.Message;
802 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested;
803 msg.fromGroup = true;
804 msg.offline = (byte)0;
805 msg.ParentEstateID = 0;
806 msg.Position = Vector3.Zero;
807 msg.RegionID = UUID.Zero.Guid;
808 msg.binaryBucket = data.BinaryBucket;
809
810 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
811 }
812 }
813
814 }
815
816 public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog)
817 {
818 m_log.WarnFormat("[GROUPS] {0} is probably not properly implemented", System.Reflection.MethodBase.GetCurrentMethod().Name);
819
820 GridInstantMessage msg = new GridInstantMessage();
821 msg.imSessionID = UUID.Zero.Guid;
822 msg.toAgentID = agentID.Guid;
823 msg.dialog = dialog;
824 // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice;
825 msg.fromGroup = true;
826 msg.offline = (byte)0;
827 msg.ParentEstateID = 0;
828 msg.Position = Vector3.Zero;
829 msg.RegionID = UUID.Zero.Guid;
830
831 GroupNoticeInfo info = m_groupData.GetGroupNotice(groupNoticeID);
832 if (info != null)
833 {
834 msg.fromAgentID = info.GroupID.Guid;
835 msg.timestamp = info.noticeData.Timestamp;
836 msg.fromAgentName = info.noticeData.FromName;
837 msg.message = info.noticeData.Subject + "|" + info.Message;
838 msg.binaryBucket = info.BinaryBucket;
839 }
840
841 return msg;
842 }
843
844 public void SendAgentGroupDataUpdate(IClientAPI remoteClient)
845 {
846 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
847
848 UpdateClientWithGroupInfo(remoteClient);
849 }
850
851 public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID)
852 {
853 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
854
855 // Should check to see if OpenEnrollment, or if there's an outstanding invitation
856 m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero);
857
858 remoteClient.SendJoinGroupReply(groupID, true);
859
860 UpdateClientWithGroupInfo(remoteClient);
861 }
862
863 public void LeaveGroupRequest(IClientAPI remoteClient, UUID GroupID)
864 {
865 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
866
867 m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, GroupID);
868
869 remoteClient.SendLeaveGroupReply(GroupID, true);
870
871 remoteClient.SendAgentDropGroup(GroupID);
872
873 UpdateClientWithGroupInfo(remoteClient);
874 }
875
876 public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID GroupID, UUID EjecteeID)
877 {
878 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
879
880 // Todo: Security check?
881 m_groupData.RemoveAgentFromGroup(EjecteeID, GroupID);
882
883 remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, GroupID, true);
884
885 if (m_MsgTransferModule != null)
886 {
887 GroupRecord groupInfo = m_groupData.GetGroupRecord(GroupID, null);
888 UserProfileData userProfile = m_SceneList[0].CommsManager.UserService.GetUserProfile(EjecteeID);
889
890 if ((groupInfo == null) || (userProfile == null))
891 {
892 return;
893 }
894
895
896 // Send Message to Ejectee
897 GridInstantMessage msg = new GridInstantMessage();
898
899 msg.imSessionID = UUID.Zero.Guid;
900 msg.fromAgentID = remoteClient.AgentId.Guid;
901 // msg.fromAgentID = info.GroupID;
902 msg.toAgentID = EjecteeID.Guid;
903 //msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
904 msg.timestamp = 0;
905 msg.fromAgentName = remoteClient.Name;
906 msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName);
907 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent;
908 msg.fromGroup = false;
909 msg.offline = (byte)0;
910 msg.ParentEstateID = 0;
911 msg.Position = Vector3.Zero;
912 msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid;
913 msg.binaryBucket = new byte[0];
914 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); });
915
916
917 // Message to ejector
918 // Interop, received special 210 code for ejecting a group member
919 // this only works within the comms servers domain, and won't work hypergrid
920 // TODO:FIXME: Use a presense server of some kind to find out where the
921 // client actually is, and try contacting that region directly to notify them,
922 // or provide the notification via xmlrpc update queue
923
924 msg = new GridInstantMessage();
925 msg.imSessionID = UUID.Zero.Guid;
926 msg.fromAgentID = remoteClient.AgentId.Guid;
927 msg.toAgentID = remoteClient.AgentId.Guid;
928 msg.timestamp = 0;
929 msg.fromAgentName = remoteClient.Name;
930 if (userProfile != null)
931 {
932 msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name);
933 }
934 else
935 {
936 msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member");
937 }
938 msg.dialog = (byte)210; //interop
939 msg.fromGroup = false;
940 msg.offline = (byte)0;
941 msg.ParentEstateID = 0;
942 msg.Position = Vector3.Zero;
943 msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid;
944 msg.binaryBucket = new byte[0];
945 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success, ToString()); });
946
947
948
949 }
950
951
952 UpdateAllClientsWithGroupInfo();
953 }
954
955 public void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InvitedAgentID, UUID RoleID)
956 {
957 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
958 m_log.WarnFormat("[GROUPS] GID {0}, AID {1}, RID {2} ", GroupID, InvitedAgentID, RoleID);
959
960 // Todo: Security check, probably also want to send some kind of notification
961 UUID InviteID = UUID.Random();
962 m_log.WarnFormat("[GROUPS] Invite ID: {0}", InviteID);
963 m_groupData.AddAgentToGroupInvite(InviteID, GroupID, RoleID, InvitedAgentID);
964
965 if (m_MsgTransferModule != null)
966 {
967 Guid inviteUUID = InviteID.Guid;
968
969 GridInstantMessage msg = new GridInstantMessage();
970
971 msg.imSessionID = inviteUUID;
972
973 // msg.fromAgentID = remoteClient.AgentId.Guid;
974 msg.fromAgentID = GroupID.Guid;
975 msg.toAgentID = InvitedAgentID.Guid;
976 //msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
977 msg.timestamp = 0;
978 msg.fromAgentName = remoteClient.Name;
979 msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name);
980 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation;
981 msg.fromGroup = true;
982 msg.offline = (byte)0;
983 msg.ParentEstateID = 0;
984 msg.Position = Vector3.Zero;
985 msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid;
986 msg.binaryBucket = new byte[20];
987
988 m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) { m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); });
989 }
990 }
991
992 #endregion
993
994 void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, GroupMembershipData[] data)
995 {
996 if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
997
998 OSDArray AgentData = new OSDArray(1);
999 OSDMap AgentDataMap = new OSDMap(1);
1000 AgentDataMap.Add("AgentID", OSD.FromUUID(remoteClient.AgentId));
1001 AgentData.Add(AgentDataMap);
1002
1003
1004 OSDArray GroupData = new OSDArray(data.Length);
1005 OSDArray NewGroupData = new OSDArray(data.Length);
1006
1007 foreach (GroupMembershipData membership in data)
1008 {
1009 OSDMap GroupDataMap = new OSDMap(6);
1010 OSDMap NewGroupDataMap = new OSDMap(1);
1011
1012 GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID));
1013 GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers));
1014 GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices));
1015 GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture));
1016 GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution));
1017 GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName));
1018 NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile));
1019
1020 GroupData.Add(GroupDataMap);
1021 NewGroupData.Add(NewGroupDataMap);
1022 }
1023
1024 OSDMap llDataStruct = new OSDMap(3);
1025 llDataStruct.Add("AgentData", AgentData);
1026 llDataStruct.Add("GroupData", GroupData);
1027 llDataStruct.Add("NewGroupData", NewGroupData);
1028
1029 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
1030
1031 if (queue != null)
1032 {
1033 queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId);
1034 }
1035
1036 }
1037 }
1038
1039}
diff --git a/OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml b/OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml
new file mode 100644
index 0000000..4795edc
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Resources/OptionalModules.addin.xml
@@ -0,0 +1,14 @@
1<Addin id="OpenSim.Region.OptionalModules" version="0.1">
2 <Runtime>
3 <Import assembly="OpenSim.Region.OptionalModules.dll"/>
4 </Runtime>
5
6 <Dependencies>
7 <Addin id="OpenSim" version="0.5" />
8 </Dependencies>
9
10 <Extension path = "/OpenSim/RegionModules">
11 <RegionModule id="XmlRpcGroups" type="OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.XmlRpcGroupsModule" />
12 <RegionModule id="XmlRpcGroupsMessaging" type="OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.XmlRpcGroupsMessaging" />
13 </Extension>
14</Addin>
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 127501c..27aa5e0 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -1229,4 +1229,26 @@ freeswitch_echo_port = 50505
1229freeswitch_well_known_ip = ip.address.of.freeswitch.server 1229freeswitch_well_known_ip = ip.address.of.freeswitch.server
1230freeswitch_default_timeout = 5000 1230freeswitch_default_timeout = 5000
1231freeswitch_subscribe_retry = 120 1231freeswitch_subscribe_retry = 120
1232; freeswitch_password_reset_url = \ No newline at end of file 1232; freeswitch_password_reset_url =
1233
1234
1235[Groups]
1236 Enabled = false
1237
1238 ; This is the current groups stub in Region.CoreModules.Avatar.Groups
1239 Module = Default
1240
1241
1242 ; The XmlRpcGroups implementation can be used against the publically available service
1243 ; that I have made available for testing. Your group data is not guarenteed safe
1244 ; or available if you use this service, but it's available now and seems to work.
1245 ; The PHP code for the service is available for you to deploy to your own server.
1246 ;
1247 ;Module = XmlRpcGroups
1248
1249 ;XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php
1250 ;XmlRpcMessagingEnabled = true
1251 ;XmlRpcNoticesEnabled = true
1252
1253 ; This makes the XmlRpcGroups modules very chatty on the console.
1254 ;XmlRpcDebugEnabled = true
diff --git a/prebuild.xml b/prebuild.xml
index 72cfb76..7d33fac 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1268,6 +1268,7 @@
1268 <Reference name="OpenSim.Framework.Servers"/> 1268 <Reference name="OpenSim.Framework.Servers"/>
1269 <Reference name="OpenSim.Framework.Statistics"/> 1269 <Reference name="OpenSim.Framework.Statistics"/>
1270 <Reference name="OpenSim.Region.Physics.Manager"/> 1270 <Reference name="OpenSim.Region.Physics.Manager"/>
1271 <Reference name="Mono.Addins.dll" />
1271 1272
1272 <!-- For scripting in funny languages by default --> 1273 <!-- For scripting in funny languages by default -->
1273 <Reference name="Microsoft.JScript"/> 1274 <Reference name="Microsoft.JScript"/>
@@ -1277,10 +1278,12 @@
1277 <Reference name="log4net.dll"/> 1278 <Reference name="log4net.dll"/>
1278 <Reference name="DotNetOpenMail.dll"/> 1279 <Reference name="DotNetOpenMail.dll"/>
1279 1280
1281
1280 <Files> 1282 <Files>
1281 <Match pattern="*.cs" recurse="true"> 1283 <Match pattern="*.cs" recurse="true">
1282 <Exclude name="Tests" pattern="Tests" /> 1284 <Exclude name="Tests" pattern="Tests" />
1283 </Match> 1285 </Match>
1286 <Match pattern="*.addin.xml" path="Resources" buildAction="EmbeddedResource" recurse="true"/>
1284 </Files> 1287 </Files>
1285 </Project> 1288 </Project>
1286 1289
@@ -3289,3 +3292,4 @@
3289 3292
3290 3293
3291 3294
3295