SimianGroupsServicesConnectorModule.cs 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390
  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. using System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.Collections.Specialized;
  31. using System.Reflection;
  32. using Nwc.XmlRpc;
  33. using log4net;
  34. using Mono.Addins;
  35. using Nini.Config;
  36. using OpenMetaverse;
  37. using OpenMetaverse.StructuredData;
  38. using OpenSim.Framework;
  39. using OpenSim.Framework.Communications;
  40. using OpenSim.Region.Framework.Interfaces;
  41. using OpenSim.Services.Interfaces;
  42. /***************************************************************************
  43. * Simian Data Map
  44. * ===============
  45. *
  46. * OwnerID -> Type -> Key
  47. * -----------------------
  48. *
  49. * UserID -> Group -> ActiveGroup
  50. * + GroupID
  51. *
  52. * UserID -> GroupSessionDropped -> GroupID
  53. * UserID -> GroupSessionInvited -> GroupID
  54. *
  55. * UserID -> GroupMember -> GroupID
  56. * + SelectedRoleID [UUID]
  57. * + AcceptNotices [bool]
  58. * + ListInProfile [bool]
  59. * + Contribution [int]
  60. *
  61. * UserID -> GroupRole[GroupID] -> RoleID
  62. *
  63. *
  64. * GroupID -> Group -> GroupName
  65. * + Charter
  66. * + ShowInList
  67. * + InsigniaID
  68. * + MembershipFee
  69. * + OpenEnrollment
  70. * + AllowPublish
  71. * + MaturePublish
  72. * + FounderID
  73. * + EveryonePowers
  74. * + OwnerRoleID
  75. * + OwnersPowers
  76. *
  77. * GroupID -> GroupRole -> RoleID
  78. * + Name
  79. * + Description
  80. * + Title
  81. * + Powers
  82. *
  83. * GroupID -> GroupMemberInvite -> InviteID
  84. * + AgentID
  85. * + RoleID
  86. *
  87. * GroupID -> GroupNotice -> NoticeID
  88. * + TimeStamp [uint]
  89. * + FromName [string]
  90. * + Subject [string]
  91. * + Message [string]
  92. * + BinaryBucket [byte[]]
  93. *
  94. * */
  95. namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
  96. {
  97. [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
  98. public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector
  99. {
  100. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  101. public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome |
  102. GroupPowers.Accountable |
  103. GroupPowers.JoinChat |
  104. GroupPowers.AllowVoiceChat |
  105. GroupPowers.ReceiveNotices |
  106. GroupPowers.StartProposal |
  107. GroupPowers.VoteOnProposal;
  108. // Would this be cleaner as (GroupPowers)ulong.MaxValue;
  109. public const GroupPowers m_DefaultOwnerPowers = GroupPowers.Accountable
  110. | GroupPowers.AllowEditLand
  111. | GroupPowers.AllowFly
  112. | GroupPowers.AllowLandmark
  113. | GroupPowers.AllowRez
  114. | GroupPowers.AllowSetHome
  115. | GroupPowers.AllowVoiceChat
  116. | GroupPowers.AssignMember
  117. | GroupPowers.AssignMemberLimited
  118. | GroupPowers.ChangeActions
  119. | GroupPowers.ChangeIdentity
  120. | GroupPowers.ChangeMedia
  121. | GroupPowers.ChangeOptions
  122. | GroupPowers.CreateRole
  123. | GroupPowers.DeedObject
  124. | GroupPowers.DeleteRole
  125. | GroupPowers.Eject
  126. | GroupPowers.FindPlaces
  127. | GroupPowers.Invite
  128. | GroupPowers.JoinChat
  129. | GroupPowers.LandChangeIdentity
  130. | GroupPowers.LandDeed
  131. | GroupPowers.LandDivideJoin
  132. | GroupPowers.LandEdit
  133. | GroupPowers.LandEjectAndFreeze
  134. | GroupPowers.LandGardening
  135. | GroupPowers.LandManageAllowed
  136. | GroupPowers.LandManageBanned
  137. | GroupPowers.LandManagePasses
  138. | GroupPowers.LandOptions
  139. | GroupPowers.LandRelease
  140. | GroupPowers.LandSetSale
  141. | GroupPowers.ModerateChat
  142. | GroupPowers.ObjectManipulate
  143. | GroupPowers.ObjectSetForSale
  144. | GroupPowers.ReceiveNotices
  145. | GroupPowers.RemoveMember
  146. | GroupPowers.ReturnGroupOwned
  147. | GroupPowers.ReturnGroupSet
  148. | GroupPowers.ReturnNonGroup
  149. | GroupPowers.RoleProperties
  150. | GroupPowers.SendNotices
  151. | GroupPowers.SetLandingPoint
  152. | GroupPowers.StartProposal
  153. | GroupPowers.VoteOnProposal;
  154. private bool m_connectorEnabled = false;
  155. private string m_groupsServerURI = string.Empty;
  156. private bool m_debugEnabled = false;
  157. private ExpiringCache<string, OSDMap> m_memoryCache;
  158. private int m_cacheTimeout = 30;
  159. // private IUserAccountService m_accountService = null;
  160. #region IRegionModuleBase Members
  161. public string Name
  162. {
  163. get { return "SimianGroupsServicesConnector"; }
  164. }
  165. // this module is not intended to be replaced, but there should only be 1 of them.
  166. public Type ReplaceableInterface
  167. {
  168. get { return null; }
  169. }
  170. public void Initialise(IConfigSource config)
  171. {
  172. IConfig groupsConfig = config.Configs["Groups"];
  173. if (groupsConfig == null)
  174. {
  175. // Do not run this module by default.
  176. return;
  177. }
  178. else
  179. {
  180. // if groups aren't enabled, we're not needed.
  181. // if we're not specified as the connector to use, then we're not wanted
  182. if ((groupsConfig.GetBoolean("Enabled", false) == false)
  183. || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name))
  184. {
  185. m_connectorEnabled = false;
  186. return;
  187. }
  188. m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name);
  189. m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty);
  190. if ((m_groupsServerURI == null) ||
  191. (m_groupsServerURI == string.Empty))
  192. {
  193. m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]");
  194. m_connectorEnabled = false;
  195. return;
  196. }
  197. m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30);
  198. if (m_cacheTimeout == 0)
  199. {
  200. m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Disabled.");
  201. }
  202. else
  203. {
  204. m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Timeout set to {0}.", m_cacheTimeout);
  205. }
  206. m_memoryCache = new ExpiringCache<string,OSDMap>();
  207. // If we got all the config options we need, lets start'er'up
  208. m_connectorEnabled = true;
  209. m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
  210. }
  211. }
  212. public void Close()
  213. {
  214. m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Closing {0}", this.Name);
  215. }
  216. public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene)
  217. {
  218. if (m_connectorEnabled)
  219. {
  220. scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
  221. }
  222. }
  223. public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene)
  224. {
  225. if (scene.RequestModuleInterface<IGroupsServicesConnector>() == this)
  226. {
  227. scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
  228. }
  229. }
  230. public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene)
  231. {
  232. // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info
  233. // scene.EventManager.OnNewClient += OnNewClient;
  234. }
  235. #endregion
  236. #region ISharedRegionModule Members
  237. public void PostInitialise()
  238. {
  239. // NoOp
  240. }
  241. #endregion
  242. #region IGroupsServicesConnector Members
  243. /// <summary>
  244. /// 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.
  245. /// </summary>
  246. public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID,
  247. int membershipFee, bool openEnrollment, bool allowPublish,
  248. bool maturePublish, UUID founderID)
  249. {
  250. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  251. UUID GroupID = UUID.Random();
  252. UUID OwnerRoleID = UUID.Random();
  253. OSDMap GroupInfoMap = new OSDMap();
  254. GroupInfoMap["Charter"] = OSD.FromString(charter);
  255. GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList);
  256. GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID);
  257. GroupInfoMap["MembershipFee"] = OSD.FromInteger(0);
  258. GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment);
  259. GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish);
  260. GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish);
  261. GroupInfoMap["FounderID"] = OSD.FromUUID(founderID);
  262. GroupInfoMap["EveryonePowers"] = OSD.FromULong((ulong)m_DefaultEveryonePowers);
  263. GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID);
  264. GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers);
  265. if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap))
  266. {
  267. AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers);
  268. AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers);
  269. AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID);
  270. return GroupID;
  271. }
  272. else
  273. {
  274. return UUID.Zero;
  275. }
  276. }
  277. public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList,
  278. UUID insigniaID, int membershipFee, bool openEnrollment,
  279. bool allowPublish, bool maturePublish)
  280. {
  281. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  282. // TODO: Check to make sure requestingAgentID has permission to update group
  283. string GroupName;
  284. OSDMap GroupInfoMap;
  285. if( SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap) )
  286. {
  287. GroupInfoMap["Charter"] = OSD.FromString(charter);
  288. GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList);
  289. GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID);
  290. GroupInfoMap["MembershipFee"] = OSD.FromInteger(0);
  291. GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment);
  292. GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish);
  293. GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish);
  294. SimianAddGeneric(groupID, "Group", GroupName, GroupInfoMap);
  295. }
  296. }
  297. public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
  298. string title, ulong powers)
  299. {
  300. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  301. OSDMap GroupRoleInfo = new OSDMap();
  302. GroupRoleInfo["Name"] = OSD.FromString(name);
  303. GroupRoleInfo["Description"] = OSD.FromString(description);
  304. GroupRoleInfo["Title"] = OSD.FromString(title);
  305. GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers);
  306. // TODO: Add security, make sure that requestingAgentID has permision to add roles
  307. SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo);
  308. }
  309. public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID)
  310. {
  311. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  312. // TODO: Add security
  313. // Can't delete the Everyone Role
  314. if (roleID != UUID.Zero)
  315. {
  316. // Remove all GroupRole Members from Role
  317. Dictionary<UUID, OSDMap> GroupRoleMembers;
  318. string GroupRoleMemberType = "GroupRole" + groupID.ToString();
  319. if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers))
  320. {
  321. foreach(UUID UserID in GroupRoleMembers.Keys)
  322. {
  323. EnsureRoleNotSelectedByMember(groupID, roleID, UserID);
  324. SimianRemoveGenericEntry(UserID, GroupRoleMemberType, roleID.ToString());
  325. }
  326. }
  327. // Remove role
  328. SimianRemoveGenericEntry(groupID, "GroupRole", roleID.ToString());
  329. }
  330. }
  331. public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
  332. string title, ulong powers)
  333. {
  334. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  335. // TODO: Security, check that requestingAgentID is allowed to update group roles
  336. OSDMap GroupRoleInfo;
  337. if (SimianGetGenericEntry(groupID, "GroupRole", roleID.ToString(), out GroupRoleInfo))
  338. {
  339. if (name != null)
  340. {
  341. GroupRoleInfo["Name"] = OSD.FromString(name);
  342. }
  343. if (description != null)
  344. {
  345. GroupRoleInfo["Description"] = OSD.FromString(description);
  346. }
  347. if (title != null)
  348. {
  349. GroupRoleInfo["Title"] = OSD.FromString(title);
  350. }
  351. GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers);
  352. }
  353. SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo);
  354. }
  355. public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID groupID, string groupName)
  356. {
  357. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  358. OSDMap GroupInfoMap = null;
  359. if (groupID != UUID.Zero)
  360. {
  361. if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out GroupInfoMap))
  362. {
  363. return null;
  364. }
  365. }
  366. else if ((groupName != null) && (groupName != string.Empty))
  367. {
  368. if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap))
  369. {
  370. return null;
  371. }
  372. }
  373. GroupRecord GroupInfo = new GroupRecord();
  374. GroupInfo.GroupID = groupID;
  375. GroupInfo.GroupName = groupName;
  376. GroupInfo.Charter = GroupInfoMap["Charter"].AsString();
  377. GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean();
  378. GroupInfo.GroupPicture = GroupInfoMap["InsigniaID"].AsUUID();
  379. GroupInfo.MembershipFee = GroupInfoMap["MembershipFee"].AsInteger();
  380. GroupInfo.OpenEnrollment = GroupInfoMap["OpenEnrollment"].AsBoolean();
  381. GroupInfo.AllowPublish = GroupInfoMap["AllowPublish"].AsBoolean();
  382. GroupInfo.MaturePublish = GroupInfoMap["MaturePublish"].AsBoolean();
  383. GroupInfo.FounderID = GroupInfoMap["FounderID"].AsUUID();
  384. GroupInfo.OwnerRoleID = GroupInfoMap["OwnerRoleID"].AsUUID();
  385. return GroupInfo;
  386. }
  387. public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID groupID, UUID memberID)
  388. {
  389. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  390. OSDMap groupProfile;
  391. string groupName;
  392. if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out groupProfile))
  393. {
  394. // GroupProfileData is not nullable
  395. return new GroupProfileData();
  396. }
  397. GroupProfileData MemberGroupProfile = new GroupProfileData();
  398. MemberGroupProfile.GroupID = groupID;
  399. MemberGroupProfile.Name = groupName;
  400. if (groupProfile["Charter"] != null)
  401. {
  402. MemberGroupProfile.Charter = groupProfile["Charter"].AsString();
  403. }
  404. MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1";
  405. MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID();
  406. MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger();
  407. MemberGroupProfile.OpenEnrollment = groupProfile["OpenEnrollment"].AsBoolean();
  408. MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean();
  409. MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean();
  410. MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();;
  411. MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID();
  412. Dictionary<UUID, OSDMap> Members;
  413. if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members))
  414. {
  415. MemberGroupProfile.GroupMembershipCount = Members.Count;
  416. }
  417. Dictionary<string, OSDMap> Roles;
  418. if (SimianGetGenericEntries(groupID, "GroupRole", out Roles))
  419. {
  420. MemberGroupProfile.GroupRolesCount = Roles.Count;
  421. }
  422. // TODO: Get Group Money balance from somewhere
  423. // group.Money = 0;
  424. GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, memberID, groupID);
  425. MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle;
  426. MemberGroupProfile.PowersMask = MemberInfo.GroupPowers;
  427. return MemberGroupProfile;
  428. }
  429. public void SetAgentActiveGroup(UUID requestingAgentID, UUID agentID, UUID groupID)
  430. {
  431. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  432. OSDMap ActiveGroup = new OSDMap();
  433. ActiveGroup.Add("GroupID", OSD.FromUUID(groupID));
  434. SimianAddGeneric(agentID, "Group", "ActiveGroup", ActiveGroup);
  435. }
  436. public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID)
  437. {
  438. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  439. OSDMap GroupMemberInfo;
  440. if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo))
  441. {
  442. GroupMemberInfo = new OSDMap();
  443. }
  444. GroupMemberInfo["SelectedRoleID"] = OSD.FromUUID(roleID);
  445. SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo);
  446. }
  447. public void SetAgentGroupInfo(UUID requestingAgentID, UUID agentID, UUID groupID, bool acceptNotices, bool listInProfile)
  448. {
  449. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  450. OSDMap GroupMemberInfo;
  451. if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo))
  452. {
  453. GroupMemberInfo = new OSDMap();
  454. }
  455. GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices);
  456. GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile);
  457. GroupMemberInfo["Contribution"] = OSD.FromInteger(0);
  458. GroupMemberInfo["SelectedRole"] = OSD.FromUUID(UUID.Zero);
  459. SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo);
  460. }
  461. public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID)
  462. {
  463. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  464. OSDMap Invite = new OSDMap();
  465. Invite["AgentID"] = OSD.FromUUID(agentID);
  466. Invite["RoleID"] = OSD.FromUUID(roleID);
  467. SimianAddGeneric(groupID, "GroupMemberInvite", inviteID.ToString(), Invite);
  468. }
  469. public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID)
  470. {
  471. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  472. OSDMap GroupMemberInvite;
  473. UUID GroupID;
  474. if (!SimianGetFirstGenericEntry("GroupMemberInvite", inviteID.ToString(), out GroupID, out GroupMemberInvite))
  475. {
  476. return null;
  477. }
  478. GroupInviteInfo inviteInfo = new GroupInviteInfo();
  479. inviteInfo.InviteID = inviteID;
  480. inviteInfo.GroupID = GroupID;
  481. inviteInfo.AgentID = GroupMemberInvite["AgentID"].AsUUID();
  482. inviteInfo.RoleID = GroupMemberInvite["RoleID"].AsUUID();
  483. return inviteInfo;
  484. }
  485. public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID)
  486. {
  487. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  488. GroupInviteInfo invite = GetAgentToGroupInvite(requestingAgentID, inviteID);
  489. SimianRemoveGenericEntry(invite.GroupID, "GroupMemberInvite", inviteID.ToString());
  490. }
  491. public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID)
  492. {
  493. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  494. // Setup Agent/Group information
  495. SetAgentGroupInfo(requestingAgentID, AgentID, GroupID, true, true);
  496. // Add agent to Everyone Group
  497. AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, UUID.Zero);
  498. // Add agent to Specified Role
  499. AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, RoleID);
  500. // Set selected role in this group to specified role
  501. SetAgentActiveGroupRole(requestingAgentID, AgentID, GroupID, RoleID);
  502. }
  503. public void RemoveAgentFromGroup(UUID requestingAgentID, UUID agentID, UUID groupID)
  504. {
  505. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  506. // If current active group is the group the agent is being removed from, change their group to UUID.Zero
  507. GroupMembershipData memberActiveMembership = GetAgentActiveMembership(requestingAgentID, agentID);
  508. if (memberActiveMembership.GroupID == groupID)
  509. {
  510. SetAgentActiveGroup(agentID, agentID, UUID.Zero);
  511. }
  512. // Remove Group Member information for this group
  513. SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString());
  514. // By using a Simian Generics Type consisting of a prefix and a groupID,
  515. // combined with RoleID as key allows us to get a list of roles a particular member
  516. // of a group is assigned to.
  517. string GroupRoleMemberType = "GroupRole" + groupID.ToString();
  518. // Take Agent out of all other group roles
  519. Dictionary<string, OSDMap> GroupRoles;
  520. if (SimianGetGenericEntries(agentID, GroupRoleMemberType, out GroupRoles))
  521. {
  522. foreach (string roleID in GroupRoles.Keys)
  523. {
  524. SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID);
  525. }
  526. }
  527. }
  528. public void AddAgentToGroupRole(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. SimianAddGeneric(agentID, "GroupRole" + groupID.ToString(), roleID.ToString(), new OSDMap());
  532. }
  533. public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID)
  534. {
  535. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  536. // Cannot remove members from the Everyone Role
  537. if (roleID != UUID.Zero)
  538. {
  539. EnsureRoleNotSelectedByMember(groupID, roleID, agentID);
  540. string GroupRoleMemberType = "GroupRole" + groupID.ToString();
  541. SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID.ToString());
  542. }
  543. }
  544. public List<DirGroupsReplyData> FindGroups(UUID requestingAgentID, string search)
  545. {
  546. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  547. List<DirGroupsReplyData> findings = new List<DirGroupsReplyData>();
  548. NameValueCollection requestArgs = new NameValueCollection
  549. {
  550. { "RequestMethod", "GetGenerics" },
  551. { "Type", "Group" },
  552. { "Key", search },
  553. { "Fuzzy", "1" }
  554. };
  555. OSDMap response = CachedPostRequest(requestArgs);
  556. if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
  557. {
  558. OSDArray entryArray = (OSDArray)response["Entries"];
  559. foreach (OSDMap entryMap in entryArray)
  560. {
  561. DirGroupsReplyData data = new DirGroupsReplyData();
  562. data.groupID = entryMap["OwnerID"].AsUUID();
  563. data.groupName = entryMap["Key"].AsString();
  564. // TODO: is there a better way to do this?
  565. Dictionary<UUID, OSDMap> Members;
  566. if (SimianGetGenericEntries("GroupMember", data.groupID.ToString(), out Members))
  567. {
  568. data.members = Members.Count;
  569. }
  570. else
  571. {
  572. data.members = 0;
  573. }
  574. // TODO: sort results?
  575. // data.searchOrder = order;
  576. findings.Add(data);
  577. }
  578. }
  579. return findings;
  580. }
  581. public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID agentID, UUID groupID)
  582. {
  583. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  584. GroupMembershipData data = new GroupMembershipData();
  585. ///////////////////////////////
  586. // Agent Specific Information:
  587. //
  588. OSDMap UserActiveGroup;
  589. if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup))
  590. {
  591. data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID);
  592. }
  593. OSDMap UserGroupMemberInfo;
  594. if( SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo) )
  595. {
  596. data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean();
  597. data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger();
  598. data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean();
  599. data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID();
  600. ///////////////////////////////
  601. // Role Specific Information:
  602. //
  603. OSDMap GroupRoleInfo;
  604. if( SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo) )
  605. {
  606. data.GroupTitle = GroupRoleInfo["Title"].AsString();
  607. data.GroupPowers = GroupRoleInfo["Powers"].AsULong();
  608. }
  609. }
  610. ///////////////////////////////
  611. // Group Specific Information:
  612. //
  613. OSDMap GroupInfo;
  614. string GroupName;
  615. if( SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo) )
  616. {
  617. data.GroupID = groupID;
  618. data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean();
  619. data.Charter = GroupInfo["Charter"].AsString();
  620. data.FounderID = GroupInfo["FounderID"].AsUUID();
  621. data.GroupName = GroupName;
  622. data.GroupPicture = GroupInfo["InsigniaID"].AsUUID();
  623. data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean();
  624. data.MembershipFee = GroupInfo["MembershipFee"].AsInteger();
  625. data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean();
  626. data.ShowInList = GroupInfo["ShowInList"].AsBoolean();
  627. }
  628. return data;
  629. }
  630. public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID agentID)
  631. {
  632. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  633. UUID GroupID = UUID.Zero;
  634. OSDMap UserActiveGroup;
  635. if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup))
  636. {
  637. GroupID = UserActiveGroup["GroupID"].AsUUID();
  638. }
  639. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString());
  640. return GetAgentGroupMembership(requestingAgentID, agentID, GroupID);
  641. }
  642. public List<GroupMembershipData> GetAgentGroupMemberships(UUID requestingAgentID, UUID agentID)
  643. {
  644. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  645. List<GroupMembershipData> memberships = new List<GroupMembershipData>();
  646. Dictionary<string,OSDMap> GroupMemberShips;
  647. if (SimianGetGenericEntries(agentID, "GroupMember", out GroupMemberShips))
  648. {
  649. foreach (string key in GroupMemberShips.Keys)
  650. {
  651. memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key)));
  652. }
  653. }
  654. return memberships;
  655. }
  656. public List<GroupRolesData> GetAgentGroupRoles(UUID requestingAgentID, UUID agentID, UUID groupID)
  657. {
  658. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  659. List<GroupRolesData> Roles = new List<GroupRolesData>();
  660. Dictionary<string, OSDMap> GroupRoles;
  661. if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles))
  662. {
  663. Dictionary<string, OSDMap> MemberRoles;
  664. if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles))
  665. {
  666. foreach (KeyValuePair<string, OSDMap> kvp in MemberRoles)
  667. {
  668. GroupRolesData data = new GroupRolesData();
  669. data.RoleID = UUID.Parse(kvp.Key);
  670. data.Name = GroupRoles[kvp.Key]["Name"].AsString();
  671. data.Description = GroupRoles[kvp.Key]["Description"].AsString();
  672. data.Title = GroupRoles[kvp.Key]["Title"].AsString();
  673. data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong();
  674. Roles.Add(data);
  675. }
  676. }
  677. }
  678. return Roles;
  679. }
  680. public List<GroupRolesData> GetGroupRoles(UUID requestingAgentID, UUID groupID)
  681. {
  682. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  683. List<GroupRolesData> Roles = new List<GroupRolesData>();
  684. Dictionary<string, OSDMap> GroupRoles;
  685. if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles))
  686. {
  687. foreach (KeyValuePair<string, OSDMap> role in GroupRoles)
  688. {
  689. GroupRolesData data = new GroupRolesData();
  690. data.RoleID = UUID.Parse(role.Key);
  691. data.Name = role.Value["Name"].AsString();
  692. data.Description = role.Value["Description"].AsString();
  693. data.Title = role.Value["Title"].AsString();
  694. data.Powers = role.Value["Powers"].AsULong();
  695. Dictionary<UUID, OSDMap> GroupRoleMembers;
  696. if (SimianGetGenericEntries("GroupRole" + groupID.ToString(), role.Key, out GroupRoleMembers))
  697. {
  698. data.Members = GroupRoleMembers.Count;
  699. }
  700. else
  701. {
  702. data.Members = 0;
  703. }
  704. Roles.Add(data);
  705. }
  706. }
  707. return Roles;
  708. }
  709. public List<GroupMembersData> GetGroupMembers(UUID requestingAgentID, UUID GroupID)
  710. {
  711. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  712. List<GroupMembersData> members = new List<GroupMembersData>();
  713. OSDMap GroupInfo;
  714. string GroupName;
  715. UUID GroupOwnerRoleID = UUID.Zero;
  716. if (!SimianGetFirstGenericEntry(GroupID, "Group", out GroupName, out GroupInfo))
  717. {
  718. return members;
  719. }
  720. GroupOwnerRoleID = GroupInfo["OwnerRoleID"].AsUUID();
  721. // Locally cache group roles, since we'll be needing this data for each member
  722. Dictionary<string,OSDMap> GroupRoles;
  723. SimianGetGenericEntries(GroupID, "GroupRole", out GroupRoles);
  724. // Locally cache list of group owners
  725. Dictionary<UUID, OSDMap> GroupOwners;
  726. SimianGetGenericEntries("GroupRole" + GroupID.ToString(), GroupOwnerRoleID.ToString(), out GroupOwners);
  727. Dictionary<UUID, OSDMap> GroupMembers;
  728. if (SimianGetGenericEntries("GroupMember", GroupID.ToString(), out GroupMembers))
  729. {
  730. foreach (KeyValuePair<UUID, OSDMap> member in GroupMembers)
  731. {
  732. GroupMembersData data = new GroupMembersData();
  733. data.AgentID = member.Key;
  734. UUID SelectedRoleID = member.Value["SelectedRoleID"].AsUUID();
  735. data.AcceptNotices = member.Value["AcceptNotices"].AsBoolean();
  736. data.ListInProfile = member.Value["ListInProfile"].AsBoolean();
  737. data.Contribution = member.Value["Contribution"].AsInteger();
  738. data.IsOwner = GroupOwners.ContainsKey(member.Key);
  739. OSDMap GroupRoleInfo = GroupRoles[SelectedRoleID.ToString()];
  740. data.Title = GroupRoleInfo["Title"].AsString();
  741. data.AgentPowers = GroupRoleInfo["Powers"].AsULong();
  742. members.Add(data);
  743. }
  744. }
  745. return members;
  746. }
  747. public List<GroupRoleMembersData> GetGroupRoleMembers(UUID requestingAgentID, UUID groupID)
  748. {
  749. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  750. List<GroupRoleMembersData> members = new List<GroupRoleMembersData>();
  751. Dictionary<string, OSDMap> GroupRoles;
  752. if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles))
  753. {
  754. foreach( KeyValuePair<string, OSDMap> Role in GroupRoles )
  755. {
  756. Dictionary<UUID, OSDMap> GroupRoleMembers;
  757. if( SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers) )
  758. {
  759. foreach( KeyValuePair<UUID, OSDMap> GroupRoleMember in GroupRoleMembers )
  760. {
  761. GroupRoleMembersData data = new GroupRoleMembersData();
  762. data.MemberID = GroupRoleMember.Key;
  763. data.RoleID = UUID.Parse(Role.Key);
  764. members.Add(data);
  765. }
  766. }
  767. }
  768. }
  769. return members;
  770. }
  771. public List<GroupNoticeData> GetGroupNotices(UUID requestingAgentID, UUID GroupID)
  772. {
  773. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  774. List<GroupNoticeData> values = new List<GroupNoticeData>();
  775. Dictionary<string, OSDMap> Notices;
  776. if (SimianGetGenericEntries(GroupID, "GroupNotice", out Notices))
  777. {
  778. foreach (KeyValuePair<string, OSDMap> Notice in Notices)
  779. {
  780. GroupNoticeData data = new GroupNoticeData();
  781. data.NoticeID = UUID.Parse(Notice.Key);
  782. data.Timestamp = Notice.Value["TimeStamp"].AsUInteger();
  783. data.FromName = Notice.Value["FromName"].AsString();
  784. data.Subject = Notice.Value["Subject"].AsString();
  785. data.HasAttachment = Notice.Value["BinaryBucket"].AsBinary().Length > 0;
  786. //TODO: Figure out how to get this
  787. data.AssetType = 0;
  788. values.Add(data);
  789. }
  790. }
  791. return values;
  792. }
  793. public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID)
  794. {
  795. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  796. OSDMap GroupNotice;
  797. UUID GroupID;
  798. if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice))
  799. {
  800. GroupNoticeInfo data = new GroupNoticeInfo();
  801. data.GroupID = GroupID;
  802. data.Message = GroupNotice["Message"].AsString();
  803. data.BinaryBucket = GroupNotice["BinaryBucket"].AsBinary();
  804. data.noticeData.NoticeID = noticeID;
  805. data.noticeData.Timestamp = GroupNotice["TimeStamp"].AsUInteger();
  806. data.noticeData.FromName = GroupNotice["FromName"].AsString();
  807. data.noticeData.Subject = GroupNotice["Subject"].AsString();
  808. data.noticeData.HasAttachment = data.BinaryBucket.Length > 0;
  809. data.noticeData.AssetType = 0;
  810. if (data.Message == null)
  811. {
  812. data.Message = string.Empty;
  813. }
  814. return data;
  815. }
  816. return null;
  817. }
  818. public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket)
  819. {
  820. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  821. OSDMap Notice = new OSDMap();
  822. Notice["TimeStamp"] = OSD.FromUInteger((uint)Util.UnixTimeSinceEpoch());
  823. Notice["FromName"] = OSD.FromString(fromName);
  824. Notice["Subject"] = OSD.FromString(subject);
  825. Notice["Message"] = OSD.FromString(message);
  826. Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket);
  827. SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice);
  828. }
  829. #endregion
  830. #region GroupSessionTracking
  831. public void ResetAgentGroupChatSessions(UUID agentID)
  832. {
  833. Dictionary<string, OSDMap> agentSessions;
  834. if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions))
  835. {
  836. foreach (string GroupID in agentSessions.Keys)
  837. {
  838. SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID);
  839. }
  840. }
  841. if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions))
  842. {
  843. foreach (string GroupID in agentSessions.Keys)
  844. {
  845. SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID);
  846. }
  847. }
  848. }
  849. public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID)
  850. {
  851. OSDMap session;
  852. return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session);
  853. }
  854. public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID)
  855. {
  856. SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap());
  857. }
  858. public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID)
  859. {
  860. SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap());
  861. }
  862. public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID)
  863. {
  864. OSDMap session;
  865. return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session);
  866. }
  867. #endregion
  868. private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID)
  869. {
  870. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
  871. // If member's SelectedRole is roleID, change their selected role to Everyone
  872. // before removing them from the role
  873. OSDMap UserGroupInfo;
  874. if (SimianGetGenericEntry(userID, "GroupMember", groupID.ToString(), out UserGroupInfo))
  875. {
  876. if (UserGroupInfo["SelectedRoleID"].AsUUID() == roleID)
  877. {
  878. UserGroupInfo["SelectedRoleID"] = OSD.FromUUID(UUID.Zero);
  879. }
  880. SimianAddGeneric(userID, "GroupMember", groupID.ToString(), UserGroupInfo);
  881. }
  882. }
  883. #region Simian Util Methods
  884. private bool SimianAddGeneric(UUID ownerID, string type, string key, OSDMap map)
  885. {
  886. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key);
  887. string value = OSDParser.SerializeJsonString(map);
  888. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] value: {0}", value);
  889. NameValueCollection RequestArgs = new NameValueCollection
  890. {
  891. { "RequestMethod", "AddGeneric" },
  892. { "OwnerID", ownerID.ToString() },
  893. { "Type", type },
  894. { "Key", key },
  895. { "Value", value}
  896. };
  897. OSDMap Response = CachedPostRequest(RequestArgs);
  898. if (Response["Success"].AsBoolean())
  899. {
  900. return true;
  901. }
  902. else
  903. {
  904. m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, Response["Message"]);
  905. return false;
  906. }
  907. }
  908. /// <summary>
  909. /// Returns the first of possibly many entries for Owner/Type pair
  910. /// </summary>
  911. private bool SimianGetFirstGenericEntry(UUID ownerID, string type, out string key, out OSDMap map)
  912. {
  913. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type);
  914. NameValueCollection RequestArgs = new NameValueCollection
  915. {
  916. { "RequestMethod", "GetGenerics" },
  917. { "OwnerID", ownerID.ToString() },
  918. { "Type", type }
  919. };
  920. OSDMap Response = CachedPostRequest(RequestArgs);
  921. if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray)
  922. {
  923. OSDArray entryArray = (OSDArray)Response["Entries"];
  924. if (entryArray.Count >= 1)
  925. {
  926. OSDMap entryMap = entryArray[0] as OSDMap;
  927. key = entryMap["Key"].AsString();
  928. map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString());
  929. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
  930. return true;
  931. }
  932. else
  933. {
  934. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
  935. }
  936. }
  937. else
  938. {
  939. m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]);
  940. }
  941. key = null;
  942. map = null;
  943. return false;
  944. }
  945. private bool SimianGetFirstGenericEntry(string type, string key, out UUID ownerID, out OSDMap map)
  946. {
  947. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key);
  948. NameValueCollection RequestArgs = new NameValueCollection
  949. {
  950. { "RequestMethod", "GetGenerics" },
  951. { "Type", type },
  952. { "Key", key}
  953. };
  954. OSDMap Response = CachedPostRequest(RequestArgs);
  955. if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray)
  956. {
  957. OSDArray entryArray = (OSDArray)Response["Entries"];
  958. if (entryArray.Count >= 1)
  959. {
  960. OSDMap entryMap = entryArray[0] as OSDMap;
  961. ownerID = entryMap["OwnerID"].AsUUID();
  962. map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString());
  963. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
  964. return true;
  965. }
  966. else
  967. {
  968. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
  969. }
  970. }
  971. else
  972. {
  973. m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]);
  974. }
  975. ownerID = UUID.Zero;
  976. map = null;
  977. return false;
  978. }
  979. private bool SimianGetGenericEntry(UUID ownerID, string type, string key, out OSDMap map)
  980. {
  981. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key);
  982. NameValueCollection RequestArgs = new NameValueCollection
  983. {
  984. { "RequestMethod", "GetGenerics" },
  985. { "OwnerID", ownerID.ToString() },
  986. { "Type", type },
  987. { "Key", key}
  988. };
  989. OSDMap Response = CachedPostRequest(RequestArgs);
  990. if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray)
  991. {
  992. OSDArray entryArray = (OSDArray)Response["Entries"];
  993. if (entryArray.Count == 1)
  994. {
  995. OSDMap entryMap = entryArray[0] as OSDMap;
  996. key = entryMap["Key"].AsString();
  997. map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString());
  998. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
  999. return true;
  1000. }
  1001. else
  1002. {
  1003. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
  1004. }
  1005. }
  1006. else
  1007. {
  1008. m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]);
  1009. }
  1010. map = null;
  1011. return false;
  1012. }
  1013. private bool SimianGetGenericEntries(UUID ownerID, string type, out Dictionary<string, OSDMap> maps)
  1014. {
  1015. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name,ownerID, type);
  1016. NameValueCollection requestArgs = new NameValueCollection
  1017. {
  1018. { "RequestMethod", "GetGenerics" },
  1019. { "OwnerID", ownerID.ToString() },
  1020. { "Type", type }
  1021. };
  1022. OSDMap response = CachedPostRequest(requestArgs);
  1023. if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
  1024. {
  1025. maps = new Dictionary<string, OSDMap>();
  1026. OSDArray entryArray = (OSDArray)response["Entries"];
  1027. foreach (OSDMap entryMap in entryArray)
  1028. {
  1029. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
  1030. maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()));
  1031. }
  1032. if(maps.Count == 0)
  1033. {
  1034. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
  1035. }
  1036. return true;
  1037. }
  1038. else
  1039. {
  1040. maps = null;
  1041. m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", response["Message"]);
  1042. }
  1043. return false;
  1044. }
  1045. private bool SimianGetGenericEntries(string type, string key, out Dictionary<UUID, OSDMap> maps)
  1046. {
  1047. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key);
  1048. NameValueCollection requestArgs = new NameValueCollection
  1049. {
  1050. { "RequestMethod", "GetGenerics" },
  1051. { "Type", type },
  1052. { "Key", key }
  1053. };
  1054. OSDMap response = CachedPostRequest(requestArgs);
  1055. if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
  1056. {
  1057. maps = new Dictionary<UUID, OSDMap>();
  1058. OSDArray entryArray = (OSDArray)response["Entries"];
  1059. foreach (OSDMap entryMap in entryArray)
  1060. {
  1061. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString());
  1062. maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()));
  1063. }
  1064. if (maps.Count == 0)
  1065. {
  1066. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results");
  1067. }
  1068. return true;
  1069. }
  1070. else
  1071. {
  1072. maps = null;
  1073. m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR]: Error retrieving group info ({0})", response["Message"]);
  1074. }
  1075. return false;
  1076. }
  1077. private bool SimianRemoveGenericEntry(UUID ownerID, string type, string key)
  1078. {
  1079. if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key);
  1080. NameValueCollection requestArgs = new NameValueCollection
  1081. {
  1082. { "RequestMethod", "RemoveGeneric" },
  1083. { "OwnerID", ownerID.ToString() },
  1084. { "Type", type },
  1085. { "Key", key }
  1086. };
  1087. OSDMap response = CachedPostRequest(requestArgs);
  1088. if (response["Success"].AsBoolean())
  1089. {
  1090. return true;
  1091. }
  1092. else
  1093. {
  1094. m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, response["Message"]);
  1095. return false;
  1096. }
  1097. }
  1098. #endregion
  1099. #region CheesyCache
  1100. OSDMap CachedPostRequest(NameValueCollection requestArgs)
  1101. {
  1102. // Immediately forward the request if the cache is disabled.
  1103. if (m_cacheTimeout == 0)
  1104. {
  1105. return WebUtil.PostToService(m_groupsServerURI, requestArgs);
  1106. }
  1107. // Check if this is an update or a request
  1108. if ( requestArgs["RequestMethod"] == "RemoveGeneric"
  1109. || requestArgs["RequestMethod"] == "AddGeneric"
  1110. )
  1111. {
  1112. // Any and all updates cause the cache to clear
  1113. m_memoryCache.Clear();
  1114. // Send update to server, return the response without caching it
  1115. return WebUtil.PostToService(m_groupsServerURI, requestArgs);
  1116. }
  1117. // If we're not doing an update, we must be requesting data
  1118. // Create the cache key for the request and see if we have it cached
  1119. string CacheKey = WebUtil.BuildQueryString(requestArgs);
  1120. OSDMap response = null;
  1121. if (!m_memoryCache.TryGetValue(CacheKey, out response))
  1122. {
  1123. // if it wasn't in the cache, pass the request to the Simian Grid Services
  1124. response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
  1125. // and cache the response
  1126. m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
  1127. }
  1128. // return cached response
  1129. return response;
  1130. }
  1131. #endregion
  1132. }
  1133. }