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