diff options
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs')
-rw-r--r-- | OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 1174 |
1 files changed, 1174 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..a040f43 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | |||
@@ -0,0 +1,1174 @@ | |||
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 | using System.Text; | ||
33 | |||
34 | using Nwc.XmlRpc; | ||
35 | |||
36 | using log4net; | ||
37 | using Mono.Addins; | ||
38 | using Nini.Config; | ||
39 | |||
40 | using OpenMetaverse; | ||
41 | using OpenMetaverse.StructuredData; | ||
42 | |||
43 | using OpenSim.Framework; | ||
44 | using OpenSim.Framework.Communications; | ||
45 | using OpenSim.Region.Framework.Interfaces; | ||
46 | using OpenSim.Services.Interfaces; | ||
47 | |||
48 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | ||
49 | { | ||
50 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XmlRpcGroupsServicesConnectorModule")] | ||
51 | public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector | ||
52 | { | ||
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
54 | |||
55 | private bool m_debugEnabled = false; | ||
56 | |||
57 | public const GroupPowers DefaultEveryonePowers | ||
58 | = GroupPowers.AllowSetHome | ||
59 | | GroupPowers.Accountable | ||
60 | | GroupPowers.JoinChat | ||
61 | | GroupPowers.AllowVoiceChat | ||
62 | | GroupPowers.ReceiveNotices | ||
63 | | GroupPowers.StartProposal | ||
64 | | GroupPowers.VoteOnProposal; | ||
65 | |||
66 | // Would this be cleaner as (GroupPowers)ulong.MaxValue? | ||
67 | public const GroupPowers DefaultOwnerPowers | ||
68 | = GroupPowers.Accountable | ||
69 | | GroupPowers.AllowEditLand | ||
70 | | GroupPowers.AllowFly | ||
71 | | GroupPowers.AllowLandmark | ||
72 | | GroupPowers.AllowRez | ||
73 | | GroupPowers.AllowSetHome | ||
74 | | GroupPowers.AllowVoiceChat | ||
75 | | GroupPowers.AssignMember | ||
76 | | GroupPowers.AssignMemberLimited | ||
77 | | GroupPowers.ChangeActions | ||
78 | | GroupPowers.ChangeIdentity | ||
79 | | GroupPowers.ChangeMedia | ||
80 | | GroupPowers.ChangeOptions | ||
81 | | GroupPowers.CreateRole | ||
82 | | GroupPowers.DeedObject | ||
83 | | GroupPowers.DeleteRole | ||
84 | | GroupPowers.Eject | ||
85 | | GroupPowers.FindPlaces | ||
86 | | GroupPowers.Invite | ||
87 | | GroupPowers.JoinChat | ||
88 | | GroupPowers.LandChangeIdentity | ||
89 | | GroupPowers.LandDeed | ||
90 | | GroupPowers.LandDivideJoin | ||
91 | | GroupPowers.LandEdit | ||
92 | | GroupPowers.LandEjectAndFreeze | ||
93 | | GroupPowers.LandGardening | ||
94 | | GroupPowers.LandManageAllowed | ||
95 | | GroupPowers.LandManageBanned | ||
96 | | GroupPowers.LandManagePasses | ||
97 | | GroupPowers.LandOptions | ||
98 | | GroupPowers.LandRelease | ||
99 | | GroupPowers.LandSetSale | ||
100 | | GroupPowers.ModerateChat | ||
101 | | GroupPowers.ObjectManipulate | ||
102 | | GroupPowers.ObjectSetForSale | ||
103 | | GroupPowers.ReceiveNotices | ||
104 | | GroupPowers.RemoveMember | ||
105 | | GroupPowers.ReturnGroupOwned | ||
106 | | GroupPowers.ReturnGroupSet | ||
107 | | GroupPowers.ReturnNonGroup | ||
108 | | GroupPowers.RoleProperties | ||
109 | | GroupPowers.SendNotices | ||
110 | | GroupPowers.SetLandingPoint | ||
111 | | GroupPowers.StartProposal | ||
112 | | GroupPowers.VoteOnProposal; | ||
113 | |||
114 | private bool m_connectorEnabled = false; | ||
115 | |||
116 | private string m_groupsServerURI = string.Empty; | ||
117 | |||
118 | private bool m_disableKeepAlive = false; | ||
119 | |||
120 | private string m_groupReadKey = string.Empty; | ||
121 | private string m_groupWriteKey = string.Empty; | ||
122 | |||
123 | private IUserAccountService m_accountService = null; | ||
124 | |||
125 | private ExpiringCache<string, XmlRpcResponse> m_memoryCache; | ||
126 | private int m_cacheTimeout = 30; | ||
127 | |||
128 | // Used to track which agents are have dropped from a group chat session | ||
129 | // Should be reset per agent, on logon | ||
130 | // TODO: move this to Flotsam XmlRpc Service | ||
131 | // SessionID, List<AgentID> | ||
132 | private Dictionary<UUID, List<UUID>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<UUID>>(); | ||
133 | private Dictionary<UUID, List<UUID>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<UUID>>(); | ||
134 | |||
135 | #region Region Module interfaceBase Members | ||
136 | |||
137 | public string Name | ||
138 | { | ||
139 | get { return "XmlRpcGroupsServicesConnector"; } | ||
140 | } | ||
141 | |||
142 | // this module is not intended to be replaced, but there should only be 1 of them. | ||
143 | public Type ReplaceableInterface | ||
144 | { | ||
145 | get { return null; } | ||
146 | } | ||
147 | |||
148 | public void Initialise(IConfigSource config) | ||
149 | { | ||
150 | IConfig groupsConfig = config.Configs["Groups"]; | ||
151 | |||
152 | if (groupsConfig == null) | ||
153 | { | ||
154 | // Do not run this module by default. | ||
155 | return; | ||
156 | } | ||
157 | else | ||
158 | { | ||
159 | // if groups aren't enabled, we're not needed. | ||
160 | // if we're not specified as the connector to use, then we're not wanted | ||
161 | if ((groupsConfig.GetBoolean("Enabled", false) == false) | ||
162 | || (groupsConfig.GetString("ServicesConnectorModule", "XmlRpcGroupsServicesConnector") != Name)) | ||
163 | { | ||
164 | m_connectorEnabled = false; | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); | ||
169 | |||
170 | m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); | ||
171 | if (string.IsNullOrEmpty(m_groupsServerURI)) | ||
172 | { | ||
173 | m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); | ||
174 | m_connectorEnabled = false; | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | m_disableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); | ||
179 | |||
180 | m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); | ||
181 | m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); | ||
182 | |||
183 | |||
184 | m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); | ||
185 | if (m_cacheTimeout == 0) | ||
186 | { | ||
187 | m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Disabled."); | ||
188 | } | ||
189 | else | ||
190 | { | ||
191 | m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Timeout set to {0}.", m_cacheTimeout); | ||
192 | } | ||
193 | |||
194 | m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false); | ||
195 | |||
196 | // If we got all the config options we need, lets start'er'up | ||
197 | m_memoryCache = new ExpiringCache<string, XmlRpcResponse>(); | ||
198 | m_connectorEnabled = true; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | public void Close() | ||
203 | { | ||
204 | m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); | ||
205 | } | ||
206 | |||
207 | public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) | ||
208 | { | ||
209 | if (m_connectorEnabled) | ||
210 | { | ||
211 | |||
212 | if (m_accountService == null) | ||
213 | { | ||
214 | m_accountService = scene.UserAccountService; | ||
215 | } | ||
216 | |||
217 | |||
218 | scene.RegisterModuleInterface<IGroupsServicesConnector>(this); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) | ||
223 | { | ||
224 | if (scene.RequestModuleInterface<IGroupsServicesConnector>() == this) | ||
225 | { | ||
226 | scene.UnregisterModuleInterface<IGroupsServicesConnector>(this); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) | ||
231 | { | ||
232 | // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info | ||
233 | // scene.EventManager.OnNewClient += OnNewClient; | ||
234 | } | ||
235 | |||
236 | #endregion | ||
237 | |||
238 | #region ISharedRegionModule Members | ||
239 | |||
240 | public void PostInitialise() | ||
241 | { | ||
242 | // NoOp | ||
243 | } | ||
244 | |||
245 | #endregion | ||
246 | |||
247 | #region IGroupsServicesConnector Members | ||
248 | |||
249 | /// <summary> | ||
250 | /// 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. | ||
251 | /// </summary> | ||
252 | public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, | ||
253 | int membershipFee, bool openEnrollment, bool allowPublish, | ||
254 | bool maturePublish, UUID founderID) | ||
255 | { | ||
256 | UUID GroupID = UUID.Random(); | ||
257 | UUID OwnerRoleID = UUID.Random(); | ||
258 | |||
259 | Hashtable param = new Hashtable(); | ||
260 | param["GroupID"] = GroupID.ToString(); | ||
261 | param["Name"] = name; | ||
262 | param["Charter"] = charter; | ||
263 | param["ShowInList"] = showInList == true ? 1 : 0; | ||
264 | param["InsigniaID"] = insigniaID.ToString(); | ||
265 | param["MembershipFee"] = membershipFee; | ||
266 | param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; | ||
267 | param["AllowPublish"] = allowPublish == true ? 1 : 0; | ||
268 | param["MaturePublish"] = maturePublish == true ? 1 : 0; | ||
269 | param["FounderID"] = founderID.ToString(); | ||
270 | param["EveryonePowers"] = ((ulong)DefaultEveryonePowers).ToString(); | ||
271 | param["OwnerRoleID"] = OwnerRoleID.ToString(); | ||
272 | param["OwnersPowers"] = ((ulong)DefaultOwnerPowers).ToString(); | ||
273 | |||
274 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); | ||
275 | |||
276 | if (respData.Contains("error")) | ||
277 | { | ||
278 | // UUID is not nullable | ||
279 | |||
280 | return UUID.Zero; | ||
281 | } | ||
282 | |||
283 | return UUID.Parse((string)respData["GroupID"]); | ||
284 | } | ||
285 | |||
286 | public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, | ||
287 | UUID insigniaID, int membershipFee, bool openEnrollment, | ||
288 | bool allowPublish, bool maturePublish) | ||
289 | { | ||
290 | Hashtable param = new Hashtable(); | ||
291 | param["GroupID"] = groupID.ToString(); | ||
292 | param["Charter"] = charter; | ||
293 | param["ShowInList"] = showInList == true ? 1 : 0; | ||
294 | param["InsigniaID"] = insigniaID.ToString(); | ||
295 | param["MembershipFee"] = membershipFee; | ||
296 | param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; | ||
297 | param["AllowPublish"] = allowPublish == true ? 1 : 0; | ||
298 | param["MaturePublish"] = maturePublish == true ? 1 : 0; | ||
299 | |||
300 | XmlRpcCall(requestingAgentID, "groups.updateGroup", param); | ||
301 | } | ||
302 | |||
303 | public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, | ||
304 | string title, ulong powers) | ||
305 | { | ||
306 | Hashtable param = new Hashtable(); | ||
307 | param["GroupID"] = groupID.ToString(); | ||
308 | param["RoleID"] = roleID.ToString(); | ||
309 | param["Name"] = name; | ||
310 | param["Description"] = description; | ||
311 | param["Title"] = title; | ||
312 | param["Powers"] = powers.ToString(); | ||
313 | |||
314 | XmlRpcCall(requestingAgentID, "groups.addRoleToGroup", param); | ||
315 | } | ||
316 | |||
317 | public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) | ||
318 | { | ||
319 | Hashtable param = new Hashtable(); | ||
320 | param["GroupID"] = groupID.ToString(); | ||
321 | param["RoleID"] = roleID.ToString(); | ||
322 | |||
323 | XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param); | ||
324 | } | ||
325 | |||
326 | public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, | ||
327 | string title, ulong powers) | ||
328 | { | ||
329 | Hashtable param = new Hashtable(); | ||
330 | param["GroupID"] = groupID.ToString(); | ||
331 | param["RoleID"] = roleID.ToString(); | ||
332 | if (name != null) | ||
333 | { | ||
334 | param["Name"] = name; | ||
335 | } | ||
336 | if (description != null) | ||
337 | { | ||
338 | param["Description"] = description; | ||
339 | } | ||
340 | if (title != null) | ||
341 | { | ||
342 | param["Title"] = title; | ||
343 | } | ||
344 | param["Powers"] = powers.ToString(); | ||
345 | |||
346 | XmlRpcCall(requestingAgentID, "groups.updateGroupRole", param); | ||
347 | } | ||
348 | |||
349 | public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID GroupID, string GroupName) | ||
350 | { | ||
351 | Hashtable param = new Hashtable(); | ||
352 | if (GroupID != UUID.Zero) | ||
353 | { | ||
354 | param["GroupID"] = GroupID.ToString(); | ||
355 | } | ||
356 | if (!string.IsNullOrEmpty(GroupName)) | ||
357 | { | ||
358 | param["Name"] = GroupName.ToString(); | ||
359 | } | ||
360 | |||
361 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); | ||
362 | |||
363 | if (respData.Contains("error")) | ||
364 | { | ||
365 | return null; | ||
366 | } | ||
367 | |||
368 | return GroupProfileHashtableToGroupRecord(respData); | ||
369 | |||
370 | } | ||
371 | |||
372 | public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID GroupID, UUID AgentID) | ||
373 | { | ||
374 | Hashtable param = new Hashtable(); | ||
375 | param["GroupID"] = GroupID.ToString(); | ||
376 | |||
377 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); | ||
378 | |||
379 | if (respData.Contains("error")) | ||
380 | { | ||
381 | // GroupProfileData is not nullable | ||
382 | return new GroupProfileData(); | ||
383 | } | ||
384 | |||
385 | GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, AgentID, GroupID); | ||
386 | GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); | ||
387 | |||
388 | MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; | ||
389 | MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; | ||
390 | |||
391 | return MemberGroupProfile; | ||
392 | } | ||
393 | |||
394 | public void SetAgentActiveGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) | ||
395 | { | ||
396 | Hashtable param = new Hashtable(); | ||
397 | param["AgentID"] = AgentID.ToString(); | ||
398 | param["GroupID"] = GroupID.ToString(); | ||
399 | |||
400 | XmlRpcCall(requestingAgentID, "groups.setAgentActiveGroup", param); | ||
401 | } | ||
402 | |||
403 | public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
404 | { | ||
405 | Hashtable param = new Hashtable(); | ||
406 | param["AgentID"] = AgentID.ToString(); | ||
407 | param["GroupID"] = GroupID.ToString(); | ||
408 | param["SelectedRoleID"] = RoleID.ToString(); | ||
409 | |||
410 | XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); | ||
411 | } | ||
412 | |||
413 | public void SetAgentGroupInfo(UUID requestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) | ||
414 | { | ||
415 | Hashtable param = new Hashtable(); | ||
416 | param["AgentID"] = AgentID.ToString(); | ||
417 | param["GroupID"] = GroupID.ToString(); | ||
418 | param["AcceptNotices"] = AcceptNotices ? "1" : "0"; | ||
419 | param["ListInProfile"] = ListInProfile ? "1" : "0"; | ||
420 | |||
421 | XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); | ||
422 | |||
423 | } | ||
424 | |||
425 | public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) | ||
426 | { | ||
427 | Hashtable param = new Hashtable(); | ||
428 | param["InviteID"] = inviteID.ToString(); | ||
429 | param["AgentID"] = agentID.ToString(); | ||
430 | param["RoleID"] = roleID.ToString(); | ||
431 | param["GroupID"] = groupID.ToString(); | ||
432 | |||
433 | XmlRpcCall(requestingAgentID, "groups.addAgentToGroupInvite", param); | ||
434 | |||
435 | } | ||
436 | |||
437 | public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) | ||
438 | { | ||
439 | Hashtable param = new Hashtable(); | ||
440 | param["InviteID"] = inviteID.ToString(); | ||
441 | |||
442 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentToGroupInvite", param); | ||
443 | |||
444 | if (respData.Contains("error")) | ||
445 | { | ||
446 | return null; | ||
447 | } | ||
448 | |||
449 | GroupInviteInfo inviteInfo = new GroupInviteInfo(); | ||
450 | inviteInfo.InviteID = inviteID; | ||
451 | inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]); | ||
452 | inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]); | ||
453 | inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]); | ||
454 | |||
455 | return inviteInfo; | ||
456 | } | ||
457 | |||
458 | public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) | ||
459 | { | ||
460 | Hashtable param = new Hashtable(); | ||
461 | param["InviteID"] = inviteID.ToString(); | ||
462 | |||
463 | XmlRpcCall(requestingAgentID, "groups.removeAgentToGroupInvite", param); | ||
464 | } | ||
465 | |||
466 | public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
467 | { | ||
468 | Hashtable param = new Hashtable(); | ||
469 | param["AgentID"] = AgentID.ToString(); | ||
470 | param["GroupID"] = GroupID.ToString(); | ||
471 | param["RoleID"] = RoleID.ToString(); | ||
472 | |||
473 | XmlRpcCall(requestingAgentID, "groups.addAgentToGroup", param); | ||
474 | } | ||
475 | |||
476 | public void RemoveAgentFromGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) | ||
477 | { | ||
478 | Hashtable param = new Hashtable(); | ||
479 | param["AgentID"] = AgentID.ToString(); | ||
480 | param["GroupID"] = GroupID.ToString(); | ||
481 | |||
482 | XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroup", param); | ||
483 | } | ||
484 | |||
485 | public void AddAgentToGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
486 | { | ||
487 | Hashtable param = new Hashtable(); | ||
488 | param["AgentID"] = AgentID.ToString(); | ||
489 | param["GroupID"] = GroupID.ToString(); | ||
490 | param["RoleID"] = RoleID.ToString(); | ||
491 | |||
492 | XmlRpcCall(requestingAgentID, "groups.addAgentToGroupRole", param); | ||
493 | } | ||
494 | |||
495 | public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
496 | { | ||
497 | Hashtable param = new Hashtable(); | ||
498 | param["AgentID"] = AgentID.ToString(); | ||
499 | param["GroupID"] = GroupID.ToString(); | ||
500 | param["RoleID"] = RoleID.ToString(); | ||
501 | |||
502 | XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroupRole", param); | ||
503 | } | ||
504 | |||
505 | public List<DirGroupsReplyData> FindGroups(UUID requestingAgentID, string search) | ||
506 | { | ||
507 | Hashtable param = new Hashtable(); | ||
508 | param["Search"] = search; | ||
509 | |||
510 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.findGroups", param); | ||
511 | |||
512 | List<DirGroupsReplyData> findings = new List<DirGroupsReplyData>(); | ||
513 | |||
514 | if (!respData.Contains("error")) | ||
515 | { | ||
516 | Hashtable results = (Hashtable)respData["results"]; | ||
517 | foreach (Hashtable groupFind in results.Values) | ||
518 | { | ||
519 | DirGroupsReplyData data = new DirGroupsReplyData(); | ||
520 | data.groupID = new UUID((string)groupFind["GroupID"]); ; | ||
521 | data.groupName = (string)groupFind["Name"]; | ||
522 | data.members = int.Parse((string)groupFind["Members"]); | ||
523 | // data.searchOrder = order; | ||
524 | |||
525 | findings.Add(data); | ||
526 | } | ||
527 | } | ||
528 | |||
529 | return findings; | ||
530 | } | ||
531 | |||
532 | public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID AgentID, UUID GroupID) | ||
533 | { | ||
534 | Hashtable param = new Hashtable(); | ||
535 | param["AgentID"] = AgentID.ToString(); | ||
536 | param["GroupID"] = GroupID.ToString(); | ||
537 | |||
538 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMembership", param); | ||
539 | |||
540 | if (respData.Contains("error")) | ||
541 | { | ||
542 | return null; | ||
543 | } | ||
544 | |||
545 | GroupMembershipData data = HashTableToGroupMembershipData(respData); | ||
546 | |||
547 | return data; | ||
548 | } | ||
549 | |||
550 | public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID AgentID) | ||
551 | { | ||
552 | Hashtable param = new Hashtable(); | ||
553 | param["AgentID"] = AgentID.ToString(); | ||
554 | |||
555 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentActiveMembership", param); | ||
556 | |||
557 | if (respData.Contains("error")) | ||
558 | { | ||
559 | return null; | ||
560 | } | ||
561 | |||
562 | return HashTableToGroupMembershipData(respData); | ||
563 | } | ||
564 | |||
565 | public List<GroupMembershipData> GetAgentGroupMemberships(UUID requestingAgentID, UUID AgentID) | ||
566 | { | ||
567 | Hashtable param = new Hashtable(); | ||
568 | param["AgentID"] = AgentID.ToString(); | ||
569 | |||
570 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMemberships", param); | ||
571 | |||
572 | List<GroupMembershipData> memberships = new List<GroupMembershipData>(); | ||
573 | |||
574 | if (!respData.Contains("error")) | ||
575 | { | ||
576 | foreach (object membership in respData.Values) | ||
577 | { | ||
578 | memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); | ||
579 | } | ||
580 | } | ||
581 | |||
582 | return memberships; | ||
583 | } | ||
584 | |||
585 | public List<GroupRolesData> GetAgentGroupRoles(UUID requestingAgentID, UUID AgentID, UUID GroupID) | ||
586 | { | ||
587 | Hashtable param = new Hashtable(); | ||
588 | param["AgentID"] = AgentID.ToString(); | ||
589 | param["GroupID"] = GroupID.ToString(); | ||
590 | |||
591 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentRoles", param); | ||
592 | |||
593 | List<GroupRolesData> Roles = new List<GroupRolesData>(); | ||
594 | |||
595 | if (respData.Contains("error")) | ||
596 | { | ||
597 | return Roles; | ||
598 | } | ||
599 | |||
600 | foreach (Hashtable role in respData.Values) | ||
601 | { | ||
602 | GroupRolesData data = new GroupRolesData(); | ||
603 | data.RoleID = new UUID((string)role["RoleID"]); | ||
604 | data.Name = (string)role["Name"]; | ||
605 | data.Description = (string)role["Description"]; | ||
606 | data.Powers = ulong.Parse((string)role["Powers"]); | ||
607 | data.Title = (string)role["Title"]; | ||
608 | |||
609 | Roles.Add(data); | ||
610 | } | ||
611 | |||
612 | return Roles; | ||
613 | } | ||
614 | |||
615 | public List<GroupRolesData> GetGroupRoles(UUID requestingAgentID, UUID GroupID) | ||
616 | { | ||
617 | Hashtable param = new Hashtable(); | ||
618 | param["GroupID"] = GroupID.ToString(); | ||
619 | |||
620 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoles", param); | ||
621 | |||
622 | List<GroupRolesData> Roles = new List<GroupRolesData>(); | ||
623 | |||
624 | if (respData.Contains("error")) | ||
625 | { | ||
626 | return Roles; | ||
627 | } | ||
628 | |||
629 | foreach (Hashtable role in respData.Values) | ||
630 | { | ||
631 | GroupRolesData data = new GroupRolesData(); | ||
632 | data.Description = (string)role["Description"]; | ||
633 | data.Members = int.Parse((string)role["Members"]); | ||
634 | data.Name = (string)role["Name"]; | ||
635 | data.Powers = ulong.Parse((string)role["Powers"]); | ||
636 | data.RoleID = new UUID((string)role["RoleID"]); | ||
637 | data.Title = (string)role["Title"]; | ||
638 | |||
639 | Roles.Add(data); | ||
640 | } | ||
641 | |||
642 | return Roles; | ||
643 | } | ||
644 | |||
645 | public List<GroupMembersData> GetGroupMembers(UUID requestingAgentID, UUID GroupID) | ||
646 | { | ||
647 | Hashtable param = new Hashtable(); | ||
648 | param["GroupID"] = GroupID.ToString(); | ||
649 | |||
650 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupMembers", param); | ||
651 | |||
652 | List<GroupMembersData> members = new List<GroupMembersData>(); | ||
653 | |||
654 | if (respData.Contains("error")) | ||
655 | { | ||
656 | return members; | ||
657 | } | ||
658 | |||
659 | foreach (Hashtable membership in respData.Values) | ||
660 | { | ||
661 | GroupMembersData data = new GroupMembersData(); | ||
662 | |||
663 | data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1"; | ||
664 | data.AgentID = new UUID((string)membership["AgentID"]); | ||
665 | data.Contribution = int.Parse((string)membership["Contribution"]); | ||
666 | data.IsOwner = ((string)membership["IsOwner"]) == "1"; | ||
667 | data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; | ||
668 | data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); | ||
669 | data.Title = (string)membership["Title"]; | ||
670 | |||
671 | members.Add(data); | ||
672 | } | ||
673 | |||
674 | return members; | ||
675 | } | ||
676 | |||
677 | public List<GroupRoleMembersData> GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) | ||
678 | { | ||
679 | Hashtable param = new Hashtable(); | ||
680 | param["GroupID"] = GroupID.ToString(); | ||
681 | |||
682 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoleMembers", param); | ||
683 | |||
684 | List<GroupRoleMembersData> members = new List<GroupRoleMembersData>(); | ||
685 | |||
686 | if (!respData.Contains("error")) | ||
687 | { | ||
688 | foreach (Hashtable membership in respData.Values) | ||
689 | { | ||
690 | GroupRoleMembersData data = new GroupRoleMembersData(); | ||
691 | |||
692 | data.MemberID = new UUID((string)membership["AgentID"]); | ||
693 | data.RoleID = new UUID((string)membership["RoleID"]); | ||
694 | |||
695 | members.Add(data); | ||
696 | } | ||
697 | } | ||
698 | return members; | ||
699 | } | ||
700 | |||
701 | public List<GroupNoticeData> GetGroupNotices(UUID requestingAgentID, UUID GroupID) | ||
702 | { | ||
703 | Hashtable param = new Hashtable(); | ||
704 | param["GroupID"] = GroupID.ToString(); | ||
705 | |||
706 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotices", param); | ||
707 | |||
708 | List<GroupNoticeData> values = new List<GroupNoticeData>(); | ||
709 | |||
710 | if (!respData.Contains("error")) | ||
711 | { | ||
712 | foreach (Hashtable value in respData.Values) | ||
713 | { | ||
714 | GroupNoticeData data = new GroupNoticeData(); | ||
715 | data.NoticeID = UUID.Parse((string)value["NoticeID"]); | ||
716 | data.Timestamp = uint.Parse((string)value["Timestamp"]); | ||
717 | data.FromName = (string)value["FromName"]; | ||
718 | data.Subject = (string)value["Subject"]; | ||
719 | data.HasAttachment = false; | ||
720 | data.AssetType = 0; | ||
721 | |||
722 | values.Add(data); | ||
723 | } | ||
724 | } | ||
725 | |||
726 | return values; | ||
727 | } | ||
728 | |||
729 | public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) | ||
730 | { | ||
731 | Hashtable param = new Hashtable(); | ||
732 | param["NoticeID"] = noticeID.ToString(); | ||
733 | |||
734 | Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); | ||
735 | |||
736 | if (respData.Contains("error")) | ||
737 | { | ||
738 | return null; | ||
739 | } | ||
740 | |||
741 | GroupNoticeInfo data = new GroupNoticeInfo(); | ||
742 | data.GroupID = UUID.Parse((string)respData["GroupID"]); | ||
743 | data.Message = (string)respData["Message"]; | ||
744 | data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true); | ||
745 | data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]); | ||
746 | data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]); | ||
747 | data.noticeData.FromName = (string)respData["FromName"]; | ||
748 | data.noticeData.Subject = (string)respData["Subject"]; | ||
749 | data.noticeData.HasAttachment = false; | ||
750 | data.noticeData.AssetType = 0; | ||
751 | |||
752 | if (data.Message == null) | ||
753 | { | ||
754 | data.Message = string.Empty; | ||
755 | } | ||
756 | |||
757 | return data; | ||
758 | } | ||
759 | |||
760 | public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) | ||
761 | { | ||
762 | string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); | ||
763 | |||
764 | Hashtable param = new Hashtable(); | ||
765 | param["GroupID"] = groupID.ToString(); | ||
766 | param["NoticeID"] = noticeID.ToString(); | ||
767 | param["FromName"] = fromName; | ||
768 | param["Subject"] = subject; | ||
769 | param["Message"] = message; | ||
770 | param["BinaryBucket"] = binBucket; | ||
771 | param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); | ||
772 | |||
773 | XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); | ||
774 | } | ||
775 | |||
776 | #endregion | ||
777 | |||
778 | #region GroupSessionTracking | ||
779 | |||
780 | public void ResetAgentGroupChatSessions(UUID agentID) | ||
781 | { | ||
782 | foreach (List<UUID> agentList in m_groupsAgentsDroppedFromChatSession.Values) | ||
783 | { | ||
784 | agentList.Remove(agentID); | ||
785 | } | ||
786 | } | ||
787 | |||
788 | public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) | ||
789 | { | ||
790 | // If we're tracking this group, and we can find them in the tracking, then they've been invited | ||
791 | return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) | ||
792 | && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); | ||
793 | } | ||
794 | |||
795 | public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) | ||
796 | { | ||
797 | // If we're tracking drops for this group, | ||
798 | // and we find them, well... then they've dropped | ||
799 | return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) | ||
800 | && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); | ||
801 | } | ||
802 | |||
803 | public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) | ||
804 | { | ||
805 | if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) | ||
806 | { | ||
807 | // If not in dropped list, add | ||
808 | if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) | ||
809 | { | ||
810 | m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); | ||
811 | } | ||
812 | } | ||
813 | } | ||
814 | |||
815 | public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) | ||
816 | { | ||
817 | // Add Session Status if it doesn't exist for this session | ||
818 | CreateGroupChatSessionTracking(groupID); | ||
819 | |||
820 | // If nessesary, remove from dropped list | ||
821 | if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) | ||
822 | { | ||
823 | m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); | ||
824 | } | ||
825 | } | ||
826 | |||
827 | private void CreateGroupChatSessionTracking(UUID groupID) | ||
828 | { | ||
829 | if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) | ||
830 | { | ||
831 | m_groupsAgentsDroppedFromChatSession.Add(groupID, new List<UUID>()); | ||
832 | m_groupsAgentsInvitedToChatSession.Add(groupID, new List<UUID>()); | ||
833 | } | ||
834 | |||
835 | } | ||
836 | #endregion | ||
837 | |||
838 | #region XmlRpcHashtableMarshalling | ||
839 | private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) | ||
840 | { | ||
841 | GroupProfileData group = new GroupProfileData(); | ||
842 | group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); | ||
843 | group.Name = (string)groupProfile["Name"]; | ||
844 | |||
845 | if (groupProfile["Charter"] != null) | ||
846 | { | ||
847 | group.Charter = (string)groupProfile["Charter"]; | ||
848 | } | ||
849 | |||
850 | group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; | ||
851 | group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]); | ||
852 | group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); | ||
853 | group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; | ||
854 | group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; | ||
855 | group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; | ||
856 | group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); | ||
857 | group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]); | ||
858 | |||
859 | group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]); | ||
860 | group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]); | ||
861 | |||
862 | return group; | ||
863 | } | ||
864 | |||
865 | private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) | ||
866 | { | ||
867 | GroupRecord group = new GroupRecord(); | ||
868 | group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); | ||
869 | group.GroupName = groupProfile["Name"].ToString(); | ||
870 | if (groupProfile["Charter"] != null) | ||
871 | { | ||
872 | group.Charter = (string)groupProfile["Charter"]; | ||
873 | } | ||
874 | group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; | ||
875 | group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); | ||
876 | group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); | ||
877 | group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; | ||
878 | group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; | ||
879 | group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; | ||
880 | group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); | ||
881 | group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); | ||
882 | |||
883 | return group; | ||
884 | } | ||
885 | |||
886 | private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) | ||
887 | { | ||
888 | GroupMembershipData data = new GroupMembershipData(); | ||
889 | data.AcceptNotices = ((string)respData["AcceptNotices"] == "1"); | ||
890 | data.Contribution = int.Parse((string)respData["Contribution"]); | ||
891 | data.ListInProfile = ((string)respData["ListInProfile"] == "1"); | ||
892 | |||
893 | data.ActiveRole = new UUID((string)respData["SelectedRoleID"]); | ||
894 | data.GroupTitle = (string)respData["Title"]; | ||
895 | |||
896 | data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]); | ||
897 | |||
898 | // Is this group the agent's active group | ||
899 | |||
900 | data.GroupID = new UUID((string)respData["GroupID"]); | ||
901 | |||
902 | UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]); | ||
903 | data.Active = data.GroupID.Equals(ActiveGroup); | ||
904 | |||
905 | data.AllowPublish = ((string)respData["AllowPublish"] == "1"); | ||
906 | if (respData["Charter"] != null) | ||
907 | { | ||
908 | data.Charter = (string)respData["Charter"]; | ||
909 | } | ||
910 | data.FounderID = new UUID((string)respData["FounderID"]); | ||
911 | data.GroupID = new UUID((string)respData["GroupID"]); | ||
912 | data.GroupName = (string)respData["GroupName"]; | ||
913 | data.GroupPicture = new UUID((string)respData["InsigniaID"]); | ||
914 | data.MaturePublish = ((string)respData["MaturePublish"] == "1"); | ||
915 | data.MembershipFee = int.Parse((string)respData["MembershipFee"]); | ||
916 | data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); | ||
917 | data.ShowInList = ((string)respData["ShowInList"] == "1"); | ||
918 | |||
919 | return data; | ||
920 | } | ||
921 | |||
922 | #endregion | ||
923 | |||
924 | /// <summary> | ||
925 | /// Encapsulate the XmlRpc call to standardize security and error handling. | ||
926 | /// </summary> | ||
927 | private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) | ||
928 | { | ||
929 | XmlRpcResponse resp = null; | ||
930 | string CacheKey = null; | ||
931 | |||
932 | // Only bother with the cache if it isn't disabled. | ||
933 | if (m_cacheTimeout > 0) | ||
934 | { | ||
935 | if (!function.StartsWith("groups.get")) | ||
936 | { | ||
937 | // Any and all updates cause the cache to clear | ||
938 | m_memoryCache.Clear(); | ||
939 | } | ||
940 | else | ||
941 | { | ||
942 | StringBuilder sb = new StringBuilder(requestingAgentID + function); | ||
943 | foreach (object key in param.Keys) | ||
944 | { | ||
945 | if (param[key] != null) | ||
946 | { | ||
947 | sb.AppendFormat(",{0}:{1}", key.ToString(), param[key].ToString()); | ||
948 | } | ||
949 | } | ||
950 | |||
951 | CacheKey = sb.ToString(); | ||
952 | m_memoryCache.TryGetValue(CacheKey, out resp); | ||
953 | } | ||
954 | } | ||
955 | |||
956 | if (resp == null) | ||
957 | { | ||
958 | if (m_debugEnabled) | ||
959 | m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Cache miss for key {0}", CacheKey); | ||
960 | |||
961 | string UserService; | ||
962 | UUID SessionID; | ||
963 | GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); | ||
964 | |||
965 | param.Add("RequestingAgentID", requestingAgentID.ToString()); | ||
966 | param.Add("RequestingAgentUserService", UserService); | ||
967 | param.Add("RequestingSessionID", SessionID.ToString()); | ||
968 | param.Add("ReadKey", m_groupReadKey); | ||
969 | param.Add("WriteKey", m_groupWriteKey); | ||
970 | |||
971 | IList parameters = new ArrayList(); | ||
972 | parameters.Add(param); | ||
973 | |||
974 | ConfigurableKeepAliveXmlRpcRequest req; | ||
975 | req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); | ||
976 | |||
977 | try | ||
978 | { | ||
979 | resp = req.Send(m_groupsServerURI, 10000); | ||
980 | |||
981 | if ((m_cacheTimeout > 0) && (CacheKey != null)) | ||
982 | { | ||
983 | m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout)); | ||
984 | } | ||
985 | } | ||
986 | catch (Exception e) | ||
987 | { | ||
988 | m_log.ErrorFormat( | ||
989 | "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}", | ||
990 | function, m_groupsServerURI); | ||
991 | |||
992 | m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}{1}", e.Message, e.StackTrace); | ||
993 | |||
994 | foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) | ||
995 | { | ||
996 | m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", ResponseLine); | ||
997 | } | ||
998 | |||
999 | foreach (string key in param.Keys) | ||
1000 | { | ||
1001 | m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", key, param[key].ToString()); | ||
1002 | } | ||
1003 | |||
1004 | Hashtable respData = new Hashtable(); | ||
1005 | respData.Add("error", e.ToString()); | ||
1006 | return respData; | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | if (resp.Value is Hashtable) | ||
1011 | { | ||
1012 | Hashtable respData = (Hashtable)resp.Value; | ||
1013 | if (respData.Contains("error") && !respData.Contains("succeed")) | ||
1014 | { | ||
1015 | LogRespDataToConsoleError(requestingAgentID, function, param, respData); | ||
1016 | } | ||
1017 | |||
1018 | return respData; | ||
1019 | } | ||
1020 | |||
1021 | m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); | ||
1022 | |||
1023 | if (resp.Value is ArrayList) | ||
1024 | { | ||
1025 | ArrayList al = (ArrayList)resp.Value; | ||
1026 | m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Contains {0} elements", al.Count); | ||
1027 | |||
1028 | foreach (object o in al) | ||
1029 | { | ||
1030 | m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", o.GetType().ToString(), o.ToString()); | ||
1031 | } | ||
1032 | } | ||
1033 | else | ||
1034 | { | ||
1035 | m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Function returned: {0}", resp.Value.ToString()); | ||
1036 | } | ||
1037 | |||
1038 | Hashtable error = new Hashtable(); | ||
1039 | error.Add("error", "invalid return value"); | ||
1040 | return error; | ||
1041 | } | ||
1042 | |||
1043 | private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData) | ||
1044 | { | ||
1045 | m_log.ErrorFormat( | ||
1046 | "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}", | ||
1047 | function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData)); | ||
1048 | } | ||
1049 | |||
1050 | /// <summary> | ||
1051 | /// Group Request Tokens are an attempt to allow the groups service to authenticate | ||
1052 | /// requests. | ||
1053 | /// TODO: This broke after the big grid refactor, either find a better way, or discard this | ||
1054 | /// </summary> | ||
1055 | /// <param name="client"></param> | ||
1056 | /// <returns></returns> | ||
1057 | private void GetClientGroupRequestID(UUID AgentID, out string UserServiceURL, out UUID SessionID) | ||
1058 | { | ||
1059 | UserServiceURL = ""; | ||
1060 | SessionID = UUID.Zero; | ||
1061 | |||
1062 | |||
1063 | // Need to rework this based on changes to User Services | ||
1064 | /* | ||
1065 | UserAccount userAccount = m_accountService.GetUserAccount(UUID.Zero,AgentID); | ||
1066 | if (userAccount == null) | ||
1067 | { | ||
1068 | // This should be impossible. If I've been passed a reference to a client | ||
1069 | // that client should be registered with the UserService. So something | ||
1070 | // is horribly wrong somewhere. | ||
1071 | |||
1072 | m_log.WarnFormat("[GROUPS]: Could not find a UserServiceURL for {0}", AgentID); | ||
1073 | |||
1074 | } | ||
1075 | else if (userProfile is ForeignUserProfileData) | ||
1076 | { | ||
1077 | // They aren't from around here | ||
1078 | ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; | ||
1079 | UserServiceURL = fupd.UserServerURI; | ||
1080 | SessionID = fupd.CurrentAgent.SessionID; | ||
1081 | |||
1082 | } | ||
1083 | else | ||
1084 | { | ||
1085 | // They're a local user, use this: | ||
1086 | UserServiceURL = m_commManager.NetworkServersInfo.UserURL; | ||
1087 | SessionID = userProfile.CurrentAgent.SessionID; | ||
1088 | } | ||
1089 | */ | ||
1090 | } | ||
1091 | |||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | namespace Nwc.XmlRpc | ||
1096 | { | ||
1097 | using System; | ||
1098 | using System.Collections; | ||
1099 | using System.IO; | ||
1100 | using System.Xml; | ||
1101 | using System.Net; | ||
1102 | using System.Text; | ||
1103 | using System.Reflection; | ||
1104 | |||
1105 | /// <summary>Class supporting the request side of an XML-RPC transaction.</summary> | ||
1106 | public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest | ||
1107 | { | ||
1108 | private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); | ||
1109 | private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); | ||
1110 | private bool _disableKeepAlive = true; | ||
1111 | |||
1112 | public string RequestResponse = String.Empty; | ||
1113 | |||
1114 | /// <summary>Instantiate an <c>XmlRpcRequest</c> for a specified method and parameters.</summary> | ||
1115 | /// <param name="methodName"><c>String</c> designating the <i>object.method</i> on the server the request | ||
1116 | /// should be directed to.</param> | ||
1117 | /// <param name="parameters"><c>ArrayList</c> of XML-RPC type parameters to invoke the request with.</param> | ||
1118 | public ConfigurableKeepAliveXmlRpcRequest(String methodName, IList parameters, bool disableKeepAlive) | ||
1119 | { | ||
1120 | MethodName = methodName; | ||
1121 | _params = parameters; | ||
1122 | _disableKeepAlive = disableKeepAlive; | ||
1123 | } | ||
1124 | |||
1125 | /// <summary>Send the request to the server.</summary> | ||
1126 | /// <param name="url"><c>String</c> The url of the XML-RPC server.</param> | ||
1127 | /// <returns><c>XmlRpcResponse</c> The response generated.</returns> | ||
1128 | public XmlRpcResponse Send(String url) | ||
1129 | { | ||
1130 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); | ||
1131 | if (request == null) | ||
1132 | throw new XmlRpcException(XmlRpcErrorCodes.TRANSPORT_ERROR, | ||
1133 | XmlRpcErrorCodes.TRANSPORT_ERROR_MSG + ": Could not create request with " + url); | ||
1134 | request.Method = "POST"; | ||
1135 | request.ContentType = "text/xml"; | ||
1136 | request.AllowWriteStreamBuffering = true; | ||
1137 | request.KeepAlive = !_disableKeepAlive; | ||
1138 | |||
1139 | using (Stream stream = request.GetRequestStream()) | ||
1140 | { | ||
1141 | using (XmlTextWriter xml = new XmlTextWriter(stream, Encoding.ASCII)) | ||
1142 | { | ||
1143 | _serializer.Serialize(xml, this); | ||
1144 | xml.Flush(); | ||
1145 | } | ||
1146 | } | ||
1147 | |||
1148 | XmlRpcResponse resp; | ||
1149 | |||
1150 | using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) | ||
1151 | { | ||
1152 | using (Stream s = response.GetResponseStream()) | ||
1153 | { | ||
1154 | using (StreamReader input = new StreamReader(s)) | ||
1155 | { | ||
1156 | string inputXml = input.ReadToEnd(); | ||
1157 | |||
1158 | try | ||
1159 | { | ||
1160 | resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml); | ||
1161 | } | ||
1162 | catch (Exception e) | ||
1163 | { | ||
1164 | RequestResponse = inputXml; | ||
1165 | throw e; | ||
1166 | } | ||
1167 | } | ||
1168 | } | ||
1169 | } | ||
1170 | |||
1171 | return resp; | ||
1172 | } | ||
1173 | } | ||
1174 | } | ||