diff options
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs')
-rw-r--r-- | OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 1009 |
1 files changed, 1009 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs new file mode 100644 index 0000000..d77fe5b --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | |||
@@ -0,0 +1,1009 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using Nwc.XmlRpc; | ||
34 | |||
35 | using log4net; | ||
36 | using Mono.Addins; | ||
37 | using Nini.Config; | ||
38 | |||
39 | using OpenMetaverse; | ||
40 | using OpenMetaverse.StructuredData; | ||
41 | |||
42 | using OpenSim.Framework; | ||
43 | using OpenSim.Region.Framework.Interfaces; | ||
44 | |||
45 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | ||
46 | { | ||
47 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] | ||
48 | public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector | ||
49 | { | ||
50 | private static readonly ILog m_log = | ||
51 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
52 | |||
53 | |||
54 | public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | | ||
55 | GroupPowers.Accountable | | ||
56 | GroupPowers.JoinChat | | ||
57 | GroupPowers.AllowVoiceChat | | ||
58 | GroupPowers.ReceiveNotices | | ||
59 | GroupPowers.StartProposal | | ||
60 | GroupPowers.VoteOnProposal; | ||
61 | |||
62 | private bool m_connectorEnabled = false; | ||
63 | |||
64 | private string m_serviceURL = string.Empty; | ||
65 | |||
66 | private bool m_disableKeepAlive = false; | ||
67 | |||
68 | private string m_groupReadKey = string.Empty; | ||
69 | private string m_groupWriteKey = string.Empty; | ||
70 | |||
71 | |||
72 | #region IRegionModuleBase Members | ||
73 | |||
74 | public string Name | ||
75 | { | ||
76 | get { return "XmlRpcGroupsServicesConnector"; } | ||
77 | } | ||
78 | |||
79 | // this module is not intended to be replaced, but there should only be 1 of them. | ||
80 | public Type ReplacableInterface | ||
81 | { | ||
82 | get { return null; } | ||
83 | } | ||
84 | |||
85 | public void Initialise(IConfigSource config) | ||
86 | { | ||
87 | IConfig groupsConfig = config.Configs["Groups"]; | ||
88 | |||
89 | if (groupsConfig == null) | ||
90 | { | ||
91 | // Do not run this module by default. | ||
92 | return; | ||
93 | } | ||
94 | else | ||
95 | { | ||
96 | // if groups aren't enabled, we're not needed. | ||
97 | // if we're not specified as the connector to use, then we're not wanted | ||
98 | if ( (groupsConfig.GetBoolean("Enabled", false) == false) | ||
99 | || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) | ||
100 | { | ||
101 | m_connectorEnabled = false; | ||
102 | return; | ||
103 | } | ||
104 | |||
105 | m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); | ||
106 | |||
107 | m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); | ||
108 | if ((m_serviceURL == null) || | ||
109 | (m_serviceURL == string.Empty)) | ||
110 | { | ||
111 | m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); | ||
112 | m_connectorEnabled = false; | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | m_disableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); | ||
117 | |||
118 | m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); | ||
119 | m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); | ||
120 | |||
121 | // If we got all the config options we need, lets start'er'up | ||
122 | m_connectorEnabled = true; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | public void Close() | ||
127 | { | ||
128 | m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); | ||
129 | } | ||
130 | |||
131 | public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) | ||
132 | { | ||
133 | if (m_connectorEnabled) | ||
134 | scene.RegisterModuleInterface<IGroupsServicesConnector>(this); | ||
135 | } | ||
136 | |||
137 | public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) | ||
138 | { | ||
139 | if (scene.RequestModuleInterface<IGroupsServicesConnector>() == this) | ||
140 | scene.UnregisterModuleInterface<IGroupsServicesConnector>(this); | ||
141 | } | ||
142 | |||
143 | public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) | ||
144 | { | ||
145 | // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info | ||
146 | // scene.EventManager.OnNewClient += OnNewClient; | ||
147 | } | ||
148 | |||
149 | #endregion | ||
150 | |||
151 | #region ISharedRegionModule Members | ||
152 | |||
153 | public void PostInitialise() | ||
154 | { | ||
155 | // NoOp | ||
156 | } | ||
157 | |||
158 | #endregion | ||
159 | |||
160 | |||
161 | |||
162 | #region IGroupsServicesConnector Members | ||
163 | |||
164 | /// <summary> | ||
165 | /// 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. | ||
166 | /// </summary> | ||
167 | public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, | ||
168 | int membershipFee, bool openEnrollment, bool allowPublish, | ||
169 | bool maturePublish, UUID founderID) | ||
170 | { | ||
171 | UUID GroupID = UUID.Random(); | ||
172 | UUID OwnerRoleID = UUID.Random(); | ||
173 | |||
174 | Hashtable param = new Hashtable(); | ||
175 | param["GroupID"] = GroupID.ToString(); | ||
176 | param["Name"] = name; | ||
177 | param["Charter"] = charter; | ||
178 | param["ShowInList"] = showInList == true ? 1 : 0; | ||
179 | param["InsigniaID"] = insigniaID.ToString(); | ||
180 | param["MembershipFee"] = 0; | ||
181 | param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; | ||
182 | param["AllowPublish"] = allowPublish == true ? 1 : 0; | ||
183 | param["MaturePublish"] = maturePublish == true ? 1 : 0; | ||
184 | param["FounderID"] = founderID.ToString(); | ||
185 | param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); | ||
186 | param["OwnerRoleID"] = OwnerRoleID.ToString(); | ||
187 | |||
188 | // Would this be cleaner as (GroupPowers)ulong.MaxValue; | ||
189 | GroupPowers OwnerPowers = GroupPowers.Accountable | ||
190 | | GroupPowers.AllowEditLand | ||
191 | | GroupPowers.AllowFly | ||
192 | | GroupPowers.AllowLandmark | ||
193 | | GroupPowers.AllowRez | ||
194 | | GroupPowers.AllowSetHome | ||
195 | | GroupPowers.AllowVoiceChat | ||
196 | | GroupPowers.AssignMember | ||
197 | | GroupPowers.AssignMemberLimited | ||
198 | | GroupPowers.ChangeActions | ||
199 | | GroupPowers.ChangeIdentity | ||
200 | | GroupPowers.ChangeMedia | ||
201 | | GroupPowers.ChangeOptions | ||
202 | | GroupPowers.CreateRole | ||
203 | | GroupPowers.DeedObject | ||
204 | | GroupPowers.DeleteRole | ||
205 | | GroupPowers.Eject | ||
206 | | GroupPowers.FindPlaces | ||
207 | | GroupPowers.Invite | ||
208 | | GroupPowers.JoinChat | ||
209 | | GroupPowers.LandChangeIdentity | ||
210 | | GroupPowers.LandDeed | ||
211 | | GroupPowers.LandDivideJoin | ||
212 | | GroupPowers.LandEdit | ||
213 | | GroupPowers.LandEjectAndFreeze | ||
214 | | GroupPowers.LandGardening | ||
215 | | GroupPowers.LandManageAllowed | ||
216 | | GroupPowers.LandManageBanned | ||
217 | | GroupPowers.LandManagePasses | ||
218 | | GroupPowers.LandOptions | ||
219 | | GroupPowers.LandRelease | ||
220 | | GroupPowers.LandSetSale | ||
221 | | GroupPowers.ModerateChat | ||
222 | | GroupPowers.ObjectManipulate | ||
223 | | GroupPowers.ObjectSetForSale | ||
224 | | GroupPowers.ReceiveNotices | ||
225 | | GroupPowers.RemoveMember | ||
226 | | GroupPowers.ReturnGroupOwned | ||
227 | | GroupPowers.ReturnGroupSet | ||
228 | | GroupPowers.ReturnNonGroup | ||
229 | | GroupPowers.RoleProperties | ||
230 | | GroupPowers.SendNotices | ||
231 | | GroupPowers.SetLandingPoint | ||
232 | | GroupPowers.StartProposal | ||
233 | | GroupPowers.VoteOnProposal; | ||
234 | param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); | ||
235 | |||
236 | |||
237 | |||
238 | |||
239 | Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); | ||
240 | |||
241 | if (respData.Contains("error")) | ||
242 | { | ||
243 | // UUID is not nullable | ||
244 | |||
245 | return UUID.Zero; | ||
246 | } | ||
247 | |||
248 | return UUID.Parse((string)respData["GroupID"]); | ||
249 | } | ||
250 | |||
251 | public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, | ||
252 | UUID insigniaID, int membershipFee, bool openEnrollment, | ||
253 | bool allowPublish, bool maturePublish) | ||
254 | { | ||
255 | Hashtable param = new Hashtable(); | ||
256 | param["GroupID"] = groupID.ToString(); | ||
257 | param["Charter"] = charter; | ||
258 | param["ShowInList"] = showInList == true ? 1 : 0; | ||
259 | param["InsigniaID"] = insigniaID.ToString(); | ||
260 | param["MembershipFee"] = membershipFee; | ||
261 | param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; | ||
262 | param["AllowPublish"] = allowPublish == true ? 1 : 0; | ||
263 | param["MaturePublish"] = maturePublish == true ? 1 : 0; | ||
264 | |||
265 | XmlRpcCall(requestID, "groups.updateGroup", param); | ||
266 | } | ||
267 | |||
268 | public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, | ||
269 | string title, ulong powers) | ||
270 | { | ||
271 | Hashtable param = new Hashtable(); | ||
272 | param["GroupID"] = groupID.ToString(); | ||
273 | param["RoleID"] = roleID.ToString(); | ||
274 | param["Name"] = name; | ||
275 | param["Description"] = description; | ||
276 | param["Title"] = title; | ||
277 | param["Powers"] = powers.ToString(); | ||
278 | |||
279 | XmlRpcCall(requestID, "groups.addRoleToGroup", param); | ||
280 | } | ||
281 | |||
282 | public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) | ||
283 | { | ||
284 | Hashtable param = new Hashtable(); | ||
285 | param["GroupID"] = groupID.ToString(); | ||
286 | param["RoleID"] = roleID.ToString(); | ||
287 | |||
288 | XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); | ||
289 | } | ||
290 | |||
291 | public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, | ||
292 | string title, ulong powers) | ||
293 | { | ||
294 | Hashtable param = new Hashtable(); | ||
295 | param["GroupID"] = groupID.ToString(); | ||
296 | param["RoleID"] = roleID.ToString(); | ||
297 | if (name != null) | ||
298 | { | ||
299 | param["Name"] = name; | ||
300 | } | ||
301 | if (description != null) | ||
302 | { | ||
303 | param["Description"] = description; | ||
304 | } | ||
305 | if (title != null) | ||
306 | { | ||
307 | param["Title"] = title; | ||
308 | } | ||
309 | param["Powers"] = powers.ToString(); | ||
310 | |||
311 | XmlRpcCall(requestID, "groups.updateGroupRole", param); | ||
312 | } | ||
313 | |||
314 | public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) | ||
315 | { | ||
316 | Hashtable param = new Hashtable(); | ||
317 | if (GroupID != UUID.Zero) | ||
318 | { | ||
319 | param["GroupID"] = GroupID.ToString(); | ||
320 | } | ||
321 | if ((GroupName != null) && (GroupName != string.Empty)) | ||
322 | { | ||
323 | param["Name"] = GroupName.ToString(); | ||
324 | } | ||
325 | |||
326 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); | ||
327 | |||
328 | if (respData.Contains("error")) | ||
329 | { | ||
330 | return null; | ||
331 | } | ||
332 | |||
333 | return GroupProfileHashtableToGroupRecord(respData); | ||
334 | |||
335 | } | ||
336 | |||
337 | public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) | ||
338 | { | ||
339 | Hashtable param = new Hashtable(); | ||
340 | param["GroupID"] = GroupID.ToString(); | ||
341 | |||
342 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); | ||
343 | |||
344 | if (respData.Contains("error")) | ||
345 | { | ||
346 | // GroupProfileData is not nullable | ||
347 | return new GroupProfileData(); | ||
348 | } | ||
349 | |||
350 | GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); | ||
351 | GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); | ||
352 | |||
353 | MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; | ||
354 | MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; | ||
355 | |||
356 | return MemberGroupProfile; | ||
357 | |||
358 | } | ||
359 | |||
360 | |||
361 | |||
362 | public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) | ||
363 | { | ||
364 | Hashtable param = new Hashtable(); | ||
365 | param["AgentID"] = AgentID.ToString(); | ||
366 | param["GroupID"] = GroupID.ToString(); | ||
367 | |||
368 | XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); | ||
369 | } | ||
370 | |||
371 | public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
372 | { | ||
373 | Hashtable param = new Hashtable(); | ||
374 | param["AgentID"] = AgentID.ToString(); | ||
375 | param["GroupID"] = GroupID.ToString(); | ||
376 | param["SelectedRoleID"] = RoleID.ToString(); | ||
377 | |||
378 | XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); | ||
379 | } | ||
380 | |||
381 | public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) | ||
382 | { | ||
383 | Hashtable param = new Hashtable(); | ||
384 | param["AgentID"] = AgentID.ToString(); | ||
385 | param["GroupID"] = GroupID.ToString(); | ||
386 | param["AcceptNotices"] = AcceptNotices ? "1" : "0"; | ||
387 | param["ListInProfile"] = ListInProfile ? "1" : "0"; | ||
388 | |||
389 | XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); | ||
390 | |||
391 | } | ||
392 | |||
393 | public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) | ||
394 | { | ||
395 | Hashtable param = new Hashtable(); | ||
396 | param["InviteID"] = inviteID.ToString(); | ||
397 | param["AgentID"] = agentID.ToString(); | ||
398 | param["RoleID"] = roleID.ToString(); | ||
399 | param["GroupID"] = groupID.ToString(); | ||
400 | |||
401 | XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); | ||
402 | |||
403 | } | ||
404 | |||
405 | public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) | ||
406 | { | ||
407 | Hashtable param = new Hashtable(); | ||
408 | param["InviteID"] = inviteID.ToString(); | ||
409 | |||
410 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); | ||
411 | |||
412 | if (respData.Contains("error")) | ||
413 | { | ||
414 | return null; | ||
415 | } | ||
416 | |||
417 | GroupInviteInfo inviteInfo = new GroupInviteInfo(); | ||
418 | inviteInfo.InviteID = inviteID; | ||
419 | inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]); | ||
420 | inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]); | ||
421 | inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]); | ||
422 | |||
423 | return inviteInfo; | ||
424 | } | ||
425 | |||
426 | public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) | ||
427 | { | ||
428 | Hashtable param = new Hashtable(); | ||
429 | param["InviteID"] = inviteID.ToString(); | ||
430 | |||
431 | XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); | ||
432 | } | ||
433 | |||
434 | public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
435 | { | ||
436 | Hashtable param = new Hashtable(); | ||
437 | param["AgentID"] = AgentID.ToString(); | ||
438 | param["GroupID"] = GroupID.ToString(); | ||
439 | param["RoleID"] = RoleID.ToString(); | ||
440 | |||
441 | XmlRpcCall(requestID, "groups.addAgentToGroup", param); | ||
442 | } | ||
443 | |||
444 | public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) | ||
445 | { | ||
446 | Hashtable param = new Hashtable(); | ||
447 | param["AgentID"] = AgentID.ToString(); | ||
448 | param["GroupID"] = GroupID.ToString(); | ||
449 | |||
450 | XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); | ||
451 | } | ||
452 | |||
453 | public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
454 | { | ||
455 | Hashtable param = new Hashtable(); | ||
456 | param["AgentID"] = AgentID.ToString(); | ||
457 | param["GroupID"] = GroupID.ToString(); | ||
458 | param["RoleID"] = RoleID.ToString(); | ||
459 | |||
460 | XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); | ||
461 | } | ||
462 | |||
463 | public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
464 | { | ||
465 | Hashtable param = new Hashtable(); | ||
466 | param["AgentID"] = AgentID.ToString(); | ||
467 | param["GroupID"] = GroupID.ToString(); | ||
468 | param["RoleID"] = RoleID.ToString(); | ||
469 | |||
470 | XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); | ||
471 | } | ||
472 | |||
473 | |||
474 | public List<DirGroupsReplyData> FindGroups(GroupRequestID requestID, string search) | ||
475 | { | ||
476 | Hashtable param = new Hashtable(); | ||
477 | param["Search"] = search; | ||
478 | |||
479 | Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); | ||
480 | |||
481 | List<DirGroupsReplyData> findings = new List<DirGroupsReplyData>(); | ||
482 | |||
483 | if (!respData.Contains("error")) | ||
484 | { | ||
485 | Hashtable results = (Hashtable)respData["results"]; | ||
486 | foreach (Hashtable groupFind in results.Values) | ||
487 | { | ||
488 | DirGroupsReplyData data = new DirGroupsReplyData(); | ||
489 | data.groupID = new UUID((string)groupFind["GroupID"]); ; | ||
490 | data.groupName = (string)groupFind["Name"]; | ||
491 | data.members = int.Parse((string)groupFind["Members"]); | ||
492 | // data.searchOrder = order; | ||
493 | |||
494 | findings.Add(data); | ||
495 | } | ||
496 | } | ||
497 | |||
498 | return findings; | ||
499 | } | ||
500 | |||
501 | public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) | ||
502 | { | ||
503 | Hashtable param = new Hashtable(); | ||
504 | param["AgentID"] = AgentID.ToString(); | ||
505 | param["GroupID"] = GroupID.ToString(); | ||
506 | |||
507 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); | ||
508 | |||
509 | if (respData.Contains("error")) | ||
510 | { | ||
511 | return null; | ||
512 | } | ||
513 | |||
514 | GroupMembershipData data = HashTableToGroupMembershipData(respData); | ||
515 | |||
516 | return data; | ||
517 | } | ||
518 | |||
519 | public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) | ||
520 | { | ||
521 | Hashtable param = new Hashtable(); | ||
522 | param["AgentID"] = AgentID.ToString(); | ||
523 | |||
524 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); | ||
525 | |||
526 | if (respData.Contains("error")) | ||
527 | { | ||
528 | return null; | ||
529 | } | ||
530 | |||
531 | return HashTableToGroupMembershipData(respData); | ||
532 | } | ||
533 | |||
534 | |||
535 | public List<GroupMembershipData> GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) | ||
536 | { | ||
537 | Hashtable param = new Hashtable(); | ||
538 | param["AgentID"] = AgentID.ToString(); | ||
539 | |||
540 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); | ||
541 | |||
542 | List<GroupMembershipData> memberships = new List<GroupMembershipData>(); | ||
543 | |||
544 | if (!respData.Contains("error")) | ||
545 | { | ||
546 | foreach (object membership in respData.Values) | ||
547 | { | ||
548 | memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); | ||
549 | } | ||
550 | } | ||
551 | |||
552 | return memberships; | ||
553 | } | ||
554 | |||
555 | public List<GroupRolesData> GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) | ||
556 | { | ||
557 | Hashtable param = new Hashtable(); | ||
558 | param["AgentID"] = AgentID.ToString(); | ||
559 | param["GroupID"] = GroupID.ToString(); | ||
560 | |||
561 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); | ||
562 | |||
563 | List<GroupRolesData> Roles = new List<GroupRolesData>(); | ||
564 | |||
565 | if (respData.Contains("error")) | ||
566 | { | ||
567 | return Roles; | ||
568 | } | ||
569 | |||
570 | foreach (Hashtable role in respData.Values) | ||
571 | { | ||
572 | GroupRolesData data = new GroupRolesData(); | ||
573 | data.RoleID = new UUID((string)role["RoleID"]); | ||
574 | data.Name = (string)role["Name"]; | ||
575 | data.Description = (string)role["Description"]; | ||
576 | data.Powers = ulong.Parse((string)role["Powers"]); | ||
577 | data.Title = (string)role["Title"]; | ||
578 | |||
579 | Roles.Add(data); | ||
580 | } | ||
581 | |||
582 | return Roles; | ||
583 | |||
584 | |||
585 | } | ||
586 | |||
587 | public List<GroupRolesData> GetGroupRoles(GroupRequestID requestID, UUID GroupID) | ||
588 | { | ||
589 | Hashtable param = new Hashtable(); | ||
590 | param["GroupID"] = GroupID.ToString(); | ||
591 | |||
592 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); | ||
593 | |||
594 | List<GroupRolesData> Roles = new List<GroupRolesData>(); | ||
595 | |||
596 | if (respData.Contains("error")) | ||
597 | { | ||
598 | return Roles; | ||
599 | } | ||
600 | |||
601 | foreach (Hashtable role in respData.Values) | ||
602 | { | ||
603 | GroupRolesData data = new GroupRolesData(); | ||
604 | data.Description = (string)role["Description"]; | ||
605 | data.Members = int.Parse((string)role["Members"]); | ||
606 | data.Name = (string)role["Name"]; | ||
607 | data.Powers = ulong.Parse((string)role["Powers"]); | ||
608 | data.RoleID = new UUID((string)role["RoleID"]); | ||
609 | data.Title = (string)role["Title"]; | ||
610 | |||
611 | Roles.Add(data); | ||
612 | } | ||
613 | |||
614 | return Roles; | ||
615 | |||
616 | } | ||
617 | |||
618 | |||
619 | |||
620 | public List<GroupMembersData> GetGroupMembers(GroupRequestID requestID, UUID GroupID) | ||
621 | { | ||
622 | Hashtable param = new Hashtable(); | ||
623 | param["GroupID"] = GroupID.ToString(); | ||
624 | |||
625 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); | ||
626 | |||
627 | List<GroupMembersData> members = new List<GroupMembersData>(); | ||
628 | |||
629 | if (respData.Contains("error")) | ||
630 | { | ||
631 | return members; | ||
632 | } | ||
633 | |||
634 | foreach (Hashtable membership in respData.Values) | ||
635 | { | ||
636 | GroupMembersData data = new GroupMembersData(); | ||
637 | |||
638 | data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1"; | ||
639 | data.AgentID = new UUID((string)membership["AgentID"]); | ||
640 | data.Contribution = int.Parse((string)membership["Contribution"]); | ||
641 | data.IsOwner = ((string)membership["IsOwner"]) == "1"; | ||
642 | data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; | ||
643 | data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); | ||
644 | data.Title = (string)membership["Title"]; | ||
645 | |||
646 | members.Add(data); | ||
647 | } | ||
648 | |||
649 | return members; | ||
650 | |||
651 | } | ||
652 | |||
653 | public List<GroupRoleMembersData> GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) | ||
654 | { | ||
655 | Hashtable param = new Hashtable(); | ||
656 | param["GroupID"] = GroupID.ToString(); | ||
657 | |||
658 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); | ||
659 | |||
660 | List<GroupRoleMembersData> members = new List<GroupRoleMembersData>(); | ||
661 | |||
662 | if (!respData.Contains("error")) | ||
663 | { | ||
664 | foreach (Hashtable membership in respData.Values) | ||
665 | { | ||
666 | GroupRoleMembersData data = new GroupRoleMembersData(); | ||
667 | |||
668 | data.MemberID = new UUID((string)membership["AgentID"]); | ||
669 | data.RoleID = new UUID((string)membership["RoleID"]); | ||
670 | |||
671 | members.Add(data); | ||
672 | } | ||
673 | } | ||
674 | return members; | ||
675 | } | ||
676 | |||
677 | public List<GroupNoticeData> GetGroupNotices(GroupRequestID requestID, UUID GroupID) | ||
678 | { | ||
679 | Hashtable param = new Hashtable(); | ||
680 | param["GroupID"] = GroupID.ToString(); | ||
681 | |||
682 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); | ||
683 | |||
684 | List<GroupNoticeData> values = new List<GroupNoticeData>(); | ||
685 | |||
686 | if (!respData.Contains("error")) | ||
687 | { | ||
688 | foreach (Hashtable value in respData.Values) | ||
689 | { | ||
690 | GroupNoticeData data = new GroupNoticeData(); | ||
691 | data.NoticeID = UUID.Parse((string)value["NoticeID"]); | ||
692 | data.Timestamp = uint.Parse((string)value["Timestamp"]); | ||
693 | data.FromName = (string)value["FromName"]; | ||
694 | data.Subject = (string)value["Subject"]; | ||
695 | data.HasAttachment = false; | ||
696 | data.AssetType = 0; | ||
697 | |||
698 | values.Add(data); | ||
699 | } | ||
700 | } | ||
701 | return values; | ||
702 | |||
703 | } | ||
704 | public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) | ||
705 | { | ||
706 | Hashtable param = new Hashtable(); | ||
707 | param["NoticeID"] = noticeID.ToString(); | ||
708 | |||
709 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); | ||
710 | |||
711 | |||
712 | if (respData.Contains("error")) | ||
713 | { | ||
714 | return null; | ||
715 | } | ||
716 | |||
717 | GroupNoticeInfo data = new GroupNoticeInfo(); | ||
718 | data.GroupID = UUID.Parse((string)respData["GroupID"]); | ||
719 | data.Message = (string)respData["Message"]; | ||
720 | data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true); | ||
721 | data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]); | ||
722 | data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]); | ||
723 | data.noticeData.FromName = (string)respData["FromName"]; | ||
724 | data.noticeData.Subject = (string)respData["Subject"]; | ||
725 | data.noticeData.HasAttachment = false; | ||
726 | data.noticeData.AssetType = 0; | ||
727 | |||
728 | if (data.Message == null) | ||
729 | { | ||
730 | data.Message = string.Empty; | ||
731 | } | ||
732 | |||
733 | return data; | ||
734 | } | ||
735 | public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) | ||
736 | { | ||
737 | string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); | ||
738 | |||
739 | Hashtable param = new Hashtable(); | ||
740 | param["GroupID"] = groupID.ToString(); | ||
741 | param["NoticeID"] = noticeID.ToString(); | ||
742 | param["FromName"] = fromName; | ||
743 | param["Subject"] = subject; | ||
744 | param["Message"] = message; | ||
745 | param["BinaryBucket"] = binBucket; | ||
746 | param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); | ||
747 | |||
748 | XmlRpcCall(requestID, "groups.addGroupNotice", param); | ||
749 | } | ||
750 | #endregion | ||
751 | |||
752 | #region XmlRpcHashtableMarshalling | ||
753 | private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) | ||
754 | { | ||
755 | GroupProfileData group = new GroupProfileData(); | ||
756 | group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); | ||
757 | group.Name = (string)groupProfile["Name"]; | ||
758 | |||
759 | if (groupProfile["Charter"] != null) | ||
760 | { | ||
761 | group.Charter = (string)groupProfile["Charter"]; | ||
762 | } | ||
763 | |||
764 | group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; | ||
765 | group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]); | ||
766 | group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); | ||
767 | group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; | ||
768 | group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; | ||
769 | group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; | ||
770 | group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); | ||
771 | group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]); | ||
772 | |||
773 | group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]); | ||
774 | group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]); | ||
775 | |||
776 | return group; | ||
777 | } | ||
778 | |||
779 | private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) | ||
780 | { | ||
781 | |||
782 | GroupRecord group = new GroupRecord(); | ||
783 | group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); | ||
784 | group.GroupName = groupProfile["Name"].ToString(); | ||
785 | if (groupProfile["Charter"] != null) | ||
786 | { | ||
787 | group.Charter = (string)groupProfile["Charter"]; | ||
788 | } | ||
789 | group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; | ||
790 | group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); | ||
791 | group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); | ||
792 | group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; | ||
793 | group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; | ||
794 | group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; | ||
795 | group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); | ||
796 | group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); | ||
797 | |||
798 | return group; | ||
799 | } | ||
800 | private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) | ||
801 | { | ||
802 | GroupMembershipData data = new GroupMembershipData(); | ||
803 | data.AcceptNotices = ((string)respData["AcceptNotices"] == "1"); | ||
804 | data.Contribution = int.Parse((string)respData["Contribution"]); | ||
805 | data.ListInProfile = ((string)respData["ListInProfile"] == "1"); | ||
806 | |||
807 | data.ActiveRole = new UUID((string)respData["SelectedRoleID"]); | ||
808 | data.GroupTitle = (string)respData["Title"]; | ||
809 | |||
810 | data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]); | ||
811 | |||
812 | // Is this group the agent's active group | ||
813 | |||
814 | data.GroupID = new UUID((string)respData["GroupID"]); | ||
815 | |||
816 | UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]); | ||
817 | data.Active = data.GroupID.Equals(ActiveGroup); | ||
818 | |||
819 | data.AllowPublish = ((string)respData["AllowPublish"] == "1"); | ||
820 | if (respData["Charter"] != null) | ||
821 | { | ||
822 | data.Charter = (string)respData["Charter"]; | ||
823 | } | ||
824 | data.FounderID = new UUID((string)respData["FounderID"]); | ||
825 | data.GroupID = new UUID((string)respData["GroupID"]); | ||
826 | data.GroupName = (string)respData["GroupName"]; | ||
827 | data.GroupPicture = new UUID((string)respData["InsigniaID"]); | ||
828 | data.MaturePublish = ((string)respData["MaturePublish"] == "1"); | ||
829 | data.MembershipFee = int.Parse((string)respData["MembershipFee"]); | ||
830 | data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); | ||
831 | data.ShowInList = ((string)respData["ShowInList"] == "1"); | ||
832 | return data; | ||
833 | } | ||
834 | |||
835 | #endregion | ||
836 | |||
837 | /// <summary> | ||
838 | /// Encapsulate the XmlRpc call to standardize security and error handling. | ||
839 | /// </summary> | ||
840 | private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) | ||
841 | { | ||
842 | if (requestID == null) | ||
843 | { | ||
844 | requestID = new GroupRequestID(); | ||
845 | } | ||
846 | param.Add("RequestingAgentID", requestID.AgentID.ToString()); | ||
847 | param.Add("RequestingAgentUserService", requestID.UserServiceURL); | ||
848 | param.Add("RequestingSessionID", requestID.SessionID.ToString()); | ||
849 | |||
850 | |||
851 | param.Add("ReadKey", m_groupReadKey); | ||
852 | param.Add("WriteKey", m_groupWriteKey); | ||
853 | |||
854 | |||
855 | IList parameters = new ArrayList(); | ||
856 | parameters.Add(param); | ||
857 | |||
858 | XmlRpcRequest req; | ||
859 | if (!m_disableKeepAlive) | ||
860 | { | ||
861 | req = new XmlRpcRequest(function, parameters); | ||
862 | } | ||
863 | else | ||
864 | { | ||
865 | // This seems to solve a major problem on some windows servers | ||
866 | req = new NoKeepAliveXmlRpcRequest(function, parameters); | ||
867 | } | ||
868 | |||
869 | XmlRpcResponse resp = null; | ||
870 | |||
871 | try | ||
872 | { | ||
873 | resp = req.Send(m_serviceURL, 10000); | ||
874 | } | ||
875 | catch (Exception e) | ||
876 | { | ||
877 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); | ||
878 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); | ||
879 | |||
880 | |||
881 | foreach (string key in param.Keys) | ||
882 | { | ||
883 | m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); | ||
884 | } | ||
885 | |||
886 | Hashtable respData = new Hashtable(); | ||
887 | respData.Add("error", e.ToString()); | ||
888 | return respData; | ||
889 | } | ||
890 | |||
891 | if (resp.Value is Hashtable) | ||
892 | { | ||
893 | Hashtable respData = (Hashtable)resp.Value; | ||
894 | if (respData.Contains("error") && !respData.Contains("succeed")) | ||
895 | { | ||
896 | LogRespDataToConsoleError(respData); | ||
897 | } | ||
898 | |||
899 | return respData; | ||
900 | } | ||
901 | |||
902 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); | ||
903 | |||
904 | if (resp.Value is ArrayList) | ||
905 | { | ||
906 | ArrayList al = (ArrayList)resp.Value; | ||
907 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); | ||
908 | |||
909 | foreach (object o in al) | ||
910 | { | ||
911 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); | ||
912 | } | ||
913 | } | ||
914 | else | ||
915 | { | ||
916 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); | ||
917 | } | ||
918 | |||
919 | Hashtable error = new Hashtable(); | ||
920 | error.Add("error", "invalid return value"); | ||
921 | return error; | ||
922 | } | ||
923 | |||
924 | private void LogRespDataToConsoleError(Hashtable respData) | ||
925 | { | ||
926 | m_log.Error("[XMLRPCGROUPDATA]: Error:"); | ||
927 | |||
928 | foreach (string key in respData.Keys) | ||
929 | { | ||
930 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); | ||
931 | |||
932 | string[] lines = respData[key].ToString().Split(new char[] { '\n' }); | ||
933 | foreach (string line in lines) | ||
934 | { | ||
935 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); | ||
936 | } | ||
937 | |||
938 | } | ||
939 | } | ||
940 | |||
941 | |||
942 | } | ||
943 | |||
944 | public class GroupNoticeInfo | ||
945 | { | ||
946 | public GroupNoticeData noticeData = new GroupNoticeData(); | ||
947 | public UUID GroupID = UUID.Zero; | ||
948 | public string Message = string.Empty; | ||
949 | public byte[] BinaryBucket = new byte[0]; | ||
950 | } | ||
951 | } | ||
952 | |||
953 | namespace Nwc.XmlRpc | ||
954 | { | ||
955 | using System; | ||
956 | using System.Collections; | ||
957 | using System.IO; | ||
958 | using System.Xml; | ||
959 | using System.Net; | ||
960 | using System.Text; | ||
961 | using System.Reflection; | ||
962 | |||
963 | /// <summary>Class supporting the request side of an XML-RPC transaction.</summary> | ||
964 | public class NoKeepAliveXmlRpcRequest : XmlRpcRequest | ||
965 | { | ||
966 | private Encoding _encoding = new ASCIIEncoding(); | ||
967 | private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); | ||
968 | private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); | ||
969 | |||
970 | /// <summary>Instantiate an <c>XmlRpcRequest</c> for a specified method and parameters.</summary> | ||
971 | /// <param name="methodName"><c>String</c> designating the <i>object.method</i> on the server the request | ||
972 | /// should be directed to.</param> | ||
973 | /// <param name="parameters"><c>ArrayList</c> of XML-RPC type parameters to invoke the request with.</param> | ||
974 | public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) | ||
975 | { | ||
976 | MethodName = methodName; | ||
977 | _params = parameters; | ||
978 | } | ||
979 | |||
980 | /// <summary>Send the request to the server.</summary> | ||
981 | /// <param name="url"><c>String</c> The url of the XML-RPC server.</param> | ||
982 | /// <returns><c>XmlRpcResponse</c> The response generated.</returns> | ||
983 | public XmlRpcResponse Send(String url) | ||
984 | { | ||
985 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); | ||
986 | if (request == null) | ||
987 | throw new XmlRpcException(XmlRpcErrorCodes.TRANSPORT_ERROR, | ||
988 | XmlRpcErrorCodes.TRANSPORT_ERROR_MSG + ": Could not create request with " + url); | ||
989 | request.Method = "POST"; | ||
990 | request.ContentType = "text/xml"; | ||
991 | request.AllowWriteStreamBuffering = true; | ||
992 | request.KeepAlive = false; | ||
993 | |||
994 | Stream stream = request.GetRequestStream(); | ||
995 | XmlTextWriter xml = new XmlTextWriter(stream, _encoding); | ||
996 | _serializer.Serialize(xml, this); | ||
997 | xml.Flush(); | ||
998 | xml.Close(); | ||
999 | |||
1000 | HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | ||
1001 | StreamReader input = new StreamReader(response.GetResponseStream()); | ||
1002 | |||
1003 | XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); | ||
1004 | input.Close(); | ||
1005 | response.Close(); | ||
1006 | return resp; | ||
1007 | } | ||
1008 | } | ||
1009 | } | ||