aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
diff options
context:
space:
mode:
authorUbitUmarov2015-09-01 11:43:07 +0100
committerUbitUmarov2015-09-01 11:43:07 +0100
commitfb78b182520fc9bb0f971afd0322029c70278ea6 (patch)
treeb4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
parentlixo (diff)
parentMantis #7713: fixed bug introduced by 1st MOSES patch. (diff)
downloadopensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.zip
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs1441
1 files changed, 1441 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
new file mode 100644
index 0000000..8095b28
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
@@ -0,0 +1,1441 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Collections.Specialized;
32using System.Reflection;
33using System.Threading;
34
35using Nwc.XmlRpc;
36
37using log4net;
38using Mono.Addins;
39using Nini.Config;
40
41using OpenMetaverse;
42using OpenMetaverse.StructuredData;
43
44using OpenSim.Framework;
45using OpenSim.Framework.Communications;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Services.Interfaces;
48
49/***************************************************************************
50 * Simian Data Map
51 * ===============
52 *
53 * OwnerID -> Type -> Key
54 * -----------------------
55 *
56 * UserID -> Group -> ActiveGroup
57 * + GroupID
58 *
59 * UserID -> GroupSessionDropped -> GroupID
60 * UserID -> GroupSessionInvited -> GroupID
61 *
62 * UserID -> GroupMember -> GroupID
63 * + SelectedRoleID [UUID]
64 * + AcceptNotices [bool]
65 * + ListInProfile [bool]
66 * + Contribution [int]
67 *
68 * UserID -> GroupRole[GroupID] -> RoleID
69 *
70 *
71 * GroupID -> Group -> GroupName
72 * + Charter
73 * + ShowInList
74 * + InsigniaID
75 * + MembershipFee
76 * + OpenEnrollment
77 * + AllowPublish
78 * + MaturePublish
79 * + FounderID
80 * + EveryonePowers
81 * + OwnerRoleID
82 * + OwnersPowers
83 *
84 * GroupID -> GroupRole -> RoleID
85 * + Name
86 * + Description
87 * + Title
88 * + Powers
89 *
90 * GroupID -> GroupMemberInvite -> InviteID
91 * + AgentID
92 * + RoleID
93 *
94 * GroupID -> GroupNotice -> NoticeID
95 * + TimeStamp [uint]
96 * + FromName [string]
97 * + Subject [string]
98 * + Message [string]
99 * + BinaryBucket [byte[]]
100 *
101 * */
102
103namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
104{
105 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianGroupsServicesConnectorModule")]
106 public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector
107 {
108 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
109
110 public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome |
111 GroupPowers.Accountable |
112 GroupPowers.JoinChat |
113 GroupPowers.AllowVoiceChat |
114 GroupPowers.ReceiveNotices |
115 GroupPowers.StartProposal |
116 GroupPowers.VoteOnProposal;
117
118 // Would this be cleaner as (GroupPowers)ulong.MaxValue;
119 public const GroupPowers m_DefaultOwnerPowers = GroupPowers.Accountable
120 | GroupPowers.AllowEditLand
121 | GroupPowers.AllowFly
122 | GroupPowers.AllowLandmark
123 | GroupPowers.AllowRez
124 | GroupPowers.AllowSetHome
125 | GroupPowers.AllowVoiceChat
126 | GroupPowers.AssignMember
127 | GroupPowers.AssignMemberLimited
128 | GroupPowers.ChangeActions
129 | GroupPowers.ChangeIdentity
130 | GroupPowers.ChangeMedia
131 | GroupPowers.ChangeOptions
132 | GroupPowers.CreateRole
133 | GroupPowers.DeedObject
134 | GroupPowers.DeleteRole
135 | GroupPowers.Eject
136 | GroupPowers.FindPlaces
137 | GroupPowers.Invite
138 | GroupPowers.JoinChat
139 | GroupPowers.LandChangeIdentity
140 | GroupPowers.LandDeed
141 | GroupPowers.LandDivideJoin
142 | GroupPowers.LandEdit
143 | GroupPowers.LandEjectAndFreeze
144 | GroupPowers.LandGardening
145 | GroupPowers.LandManageAllowed
146 | GroupPowers.LandManageBanned
147 | GroupPowers.LandManagePasses
148 | GroupPowers.LandOptions
149 | GroupPowers.LandRelease
150 | GroupPowers.LandSetSale
151 | GroupPowers.ModerateChat
152 | GroupPowers.ObjectManipulate
153 | GroupPowers.ObjectSetForSale
154 | GroupPowers.ReceiveNotices
155 | GroupPowers.RemoveMember
156 | GroupPowers.ReturnGroupOwned
157 | GroupPowers.ReturnGroupSet
158 | GroupPowers.ReturnNonGroup
159 | GroupPowers.RoleProperties
160 | GroupPowers.SendNotices
161 | GroupPowers.SetLandingPoint
162 | GroupPowers.StartProposal
163 | GroupPowers.VoteOnProposal;
164
165 private bool m_connectorEnabled = false;
166
167 private string m_groupsServerURI = string.Empty;
168
169 private bool m_debugEnabled = false;
170
171 private Dictionary<string, bool> m_pendingRequests = new Dictionary<string,bool>();
172
173 private ExpiringCache<string, OSDMap> m_memoryCache;
174 private int m_cacheTimeout = 30;
175
176 // private IUserAccountService m_accountService = null;
177
178
179 #region Region Module interfaceBase Members
180
181 public string Name
182 {
183 get { return "SimianGroupsServicesConnector"; }
184 }
185
186 // this module is not intended to be replaced, but there should only be 1 of them.
187 public Type ReplaceableInterface
188 {
189 get { return null; }
190 }
191
192 public void Initialise(IConfigSource config)
193 {
194 IConfig groupsConfig = config.Configs["Groups"];
195
196 if (groupsConfig == null)
197 {
198 // Do not run this module by default.
199 return;
200 }
201 else
202 {
203 // if groups aren't enabled, we're not needed.
204 // if we're not specified as the connector to use, then we're not wanted
205 if ((groupsConfig.GetBoolean("Enabled", false) == false)
206 || (groupsConfig.GetString("ServicesConnectorModule", "XmlRpcGroupsServicesConnector") != Name))
207 {
208 m_connectorEnabled = false;
209 return;
210 }
211
212 m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name);
213
214 m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty);
215 if (string.IsNullOrEmpty(m_groupsServerURI))
216 {
217 m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]");
218 m_connectorEnabled = false;
219 return;
220 }
221
222
223 m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30);
224 if (m_cacheTimeout == 0)
225 {
226 m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Disabled.");
227 }
228 else
229 {
230 m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Timeout set to {0}.", m_cacheTimeout);
231 }
232
233
234
235 m_memoryCache = new ExpiringCache<string,OSDMap>();
236
237
238 // If we got all the config options we need, lets start'er'up
239 m_connectorEnabled = true;
240
241 m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
242
243 }
244 }
245
246 public void Close()
247 {
248 m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Closing {0}", this.Name);
249 }
250
251 public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene)
252 {
253 if (m_connectorEnabled)
254 {
255 scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
256 }
257 }
258
259 public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene)
260 {
261 if (scene.RequestModuleInterface<IGroupsServicesConnector>() == this)
262 {
263 scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
264 }
265 }
266
267 public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene)
268 {
269 // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info
270 // scene.EventManager.OnNewClient += OnNewClient;
271 }
272
273 #endregion
274
275 #region ISharedRegionModule Members
276
277 public void PostInitialise()
278 {
279 // NoOp
280 }
281
282 #endregion
283
284
285
286
287 #region IGroupsServicesConnector Members
288
289 /// <summary>
290 /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role.
291 /// </summary>
292 public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID,
293 int membershipFee, bool openEnrollment, bool allowPublish,
294 bool maturePublish, UUID founderID)
295 {
296 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
297
298 UUID GroupID = UUID.Random();
299 UUID OwnerRoleID = UUID.Random();
300
301 OSDMap GroupInfoMap = new OSDMap();
302 GroupInfoMap["Charter"] = OSD.FromString(charter);
303 GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList);
304 GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID);
305 GroupInfoMap["MembershipFee"] = OSD.FromInteger(0);
306 GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment);
307 GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish);
308 GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish);
309 GroupInfoMap["FounderID"] = OSD.FromUUID(founderID);
310 GroupInfoMap["EveryonePowers"] = OSD.FromULong((ulong)m_DefaultEveryonePowers);
311 GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID);
312 GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers);
313
314 if (SimianAddGeneric(GroupID, "Group", name, GroupInfoMap))
315 {
316 AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers);
317 AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers);
318
319 AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID);
320
321 return GroupID;
322 }
323 else
324 {
325 return UUID.Zero;
326 }
327 }
328
329
330 public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList,
331 UUID insigniaID, int membershipFee, bool openEnrollment,
332 bool allowPublish, bool maturePublish)
333 {
334 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
335 // TODO: Check to make sure requestingAgentID has permission to update group
336
337 string GroupName;
338 OSDMap GroupInfoMap;
339 if (SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap))
340 {
341 GroupInfoMap["Charter"] = OSD.FromString(charter);
342 GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList);
343 GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID);
344 GroupInfoMap["MembershipFee"] = OSD.FromInteger(0);
345 GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment);
346 GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish);
347 GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish);
348
349 SimianAddGeneric(groupID, "Group", GroupName, GroupInfoMap);
350 }
351
352 }
353
354
355 public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
356 string title, ulong powers)
357 {
358 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
359
360 OSDMap GroupRoleInfo = new OSDMap();
361 GroupRoleInfo["Name"] = OSD.FromString(name);
362 GroupRoleInfo["Description"] = OSD.FromString(description);
363 GroupRoleInfo["Title"] = OSD.FromString(title);
364 GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers);
365
366 // TODO: Add security, make sure that requestingAgentID has permision to add roles
367 SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo);
368 }
369
370 public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID)
371 {
372 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
373
374 // TODO: Add security
375
376 // Can't delete the Everyone Role
377 if (roleID != UUID.Zero)
378 {
379 // Remove all GroupRole Members from Role
380 Dictionary<UUID, OSDMap> GroupRoleMembers;
381 string GroupRoleMemberType = "GroupRole" + groupID.ToString();
382 if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers))
383 {
384 foreach (UUID UserID in GroupRoleMembers.Keys)
385 {
386 EnsureRoleNotSelectedByMember(groupID, roleID, UserID);
387
388 SimianRemoveGenericEntry(UserID, GroupRoleMemberType, roleID.ToString());
389 }
390 }
391
392 // Remove role
393 SimianRemoveGenericEntry(groupID, "GroupRole", roleID.ToString());
394 }
395 }
396
397
398 public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
399 string title, ulong powers)
400 {
401 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
402
403 // TODO: Security, check that requestingAgentID is allowed to update group roles
404
405 OSDMap GroupRoleInfo;
406 if (SimianGetGenericEntry(groupID, "GroupRole", roleID.ToString(), out GroupRoleInfo))
407 {
408 if (name != null)
409 {
410 GroupRoleInfo["Name"] = OSD.FromString(name);
411 }
412 if (description != null)
413 {
414 GroupRoleInfo["Description"] = OSD.FromString(description);
415 }
416 if (title != null)
417 {
418 GroupRoleInfo["Title"] = OSD.FromString(title);
419 }
420 GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers);
421
422 }
423
424
425 SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo);
426 }
427
428 public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID groupID, string groupName)
429 {
430 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
431
432 OSDMap GroupInfoMap = null;
433 if (groupID != UUID.Zero)
434 {
435 if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out GroupInfoMap))
436 {
437 return null;
438 }
439 }
440 else if (!string.IsNullOrEmpty(groupName))
441 {
442 if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap))
443 {
444 return null;
445 }
446 }
447
448 GroupRecord GroupInfo = new GroupRecord();
449
450 GroupInfo.GroupID = groupID;
451 GroupInfo.GroupName = groupName;
452 GroupInfo.Charter = GroupInfoMap["Charter"].AsString();
453 GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean();
454 GroupInfo.GroupPicture = GroupInfoMap["InsigniaID"].AsUUID();
455 GroupInfo.MembershipFee = GroupInfoMap["MembershipFee"].AsInteger();
456 GroupInfo.OpenEnrollment = GroupInfoMap["OpenEnrollment"].AsBoolean();
457 GroupInfo.AllowPublish = GroupInfoMap["AllowPublish"].AsBoolean();
458 GroupInfo.MaturePublish = GroupInfoMap["MaturePublish"].AsBoolean();
459 GroupInfo.FounderID = GroupInfoMap["FounderID"].AsUUID();
460 GroupInfo.OwnerRoleID = GroupInfoMap["OwnerRoleID"].AsUUID();
461
462 return GroupInfo;
463
464 }
465
466 public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID groupID, UUID memberID)
467 {
468 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
469
470 OSDMap groupProfile;
471 string groupName;
472 if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out groupProfile))
473 {
474 // GroupProfileData is not nullable
475 return new GroupProfileData();
476 }
477
478 GroupProfileData MemberGroupProfile = new GroupProfileData();
479 MemberGroupProfile.GroupID = groupID;
480 MemberGroupProfile.Name = groupName;
481
482 if (groupProfile["Charter"] != null)
483 {
484 MemberGroupProfile.Charter = groupProfile["Charter"].AsString();
485 }
486
487 MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1";
488 MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID();
489 MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger();
490 MemberGroupProfile.OpenEnrollment = groupProfile["OpenEnrollment"].AsBoolean();
491 MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean();
492 MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean();
493 MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();;
494 MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID();
495
496 Dictionary<UUID, OSDMap> Members;
497 if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members))
498 {
499 MemberGroupProfile.GroupMembershipCount = Members.Count;
500 }
501
502 Dictionary<string, OSDMap> Roles;
503 if (SimianGetGenericEntries(groupID, "GroupRole", out Roles))
504 {
505 MemberGroupProfile.GroupRolesCount = Roles.Count;
506 }
507
508 // TODO: Get Group Money balance from somewhere
509 // group.Money = 0;
510
511 GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, memberID, groupID);
512
513 MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle;
514 MemberGroupProfile.PowersMask = MemberInfo.GroupPowers;
515
516 return MemberGroupProfile;
517 }
518
519 public void SetAgentActiveGroup(UUID requestingAgentID, UUID agentID, UUID groupID)
520 {
521 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
522
523 OSDMap ActiveGroup = new OSDMap();
524 ActiveGroup.Add("GroupID", OSD.FromUUID(groupID));
525 SimianAddGeneric(agentID, "Group", "ActiveGroup", ActiveGroup);
526 }
527
528 public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID)
529 {
530 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
531
532 OSDMap GroupMemberInfo;
533 if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo))
534 {
535 GroupMemberInfo = new OSDMap();
536 }
537
538 GroupMemberInfo["SelectedRoleID"] = OSD.FromUUID(roleID);
539 SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo);
540 }
541
542 public void SetAgentGroupInfo(UUID requestingAgentID, UUID agentID, UUID groupID, bool acceptNotices, bool listInProfile)
543 {
544 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
545
546 OSDMap GroupMemberInfo;
547 if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo))
548 {
549 GroupMemberInfo = new OSDMap();
550 }
551
552 GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices);
553 GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile);
554 GroupMemberInfo["Contribution"] = OSD.FromInteger(0);
555 GroupMemberInfo["SelectedRole"] = OSD.FromUUID(UUID.Zero);
556 SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo);
557 }
558
559 public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID)
560 {
561 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
562
563 OSDMap Invite = new OSDMap();
564 Invite["AgentID"] = OSD.FromUUID(agentID);
565 Invite["RoleID"] = OSD.FromUUID(roleID);
566
567 SimianAddGeneric(groupID, "GroupMemberInvite", inviteID.ToString(), Invite);
568 }
569
570 public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID)
571 {
572 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
573
574 OSDMap GroupMemberInvite;
575 UUID GroupID;
576 if (!SimianGetFirstGenericEntry("GroupMemberInvite", inviteID.ToString(), out GroupID, out GroupMemberInvite))
577 {
578 return null;
579 }
580
581 GroupInviteInfo inviteInfo = new GroupInviteInfo();
582 inviteInfo.InviteID = inviteID;
583 inviteInfo.GroupID = GroupID;
584 inviteInfo.AgentID = GroupMemberInvite["AgentID"].AsUUID();
585 inviteInfo.RoleID = GroupMemberInvite["RoleID"].AsUUID();
586
587 return inviteInfo;
588 }
589
590 public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID)
591 {
592 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
593
594 GroupInviteInfo invite = GetAgentToGroupInvite(requestingAgentID, inviteID);
595 SimianRemoveGenericEntry(invite.GroupID, "GroupMemberInvite", inviteID.ToString());
596 }
597
598 public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID)
599 {
600 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
601
602 // Setup Agent/Group information
603 SetAgentGroupInfo(requestingAgentID, AgentID, GroupID, true, true);
604
605 // Add agent to Everyone Group
606 AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, UUID.Zero);
607
608 // Add agent to Specified Role
609 AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, RoleID);
610
611 // Set selected role in this group to specified role
612 SetAgentActiveGroupRole(requestingAgentID, AgentID, GroupID, RoleID);
613 }
614
615 public void RemoveAgentFromGroup(UUID requestingAgentID, UUID agentID, UUID groupID)
616 {
617 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
618
619 // If current active group is the group the agent is being removed from, change their group to UUID.Zero
620 GroupMembershipData memberActiveMembership = GetAgentActiveMembership(requestingAgentID, agentID);
621 if (memberActiveMembership.GroupID == groupID)
622 {
623 SetAgentActiveGroup(agentID, agentID, UUID.Zero);
624 }
625
626 // Remove Group Member information for this group
627 SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString());
628
629 // By using a Simian Generics Type consisting of a prefix and a groupID,
630 // combined with RoleID as key allows us to get a list of roles a particular member
631 // of a group is assigned to.
632 string GroupRoleMemberType = "GroupRole" + groupID.ToString();
633
634 // Take Agent out of all other group roles
635 Dictionary<string, OSDMap> GroupRoles;
636 if (SimianGetGenericEntries(agentID, GroupRoleMemberType, out GroupRoles))
637 {
638 foreach (string roleID in GroupRoles.Keys)
639 {
640 SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID);
641 }
642 }
643 }
644
645 public void AddAgentToGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID)
646 {
647 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
648
649 SimianAddGeneric(agentID, "GroupRole" + groupID.ToString(), roleID.ToString(), new OSDMap());
650 }
651
652 public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID)
653 {
654 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
655
656 // Cannot remove members from the Everyone Role
657 if (roleID != UUID.Zero)
658 {
659 EnsureRoleNotSelectedByMember(groupID, roleID, agentID);
660
661 string GroupRoleMemberType = "GroupRole" + groupID.ToString();
662 SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID.ToString());
663 }
664 }
665
666 public List<DirGroupsReplyData> FindGroups(UUID requestingAgentID, string search)
667 {
668 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
669
670 List<DirGroupsReplyData> findings = new List<DirGroupsReplyData>();
671
672 NameValueCollection requestArgs = new NameValueCollection
673 {
674 { "RequestMethod", "GetGenerics" },
675 { "Type", "Group" },
676 { "Key", search },
677 { "Fuzzy", "1" }
678 };
679
680
681 OSDMap response = CachedPostRequest(requestArgs);
682 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
683 {
684 OSDArray entryArray = (OSDArray)response["Entries"];
685 foreach (OSDMap entryMap in entryArray)
686 {
687 DirGroupsReplyData data = new DirGroupsReplyData();
688 data.groupID = entryMap["OwnerID"].AsUUID();
689 data.groupName = entryMap["Key"].AsString();
690
691 // TODO: is there a better way to do this?
692 Dictionary<UUID, OSDMap> Members;
693 if (SimianGetGenericEntries("GroupMember", data.groupID.ToString(), out Members))
694 {
695 data.members = Members.Count;
696 }
697 else
698 {
699 data.members = 0;
700 }
701
702 // TODO: sort results?
703 // data.searchOrder = order;
704
705 findings.Add(data);
706 }
707 }
708
709 return findings;
710 }
711
712 public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID agentID, UUID groupID)
713 {
714 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
715
716 GroupMembershipData data = null;
717// bool foundData = false;
718
719 OSDMap UserGroupMemberInfo;
720 if (SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo))
721 {
722 data = new GroupMembershipData();
723 data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean();
724 data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger();
725 data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean();
726 data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID();
727
728 ///////////////////////////////
729 // Agent Specific Information:
730 //
731 OSDMap UserActiveGroup;
732 if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup))
733 {
734 data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID);
735 }
736
737 ///////////////////////////////
738 // Role Specific Information:
739 //
740 OSDMap GroupRoleInfo;
741 if (SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo))
742 {
743 data.GroupTitle = GroupRoleInfo["Title"].AsString();
744 data.GroupPowers = GroupRoleInfo["Powers"].AsULong();
745 }
746
747 ///////////////////////////////
748 // Group Specific Information:
749 //
750 OSDMap GroupInfo;
751 string GroupName;
752 if (SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo))
753 {
754 data.GroupID = groupID;
755 data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean();
756 data.Charter = GroupInfo["Charter"].AsString();
757 data.FounderID = GroupInfo["FounderID"].AsUUID();
758 data.GroupName = GroupName;
759 data.GroupPicture = GroupInfo["InsigniaID"].AsUUID();
760 data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean();
761 data.MembershipFee = GroupInfo["MembershipFee"].AsInteger();
762 data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean();
763 data.ShowInList = GroupInfo["ShowInList"].AsBoolean();
764 }
765 }
766
767 return data;
768 }
769
770 public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID agentID)
771 {
772 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
773
774 UUID GroupID = UUID.Zero;
775 OSDMap UserActiveGroup;
776 if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup))
777 {
778 GroupID = UserActiveGroup["GroupID"].AsUUID();
779 }
780
781 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString());
782 return GetAgentGroupMembership(requestingAgentID, agentID, GroupID);
783 }
784
785 public List<GroupMembershipData> GetAgentGroupMemberships(UUID requestingAgentID, UUID agentID)
786 {
787 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
788
789 List<GroupMembershipData> memberships = new List<GroupMembershipData>();
790
791 Dictionary<string,OSDMap> GroupMemberShips;
792 if (SimianGetGenericEntries(agentID, "GroupMember", out GroupMemberShips))
793 {
794 foreach (string key in GroupMemberShips.Keys)
795 {
796 memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key)));
797 }
798 }
799
800 return memberships;
801 }
802
803 public List<GroupRolesData> GetAgentGroupRoles(UUID requestingAgentID, UUID agentID, UUID groupID)
804 {
805 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
806
807 List<GroupRolesData> Roles = new List<GroupRolesData>();
808
809 Dictionary<string, OSDMap> GroupRoles;
810 if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles))
811 {
812 Dictionary<string, OSDMap> MemberRoles;
813 if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles))
814 {
815 foreach (KeyValuePair<string, OSDMap> kvp in MemberRoles)
816 {
817 GroupRolesData data = new GroupRolesData();
818 data.RoleID = UUID.Parse(kvp.Key);
819 data.Name = GroupRoles[kvp.Key]["Name"].AsString();
820 data.Description = GroupRoles[kvp.Key]["Description"].AsString();
821 data.Title = GroupRoles[kvp.Key]["Title"].AsString();
822 data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong();
823
824 Roles.Add(data);
825 }
826 }
827 }
828 return Roles;
829 }
830
831 public List<GroupRolesData> GetGroupRoles(UUID requestingAgentID, UUID groupID)
832 {
833 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
834
835 List<GroupRolesData> Roles = new List<GroupRolesData>();
836
837 Dictionary<string, OSDMap> GroupRoles;
838 if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles))
839 {
840 foreach (KeyValuePair<string, OSDMap> role in GroupRoles)
841 {
842 GroupRolesData data = new GroupRolesData();
843
844 data.RoleID = UUID.Parse(role.Key);
845
846 data.Name = role.Value["Name"].AsString();
847 data.Description = role.Value["Description"].AsString();
848 data.Title = role.Value["Title"].AsString();
849 data.Powers = role.Value["Powers"].AsULong();
850
851 Dictionary<UUID, OSDMap> GroupRoleMembers;
852 if (SimianGetGenericEntries("GroupRole" + groupID.ToString(), role.Key, out GroupRoleMembers))
853 {
854 data.Members = GroupRoleMembers.Count;
855 }
856 else
857 {
858 data.Members = 0;
859 }
860
861 Roles.Add(data);
862 }
863 }
864
865 return Roles;
866
867 }
868
869
870
871 public List<GroupMembersData> GetGroupMembers(UUID requestingAgentID, UUID GroupID)
872 {
873 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
874
875 List<GroupMembersData> members = new List<GroupMembersData>();
876
877 OSDMap GroupInfo;
878 string GroupName;
879 UUID GroupOwnerRoleID = UUID.Zero;
880 if (!SimianGetFirstGenericEntry(GroupID, "Group", out GroupName, out GroupInfo))
881 {
882 return members;
883 }
884 GroupOwnerRoleID = GroupInfo["OwnerRoleID"].AsUUID();
885
886 // Locally cache group roles, since we'll be needing this data for each member
887 Dictionary<string,OSDMap> GroupRoles;
888 SimianGetGenericEntries(GroupID, "GroupRole", out GroupRoles);
889
890 // Locally cache list of group owners
891 Dictionary<UUID, OSDMap> GroupOwners;
892 SimianGetGenericEntries("GroupRole" + GroupID.ToString(), GroupOwnerRoleID.ToString(), out GroupOwners);
893
894
895 Dictionary<UUID, OSDMap> GroupMembers;
896 if (SimianGetGenericEntries("GroupMember", GroupID.ToString(), out GroupMembers))
897 {
898 foreach (KeyValuePair<UUID, OSDMap> member in GroupMembers)
899 {
900 GroupMembersData data = new GroupMembersData();
901
902 data.AgentID = member.Key;
903
904 UUID SelectedRoleID = member.Value["SelectedRoleID"].AsUUID();
905
906 data.AcceptNotices = member.Value["AcceptNotices"].AsBoolean();
907 data.ListInProfile = member.Value["ListInProfile"].AsBoolean();
908 data.Contribution = member.Value["Contribution"].AsInteger();
909
910 data.IsOwner = GroupOwners.ContainsKey(member.Key);
911
912 OSDMap GroupRoleInfo = GroupRoles[SelectedRoleID.ToString()];
913 data.Title = GroupRoleInfo["Title"].AsString();
914 data.AgentPowers = GroupRoleInfo["Powers"].AsULong();
915
916 members.Add(data);
917 }
918 }
919
920 return members;
921
922 }
923
924 public List<GroupRoleMembersData> GetGroupRoleMembers(UUID requestingAgentID, UUID groupID)
925 {
926 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
927
928 List<GroupRoleMembersData> members = new List<GroupRoleMembersData>();
929
930 Dictionary<string, OSDMap> GroupRoles;
931 if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles))
932 {
933 foreach (KeyValuePair<string, OSDMap> Role in GroupRoles)
934 {
935 Dictionary<UUID, OSDMap> GroupRoleMembers;
936 if (SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers))
937 {
938 foreach (KeyValuePair<UUID, OSDMap> GroupRoleMember in GroupRoleMembers)
939 {
940 GroupRoleMembersData data = new GroupRoleMembersData();
941
942 data.MemberID = GroupRoleMember.Key;
943 data.RoleID = UUID.Parse(Role.Key);
944
945 members.Add(data);
946 }
947 }
948 }
949 }
950
951 return members;
952 }
953
954 public List<GroupNoticeData> GetGroupNotices(UUID requestingAgentID, UUID GroupID)
955 {
956 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
957
958 List<GroupNoticeData> values = new List<GroupNoticeData>();
959
960 Dictionary<string, OSDMap> Notices;
961 if (SimianGetGenericEntries(GroupID, "GroupNotice", out Notices))
962 {
963 foreach (KeyValuePair<string, OSDMap> Notice in Notices)
964 {
965 GroupNoticeData data = new GroupNoticeData();
966 data.NoticeID = UUID.Parse(Notice.Key);
967 data.Timestamp = Notice.Value["TimeStamp"].AsUInteger();
968 data.FromName = Notice.Value["FromName"].AsString();
969 data.Subject = Notice.Value["Subject"].AsString();
970 data.HasAttachment = Notice.Value["BinaryBucket"].AsBinary().Length > 0;
971
972 //TODO: Figure out how to get this
973 data.AssetType = 0;
974
975 values.Add(data);
976 }
977 }
978
979 return values;
980
981 }
982 public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
983 {
984 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
985
986 OSDMap GroupNotice;
987 UUID GroupID;
988 if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice))
989 {
990 GroupNoticeInfo data = new GroupNoticeInfo();
991 data.GroupID = GroupID;
992 data.Message = GroupNotice["Message"].AsString();
993 data.BinaryBucket = GroupNotice["BinaryBucket"].AsBinary();
994 data.noticeData.NoticeID = noticeID;
995 data.noticeData.Timestamp = GroupNotice["TimeStamp"].AsUInteger();
996 data.noticeData.FromName = GroupNotice["FromName"].AsString();
997 data.noticeData.Subject = GroupNotice["Subject"].AsString();
998 data.noticeData.HasAttachment = data.BinaryBucket.Length > 0;
999 data.noticeData.AssetType = 0;
1000
1001 if (data.Message == null)
1002 {
1003 data.Message = string.Empty;
1004 }
1005
1006 return data;
1007 }
1008 return null;
1009 }
1010 public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket)
1011 {
1012 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1013
1014 OSDMap Notice = new OSDMap();
1015 Notice["TimeStamp"] = OSD.FromUInteger((uint)Util.UnixTimeSinceEpoch());
1016 Notice["FromName"] = OSD.FromString(fromName);
1017 Notice["Subject"] = OSD.FromString(subject);
1018 Notice["Message"] = OSD.FromString(message);
1019 Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket);
1020
1021 SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice);
1022
1023 }
1024 #endregion
1025
1026 #region GroupSessionTracking
1027
1028 public void ResetAgentGroupChatSessions(UUID agentID)
1029 {
1030 Dictionary<string, OSDMap> agentSessions;
1031
1032 if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions))
1033 {
1034 foreach (string GroupID in agentSessions.Keys)
1035 {
1036 SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID);
1037 }
1038 }
1039
1040 if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions))
1041 {
1042 foreach (string GroupID in agentSessions.Keys)
1043 {
1044 SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID);
1045 }
1046 }
1047 }
1048
1049 public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID)
1050 {
1051 OSDMap session;
1052 return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session);
1053 }
1054
1055 public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID)
1056 {
1057 SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap());
1058 }
1059
1060 public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID)
1061 {
1062 SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap());
1063 }
1064
1065 public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID)
1066 {
1067 OSDMap session;
1068 return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session);
1069 }
1070
1071 #endregion
1072
1073 private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID)
1074 {
1075 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1076
1077 // If member's SelectedRole is roleID, change their selected role to Everyone
1078 // before removing them from the role
1079 OSDMap UserGroupInfo;
1080 if (SimianGetGenericEntry(userID, "GroupMember", groupID.ToString(), out UserGroupInfo))
1081 {
1082 if (UserGroupInfo["SelectedRoleID"].AsUUID() == roleID)
1083 {
1084 UserGroupInfo["SelectedRoleID"] = OSD.FromUUID(UUID.Zero);
1085 }
1086 SimianAddGeneric(userID, "GroupMember", groupID.ToString(), UserGroupInfo);
1087 }
1088 }
1089
1090
1091 #region Simian Util Methods
1092 private bool SimianAddGeneric(UUID ownerID, string type, string key, OSDMap map)
1093 {
1094 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key);
1095
1096 string value = OSDParser.SerializeJsonString(map);
1097
1098 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] value: {0}", value);
1099
1100 NameValueCollection RequestArgs = new NameValueCollection
1101 {
1102 { "RequestMethod", "AddGeneric" },
1103 { "OwnerID", ownerID.ToString() },
1104 { "Type", type },
1105 { "Key", key },
1106 { "Value", value}
1107 };
1108
1109
1110 OSDMap Response = CachedPostRequest(RequestArgs);
1111 if (Response["Success"].AsBoolean())
1112 {
1113 return true;
1114 }
1115 else
1116 {
1117 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, Response["Message"]);
1118 return false;
1119 }
1120 }
1121
1122 /// <summary>
1123 /// Returns the first of possibly many entries for Owner/Type pair
1124 /// </summary>
1125 private bool SimianGetFirstGenericEntry(UUID ownerID, string type, out string key, out OSDMap map)
1126 {
1127 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type);
1128
1129 NameValueCollection RequestArgs = new NameValueCollection
1130 {
1131 { "RequestMethod", "GetGenerics" },
1132 { "OwnerID", ownerID.ToString() },
1133 { "Type", type }
1134 };
1135
1136
1137 OSDMap Response = CachedPostRequest(RequestArgs);
1138 if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray)
1139 {
1140 OSDArray entryArray = (OSDArray)Response["Entries"];
1141 if (entryArray.Count >= 1)
1142 {
1143 OSDMap entryMap = entryArray[0] as OSDMap;
1144 key = entryMap["Key"].AsString();
1145 map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString());
1146
1147 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
1148
1149 return true;
1150 }
1151 else
1152 {
1153 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
1154 }
1155 }
1156 else
1157 {
1158 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]);
1159 }
1160 key = null;
1161 map = null;
1162 return false;
1163 }
1164 private bool SimianGetFirstGenericEntry(string type, string key, out UUID ownerID, out OSDMap map)
1165 {
1166 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key);
1167
1168
1169 NameValueCollection RequestArgs = new NameValueCollection
1170 {
1171 { "RequestMethod", "GetGenerics" },
1172 { "Type", type },
1173 { "Key", key}
1174 };
1175
1176
1177 OSDMap Response = CachedPostRequest(RequestArgs);
1178 if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray)
1179 {
1180 OSDArray entryArray = (OSDArray)Response["Entries"];
1181 if (entryArray.Count >= 1)
1182 {
1183 OSDMap entryMap = entryArray[0] as OSDMap;
1184 ownerID = entryMap["OwnerID"].AsUUID();
1185 map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString());
1186
1187 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
1188
1189 return true;
1190 }
1191 else
1192 {
1193 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
1194 }
1195 }
1196 else
1197 {
1198 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]);
1199 }
1200 ownerID = UUID.Zero;
1201 map = null;
1202 return false;
1203 }
1204
1205 private bool SimianGetGenericEntry(UUID ownerID, string type, string key, out OSDMap map)
1206 {
1207 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key);
1208
1209 NameValueCollection RequestArgs = new NameValueCollection
1210 {
1211 { "RequestMethod", "GetGenerics" },
1212 { "OwnerID", ownerID.ToString() },
1213 { "Type", type },
1214 { "Key", key}
1215 };
1216
1217
1218 OSDMap Response = CachedPostRequest(RequestArgs);
1219 if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray)
1220 {
1221 OSDArray entryArray = (OSDArray)Response["Entries"];
1222 if (entryArray.Count == 1)
1223 {
1224 OSDMap entryMap = entryArray[0] as OSDMap;
1225 key = entryMap["Key"].AsString();
1226 map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString());
1227
1228 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
1229
1230 return true;
1231 }
1232 else
1233 {
1234 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
1235 }
1236 }
1237 else
1238 {
1239 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]);
1240 }
1241 map = null;
1242 return false;
1243 }
1244
1245 private bool SimianGetGenericEntries(UUID ownerID, string type, out Dictionary<string, OSDMap> maps)
1246 {
1247 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name,ownerID, type);
1248
1249 NameValueCollection requestArgs = new NameValueCollection
1250 {
1251 { "RequestMethod", "GetGenerics" },
1252 { "OwnerID", ownerID.ToString() },
1253 { "Type", type }
1254 };
1255
1256
1257
1258 OSDMap response = CachedPostRequest(requestArgs);
1259 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
1260 {
1261 maps = new Dictionary<string, OSDMap>();
1262
1263 OSDArray entryArray = (OSDArray)response["Entries"];
1264 foreach (OSDMap entryMap in entryArray)
1265 {
1266 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
1267 maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()));
1268 }
1269 if (maps.Count == 0)
1270 {
1271 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
1272 }
1273
1274 return true;
1275 }
1276 else
1277 {
1278 maps = null;
1279 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", response["Message"]);
1280 }
1281 return false;
1282 }
1283 private bool SimianGetGenericEntries(string type, string key, out Dictionary<UUID, OSDMap> maps)
1284 {
1285 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key);
1286
1287 NameValueCollection requestArgs = new NameValueCollection
1288 {
1289 { "RequestMethod", "GetGenerics" },
1290 { "Type", type },
1291 { "Key", key }
1292 };
1293
1294
1295
1296 OSDMap response = CachedPostRequest(requestArgs);
1297 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
1298 {
1299 maps = new Dictionary<UUID, OSDMap>();
1300
1301 OSDArray entryArray = (OSDArray)response["Entries"];
1302 foreach (OSDMap entryMap in entryArray)
1303 {
1304 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
1305 maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()));
1306 }
1307 if (maps.Count == 0)
1308 {
1309 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
1310 }
1311 return true;
1312 }
1313 else
1314 {
1315 maps = null;
1316 m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR]: Error retrieving group info ({0})", response["Message"]);
1317 }
1318 return false;
1319 }
1320
1321 private bool SimianRemoveGenericEntry(UUID ownerID, string type, string key)
1322 {
1323 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key);
1324
1325 NameValueCollection requestArgs = new NameValueCollection
1326 {
1327 { "RequestMethod", "RemoveGeneric" },
1328 { "OwnerID", ownerID.ToString() },
1329 { "Type", type },
1330 { "Key", key }
1331 };
1332
1333
1334 OSDMap response = CachedPostRequest(requestArgs);
1335 if (response["Success"].AsBoolean())
1336 {
1337 return true;
1338 }
1339 else
1340 {
1341 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, response["Message"]);
1342 return false;
1343 }
1344 }
1345 #endregion
1346
1347 #region CheesyCache
1348 OSDMap CachedPostRequest(NameValueCollection requestArgs)
1349 {
1350 // Immediately forward the request if the cache is disabled.
1351 if (m_cacheTimeout == 0)
1352 {
1353 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: cache is disabled");
1354 return WebUtil.PostToService(m_groupsServerURI, requestArgs);
1355 }
1356
1357 // Check if this is an update or a request
1358 if (requestArgs["RequestMethod"] == "RemoveGeneric"
1359 || requestArgs["RequestMethod"] == "AddGeneric")
1360 {
1361 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache");
1362
1363 // Any and all updates cause the cache to clear
1364 m_memoryCache.Clear();
1365
1366 // Send update to server, return the response without caching it
1367 return WebUtil.PostToService(m_groupsServerURI, requestArgs);
1368 }
1369
1370 // If we're not doing an update, we must be requesting data
1371
1372 // Create the cache key for the request and see if we have it cached
1373 string CacheKey = WebUtil.BuildQueryString(requestArgs);
1374
1375 // This code uses a leader/follower pattern. On a cache miss, the request is added
1376 // to a queue; the first thread to add it to the queue completes the request while
1377 // follow on threads busy wait for the results, this situation seems to happen
1378 // often when checking permissions
1379 while (true)
1380 {
1381 OSDMap response = null;
1382 bool firstRequest = false;
1383
1384 lock (m_memoryCache)
1385 {
1386 if (m_memoryCache.TryGetValue(CacheKey, out response))
1387 return response;
1388
1389 if (! m_pendingRequests.ContainsKey(CacheKey))
1390 {
1391 m_pendingRequests.Add(CacheKey,true);
1392 firstRequest = true;
1393 }
1394 }
1395
1396 if (firstRequest)
1397 {
1398 // if it wasn't in the cache, pass the request to the Simian Grid Services
1399 try
1400 {
1401 response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
1402 }
1403 catch (Exception)
1404 {
1405 m_log.ErrorFormat("[SIMIAN GROUPS CONNECTOR]: request failed {0}", CacheKey);
1406 }
1407
1408 // and cache the response
1409 lock (m_memoryCache)
1410 {
1411 m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
1412 m_pendingRequests.Remove(CacheKey);
1413 }
1414
1415 return response;
1416 }
1417
1418 Thread.Sleep(50); // waiting for a web request to complete, 50msecs is reasonable
1419 }
1420
1421 // if (!m_memoryCache.TryGetValue(CacheKey, out response))
1422 // {
1423 // m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache");
1424 // Util.PrintCallStack();
1425
1426 // // if it wasn't in the cache, pass the request to the Simian Grid Services
1427 // response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
1428
1429 // // and cache the response
1430 // m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
1431 // }
1432
1433 // // return cached response
1434 // return response;
1435 }
1436 #endregion
1437
1438 }
1439
1440}
1441