diff options
Diffstat (limited to '')
4 files changed, 2808 insertions, 0 deletions
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs new file mode 100644 index 0000000..7450c14 --- /dev/null +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs | |||
@@ -0,0 +1,696 @@ | |||
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.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Reflection; | ||
32 | using System.Text; | ||
33 | |||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Framework.ServiceAuth; | ||
36 | using OpenSim.Server.Base; | ||
37 | |||
38 | using OpenMetaverse; | ||
39 | using log4net; | ||
40 | using Nini.Config; | ||
41 | |||
42 | namespace OpenSim.Groups | ||
43 | { | ||
44 | public class GroupsServiceRemoteConnector | ||
45 | { | ||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | private string m_ServerURI; | ||
49 | private IServiceAuth m_Auth; | ||
50 | private object m_Lock = new object(); | ||
51 | |||
52 | public GroupsServiceRemoteConnector(IConfigSource config) | ||
53 | { | ||
54 | IConfig groupsConfig = config.Configs["Groups"]; | ||
55 | string url = groupsConfig.GetString("GroupsServerURI", string.Empty); | ||
56 | if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) | ||
57 | throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url)); | ||
58 | |||
59 | m_ServerURI = url; | ||
60 | if (!m_ServerURI.EndsWith("/")) | ||
61 | m_ServerURI += "/"; | ||
62 | |||
63 | /// This is from BaseServiceConnector | ||
64 | string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Groups" }, "None"); | ||
65 | |||
66 | switch (authType) | ||
67 | { | ||
68 | case "BasicHttpAuthentication": | ||
69 | m_Auth = new BasicHttpAuthentication(config, "Groups"); | ||
70 | break; | ||
71 | } | ||
72 | /// | ||
73 | |||
74 | m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}", | ||
75 | m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString())); | ||
76 | } | ||
77 | |||
78 | public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, | ||
79 | bool allowPublish, bool maturePublish, UUID founderID, out string reason) | ||
80 | { | ||
81 | reason = string.Empty; | ||
82 | |||
83 | ExtendedGroupRecord rec = new ExtendedGroupRecord(); | ||
84 | rec.AllowPublish = allowPublish; | ||
85 | rec.Charter = charter; | ||
86 | rec.FounderID = founderID; | ||
87 | rec.GroupName = name; | ||
88 | rec.GroupPicture = insigniaID; | ||
89 | rec.MaturePublish = maturePublish; | ||
90 | rec.MembershipFee = membershipFee; | ||
91 | rec.OpenEnrollment = openEnrollment; | ||
92 | rec.ShowInList = showInList; | ||
93 | |||
94 | Dictionary<string, object> sendData = GroupsDataUtils.GroupRecord(rec); | ||
95 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
96 | sendData["OP"] = "ADD"; | ||
97 | Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData); | ||
98 | |||
99 | if (ret == null) | ||
100 | return null; | ||
101 | |||
102 | if (ret["RESULT"].ToString() == "NULL") | ||
103 | { | ||
104 | reason = ret["REASON"].ToString(); | ||
105 | return null; | ||
106 | } | ||
107 | |||
108 | return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]); | ||
109 | |||
110 | } | ||
111 | |||
112 | public ExtendedGroupRecord UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) | ||
113 | { | ||
114 | ExtendedGroupRecord rec = new ExtendedGroupRecord(); | ||
115 | rec.AllowPublish = allowPublish; | ||
116 | rec.Charter = charter; | ||
117 | rec.GroupPicture = insigniaID; | ||
118 | rec.MaturePublish = maturePublish; | ||
119 | rec.GroupID = groupID; | ||
120 | rec.MembershipFee = membershipFee; | ||
121 | rec.OpenEnrollment = openEnrollment; | ||
122 | rec.ShowInList = showInList; | ||
123 | |||
124 | Dictionary<string, object> sendData = GroupsDataUtils.GroupRecord(rec); | ||
125 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
126 | sendData["OP"] = "UPDATE"; | ||
127 | Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData); | ||
128 | |||
129 | if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL"))) | ||
130 | return null; | ||
131 | |||
132 | return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]); | ||
133 | } | ||
134 | |||
135 | public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName) | ||
136 | { | ||
137 | if (GroupID == UUID.Zero && (GroupName == null || (GroupName != null && GroupName == string.Empty))) | ||
138 | return null; | ||
139 | |||
140 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
141 | if (GroupID != UUID.Zero) | ||
142 | sendData["GroupID"] = GroupID.ToString(); | ||
143 | if (!string.IsNullOrEmpty(GroupName)) | ||
144 | sendData["Name"] = GroupsDataUtils.Sanitize(GroupName); | ||
145 | |||
146 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
147 | |||
148 | Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData); | ||
149 | |||
150 | if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL"))) | ||
151 | return null; | ||
152 | |||
153 | return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]); | ||
154 | } | ||
155 | |||
156 | public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query) | ||
157 | { | ||
158 | List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>(); | ||
159 | if (string.IsNullOrEmpty(query)) | ||
160 | return hits; | ||
161 | |||
162 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
163 | sendData["Query"] = query; | ||
164 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
165 | |||
166 | Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData); | ||
167 | |||
168 | if (ret == null) | ||
169 | return hits; | ||
170 | |||
171 | if (!ret.ContainsKey("RESULT")) | ||
172 | return hits; | ||
173 | |||
174 | if (ret["RESULT"].ToString() == "NULL") | ||
175 | return hits; | ||
176 | |||
177 | foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) | ||
178 | { | ||
179 | DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary<string, object>)v); | ||
180 | hits.Add(m); | ||
181 | } | ||
182 | |||
183 | return hits; | ||
184 | } | ||
185 | |||
186 | public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) | ||
187 | { | ||
188 | reason = string.Empty; | ||
189 | |||
190 | Dictionary<string, object> sendData = new Dictionary<string,object>(); | ||
191 | sendData["AgentID"] = AgentID; | ||
192 | sendData["GroupID"] = GroupID.ToString(); | ||
193 | sendData["RoleID"] = RoleID.ToString(); | ||
194 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
195 | sendData["AccessToken"] = token; | ||
196 | Dictionary<string, object> ret = MakeRequest("ADDAGENTTOGROUP", sendData); | ||
197 | |||
198 | if (ret == null) | ||
199 | return null; | ||
200 | |||
201 | if (!ret.ContainsKey("RESULT")) | ||
202 | return null; | ||
203 | |||
204 | if (ret["RESULT"].ToString() == "NULL") | ||
205 | { | ||
206 | reason = ret["REASON"].ToString(); | ||
207 | return null; | ||
208 | } | ||
209 | |||
210 | return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]); | ||
211 | |||
212 | } | ||
213 | |||
214 | public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID) | ||
215 | { | ||
216 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
217 | sendData["AgentID"] = AgentID; | ||
218 | sendData["GroupID"] = GroupID.ToString(); | ||
219 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
220 | MakeRequest("REMOVEAGENTFROMGROUP", sendData); | ||
221 | } | ||
222 | |||
223 | public ExtendedGroupMembershipData GetMembership(string RequestingAgentID, string AgentID, UUID GroupID) | ||
224 | { | ||
225 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
226 | sendData["AgentID"] = AgentID; | ||
227 | if (GroupID != UUID.Zero) | ||
228 | sendData["GroupID"] = GroupID.ToString(); | ||
229 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
230 | Dictionary<string, object> ret = MakeRequest("GETMEMBERSHIP", sendData); | ||
231 | |||
232 | if (ret == null) | ||
233 | return null; | ||
234 | |||
235 | if (!ret.ContainsKey("RESULT")) | ||
236 | return null; | ||
237 | |||
238 | if (ret["RESULT"].ToString() == "NULL") | ||
239 | return null; | ||
240 | |||
241 | return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]); | ||
242 | } | ||
243 | |||
244 | public List<GroupMembershipData> GetMemberships(string RequestingAgentID, string AgentID) | ||
245 | { | ||
246 | List<GroupMembershipData> memberships = new List<GroupMembershipData>(); | ||
247 | |||
248 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
249 | sendData["AgentID"] = AgentID; | ||
250 | sendData["ALL"] = "true"; | ||
251 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
252 | Dictionary<string, object> ret = MakeRequest("GETMEMBERSHIP", sendData); | ||
253 | |||
254 | if (ret == null) | ||
255 | return memberships; | ||
256 | |||
257 | if (!ret.ContainsKey("RESULT")) | ||
258 | return memberships; | ||
259 | |||
260 | if (ret["RESULT"].ToString() == "NULL") | ||
261 | return memberships; | ||
262 | |||
263 | foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) | ||
264 | { | ||
265 | GroupMembershipData m = GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)v); | ||
266 | memberships.Add(m); | ||
267 | } | ||
268 | |||
269 | return memberships; | ||
270 | } | ||
271 | |||
272 | public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID) | ||
273 | { | ||
274 | List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>(); | ||
275 | |||
276 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
277 | sendData["GroupID"] = GroupID.ToString(); | ||
278 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
279 | |||
280 | Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData); | ||
281 | |||
282 | if (ret == null) | ||
283 | return members; | ||
284 | |||
285 | if (!ret.ContainsKey("RESULT")) | ||
286 | return members; | ||
287 | |||
288 | if (ret["RESULT"].ToString() == "NULL") | ||
289 | return members; | ||
290 | |||
291 | foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) | ||
292 | { | ||
293 | ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v); | ||
294 | members.Add(m); | ||
295 | } | ||
296 | |||
297 | return members; | ||
298 | } | ||
299 | |||
300 | public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason) | ||
301 | { | ||
302 | reason = string.Empty; | ||
303 | |||
304 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
305 | sendData["GroupID"] = groupID.ToString(); | ||
306 | sendData["RoleID"] = roleID.ToString(); | ||
307 | sendData["Name"] = GroupsDataUtils.Sanitize(name); | ||
308 | sendData["Description"] = GroupsDataUtils.Sanitize(description); | ||
309 | sendData["Title"] = GroupsDataUtils.Sanitize(title); | ||
310 | sendData["Powers"] = powers.ToString(); | ||
311 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
312 | sendData["OP"] = "ADD"; | ||
313 | Dictionary<string, object> ret = MakeRequest("PUTROLE", sendData); | ||
314 | |||
315 | if (ret == null) | ||
316 | return false; | ||
317 | |||
318 | if (!ret.ContainsKey("RESULT")) | ||
319 | return false; | ||
320 | |||
321 | if (ret["RESULT"].ToString().ToLower() != "true") | ||
322 | { | ||
323 | reason = ret["REASON"].ToString(); | ||
324 | return false; | ||
325 | } | ||
326 | |||
327 | return true; | ||
328 | } | ||
329 | |||
330 | public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) | ||
331 | { | ||
332 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
333 | sendData["GroupID"] = groupID.ToString(); | ||
334 | sendData["RoleID"] = roleID.ToString(); | ||
335 | sendData["Name"] = GroupsDataUtils.Sanitize(name); | ||
336 | sendData["Description"] = GroupsDataUtils.Sanitize(description); | ||
337 | sendData["Title"] = GroupsDataUtils.Sanitize(title); | ||
338 | sendData["Powers"] = powers.ToString(); | ||
339 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
340 | sendData["OP"] = "UPDATE"; | ||
341 | Dictionary<string, object> ret = MakeRequest("PUTROLE", sendData); | ||
342 | |||
343 | if (ret == null) | ||
344 | return false; | ||
345 | |||
346 | if (!ret.ContainsKey("RESULT")) | ||
347 | return false; | ||
348 | |||
349 | if (ret["RESULT"].ToString().ToLower() != "true") | ||
350 | return false; | ||
351 | |||
352 | return true; | ||
353 | } | ||
354 | |||
355 | public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID) | ||
356 | { | ||
357 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
358 | sendData["GroupID"] = groupID.ToString(); | ||
359 | sendData["RoleID"] = roleID.ToString(); | ||
360 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
361 | MakeRequest("REMOVEROLE", sendData); | ||
362 | } | ||
363 | |||
364 | public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID) | ||
365 | { | ||
366 | List<GroupRolesData> roles = new List<GroupRolesData>(); | ||
367 | |||
368 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
369 | sendData["GroupID"] = GroupID.ToString(); | ||
370 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
371 | Dictionary<string, object> ret = MakeRequest("GETGROUPROLES", sendData); | ||
372 | |||
373 | if (ret == null) | ||
374 | return roles; | ||
375 | |||
376 | if (!ret.ContainsKey("RESULT")) | ||
377 | return roles; | ||
378 | |||
379 | if (ret["RESULT"].ToString() == "NULL") | ||
380 | return roles; | ||
381 | |||
382 | foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) | ||
383 | { | ||
384 | GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v); | ||
385 | roles.Add(m); | ||
386 | } | ||
387 | |||
388 | return roles; | ||
389 | } | ||
390 | |||
391 | public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID) | ||
392 | { | ||
393 | List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>(); | ||
394 | |||
395 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
396 | sendData["GroupID"] = GroupID.ToString(); | ||
397 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
398 | Dictionary<string, object> ret = MakeRequest("GETROLEMEMBERS", sendData); | ||
399 | |||
400 | if (ret == null) | ||
401 | return rmembers; | ||
402 | |||
403 | if (!ret.ContainsKey("RESULT")) | ||
404 | return rmembers; | ||
405 | |||
406 | if (ret["RESULT"].ToString() == "NULL") | ||
407 | return rmembers; | ||
408 | |||
409 | foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) | ||
410 | { | ||
411 | ExtendedGroupRoleMembersData m = GroupsDataUtils.GroupRoleMembersData((Dictionary<string, object>)v); | ||
412 | rmembers.Add(m); | ||
413 | } | ||
414 | |||
415 | return rmembers; | ||
416 | } | ||
417 | |||
418 | public bool AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) | ||
419 | { | ||
420 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
421 | sendData["AgentID"] = AgentID.ToString(); | ||
422 | sendData["GroupID"] = GroupID.ToString(); | ||
423 | sendData["RoleID"] = RoleID.ToString(); | ||
424 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
425 | sendData["OP"] = "ADD"; | ||
426 | |||
427 | Dictionary<string, object> ret = MakeRequest("AGENTROLE", sendData); | ||
428 | |||
429 | if (ret == null) | ||
430 | return false; | ||
431 | |||
432 | if (!ret.ContainsKey("RESULT")) | ||
433 | return false; | ||
434 | |||
435 | if (ret["RESULT"].ToString().ToLower() != "true") | ||
436 | return false; | ||
437 | |||
438 | return true; | ||
439 | } | ||
440 | |||
441 | public bool RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) | ||
442 | { | ||
443 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
444 | sendData["AgentID"] = AgentID.ToString(); | ||
445 | sendData["GroupID"] = GroupID.ToString(); | ||
446 | sendData["RoleID"] = RoleID.ToString(); | ||
447 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
448 | sendData["OP"] = "DELETE"; | ||
449 | |||
450 | Dictionary<string, object> ret = MakeRequest("AGENTROLE", sendData); | ||
451 | |||
452 | if (ret == null) | ||
453 | return false; | ||
454 | |||
455 | if (!ret.ContainsKey("RESULT")) | ||
456 | return false; | ||
457 | |||
458 | if (ret["RESULT"].ToString().ToLower() != "true") | ||
459 | return false; | ||
460 | |||
461 | return true; | ||
462 | } | ||
463 | |||
464 | public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID) | ||
465 | { | ||
466 | List<GroupRolesData> roles = new List<GroupRolesData>(); | ||
467 | |||
468 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
469 | sendData["AgentID"] = AgentID.ToString(); | ||
470 | sendData["GroupID"] = GroupID.ToString(); | ||
471 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
472 | Dictionary<string, object> ret = MakeRequest("GETAGENTROLES", sendData); | ||
473 | |||
474 | if (ret == null) | ||
475 | return roles; | ||
476 | |||
477 | if (!ret.ContainsKey("RESULT")) | ||
478 | return roles; | ||
479 | |||
480 | if (ret["RESULT"].ToString() == "NULL") | ||
481 | return roles; | ||
482 | |||
483 | foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) | ||
484 | { | ||
485 | GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v); | ||
486 | roles.Add(m); | ||
487 | } | ||
488 | |||
489 | return roles; | ||
490 | } | ||
491 | |||
492 | public GroupMembershipData SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID) | ||
493 | { | ||
494 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
495 | sendData["AgentID"] = AgentID.ToString(); | ||
496 | sendData["GroupID"] = GroupID.ToString(); | ||
497 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
498 | sendData["OP"] = "GROUP"; | ||
499 | |||
500 | Dictionary<string, object> ret = MakeRequest("SETACTIVE", sendData); | ||
501 | |||
502 | if (ret == null) | ||
503 | return null; | ||
504 | |||
505 | if (!ret.ContainsKey("RESULT")) | ||
506 | return null; | ||
507 | |||
508 | if (ret["RESULT"].ToString() == "NULL") | ||
509 | return null; | ||
510 | |||
511 | return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]); | ||
512 | } | ||
513 | |||
514 | public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) | ||
515 | { | ||
516 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
517 | sendData["AgentID"] = AgentID.ToString(); | ||
518 | sendData["GroupID"] = GroupID.ToString(); | ||
519 | sendData["RoleID"] = RoleID.ToString(); | ||
520 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
521 | sendData["OP"] = "ROLE"; | ||
522 | |||
523 | MakeRequest("SETACTIVE", sendData); | ||
524 | } | ||
525 | |||
526 | public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) | ||
527 | { | ||
528 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
529 | sendData["AgentID"] = AgentID.ToString(); | ||
530 | sendData["GroupID"] = GroupID.ToString(); | ||
531 | sendData["AcceptNotices"] = AcceptNotices.ToString(); | ||
532 | sendData["ListInProfile"] = ListInProfile.ToString(); | ||
533 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
534 | MakeRequest("UPDATEMEMBERSHIP", sendData); | ||
535 | } | ||
536 | |||
537 | public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID) | ||
538 | { | ||
539 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
540 | sendData["InviteID"] = inviteID.ToString(); | ||
541 | sendData["GroupID"] = groupID.ToString(); | ||
542 | sendData["RoleID"] = roleID.ToString(); | ||
543 | sendData["AgentID"] = agentID.ToString(); | ||
544 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
545 | sendData["OP"] = "ADD"; | ||
546 | |||
547 | Dictionary<string, object> ret = MakeRequest("INVITE", sendData); | ||
548 | |||
549 | if (ret == null) | ||
550 | return false; | ||
551 | |||
552 | if (!ret.ContainsKey("RESULT")) | ||
553 | return false; | ||
554 | |||
555 | if (ret["RESULT"].ToString().ToLower() != "true") // it may return "NULL" | ||
556 | return false; | ||
557 | |||
558 | return true; | ||
559 | } | ||
560 | |||
561 | public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID) | ||
562 | { | ||
563 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
564 | sendData["InviteID"] = inviteID.ToString(); | ||
565 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
566 | sendData["OP"] = "GET"; | ||
567 | |||
568 | Dictionary<string, object> ret = MakeRequest("INVITE", sendData); | ||
569 | |||
570 | if (ret == null) | ||
571 | return null; | ||
572 | |||
573 | if (!ret.ContainsKey("RESULT")) | ||
574 | return null; | ||
575 | |||
576 | if (ret["RESULT"].ToString() == "NULL") | ||
577 | return null; | ||
578 | |||
579 | return GroupsDataUtils.GroupInviteInfo((Dictionary<string, object>)ret["RESULT"]); | ||
580 | } | ||
581 | |||
582 | public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID) | ||
583 | { | ||
584 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
585 | sendData["InviteID"] = inviteID.ToString(); | ||
586 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
587 | sendData["OP"] = "DELETE"; | ||
588 | |||
589 | MakeRequest("INVITE", sendData); | ||
590 | } | ||
591 | |||
592 | public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, | ||
593 | bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID) | ||
594 | { | ||
595 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
596 | sendData["GroupID"] = groupID.ToString(); | ||
597 | sendData["NoticeID"] = noticeID.ToString(); | ||
598 | sendData["FromName"] = GroupsDataUtils.Sanitize(fromName); | ||
599 | sendData["Subject"] = GroupsDataUtils.Sanitize(subject); | ||
600 | sendData["Message"] = GroupsDataUtils.Sanitize(message); | ||
601 | sendData["HasAttachment"] = hasAttachment.ToString(); | ||
602 | if (hasAttachment) | ||
603 | { | ||
604 | sendData["AttachmentType"] = attType.ToString(); | ||
605 | sendData["AttachmentName"] = attName.ToString(); | ||
606 | sendData["AttachmentItemID"] = attItemID.ToString(); | ||
607 | sendData["AttachmentOwnerID"] = attOwnerID; | ||
608 | } | ||
609 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
610 | |||
611 | Dictionary<string, object> ret = MakeRequest("ADDNOTICE", sendData); | ||
612 | |||
613 | if (ret == null) | ||
614 | return false; | ||
615 | |||
616 | if (!ret.ContainsKey("RESULT")) | ||
617 | return false; | ||
618 | |||
619 | if (ret["RESULT"].ToString().ToLower() != "true") | ||
620 | return false; | ||
621 | |||
622 | return true; | ||
623 | } | ||
624 | |||
625 | public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID) | ||
626 | { | ||
627 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
628 | sendData["NoticeID"] = noticeID.ToString(); | ||
629 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
630 | |||
631 | Dictionary<string, object> ret = MakeRequest("GETNOTICES", sendData); | ||
632 | |||
633 | if (ret == null) | ||
634 | return null; | ||
635 | |||
636 | if (!ret.ContainsKey("RESULT")) | ||
637 | return null; | ||
638 | |||
639 | if (ret["RESULT"].ToString() == "NULL") | ||
640 | return null; | ||
641 | |||
642 | return GroupsDataUtils.GroupNoticeInfo((Dictionary<string, object>)ret["RESULT"]); | ||
643 | } | ||
644 | |||
645 | public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID) | ||
646 | { | ||
647 | List<ExtendedGroupNoticeData> notices = new List<ExtendedGroupNoticeData>(); | ||
648 | |||
649 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
650 | sendData["GroupID"] = GroupID.ToString(); | ||
651 | sendData["RequestingAgentID"] = RequestingAgentID; | ||
652 | Dictionary<string, object> ret = MakeRequest("GETNOTICES", sendData); | ||
653 | |||
654 | if (ret == null) | ||
655 | return notices; | ||
656 | |||
657 | if (!ret.ContainsKey("RESULT")) | ||
658 | return notices; | ||
659 | |||
660 | if (ret["RESULT"].ToString() == "NULL") | ||
661 | return notices; | ||
662 | |||
663 | foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values) | ||
664 | { | ||
665 | ExtendedGroupNoticeData m = GroupsDataUtils.GroupNoticeData((Dictionary<string, object>)v); | ||
666 | notices.Add(m); | ||
667 | } | ||
668 | |||
669 | return notices; | ||
670 | } | ||
671 | |||
672 | #region Make Request | ||
673 | |||
674 | private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData) | ||
675 | { | ||
676 | sendData["METHOD"] = method; | ||
677 | |||
678 | string reply = string.Empty; | ||
679 | lock (m_Lock) | ||
680 | reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
681 | m_ServerURI + "groups", | ||
682 | ServerUtils.BuildQueryString(sendData), | ||
683 | m_Auth); | ||
684 | |||
685 | if (reply == string.Empty) | ||
686 | return null; | ||
687 | |||
688 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( | ||
689 | reply); | ||
690 | |||
691 | return replyData; | ||
692 | } | ||
693 | |||
694 | #endregion | ||
695 | } | ||
696 | } \ No newline at end of file | ||
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs new file mode 100644 index 0000000..d4739c6 --- /dev/null +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs | |||
@@ -0,0 +1,408 @@ | |||
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.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using System.Text; | ||
34 | |||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Region.Framework.Scenes; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Server.Base; | ||
39 | using OpenSim.Services.Interfaces; | ||
40 | |||
41 | using OpenMetaverse; | ||
42 | using Mono.Addins; | ||
43 | using log4net; | ||
44 | using Nini.Config; | ||
45 | |||
46 | namespace OpenSim.Groups | ||
47 | { | ||
48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceRemoteConnectorModule")] | ||
49 | public class GroupsServiceRemoteConnectorModule : ISharedRegionModule, IGroupsServicesConnector | ||
50 | { | ||
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
52 | |||
53 | private bool m_Enabled = false; | ||
54 | private GroupsServiceRemoteConnector m_GroupsService; | ||
55 | private IUserManagement m_UserManagement; | ||
56 | private List<Scene> m_Scenes; | ||
57 | |||
58 | private RemoteConnectorCacheWrapper m_CacheWrapper; | ||
59 | |||
60 | #region constructors | ||
61 | public GroupsServiceRemoteConnectorModule() | ||
62 | { | ||
63 | } | ||
64 | |||
65 | public GroupsServiceRemoteConnectorModule(IConfigSource config, IUserManagement uman) | ||
66 | { | ||
67 | Init(config); | ||
68 | m_UserManagement = uman; | ||
69 | m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement); | ||
70 | |||
71 | } | ||
72 | #endregion | ||
73 | |||
74 | private void Init(IConfigSource config) | ||
75 | { | ||
76 | m_GroupsService = new GroupsServiceRemoteConnector(config); | ||
77 | m_Scenes = new List<Scene>(); | ||
78 | |||
79 | } | ||
80 | |||
81 | #region ISharedRegionModule | ||
82 | |||
83 | public void Initialise(IConfigSource config) | ||
84 | { | ||
85 | IConfig groupsConfig = config.Configs["Groups"]; | ||
86 | if (groupsConfig == null) | ||
87 | return; | ||
88 | |||
89 | if ((groupsConfig.GetBoolean("Enabled", false) == false) | ||
90 | || (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name)) | ||
91 | { | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | Init(config); | ||
96 | |||
97 | m_Enabled = true; | ||
98 | m_log.DebugFormat("[Groups.RemoteConnector]: Initializing {0}", this.Name); | ||
99 | } | ||
100 | |||
101 | public string Name | ||
102 | { | ||
103 | get { return "Groups Remote Service Connector"; } | ||
104 | } | ||
105 | |||
106 | public Type ReplaceableInterface | ||
107 | { | ||
108 | get { return null; } | ||
109 | } | ||
110 | |||
111 | public void AddRegion(Scene scene) | ||
112 | { | ||
113 | if (!m_Enabled) | ||
114 | return; | ||
115 | |||
116 | m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName); | ||
117 | scene.RegisterModuleInterface<IGroupsServicesConnector>(this); | ||
118 | m_Scenes.Add(scene); | ||
119 | } | ||
120 | |||
121 | public void RemoveRegion(Scene scene) | ||
122 | { | ||
123 | if (!m_Enabled) | ||
124 | return; | ||
125 | |||
126 | scene.UnregisterModuleInterface<IGroupsServicesConnector>(this); | ||
127 | m_Scenes.Remove(scene); | ||
128 | } | ||
129 | |||
130 | public void RegionLoaded(Scene scene) | ||
131 | { | ||
132 | if (!m_Enabled) | ||
133 | return; | ||
134 | |||
135 | if (m_UserManagement == null) | ||
136 | { | ||
137 | m_UserManagement = scene.RequestModuleInterface<IUserManagement>(); | ||
138 | m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | public void PostInitialise() | ||
143 | { | ||
144 | } | ||
145 | |||
146 | public void Close() | ||
147 | { | ||
148 | } | ||
149 | |||
150 | #endregion | ||
151 | |||
152 | #region IGroupsServicesConnector | ||
153 | |||
154 | public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, | ||
155 | bool allowPublish, bool maturePublish, UUID founderID, out string reason) | ||
156 | { | ||
157 | m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name); | ||
158 | string r = string.Empty; | ||
159 | |||
160 | UUID groupID = m_CacheWrapper.CreateGroup(RequestingAgentID, delegate | ||
161 | { | ||
162 | return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID, | ||
163 | membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out r); | ||
164 | }); | ||
165 | |||
166 | reason = r; | ||
167 | return groupID; | ||
168 | } | ||
169 | |||
170 | public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, | ||
171 | bool openEnrollment, bool allowPublish, bool maturePublish, out string reason) | ||
172 | { | ||
173 | string r = string.Empty; | ||
174 | |||
175 | bool success = m_CacheWrapper.UpdateGroup(groupID, delegate | ||
176 | { | ||
177 | return m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); | ||
178 | }); | ||
179 | |||
180 | reason = r; | ||
181 | return success; | ||
182 | } | ||
183 | |||
184 | public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName) | ||
185 | { | ||
186 | if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty)) | ||
187 | return null; | ||
188 | |||
189 | return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate | ||
190 | { | ||
191 | return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName); | ||
192 | }); | ||
193 | } | ||
194 | |||
195 | public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search) | ||
196 | { | ||
197 | // TODO! | ||
198 | return m_GroupsService.FindGroups(RequestingAgentID, search); | ||
199 | } | ||
200 | |||
201 | public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) | ||
202 | { | ||
203 | string agentFullID = AgentID; | ||
204 | m_log.DebugFormat("[Groups.RemoteConnector]: Add agent {0} to group {1}", agentFullID, GroupID); | ||
205 | string r = string.Empty; | ||
206 | |||
207 | bool success = m_CacheWrapper.AddAgentToGroup(RequestingAgentID, AgentID, GroupID, delegate | ||
208 | { | ||
209 | return m_GroupsService.AddAgentToGroup(RequestingAgentID, agentFullID, GroupID, RoleID, token, out r); | ||
210 | }); | ||
211 | |||
212 | reason = r; | ||
213 | return success; | ||
214 | } | ||
215 | |||
216 | public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID) | ||
217 | { | ||
218 | m_CacheWrapper.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID, delegate | ||
219 | { | ||
220 | m_GroupsService.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID); | ||
221 | }); | ||
222 | |||
223 | } | ||
224 | |||
225 | public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID) | ||
226 | { | ||
227 | m_CacheWrapper.SetAgentActiveGroup(AgentID, delegate | ||
228 | { | ||
229 | return m_GroupsService.SetAgentActiveGroup(RequestingAgentID, AgentID, GroupID); | ||
230 | }); | ||
231 | } | ||
232 | |||
233 | public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID) | ||
234 | { | ||
235 | return m_CacheWrapper.GetAgentActiveMembership(AgentID, delegate | ||
236 | { | ||
237 | return m_GroupsService.GetMembership(RequestingAgentID, AgentID, UUID.Zero); | ||
238 | }); | ||
239 | } | ||
240 | |||
241 | public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID) | ||
242 | { | ||
243 | return m_CacheWrapper.GetAgentGroupMembership(AgentID, GroupID, delegate | ||
244 | { | ||
245 | return m_GroupsService.GetMembership(RequestingAgentID, AgentID, GroupID); | ||
246 | }); | ||
247 | } | ||
248 | |||
249 | public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID) | ||
250 | { | ||
251 | return m_CacheWrapper.GetAgentGroupMemberships(AgentID, delegate | ||
252 | { | ||
253 | return m_GroupsService.GetMemberships(RequestingAgentID, AgentID); | ||
254 | }); | ||
255 | } | ||
256 | |||
257 | |||
258 | public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID) | ||
259 | { | ||
260 | return m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate | ||
261 | { | ||
262 | return m_GroupsService.GetGroupMembers(RequestingAgentID, GroupID); | ||
263 | }); | ||
264 | } | ||
265 | |||
266 | public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason) | ||
267 | { | ||
268 | string r = string.Empty; | ||
269 | bool success = m_CacheWrapper.AddGroupRole(groupID, roleID, description, name, powers, title, delegate | ||
270 | { | ||
271 | return m_GroupsService.AddGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, out r); | ||
272 | }); | ||
273 | |||
274 | reason = r; | ||
275 | return success; | ||
276 | } | ||
277 | |||
278 | public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) | ||
279 | { | ||
280 | return m_CacheWrapper.UpdateGroupRole(groupID, roleID, name, description, title, powers, delegate | ||
281 | { | ||
282 | return m_GroupsService.UpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers); | ||
283 | }); | ||
284 | } | ||
285 | |||
286 | public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID) | ||
287 | { | ||
288 | m_CacheWrapper.RemoveGroupRole(RequestingAgentID, groupID, roleID, delegate | ||
289 | { | ||
290 | m_GroupsService.RemoveGroupRole(RequestingAgentID, groupID, roleID); | ||
291 | }); | ||
292 | } | ||
293 | |||
294 | public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID) | ||
295 | { | ||
296 | return m_CacheWrapper.GetGroupRoles(RequestingAgentID, GroupID, delegate | ||
297 | { | ||
298 | return m_GroupsService.GetGroupRoles(RequestingAgentID, GroupID); | ||
299 | }); | ||
300 | } | ||
301 | |||
302 | public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID) | ||
303 | { | ||
304 | return m_CacheWrapper.GetGroupRoleMembers(RequestingAgentID, GroupID, delegate | ||
305 | { | ||
306 | return m_GroupsService.GetGroupRoleMembers(RequestingAgentID, GroupID); | ||
307 | }); | ||
308 | } | ||
309 | |||
310 | public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) | ||
311 | { | ||
312 | m_CacheWrapper.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID, delegate | ||
313 | { | ||
314 | return m_GroupsService.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID); | ||
315 | }); | ||
316 | } | ||
317 | |||
318 | public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) | ||
319 | { | ||
320 | m_CacheWrapper.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID, delegate | ||
321 | { | ||
322 | return m_GroupsService.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID); | ||
323 | }); | ||
324 | } | ||
325 | |||
326 | public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID) | ||
327 | { | ||
328 | return m_CacheWrapper.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID, delegate | ||
329 | { | ||
330 | return m_GroupsService.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID); ; | ||
331 | }); | ||
332 | } | ||
333 | |||
334 | public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID) | ||
335 | { | ||
336 | m_CacheWrapper.SetAgentActiveGroupRole(AgentID, GroupID, delegate | ||
337 | { | ||
338 | m_GroupsService.SetAgentActiveGroupRole(RequestingAgentID, AgentID, GroupID, RoleID); | ||
339 | }); | ||
340 | } | ||
341 | |||
342 | public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) | ||
343 | { | ||
344 | m_CacheWrapper.UpdateMembership(AgentID, GroupID, AcceptNotices, ListInProfile, delegate | ||
345 | { | ||
346 | m_GroupsService.UpdateMembership(RequestingAgentID, AgentID, GroupID, AcceptNotices, ListInProfile); | ||
347 | }); | ||
348 | } | ||
349 | |||
350 | public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID) | ||
351 | { | ||
352 | return m_GroupsService.AddAgentToGroupInvite(RequestingAgentID, inviteID, groupID, roleID, agentID); | ||
353 | } | ||
354 | |||
355 | public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID) | ||
356 | { | ||
357 | return m_GroupsService.GetAgentToGroupInvite(RequestingAgentID, inviteID); | ||
358 | } | ||
359 | |||
360 | public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID) | ||
361 | { | ||
362 | m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID); | ||
363 | } | ||
364 | |||
365 | public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, | ||
366 | bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID) | ||
367 | { | ||
368 | GroupNoticeInfo notice = new GroupNoticeInfo(); | ||
369 | notice.GroupID = groupID; | ||
370 | notice.Message = message; | ||
371 | notice.noticeData = new ExtendedGroupNoticeData(); | ||
372 | notice.noticeData.AttachmentItemID = attItemID; | ||
373 | notice.noticeData.AttachmentName = attName; | ||
374 | notice.noticeData.AttachmentOwnerID = attOwnerID.ToString(); | ||
375 | notice.noticeData.AttachmentType = attType; | ||
376 | notice.noticeData.FromName = fromName; | ||
377 | notice.noticeData.HasAttachment = hasAttachment; | ||
378 | notice.noticeData.NoticeID = noticeID; | ||
379 | notice.noticeData.Subject = subject; | ||
380 | notice.noticeData.Timestamp = (uint)Util.UnixTimeSinceEpoch(); | ||
381 | |||
382 | return m_CacheWrapper.AddGroupNotice(groupID, noticeID, notice, delegate | ||
383 | { | ||
384 | return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message, | ||
385 | hasAttachment, attType, attName, attItemID, attOwnerID); | ||
386 | }); | ||
387 | } | ||
388 | |||
389 | public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID) | ||
390 | { | ||
391 | return m_CacheWrapper.GetGroupNotice(noticeID, delegate | ||
392 | { | ||
393 | return m_GroupsService.GetGroupNotice(RequestingAgentID, noticeID); | ||
394 | }); | ||
395 | } | ||
396 | |||
397 | public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID) | ||
398 | { | ||
399 | return m_CacheWrapper.GetGroupNotices(GroupID, delegate | ||
400 | { | ||
401 | return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID); | ||
402 | }); | ||
403 | } | ||
404 | |||
405 | #endregion | ||
406 | } | ||
407 | |||
408 | } | ||
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs new file mode 100644 index 0000000..26e844e --- /dev/null +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs | |||
@@ -0,0 +1,816 @@ | |||
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.Reflection; | ||
30 | using System.Text; | ||
31 | using System.Xml; | ||
32 | using System.Collections.Generic; | ||
33 | using System.IO; | ||
34 | using Nini.Config; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Server.Base; | ||
37 | using OpenSim.Services.Interfaces; | ||
38 | using OpenSim.Framework.Servers.HttpServer; | ||
39 | using OpenSim.Framework.ServiceAuth; | ||
40 | using OpenSim.Server.Handlers.Base; | ||
41 | using log4net; | ||
42 | using OpenMetaverse; | ||
43 | |||
44 | namespace OpenSim.Groups | ||
45 | { | ||
46 | public class GroupsServiceRobustConnector : ServiceConnector | ||
47 | { | ||
48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private GroupsService m_GroupsService; | ||
51 | private string m_ConfigName = "Groups"; | ||
52 | |||
53 | public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) : | ||
54 | base(config, server, configName) | ||
55 | { | ||
56 | string key = string.Empty; | ||
57 | if (configName != String.Empty) | ||
58 | m_ConfigName = configName; | ||
59 | |||
60 | m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName); | ||
61 | |||
62 | IConfig groupsConfig = config.Configs[m_ConfigName]; | ||
63 | if (groupsConfig != null) | ||
64 | { | ||
65 | key = groupsConfig.GetString("SecretKey", string.Empty); | ||
66 | m_log.DebugFormat("[Groups.RobustConnector]: Starting with secret key {0}", key); | ||
67 | } | ||
68 | // else | ||
69 | // m_log.DebugFormat("[Groups.RobustConnector]: Unable to find {0} section in configuration", m_ConfigName); | ||
70 | |||
71 | m_GroupsService = new GroupsService(config); | ||
72 | |||
73 | IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName); | ||
74 | |||
75 | server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService, auth)); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | public class GroupsServicePostHandler : BaseStreamHandler | ||
80 | { | ||
81 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
82 | |||
83 | private GroupsService m_GroupsService; | ||
84 | |||
85 | public GroupsServicePostHandler(GroupsService service, IServiceAuth auth) : | ||
86 | base("POST", "/groups", auth) | ||
87 | { | ||
88 | m_GroupsService = service; | ||
89 | } | ||
90 | |||
91 | protected override byte[] ProcessRequest(string path, Stream requestData, | ||
92 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
93 | { | ||
94 | StreamReader sr = new StreamReader(requestData); | ||
95 | string body = sr.ReadToEnd(); | ||
96 | sr.Close(); | ||
97 | body = body.Trim(); | ||
98 | |||
99 | //m_log.DebugFormat("[XXX]: query String: {0}", body); | ||
100 | |||
101 | try | ||
102 | { | ||
103 | Dictionary<string, object> request = | ||
104 | ServerUtils.ParseQueryString(body); | ||
105 | |||
106 | if (!request.ContainsKey("METHOD")) | ||
107 | return FailureResult(); | ||
108 | |||
109 | string method = request["METHOD"].ToString(); | ||
110 | request.Remove("METHOD"); | ||
111 | |||
112 | // m_log.DebugFormat("[Groups.Handler]: {0}", method); | ||
113 | switch (method) | ||
114 | { | ||
115 | case "PUTGROUP": | ||
116 | return HandleAddOrUpdateGroup(request); | ||
117 | case "GETGROUP": | ||
118 | return HandleGetGroup(request); | ||
119 | case "ADDAGENTTOGROUP": | ||
120 | return HandleAddAgentToGroup(request); | ||
121 | case "REMOVEAGENTFROMGROUP": | ||
122 | return HandleRemoveAgentFromGroup(request); | ||
123 | case "GETMEMBERSHIP": | ||
124 | return HandleGetMembership(request); | ||
125 | case "GETGROUPMEMBERS": | ||
126 | return HandleGetGroupMembers(request); | ||
127 | case "PUTROLE": | ||
128 | return HandlePutRole(request); | ||
129 | case "REMOVEROLE": | ||
130 | return HandleRemoveRole(request); | ||
131 | case "GETGROUPROLES": | ||
132 | return HandleGetGroupRoles(request); | ||
133 | case "GETROLEMEMBERS": | ||
134 | return HandleGetRoleMembers(request); | ||
135 | case "AGENTROLE": | ||
136 | return HandleAgentRole(request); | ||
137 | case "GETAGENTROLES": | ||
138 | return HandleGetAgentRoles(request); | ||
139 | case "SETACTIVE": | ||
140 | return HandleSetActive(request); | ||
141 | case "UPDATEMEMBERSHIP": | ||
142 | return HandleUpdateMembership(request); | ||
143 | case "INVITE": | ||
144 | return HandleInvite(request); | ||
145 | case "ADDNOTICE": | ||
146 | return HandleAddNotice(request); | ||
147 | case "GETNOTICES": | ||
148 | return HandleGetNotices(request); | ||
149 | case "FINDGROUPS": | ||
150 | return HandleFindGroups(request); | ||
151 | } | ||
152 | m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method); | ||
153 | } | ||
154 | catch (Exception e) | ||
155 | { | ||
156 | m_log.Error(string.Format("[GROUPS HANDLER]: Exception {0} ", e.Message), e); | ||
157 | } | ||
158 | |||
159 | return FailureResult(); | ||
160 | } | ||
161 | |||
162 | byte[] HandleAddOrUpdateGroup(Dictionary<string, object> request) | ||
163 | { | ||
164 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
165 | |||
166 | ExtendedGroupRecord grec = GroupsDataUtils.GroupRecord(request); | ||
167 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("OP")) | ||
168 | NullResult(result, "Bad network data"); | ||
169 | |||
170 | else | ||
171 | { | ||
172 | string RequestingAgentID = request["RequestingAgentID"].ToString(); | ||
173 | string reason = string.Empty; | ||
174 | string op = request["OP"].ToString(); | ||
175 | if (op == "ADD") | ||
176 | { | ||
177 | grec.GroupID = m_GroupsService.CreateGroup(RequestingAgentID, grec.GroupName, grec.Charter, grec.ShowInList, grec.GroupPicture, grec.MembershipFee, | ||
178 | grec.OpenEnrollment, grec.AllowPublish, grec.MaturePublish, grec.FounderID, out reason); | ||
179 | |||
180 | } | ||
181 | else if (op == "UPDATE") | ||
182 | { | ||
183 | m_GroupsService.UpdateGroup(RequestingAgentID, grec.GroupID, grec.Charter, grec.ShowInList, grec.GroupPicture, grec.MembershipFee, | ||
184 | grec.OpenEnrollment, grec.AllowPublish, grec.MaturePublish); | ||
185 | |||
186 | } | ||
187 | |||
188 | if (grec.GroupID != UUID.Zero) | ||
189 | { | ||
190 | grec = m_GroupsService.GetGroupRecord(RequestingAgentID, grec.GroupID); | ||
191 | if (grec == null) | ||
192 | NullResult(result, "Internal Error"); | ||
193 | else | ||
194 | result["RESULT"] = GroupsDataUtils.GroupRecord(grec); | ||
195 | } | ||
196 | else | ||
197 | NullResult(result, reason); | ||
198 | } | ||
199 | |||
200 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
201 | |||
202 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
203 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
204 | } | ||
205 | |||
206 | byte[] HandleGetGroup(Dictionary<string, object> request) | ||
207 | { | ||
208 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
209 | |||
210 | if (!request.ContainsKey("RequestingAgentID")) | ||
211 | NullResult(result, "Bad network data"); | ||
212 | else | ||
213 | { | ||
214 | string RequestingAgentID = request["RequestingAgentID"].ToString(); | ||
215 | ExtendedGroupRecord grec = null; | ||
216 | if (request.ContainsKey("GroupID")) | ||
217 | { | ||
218 | UUID groupID = new UUID(request["GroupID"].ToString()); | ||
219 | grec = m_GroupsService.GetGroupRecord(RequestingAgentID, groupID); | ||
220 | } | ||
221 | else if (request.ContainsKey("Name")) | ||
222 | { | ||
223 | string name = request["Name"].ToString(); | ||
224 | grec = m_GroupsService.GetGroupRecord(RequestingAgentID, name); | ||
225 | } | ||
226 | |||
227 | if (grec == null) | ||
228 | NullResult(result, "Group not found"); | ||
229 | else | ||
230 | result["RESULT"] = GroupsDataUtils.GroupRecord(grec); | ||
231 | } | ||
232 | |||
233 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
234 | |||
235 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
236 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
237 | } | ||
238 | |||
239 | byte[] HandleAddAgentToGroup(Dictionary<string, object> request) | ||
240 | { | ||
241 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
242 | |||
243 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || | ||
244 | !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID")) | ||
245 | NullResult(result, "Bad network data"); | ||
246 | else | ||
247 | { | ||
248 | UUID groupID = new UUID(request["GroupID"].ToString()); | ||
249 | UUID roleID = new UUID(request["RoleID"].ToString()); | ||
250 | string agentID = request["AgentID"].ToString(); | ||
251 | string requestingAgentID = request["RequestingAgentID"].ToString(); | ||
252 | string token = string.Empty; | ||
253 | string reason = string.Empty; | ||
254 | |||
255 | if (request.ContainsKey("AccessToken")) | ||
256 | token = request["AccessToken"].ToString(); | ||
257 | |||
258 | if (!m_GroupsService.AddAgentToGroup(requestingAgentID, agentID, groupID, roleID, token, out reason)) | ||
259 | NullResult(result, reason); | ||
260 | else | ||
261 | { | ||
262 | GroupMembershipData membership = m_GroupsService.GetAgentGroupMembership(requestingAgentID, agentID, groupID); | ||
263 | if (membership == null) | ||
264 | NullResult(result, "Internal error"); | ||
265 | else | ||
266 | result["RESULT"] = GroupsDataUtils.GroupMembershipData((ExtendedGroupMembershipData)membership); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
271 | |||
272 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
273 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
274 | } | ||
275 | |||
276 | byte[] HandleRemoveAgentFromGroup(Dictionary<string, object> request) | ||
277 | { | ||
278 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
279 | |||
280 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || !request.ContainsKey("GroupID")) | ||
281 | NullResult(result, "Bad network data"); | ||
282 | else | ||
283 | { | ||
284 | UUID groupID = new UUID(request["GroupID"].ToString()); | ||
285 | string agentID = request["AgentID"].ToString(); | ||
286 | string requestingAgentID = request["RequestingAgentID"].ToString(); | ||
287 | |||
288 | if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID)) | ||
289 | NullResult(result, string.Format("Insufficient permissions.", agentID)); | ||
290 | else | ||
291 | result["RESULT"] = "true"; | ||
292 | } | ||
293 | |||
294 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
295 | return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); | ||
296 | } | ||
297 | |||
298 | byte[] HandleGetMembership(Dictionary<string, object> request) | ||
299 | { | ||
300 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
301 | |||
302 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID")) | ||
303 | NullResult(result, "Bad network data"); | ||
304 | else | ||
305 | { | ||
306 | string agentID = request["AgentID"].ToString(); | ||
307 | UUID groupID = UUID.Zero; | ||
308 | if (request.ContainsKey("GroupID")) | ||
309 | groupID = new UUID(request["GroupID"].ToString()); | ||
310 | string requestingAgentID = request["RequestingAgentID"].ToString(); | ||
311 | bool all = request.ContainsKey("ALL"); | ||
312 | |||
313 | if (!all) | ||
314 | { | ||
315 | ExtendedGroupMembershipData membership = null; | ||
316 | if (groupID == UUID.Zero) | ||
317 | { | ||
318 | membership = m_GroupsService.GetAgentActiveMembership(requestingAgentID, agentID); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | membership = m_GroupsService.GetAgentGroupMembership(requestingAgentID, agentID, groupID); | ||
323 | } | ||
324 | |||
325 | if (membership == null) | ||
326 | NullResult(result, "No such membership"); | ||
327 | else | ||
328 | result["RESULT"] = GroupsDataUtils.GroupMembershipData(membership); | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | List<GroupMembershipData> memberships = m_GroupsService.GetAgentGroupMemberships(requestingAgentID, agentID); | ||
333 | if (memberships == null || (memberships != null && memberships.Count == 0)) | ||
334 | { | ||
335 | NullResult(result, "No memberships"); | ||
336 | } | ||
337 | else | ||
338 | { | ||
339 | Dictionary<string, object> dict = new Dictionary<string, object>(); | ||
340 | int i = 0; | ||
341 | foreach (GroupMembershipData m in memberships) | ||
342 | dict["m-" + i++] = GroupsDataUtils.GroupMembershipData((ExtendedGroupMembershipData)m); | ||
343 | |||
344 | result["RESULT"] = dict; | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | |||
349 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
350 | |||
351 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
352 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
353 | } | ||
354 | |||
355 | byte[] HandleGetGroupMembers(Dictionary<string, object> request) | ||
356 | { | ||
357 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
358 | |||
359 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID")) | ||
360 | NullResult(result, "Bad network data"); | ||
361 | else | ||
362 | { | ||
363 | UUID groupID = new UUID(request["GroupID"].ToString()); | ||
364 | string requestingAgentID = request["RequestingAgentID"].ToString(); | ||
365 | |||
366 | List<ExtendedGroupMembersData> members = m_GroupsService.GetGroupMembers(requestingAgentID, groupID); | ||
367 | if (members == null || (members != null && members.Count == 0)) | ||
368 | { | ||
369 | NullResult(result, "No members"); | ||
370 | } | ||
371 | else | ||
372 | { | ||
373 | Dictionary<string, object> dict = new Dictionary<string, object>(); | ||
374 | int i = 0; | ||
375 | foreach (ExtendedGroupMembersData m in members) | ||
376 | { | ||
377 | dict["m-" + i++] = GroupsDataUtils.GroupMembersData(m); | ||
378 | } | ||
379 | |||
380 | result["RESULT"] = dict; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
385 | |||
386 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
387 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
388 | } | ||
389 | |||
390 | byte[] HandlePutRole(Dictionary<string, object> request) | ||
391 | { | ||
392 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
393 | |||
394 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") || | ||
395 | !request.ContainsKey("Name") || !request.ContainsKey("Description") || !request.ContainsKey("Title") || | ||
396 | !request.ContainsKey("Powers") || !request.ContainsKey("OP")) | ||
397 | NullResult(result, "Bad network data"); | ||
398 | |||
399 | else | ||
400 | { | ||
401 | string op = request["OP"].ToString(); | ||
402 | string reason = string.Empty; | ||
403 | |||
404 | bool success = false; | ||
405 | if (op == "ADD") | ||
406 | success = m_GroupsService.AddGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()), | ||
407 | new UUID(request["RoleID"].ToString()), request["Name"].ToString(), request["Description"].ToString(), | ||
408 | request["Title"].ToString(), UInt64.Parse(request["Powers"].ToString()), out reason); | ||
409 | |||
410 | else if (op == "UPDATE") | ||
411 | success = m_GroupsService.UpdateGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()), | ||
412 | new UUID(request["RoleID"].ToString()), request["Name"].ToString(), request["Description"].ToString(), | ||
413 | request["Title"].ToString(), UInt64.Parse(request["Powers"].ToString())); | ||
414 | |||
415 | result["RESULT"] = success.ToString(); | ||
416 | } | ||
417 | |||
418 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
419 | |||
420 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
421 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
422 | } | ||
423 | |||
424 | byte[] HandleRemoveRole(Dictionary<string, object> request) | ||
425 | { | ||
426 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
427 | |||
428 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID")) | ||
429 | NullResult(result, "Bad network data"); | ||
430 | |||
431 | else | ||
432 | { | ||
433 | m_GroupsService.RemoveGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()), | ||
434 | new UUID(request["RoleID"].ToString())); | ||
435 | result["RESULT"] = "true"; | ||
436 | } | ||
437 | |||
438 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
439 | return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); | ||
440 | } | ||
441 | |||
442 | byte[] HandleGetGroupRoles(Dictionary<string, object> request) | ||
443 | { | ||
444 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
445 | |||
446 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID")) | ||
447 | NullResult(result, "Bad network data"); | ||
448 | else | ||
449 | { | ||
450 | UUID groupID = new UUID(request["GroupID"].ToString()); | ||
451 | string requestingAgentID = request["RequestingAgentID"].ToString(); | ||
452 | |||
453 | List<GroupRolesData> roles = m_GroupsService.GetGroupRoles(requestingAgentID, groupID); | ||
454 | if (roles == null || (roles != null && roles.Count == 0)) | ||
455 | { | ||
456 | NullResult(result, "No members"); | ||
457 | } | ||
458 | else | ||
459 | { | ||
460 | Dictionary<string, object> dict = new Dictionary<string, object>(); | ||
461 | int i = 0; | ||
462 | foreach (GroupRolesData r in roles) | ||
463 | dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r); | ||
464 | |||
465 | result["RESULT"] = dict; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
470 | |||
471 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
472 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
473 | } | ||
474 | |||
475 | byte[] HandleGetRoleMembers(Dictionary<string, object> request) | ||
476 | { | ||
477 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
478 | |||
479 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID")) | ||
480 | NullResult(result, "Bad network data"); | ||
481 | else | ||
482 | { | ||
483 | UUID groupID = new UUID(request["GroupID"].ToString()); | ||
484 | string requestingAgentID = request["RequestingAgentID"].ToString(); | ||
485 | |||
486 | List<ExtendedGroupRoleMembersData> rmembers = m_GroupsService.GetGroupRoleMembers(requestingAgentID, groupID); | ||
487 | if (rmembers == null || (rmembers != null && rmembers.Count == 0)) | ||
488 | { | ||
489 | NullResult(result, "No members"); | ||
490 | } | ||
491 | else | ||
492 | { | ||
493 | Dictionary<string, object> dict = new Dictionary<string, object>(); | ||
494 | int i = 0; | ||
495 | foreach (ExtendedGroupRoleMembersData rm in rmembers) | ||
496 | dict["rm-" + i++] = GroupsDataUtils.GroupRoleMembersData(rm); | ||
497 | |||
498 | result["RESULT"] = dict; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
503 | |||
504 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
505 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
506 | } | ||
507 | |||
508 | byte[] HandleAgentRole(Dictionary<string, object> request) | ||
509 | { | ||
510 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
511 | |||
512 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") || | ||
513 | !request.ContainsKey("AgentID") || !request.ContainsKey("OP")) | ||
514 | NullResult(result, "Bad network data"); | ||
515 | |||
516 | else | ||
517 | { | ||
518 | string op = request["OP"].ToString(); | ||
519 | |||
520 | bool success = false; | ||
521 | if (op == "ADD") | ||
522 | success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), | ||
523 | new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString())); | ||
524 | |||
525 | else if (op == "DELETE") | ||
526 | success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), | ||
527 | new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString())); | ||
528 | |||
529 | result["RESULT"] = success.ToString(); | ||
530 | } | ||
531 | |||
532 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
533 | |||
534 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
535 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
536 | } | ||
537 | |||
538 | byte[] HandleGetAgentRoles(Dictionary<string, object> request) | ||
539 | { | ||
540 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
541 | |||
542 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AgentID")) | ||
543 | NullResult(result, "Bad network data"); | ||
544 | else | ||
545 | { | ||
546 | UUID groupID = new UUID(request["GroupID"].ToString()); | ||
547 | string agentID = request["AgentID"].ToString(); | ||
548 | string requestingAgentID = request["RequestingAgentID"].ToString(); | ||
549 | |||
550 | List<GroupRolesData> roles = m_GroupsService.GetAgentGroupRoles(requestingAgentID, agentID, groupID); | ||
551 | if (roles == null || (roles != null && roles.Count == 0)) | ||
552 | { | ||
553 | NullResult(result, "No members"); | ||
554 | } | ||
555 | else | ||
556 | { | ||
557 | Dictionary<string, object> dict = new Dictionary<string, object>(); | ||
558 | int i = 0; | ||
559 | foreach (GroupRolesData r in roles) | ||
560 | dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r); | ||
561 | |||
562 | result["RESULT"] = dict; | ||
563 | } | ||
564 | } | ||
565 | |||
566 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
567 | |||
568 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
569 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
570 | } | ||
571 | |||
572 | byte[] HandleSetActive(Dictionary<string, object> request) | ||
573 | { | ||
574 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
575 | |||
576 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || | ||
577 | !request.ContainsKey("AgentID") || !request.ContainsKey("OP")) | ||
578 | { | ||
579 | NullResult(result, "Bad network data"); | ||
580 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
581 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
582 | } | ||
583 | else | ||
584 | { | ||
585 | string op = request["OP"].ToString(); | ||
586 | |||
587 | if (op == "GROUP") | ||
588 | { | ||
589 | ExtendedGroupMembershipData group = m_GroupsService.SetAgentActiveGroup(request["RequestingAgentID"].ToString(), | ||
590 | request["AgentID"].ToString(), new UUID(request["GroupID"].ToString())); | ||
591 | |||
592 | if (group == null) | ||
593 | NullResult(result, "Internal error"); | ||
594 | else | ||
595 | result["RESULT"] = GroupsDataUtils.GroupMembershipData(group); | ||
596 | |||
597 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
598 | |||
599 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
600 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
601 | |||
602 | } | ||
603 | else if (op == "ROLE" && request.ContainsKey("RoleID")) | ||
604 | { | ||
605 | m_GroupsService.SetAgentActiveGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), | ||
606 | new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString())); | ||
607 | result["RESULT"] = "true"; | ||
608 | } | ||
609 | |||
610 | return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); | ||
611 | } | ||
612 | |||
613 | } | ||
614 | |||
615 | byte[] HandleUpdateMembership(Dictionary<string, object> request) | ||
616 | { | ||
617 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
618 | |||
619 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || !request.ContainsKey("GroupID") || | ||
620 | !request.ContainsKey("AcceptNotices") || !request.ContainsKey("ListInProfile")) | ||
621 | NullResult(result, "Bad network data"); | ||
622 | |||
623 | else | ||
624 | { | ||
625 | m_GroupsService.UpdateMembership(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()), | ||
626 | bool.Parse(request["AcceptNotices"].ToString()), bool.Parse(request["ListInProfile"].ToString())); | ||
627 | |||
628 | result["RESULT"] = "true"; | ||
629 | } | ||
630 | |||
631 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
632 | return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); | ||
633 | } | ||
634 | |||
635 | byte[] HandleInvite(Dictionary<string, object> request) | ||
636 | { | ||
637 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
638 | |||
639 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("InviteID")) | ||
640 | { | ||
641 | NullResult(result, "Bad network data"); | ||
642 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
643 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
644 | } | ||
645 | else | ||
646 | { | ||
647 | string op = request["OP"].ToString(); | ||
648 | |||
649 | if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID")) | ||
650 | { | ||
651 | bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(), | ||
652 | new UUID(request["InviteID"].ToString()), new UUID(request["GroupID"].ToString()), | ||
653 | new UUID(request["RoleID"].ToString()), request["AgentID"].ToString()); | ||
654 | |||
655 | result["RESULT"] = success.ToString(); | ||
656 | return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); | ||
657 | |||
658 | } | ||
659 | else if (op == "DELETE") | ||
660 | { | ||
661 | m_GroupsService.RemoveAgentToGroupInvite(request["RequestingAgentID"].ToString(), new UUID(request["InviteID"].ToString())); | ||
662 | result["RESULT"] = "true"; | ||
663 | return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); | ||
664 | } | ||
665 | else if (op == "GET") | ||
666 | { | ||
667 | GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(), | ||
668 | new UUID(request["InviteID"].ToString())); | ||
669 | |||
670 | if (invite != null) | ||
671 | result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite); | ||
672 | else | ||
673 | result["RESULT"] = "NULL"; | ||
674 | |||
675 | return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); | ||
676 | } | ||
677 | |||
678 | NullResult(result, "Bad OP in request"); | ||
679 | return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result)); | ||
680 | } | ||
681 | |||
682 | } | ||
683 | |||
684 | byte[] HandleAddNotice(Dictionary<string, object> request) | ||
685 | { | ||
686 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
687 | |||
688 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("NoticeID") || | ||
689 | !request.ContainsKey("FromName") || !request.ContainsKey("Subject") || !request.ContainsKey("Message") || | ||
690 | !request.ContainsKey("HasAttachment")) | ||
691 | NullResult(result, "Bad network data"); | ||
692 | |||
693 | else | ||
694 | { | ||
695 | |||
696 | bool hasAtt = bool.Parse(request["HasAttachment"].ToString()); | ||
697 | byte attType = 0; | ||
698 | string attName = string.Empty; | ||
699 | string attOwner = string.Empty; | ||
700 | UUID attItem = UUID.Zero; | ||
701 | if (request.ContainsKey("AttachmentType")) | ||
702 | attType = byte.Parse(request["AttachmentType"].ToString()); | ||
703 | if (request.ContainsKey("AttachmentName")) | ||
704 | attName = request["AttachmentName"].ToString(); | ||
705 | if (request.ContainsKey("AttachmentItemID")) | ||
706 | attItem = new UUID(request["AttachmentItemID"].ToString()); | ||
707 | if (request.ContainsKey("AttachmentOwnerID")) | ||
708 | attOwner = request["AttachmentOwnerID"].ToString(); | ||
709 | |||
710 | bool success = m_GroupsService.AddGroupNotice(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()), | ||
711 | new UUID(request["NoticeID"].ToString()), request["FromName"].ToString(), request["Subject"].ToString(), | ||
712 | request["Message"].ToString(), hasAtt, attType, attName, attItem, attOwner); | ||
713 | |||
714 | result["RESULT"] = success.ToString(); | ||
715 | } | ||
716 | |||
717 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
718 | |||
719 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
720 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
721 | } | ||
722 | |||
723 | byte[] HandleGetNotices(Dictionary<string, object> request) | ||
724 | { | ||
725 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
726 | |||
727 | if (!request.ContainsKey("RequestingAgentID")) | ||
728 | NullResult(result, "Bad network data"); | ||
729 | |||
730 | else if (request.ContainsKey("NoticeID")) // just one | ||
731 | { | ||
732 | GroupNoticeInfo notice = m_GroupsService.GetGroupNotice(request["RequestingAgentID"].ToString(), new UUID(request["NoticeID"].ToString())); | ||
733 | |||
734 | if (notice == null) | ||
735 | NullResult(result, "NO such notice"); | ||
736 | else | ||
737 | result["RESULT"] = GroupsDataUtils.GroupNoticeInfo(notice); | ||
738 | |||
739 | } | ||
740 | else if (request.ContainsKey("GroupID")) // all notices for group | ||
741 | { | ||
742 | List<ExtendedGroupNoticeData> notices = m_GroupsService.GetGroupNotices(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString())); | ||
743 | |||
744 | if (notices == null || (notices != null && notices.Count == 0)) | ||
745 | NullResult(result, "No notices"); | ||
746 | else | ||
747 | { | ||
748 | Dictionary<string, object> dict = new Dictionary<string, object>(); | ||
749 | int i = 0; | ||
750 | foreach (ExtendedGroupNoticeData n in notices) | ||
751 | dict["n-" + i++] = GroupsDataUtils.GroupNoticeData(n); | ||
752 | |||
753 | result["RESULT"] = dict; | ||
754 | } | ||
755 | |||
756 | } | ||
757 | else | ||
758 | NullResult(result, "Bad OP in request"); | ||
759 | |||
760 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
761 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
762 | } | ||
763 | |||
764 | byte[] HandleFindGroups(Dictionary<string, object> request) | ||
765 | { | ||
766 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
767 | |||
768 | if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query")) | ||
769 | NullResult(result, "Bad network data"); | ||
770 | |||
771 | List<DirGroupsReplyData> hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString()); | ||
772 | |||
773 | if (hits == null || (hits != null && hits.Count == 0)) | ||
774 | NullResult(result, "No hits"); | ||
775 | else | ||
776 | { | ||
777 | Dictionary<string, object> dict = new Dictionary<string, object>(); | ||
778 | int i = 0; | ||
779 | foreach (DirGroupsReplyData n in hits) | ||
780 | dict["n-" + i++] = GroupsDataUtils.DirGroupsReplyData(n); | ||
781 | |||
782 | result["RESULT"] = dict; | ||
783 | } | ||
784 | |||
785 | |||
786 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
787 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
788 | } | ||
789 | |||
790 | |||
791 | #region Helpers | ||
792 | |||
793 | private void NullResult(Dictionary<string, object> result, string reason) | ||
794 | { | ||
795 | result["RESULT"] = "NULL"; | ||
796 | result["REASON"] = reason; | ||
797 | } | ||
798 | |||
799 | private byte[] FailureResult() | ||
800 | { | ||
801 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
802 | NullResult(result, "Unknown method"); | ||
803 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
804 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
805 | } | ||
806 | |||
807 | private byte[] FailureResult(string reason) | ||
808 | { | ||
809 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
810 | NullResult(result, reason); | ||
811 | string xmlString = ServerUtils.BuildXmlResponse(result); | ||
812 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
813 | } | ||
814 | #endregion | ||
815 | } | ||
816 | } | ||
diff --git a/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs new file mode 100644 index 0000000..813f796 --- /dev/null +++ b/OpenSim/Addons/Groups/RemoteConnectorCacheWrapper.cs | |||
@@ -0,0 +1,888 @@ | |||
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.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | |||
33 | using OpenSim.Framework; | ||
34 | //using OpenSim.Region.Framework.Interfaces; | ||
35 | using OpenSim.Services.Interfaces; | ||
36 | |||
37 | using OpenMetaverse; | ||
38 | |||
39 | namespace OpenSim.Groups | ||
40 | { | ||
41 | public delegate ExtendedGroupRecord GroupRecordDelegate(); | ||
42 | public delegate GroupMembershipData GroupMembershipDelegate(); | ||
43 | public delegate List<GroupMembershipData> GroupMembershipListDelegate(); | ||
44 | public delegate List<ExtendedGroupMembersData> GroupMembersListDelegate(); | ||
45 | public delegate List<GroupRolesData> GroupRolesListDelegate(); | ||
46 | public delegate List<ExtendedGroupRoleMembersData> RoleMembersListDelegate(); | ||
47 | public delegate GroupNoticeInfo NoticeDelegate(); | ||
48 | public delegate List<ExtendedGroupNoticeData> NoticeListDelegate(); | ||
49 | public delegate void VoidDelegate(); | ||
50 | public delegate bool BooleanDelegate(); | ||
51 | |||
52 | public class RemoteConnectorCacheWrapper | ||
53 | { | ||
54 | private ForeignImporter m_ForeignImporter; | ||
55 | |||
56 | private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>(); | ||
57 | private const int GROUPS_CACHE_TIMEOUT = 1 * 60; // 1 minutes | ||
58 | |||
59 | // This all important cache cahces objects of different types: | ||
60 | // group-<GroupID> or group-<Name> => ExtendedGroupRecord | ||
61 | // active-<AgentID> => GroupMembershipData | ||
62 | // membership-<AgentID>-<GroupID> => GroupMembershipData | ||
63 | // memberships-<AgentID> => List<GroupMembershipData> | ||
64 | // members-<RequestingAgentID>-<GroupID> => List<ExtendedGroupMembersData> | ||
65 | // role-<RoleID> => GroupRolesData | ||
66 | // roles-<GroupID> => List<GroupRolesData> ; all roles in the group | ||
67 | // roles-<GroupID>-<AgentID> => List<GroupRolesData> ; roles that the agent has | ||
68 | // rolemembers-<RequestingAgentID>-<GroupID> => List<ExtendedGroupRoleMembersData> | ||
69 | // notice-<noticeID> => GroupNoticeInfo | ||
70 | // notices-<GroupID> => List<ExtendedGroupNoticeData> | ||
71 | private ExpiringCache<string, object> m_Cache = new ExpiringCache<string, object>(); | ||
72 | |||
73 | public RemoteConnectorCacheWrapper(IUserManagement uman) | ||
74 | { | ||
75 | m_ForeignImporter = new ForeignImporter(uman); | ||
76 | } | ||
77 | |||
78 | public UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d) | ||
79 | { | ||
80 | //m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name); | ||
81 | //reason = string.Empty; | ||
82 | |||
83 | //ExtendedGroupRecord group = m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID, | ||
84 | // membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason); | ||
85 | ExtendedGroupRecord group = d(); | ||
86 | |||
87 | if (group == null) | ||
88 | return UUID.Zero; | ||
89 | |||
90 | if (group.GroupID != UUID.Zero) | ||
91 | lock (m_Cache) | ||
92 | { | ||
93 | m_Cache.Add("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT); | ||
94 | if (m_Cache.Contains("memberships-" + RequestingAgentID.ToString())) | ||
95 | m_Cache.Remove("memberships-" + RequestingAgentID.ToString()); | ||
96 | } | ||
97 | |||
98 | return group.GroupID; | ||
99 | } | ||
100 | |||
101 | public bool UpdateGroup(UUID groupID, GroupRecordDelegate d) | ||
102 | { | ||
103 | //reason = string.Empty; | ||
104 | //ExtendedGroupRecord group = m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); | ||
105 | ExtendedGroupRecord group = d(); | ||
106 | |||
107 | if (group != null && group.GroupID != UUID.Zero) | ||
108 | lock (m_Cache) | ||
109 | m_Cache.AddOrUpdate("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT); | ||
110 | return true; | ||
111 | } | ||
112 | |||
113 | public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, GroupRecordDelegate d) | ||
114 | { | ||
115 | //if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty)) | ||
116 | // return null; | ||
117 | |||
118 | object group = null; | ||
119 | bool firstCall = false; | ||
120 | string cacheKey = "group-"; | ||
121 | if (GroupID != UUID.Zero) | ||
122 | cacheKey += GroupID.ToString(); | ||
123 | else | ||
124 | cacheKey += GroupName; | ||
125 | |||
126 | //m_log.DebugFormat("[XXX]: GetGroupRecord {0}", cacheKey); | ||
127 | |||
128 | while (true) | ||
129 | { | ||
130 | lock (m_Cache) | ||
131 | { | ||
132 | if (m_Cache.TryGetValue(cacheKey, out group)) | ||
133 | { | ||
134 | //m_log.DebugFormat("[XXX]: GetGroupRecord {0} cached!", cacheKey); | ||
135 | return (ExtendedGroupRecord)group; | ||
136 | } | ||
137 | |||
138 | // not cached | ||
139 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
140 | { | ||
141 | m_ActiveRequests.Add(cacheKey, true); | ||
142 | firstCall = true; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | if (firstCall) | ||
147 | { | ||
148 | try | ||
149 | { | ||
150 | //group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName); | ||
151 | group = d(); | ||
152 | |||
153 | lock (m_Cache) | ||
154 | { | ||
155 | m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT); | ||
156 | return (ExtendedGroupRecord)group; | ||
157 | } | ||
158 | } | ||
159 | finally | ||
160 | { | ||
161 | m_ActiveRequests.Remove(cacheKey); | ||
162 | } | ||
163 | } | ||
164 | else | ||
165 | Thread.Sleep(50); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, GroupMembershipDelegate d) | ||
170 | { | ||
171 | GroupMembershipData membership = d(); | ||
172 | if (membership == null) | ||
173 | return false; | ||
174 | |||
175 | lock (m_Cache) | ||
176 | { | ||
177 | // first, remove everything! add a user is a heavy-duty op | ||
178 | m_Cache.Clear(); | ||
179 | |||
180 | m_Cache.AddOrUpdate("active-" + AgentID.ToString(), membership, GROUPS_CACHE_TIMEOUT); | ||
181 | m_Cache.AddOrUpdate("membership-" + AgentID.ToString() + "-" + GroupID.ToString(), membership, GROUPS_CACHE_TIMEOUT); | ||
182 | } | ||
183 | |||
184 | |||
185 | return true; | ||
186 | } | ||
187 | |||
188 | public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, VoidDelegate d) | ||
189 | { | ||
190 | d(); | ||
191 | |||
192 | lock (m_Cache) | ||
193 | { | ||
194 | string cacheKey = "active-" + AgentID.ToString(); | ||
195 | if (m_Cache.Contains(cacheKey)) | ||
196 | m_Cache.Remove(cacheKey); | ||
197 | |||
198 | cacheKey = "memberships-" + AgentID.ToString(); | ||
199 | if (m_Cache.Contains(cacheKey)) | ||
200 | m_Cache.Remove(cacheKey); | ||
201 | |||
202 | cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString(); | ||
203 | if (m_Cache.Contains(cacheKey)) | ||
204 | m_Cache.Remove(cacheKey); | ||
205 | |||
206 | cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString(); | ||
207 | if (m_Cache.Contains(cacheKey)) | ||
208 | m_Cache.Remove(cacheKey); | ||
209 | |||
210 | cacheKey = "roles-" + "-" + GroupID.ToString() + "-" + AgentID.ToString(); | ||
211 | if (m_Cache.Contains(cacheKey)) | ||
212 | m_Cache.Remove(cacheKey); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d) | ||
217 | { | ||
218 | GroupMembershipData activeGroup = d(); | ||
219 | string cacheKey = "active-" + AgentID.ToString(); | ||
220 | lock (m_Cache) | ||
221 | if (m_Cache.Contains(cacheKey)) | ||
222 | m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT); | ||
223 | } | ||
224 | |||
225 | public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d) | ||
226 | { | ||
227 | object membership = null; | ||
228 | bool firstCall = false; | ||
229 | string cacheKey = "active-" + AgentID.ToString(); | ||
230 | |||
231 | //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0}", cacheKey); | ||
232 | |||
233 | while (true) | ||
234 | { | ||
235 | lock (m_Cache) | ||
236 | { | ||
237 | if (m_Cache.TryGetValue(cacheKey, out membership)) | ||
238 | { | ||
239 | //m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0} cached!", cacheKey); | ||
240 | return (ExtendedGroupMembershipData)membership; | ||
241 | } | ||
242 | |||
243 | // not cached | ||
244 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
245 | { | ||
246 | m_ActiveRequests.Add(cacheKey, true); | ||
247 | firstCall = true; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | if (firstCall) | ||
252 | { | ||
253 | try | ||
254 | { | ||
255 | membership = d(); | ||
256 | |||
257 | lock (m_Cache) | ||
258 | { | ||
259 | m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT); | ||
260 | return (ExtendedGroupMembershipData)membership; | ||
261 | } | ||
262 | } | ||
263 | finally | ||
264 | { | ||
265 | m_ActiveRequests.Remove(cacheKey); | ||
266 | } | ||
267 | } | ||
268 | else | ||
269 | Thread.Sleep(50); | ||
270 | } | ||
271 | |||
272 | } | ||
273 | |||
274 | public ExtendedGroupMembershipData GetAgentGroupMembership(string AgentID, UUID GroupID, GroupMembershipDelegate d) | ||
275 | { | ||
276 | object membership = null; | ||
277 | bool firstCall = false; | ||
278 | string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString(); | ||
279 | |||
280 | //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey); | ||
281 | |||
282 | while (true) | ||
283 | { | ||
284 | lock (m_Cache) | ||
285 | { | ||
286 | if (m_Cache.TryGetValue(cacheKey, out membership)) | ||
287 | { | ||
288 | //m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey); | ||
289 | return (ExtendedGroupMembershipData)membership; | ||
290 | } | ||
291 | |||
292 | // not cached | ||
293 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
294 | { | ||
295 | m_ActiveRequests.Add(cacheKey, true); | ||
296 | firstCall = true; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | if (firstCall) | ||
301 | { | ||
302 | try | ||
303 | { | ||
304 | membership = d(); | ||
305 | lock (m_Cache) | ||
306 | { | ||
307 | m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT); | ||
308 | return (ExtendedGroupMembershipData)membership; | ||
309 | } | ||
310 | } | ||
311 | finally | ||
312 | { | ||
313 | m_ActiveRequests.Remove(cacheKey); | ||
314 | } | ||
315 | } | ||
316 | else | ||
317 | Thread.Sleep(50); | ||
318 | } | ||
319 | } | ||
320 | |||
321 | public List<GroupMembershipData> GetAgentGroupMemberships(string AgentID, GroupMembershipListDelegate d) | ||
322 | { | ||
323 | object memberships = null; | ||
324 | bool firstCall = false; | ||
325 | string cacheKey = "memberships-" + AgentID.ToString(); | ||
326 | |||
327 | //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0}", cacheKey); | ||
328 | |||
329 | while (true) | ||
330 | { | ||
331 | lock (m_Cache) | ||
332 | { | ||
333 | if (m_Cache.TryGetValue(cacheKey, out memberships)) | ||
334 | { | ||
335 | //m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0} cached!", cacheKey); | ||
336 | return (List<GroupMembershipData>)memberships; | ||
337 | } | ||
338 | |||
339 | // not cached | ||
340 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
341 | { | ||
342 | m_ActiveRequests.Add(cacheKey, true); | ||
343 | firstCall = true; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | if (firstCall) | ||
348 | { | ||
349 | try | ||
350 | { | ||
351 | memberships = d(); | ||
352 | lock (m_Cache) | ||
353 | { | ||
354 | m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT); | ||
355 | return (List<GroupMembershipData>)memberships; | ||
356 | } | ||
357 | } | ||
358 | finally | ||
359 | { | ||
360 | m_ActiveRequests.Remove(cacheKey); | ||
361 | } | ||
362 | } | ||
363 | else | ||
364 | Thread.Sleep(50); | ||
365 | } | ||
366 | } | ||
367 | |||
368 | public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, GroupMembersListDelegate d) | ||
369 | { | ||
370 | object members = null; | ||
371 | bool firstCall = false; | ||
372 | // we need to key in also on the requester, because different ppl have different view privileges | ||
373 | string cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString(); | ||
374 | |||
375 | //m_log.DebugFormat("[XXX]: GetGroupMembers {0}", cacheKey); | ||
376 | |||
377 | while (true) | ||
378 | { | ||
379 | lock (m_Cache) | ||
380 | { | ||
381 | if (m_Cache.TryGetValue(cacheKey, out members)) | ||
382 | { | ||
383 | List<ExtendedGroupMembersData> xx = (List<ExtendedGroupMembersData>)members; | ||
384 | return xx.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData)); | ||
385 | } | ||
386 | |||
387 | // not cached | ||
388 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
389 | { | ||
390 | m_ActiveRequests.Add(cacheKey, true); | ||
391 | firstCall = true; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | if (firstCall) | ||
396 | { | ||
397 | try | ||
398 | { | ||
399 | List<ExtendedGroupMembersData> _members = d(); | ||
400 | |||
401 | if (_members != null && _members.Count > 0) | ||
402 | members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData)); | ||
403 | else | ||
404 | members = new List<GroupMembersData>(); | ||
405 | |||
406 | lock (m_Cache) | ||
407 | { | ||
408 | //m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT); | ||
409 | m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT); | ||
410 | |||
411 | return (List<GroupMembersData>)members; | ||
412 | } | ||
413 | } | ||
414 | finally | ||
415 | { | ||
416 | m_ActiveRequests.Remove(cacheKey); | ||
417 | } | ||
418 | } | ||
419 | else | ||
420 | Thread.Sleep(50); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | public bool AddGroupRole(UUID groupID, UUID roleID, string description, string name, ulong powers, string title, BooleanDelegate d) | ||
425 | { | ||
426 | if (d()) | ||
427 | { | ||
428 | GroupRolesData role = new GroupRolesData(); | ||
429 | role.Description = description; | ||
430 | role.Members = 0; | ||
431 | role.Name = name; | ||
432 | role.Powers = powers; | ||
433 | role.RoleID = roleID; | ||
434 | role.Title = title; | ||
435 | |||
436 | lock (m_Cache) | ||
437 | { | ||
438 | m_Cache.AddOrUpdate("role-" + roleID.ToString(), role, GROUPS_CACHE_TIMEOUT); | ||
439 | |||
440 | // also remove this list | ||
441 | if (m_Cache.Contains("roles-" + groupID.ToString())) | ||
442 | m_Cache.Remove("roles-" + groupID.ToString()); | ||
443 | |||
444 | } | ||
445 | |||
446 | return true; | ||
447 | } | ||
448 | |||
449 | return false; | ||
450 | } | ||
451 | |||
452 | public bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d) | ||
453 | { | ||
454 | if (d()) | ||
455 | { | ||
456 | object role; | ||
457 | lock (m_Cache) | ||
458 | if (m_Cache.TryGetValue("role-" + roleID.ToString(), out role)) | ||
459 | { | ||
460 | GroupRolesData r = (GroupRolesData)role; | ||
461 | r.Description = description; | ||
462 | r.Name = name; | ||
463 | r.Powers = powers; | ||
464 | r.Title = title; | ||
465 | |||
466 | m_Cache.Update("role-" + roleID.ToString(), r, GROUPS_CACHE_TIMEOUT); | ||
467 | } | ||
468 | return true; | ||
469 | } | ||
470 | else | ||
471 | { | ||
472 | lock (m_Cache) | ||
473 | { | ||
474 | if (m_Cache.Contains("role-" + roleID.ToString())) | ||
475 | m_Cache.Remove("role-" + roleID.ToString()); | ||
476 | |||
477 | // also remove these lists, because they will have an outdated role | ||
478 | if (m_Cache.Contains("roles-" + groupID.ToString())) | ||
479 | m_Cache.Remove("roles-" + groupID.ToString()); | ||
480 | |||
481 | } | ||
482 | |||
483 | return false; | ||
484 | } | ||
485 | } | ||
486 | |||
487 | public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d) | ||
488 | { | ||
489 | d(); | ||
490 | |||
491 | lock (m_Cache) | ||
492 | { | ||
493 | if (m_Cache.Contains("role-" + roleID.ToString())) | ||
494 | m_Cache.Remove("role-" + roleID.ToString()); | ||
495 | |||
496 | // also remove the list, because it will have an removed role | ||
497 | if (m_Cache.Contains("roles-" + groupID.ToString())) | ||
498 | m_Cache.Remove("roles-" + groupID.ToString()); | ||
499 | |||
500 | if (m_Cache.Contains("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString())) | ||
501 | m_Cache.Remove("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString()); | ||
502 | |||
503 | if (m_Cache.Contains("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString())) | ||
504 | m_Cache.Remove("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString()); | ||
505 | } | ||
506 | } | ||
507 | |||
508 | public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d) | ||
509 | { | ||
510 | object roles = null; | ||
511 | bool firstCall = false; | ||
512 | string cacheKey = "roles-" + GroupID.ToString(); | ||
513 | |||
514 | while (true) | ||
515 | { | ||
516 | lock (m_Cache) | ||
517 | { | ||
518 | if (m_Cache.TryGetValue(cacheKey, out roles)) | ||
519 | return (List<GroupRolesData>)roles; | ||
520 | |||
521 | // not cached | ||
522 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
523 | { | ||
524 | m_ActiveRequests.Add(cacheKey, true); | ||
525 | firstCall = true; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | if (firstCall) | ||
530 | { | ||
531 | try | ||
532 | { | ||
533 | roles = d(); | ||
534 | if (roles != null) | ||
535 | { | ||
536 | lock (m_Cache) | ||
537 | { | ||
538 | m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT); | ||
539 | return (List<GroupRolesData>)roles; | ||
540 | } | ||
541 | } | ||
542 | } | ||
543 | finally | ||
544 | { | ||
545 | m_ActiveRequests.Remove(cacheKey); | ||
546 | } | ||
547 | } | ||
548 | else | ||
549 | Thread.Sleep(50); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d) | ||
554 | { | ||
555 | object rmembers = null; | ||
556 | bool firstCall = false; | ||
557 | // we need to key in also on the requester, because different ppl have different view privileges | ||
558 | string cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString(); | ||
559 | |||
560 | //m_log.DebugFormat("[XXX]: GetGroupRoleMembers {0}", cacheKey); | ||
561 | while (true) | ||
562 | { | ||
563 | lock (m_Cache) | ||
564 | { | ||
565 | if (m_Cache.TryGetValue(cacheKey, out rmembers)) | ||
566 | { | ||
567 | List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)rmembers; | ||
568 | return xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData); | ||
569 | } | ||
570 | |||
571 | // not cached | ||
572 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
573 | { | ||
574 | m_ActiveRequests.Add(cacheKey, true); | ||
575 | firstCall = true; | ||
576 | } | ||
577 | } | ||
578 | |||
579 | if (firstCall) | ||
580 | { | ||
581 | try | ||
582 | { | ||
583 | List<ExtendedGroupRoleMembersData> _rmembers = d(); | ||
584 | |||
585 | if (_rmembers != null && _rmembers.Count > 0) | ||
586 | rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData)); | ||
587 | else | ||
588 | rmembers = new List<GroupRoleMembersData>(); | ||
589 | |||
590 | lock (m_Cache) | ||
591 | { | ||
592 | // For some strange reason, when I cache the list of GroupRoleMembersData, | ||
593 | // it gets emptied out. The TryGet gets an empty list... | ||
594 | //m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT); | ||
595 | // Caching the list of ExtendedGroupRoleMembersData doesn't show that issue | ||
596 | // I don't get it. | ||
597 | m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT); | ||
598 | return (List<GroupRoleMembersData>)rmembers; | ||
599 | } | ||
600 | } | ||
601 | finally | ||
602 | { | ||
603 | m_ActiveRequests.Remove(cacheKey); | ||
604 | } | ||
605 | } | ||
606 | else | ||
607 | Thread.Sleep(50); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d) | ||
612 | { | ||
613 | if (d()) | ||
614 | { | ||
615 | lock (m_Cache) | ||
616 | { | ||
617 | // update the cached role | ||
618 | string cacheKey = "role-" + RoleID.ToString(); | ||
619 | object obj; | ||
620 | if (m_Cache.TryGetValue(cacheKey, out obj)) | ||
621 | { | ||
622 | GroupRolesData r = (GroupRolesData)obj; | ||
623 | r.Members++; | ||
624 | } | ||
625 | |||
626 | // add this agent to the list of role members | ||
627 | cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString(); | ||
628 | if (m_Cache.TryGetValue(cacheKey, out obj)) | ||
629 | { | ||
630 | try | ||
631 | { | ||
632 | // This may throw an exception, in which case the agentID is not a UUID but a full ID | ||
633 | // In that case, let's just remove the whoe things from the cache | ||
634 | UUID id = new UUID(AgentID); | ||
635 | List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)obj; | ||
636 | List<GroupRoleMembersData> rmlist = xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData); | ||
637 | GroupRoleMembersData rm = new GroupRoleMembersData(); | ||
638 | rm.MemberID = id; | ||
639 | rm.RoleID = RoleID; | ||
640 | rmlist.Add(rm); | ||
641 | } | ||
642 | catch | ||
643 | { | ||
644 | m_Cache.Remove(cacheKey); | ||
645 | } | ||
646 | } | ||
647 | |||
648 | // Remove the cached info about this agent's roles | ||
649 | // because we don't have enough local info about the new role | ||
650 | cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString(); | ||
651 | if (m_Cache.Contains(cacheKey)) | ||
652 | m_Cache.Remove(cacheKey); | ||
653 | |||
654 | } | ||
655 | } | ||
656 | } | ||
657 | |||
658 | public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d) | ||
659 | { | ||
660 | if (d()) | ||
661 | { | ||
662 | lock (m_Cache) | ||
663 | { | ||
664 | // update the cached role | ||
665 | string cacheKey = "role-" + RoleID.ToString(); | ||
666 | object obj; | ||
667 | if (m_Cache.TryGetValue(cacheKey, out obj)) | ||
668 | { | ||
669 | GroupRolesData r = (GroupRolesData)obj; | ||
670 | r.Members--; | ||
671 | } | ||
672 | |||
673 | cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString(); | ||
674 | if (m_Cache.Contains(cacheKey)) | ||
675 | m_Cache.Remove(cacheKey); | ||
676 | |||
677 | cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString(); | ||
678 | if (m_Cache.Contains(cacheKey)) | ||
679 | m_Cache.Remove(cacheKey); | ||
680 | } | ||
681 | } | ||
682 | } | ||
683 | |||
684 | public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d) | ||
685 | { | ||
686 | object roles = null; | ||
687 | bool firstCall = false; | ||
688 | string cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString(); | ||
689 | |||
690 | //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey); | ||
691 | |||
692 | while (true) | ||
693 | { | ||
694 | lock (m_Cache) | ||
695 | { | ||
696 | if (m_Cache.TryGetValue(cacheKey, out roles)) | ||
697 | { | ||
698 | //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0} cached!", cacheKey); | ||
699 | return (List<GroupRolesData>)roles; | ||
700 | } | ||
701 | |||
702 | // not cached | ||
703 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
704 | { | ||
705 | m_ActiveRequests.Add(cacheKey, true); | ||
706 | firstCall = true; | ||
707 | } | ||
708 | } | ||
709 | |||
710 | if (firstCall) | ||
711 | { | ||
712 | try | ||
713 | { | ||
714 | roles = d(); | ||
715 | lock (m_Cache) | ||
716 | { | ||
717 | m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT); | ||
718 | m_ActiveRequests.Remove(cacheKey); | ||
719 | return (List<GroupRolesData>)roles; | ||
720 | } | ||
721 | } | ||
722 | finally | ||
723 | { | ||
724 | m_ActiveRequests.Remove(cacheKey); | ||
725 | } | ||
726 | } | ||
727 | else | ||
728 | Thread.Sleep(50); | ||
729 | } | ||
730 | } | ||
731 | |||
732 | public void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d) | ||
733 | { | ||
734 | d(); | ||
735 | |||
736 | lock (m_Cache) | ||
737 | { | ||
738 | // Invalidate cached info, because it has ActiveRoleID and Powers | ||
739 | string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString(); | ||
740 | if (m_Cache.Contains(cacheKey)) | ||
741 | m_Cache.Remove(cacheKey); | ||
742 | |||
743 | cacheKey = "memberships-" + AgentID.ToString(); | ||
744 | if (m_Cache.Contains(cacheKey)) | ||
745 | m_Cache.Remove(cacheKey); | ||
746 | } | ||
747 | } | ||
748 | |||
749 | public void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d) | ||
750 | { | ||
751 | d(); | ||
752 | |||
753 | lock (m_Cache) | ||
754 | { | ||
755 | string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString(); | ||
756 | if (m_Cache.Contains(cacheKey)) | ||
757 | m_Cache.Remove(cacheKey); | ||
758 | |||
759 | cacheKey = "memberships-" + AgentID.ToString(); | ||
760 | if (m_Cache.Contains(cacheKey)) | ||
761 | m_Cache.Remove(cacheKey); | ||
762 | |||
763 | cacheKey = "active-" + AgentID.ToString(); | ||
764 | object m = null; | ||
765 | if (m_Cache.TryGetValue(cacheKey, out m)) | ||
766 | { | ||
767 | GroupMembershipData membership = (GroupMembershipData)m; | ||
768 | membership.ListInProfile = ListInProfile; | ||
769 | membership.AcceptNotices = AcceptNotices; | ||
770 | } | ||
771 | } | ||
772 | } | ||
773 | |||
774 | public bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d) | ||
775 | { | ||
776 | if (d()) | ||
777 | { | ||
778 | lock (m_Cache) | ||
779 | { | ||
780 | m_Cache.AddOrUpdate("notice-" + noticeID.ToString(), notice, GROUPS_CACHE_TIMEOUT); | ||
781 | string cacheKey = "notices-" + groupID.ToString(); | ||
782 | if (m_Cache.Contains(cacheKey)) | ||
783 | m_Cache.Remove(cacheKey); | ||
784 | |||
785 | } | ||
786 | |||
787 | return true; | ||
788 | } | ||
789 | |||
790 | return false; | ||
791 | } | ||
792 | |||
793 | public GroupNoticeInfo GetGroupNotice(UUID noticeID, NoticeDelegate d) | ||
794 | { | ||
795 | object notice = null; | ||
796 | bool firstCall = false; | ||
797 | string cacheKey = "notice-" + noticeID.ToString(); | ||
798 | |||
799 | //m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey); | ||
800 | |||
801 | while (true) | ||
802 | { | ||
803 | lock (m_Cache) | ||
804 | { | ||
805 | if (m_Cache.TryGetValue(cacheKey, out notice)) | ||
806 | { | ||
807 | return (GroupNoticeInfo)notice; | ||
808 | } | ||
809 | |||
810 | // not cached | ||
811 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
812 | { | ||
813 | m_ActiveRequests.Add(cacheKey, true); | ||
814 | firstCall = true; | ||
815 | } | ||
816 | } | ||
817 | |||
818 | if (firstCall) | ||
819 | { | ||
820 | try | ||
821 | { | ||
822 | GroupNoticeInfo _notice = d(); | ||
823 | |||
824 | lock (m_Cache) | ||
825 | { | ||
826 | m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT); | ||
827 | return _notice; | ||
828 | } | ||
829 | } | ||
830 | finally | ||
831 | { | ||
832 | m_ActiveRequests.Remove(cacheKey); | ||
833 | } | ||
834 | } | ||
835 | else | ||
836 | Thread.Sleep(50); | ||
837 | } | ||
838 | } | ||
839 | |||
840 | public List<ExtendedGroupNoticeData> GetGroupNotices(UUID GroupID, NoticeListDelegate d) | ||
841 | { | ||
842 | object notices = null; | ||
843 | bool firstCall = false; | ||
844 | string cacheKey = "notices-" + GroupID.ToString(); | ||
845 | |||
846 | //m_log.DebugFormat("[XXX]: GetGroupNotices {0}", cacheKey); | ||
847 | |||
848 | while (true) | ||
849 | { | ||
850 | lock (m_Cache) | ||
851 | { | ||
852 | if (m_Cache.TryGetValue(cacheKey, out notices)) | ||
853 | { | ||
854 | //m_log.DebugFormat("[XXX]: GetGroupNotices {0} cached!", cacheKey); | ||
855 | return (List<ExtendedGroupNoticeData>)notices; | ||
856 | } | ||
857 | |||
858 | // not cached | ||
859 | if (!m_ActiveRequests.ContainsKey(cacheKey)) | ||
860 | { | ||
861 | m_ActiveRequests.Add(cacheKey, true); | ||
862 | firstCall = true; | ||
863 | } | ||
864 | } | ||
865 | |||
866 | if (firstCall) | ||
867 | { | ||
868 | try | ||
869 | { | ||
870 | notices = d(); | ||
871 | |||
872 | lock (m_Cache) | ||
873 | { | ||
874 | m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT); | ||
875 | return (List<ExtendedGroupNoticeData>)notices; | ||
876 | } | ||
877 | } | ||
878 | finally | ||
879 | { | ||
880 | m_ActiveRequests.Remove(cacheKey); | ||
881 | } | ||
882 | } | ||
883 | else | ||
884 | Thread.Sleep(50); | ||
885 | } | ||
886 | } | ||
887 | } | ||
888 | } \ No newline at end of file | ||