XmlRpcGroupsServicesConnectorModule.cs 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021
  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.Reflection;
  31. using Nwc.XmlRpc;
  32. using log4net;
  33. using Mono.Addins;
  34. using Nini.Config;
  35. using OpenMetaverse;
  36. using OpenMetaverse.StructuredData;
  37. using OpenSim.Framework;
  38. using OpenSim.Region.Framework.Interfaces;
  39. namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
  40. {
  41. [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
  42. public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector
  43. {
  44. private static readonly ILog m_log =
  45. LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  46. public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome |
  47. GroupPowers.Accountable |
  48. GroupPowers.JoinChat |
  49. GroupPowers.AllowVoiceChat |
  50. GroupPowers.ReceiveNotices |
  51. GroupPowers.StartProposal |
  52. GroupPowers.VoteOnProposal;
  53. private bool m_connectorEnabled = false;
  54. private string m_serviceURL = string.Empty;
  55. private bool m_disableKeepAlive = false;
  56. private string m_groupReadKey = string.Empty;
  57. private string m_groupWriteKey = string.Empty;
  58. #region IRegionModuleBase Members
  59. public string Name
  60. {
  61. get { return "XmlRpcGroupsServicesConnector"; }
  62. }
  63. // this module is not intended to be replaced, but there should only be 1 of them.
  64. public Type ReplaceableInterface
  65. {
  66. get { return null; }
  67. }
  68. public void Initialise(IConfigSource config)
  69. {
  70. IConfig groupsConfig = config.Configs["Groups"];
  71. if (groupsConfig == null)
  72. {
  73. // Do not run this module by default.
  74. return;
  75. }
  76. else
  77. {
  78. // if groups aren't enabled, we're not needed.
  79. // if we're not specified as the connector to use, then we're not wanted
  80. if ((groupsConfig.GetBoolean("Enabled", false) == false)
  81. || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name))
  82. {
  83. m_connectorEnabled = false;
  84. return;
  85. }
  86. m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name);
  87. m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty);
  88. if ((m_serviceURL == null) ||
  89. (m_serviceURL == string.Empty))
  90. {
  91. m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]");
  92. m_connectorEnabled = false;
  93. return;
  94. }
  95. m_disableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false);
  96. m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty);
  97. m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty);
  98. // If we got all the config options we need, lets start'er'up
  99. m_connectorEnabled = true;
  100. }
  101. }
  102. public void Close()
  103. {
  104. m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name);
  105. }
  106. public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene)
  107. {
  108. if (m_connectorEnabled)
  109. scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
  110. }
  111. public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene)
  112. {
  113. if (scene.RequestModuleInterface<IGroupsServicesConnector>() == this)
  114. scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
  115. }
  116. public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene)
  117. {
  118. // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info
  119. // scene.EventManager.OnNewClient += OnNewClient;
  120. }
  121. #endregion
  122. #region ISharedRegionModule Members
  123. public void PostInitialise()
  124. {
  125. // NoOp
  126. }
  127. #endregion
  128. #region IGroupsServicesConnector Members
  129. /// <summary>
  130. /// 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.
  131. /// </summary>
  132. public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID,
  133. int membershipFee, bool openEnrollment, bool allowPublish,
  134. bool maturePublish, UUID founderID)
  135. {
  136. UUID GroupID = UUID.Random();
  137. UUID OwnerRoleID = UUID.Random();
  138. Hashtable param = new Hashtable();
  139. param["GroupID"] = GroupID.ToString();
  140. param["Name"] = name;
  141. param["Charter"] = charter;
  142. param["ShowInList"] = showInList == true ? 1 : 0;
  143. param["InsigniaID"] = insigniaID.ToString();
  144. param["MembershipFee"] = 0;
  145. param["OpenEnrollment"] = openEnrollment == true ? 1 : 0;
  146. param["AllowPublish"] = allowPublish == true ? 1 : 0;
  147. param["MaturePublish"] = maturePublish == true ? 1 : 0;
  148. param["FounderID"] = founderID.ToString();
  149. param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString();
  150. param["OwnerRoleID"] = OwnerRoleID.ToString();
  151. // Would this be cleaner as (GroupPowers)ulong.MaxValue;
  152. GroupPowers OwnerPowers = GroupPowers.Accountable
  153. | GroupPowers.AllowEditLand
  154. | GroupPowers.AllowFly
  155. | GroupPowers.AllowLandmark
  156. | GroupPowers.AllowRez
  157. | GroupPowers.AllowSetHome
  158. | GroupPowers.AllowVoiceChat
  159. | GroupPowers.AssignMember
  160. | GroupPowers.AssignMemberLimited
  161. | GroupPowers.ChangeActions
  162. | GroupPowers.ChangeIdentity
  163. | GroupPowers.ChangeMedia
  164. | GroupPowers.ChangeOptions
  165. | GroupPowers.CreateRole
  166. | GroupPowers.DeedObject
  167. | GroupPowers.DeleteRole
  168. | GroupPowers.Eject
  169. | GroupPowers.FindPlaces
  170. | GroupPowers.Invite
  171. | GroupPowers.JoinChat
  172. | GroupPowers.LandChangeIdentity
  173. | GroupPowers.LandDeed
  174. | GroupPowers.LandDivideJoin
  175. | GroupPowers.LandEdit
  176. | GroupPowers.LandEjectAndFreeze
  177. | GroupPowers.LandGardening
  178. | GroupPowers.LandManageAllowed
  179. | GroupPowers.LandManageBanned
  180. | GroupPowers.LandManagePasses
  181. | GroupPowers.LandOptions
  182. | GroupPowers.LandRelease
  183. | GroupPowers.LandSetSale
  184. | GroupPowers.ModerateChat
  185. | GroupPowers.ObjectManipulate
  186. | GroupPowers.ObjectSetForSale
  187. | GroupPowers.ReceiveNotices
  188. | GroupPowers.RemoveMember
  189. | GroupPowers.ReturnGroupOwned
  190. | GroupPowers.ReturnGroupSet
  191. | GroupPowers.ReturnNonGroup
  192. | GroupPowers.RoleProperties
  193. | GroupPowers.SendNotices
  194. | GroupPowers.SetLandingPoint
  195. | GroupPowers.StartProposal
  196. | GroupPowers.VoteOnProposal;
  197. param["OwnersPowers"] = ((ulong)OwnerPowers).ToString();
  198. Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param);
  199. if (respData.Contains("error"))
  200. {
  201. // UUID is not nullable
  202. return UUID.Zero;
  203. }
  204. return UUID.Parse((string)respData["GroupID"]);
  205. }
  206. public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList,
  207. UUID insigniaID, int membershipFee, bool openEnrollment,
  208. bool allowPublish, bool maturePublish)
  209. {
  210. Hashtable param = new Hashtable();
  211. param["GroupID"] = groupID.ToString();
  212. param["Charter"] = charter;
  213. param["ShowInList"] = showInList == true ? 1 : 0;
  214. param["InsigniaID"] = insigniaID.ToString();
  215. param["MembershipFee"] = membershipFee;
  216. param["OpenEnrollment"] = openEnrollment == true ? 1 : 0;
  217. param["AllowPublish"] = allowPublish == true ? 1 : 0;
  218. param["MaturePublish"] = maturePublish == true ? 1 : 0;
  219. XmlRpcCall(requestID, "groups.updateGroup", param);
  220. }
  221. public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description,
  222. string title, ulong powers)
  223. {
  224. Hashtable param = new Hashtable();
  225. param["GroupID"] = groupID.ToString();
  226. param["RoleID"] = roleID.ToString();
  227. param["Name"] = name;
  228. param["Description"] = description;
  229. param["Title"] = title;
  230. param["Powers"] = powers.ToString();
  231. XmlRpcCall(requestID, "groups.addRoleToGroup", param);
  232. }
  233. public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID)
  234. {
  235. Hashtable param = new Hashtable();
  236. param["GroupID"] = groupID.ToString();
  237. param["RoleID"] = roleID.ToString();
  238. XmlRpcCall(requestID, "groups.removeRoleFromGroup", param);
  239. }
  240. public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description,
  241. string title, ulong powers)
  242. {
  243. Hashtable param = new Hashtable();
  244. param["GroupID"] = groupID.ToString();
  245. param["RoleID"] = roleID.ToString();
  246. if (name != null)
  247. {
  248. param["Name"] = name;
  249. }
  250. if (description != null)
  251. {
  252. param["Description"] = description;
  253. }
  254. if (title != null)
  255. {
  256. param["Title"] = title;
  257. }
  258. param["Powers"] = powers.ToString();
  259. XmlRpcCall(requestID, "groups.updateGroupRole", param);
  260. }
  261. public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName)
  262. {
  263. Hashtable param = new Hashtable();
  264. if (GroupID != UUID.Zero)
  265. {
  266. param["GroupID"] = GroupID.ToString();
  267. }
  268. if ((GroupName != null) && (GroupName != string.Empty))
  269. {
  270. param["Name"] = GroupName.ToString();
  271. }
  272. Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param);
  273. if (respData.Contains("error"))
  274. {
  275. return null;
  276. }
  277. return GroupProfileHashtableToGroupRecord(respData);
  278. }
  279. public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID)
  280. {
  281. Hashtable param = new Hashtable();
  282. param["GroupID"] = GroupID.ToString();
  283. Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param);
  284. if (respData.Contains("error"))
  285. {
  286. // GroupProfileData is not nullable
  287. return new GroupProfileData();
  288. }
  289. GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID);
  290. GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData);
  291. MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle;
  292. MemberGroupProfile.PowersMask = MemberInfo.GroupPowers;
  293. return MemberGroupProfile;
  294. }
  295. public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID)
  296. {
  297. Hashtable param = new Hashtable();
  298. param["AgentID"] = AgentID.ToString();
  299. param["GroupID"] = GroupID.ToString();
  300. XmlRpcCall(requestID, "groups.setAgentActiveGroup", param);
  301. }
  302. public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID)
  303. {
  304. Hashtable param = new Hashtable();
  305. param["AgentID"] = AgentID.ToString();
  306. param["GroupID"] = GroupID.ToString();
  307. param["SelectedRoleID"] = RoleID.ToString();
  308. XmlRpcCall(requestID, "groups.setAgentGroupInfo", param);
  309. }
  310. public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
  311. {
  312. Hashtable param = new Hashtable();
  313. param["AgentID"] = AgentID.ToString();
  314. param["GroupID"] = GroupID.ToString();
  315. param["AcceptNotices"] = AcceptNotices ? "1" : "0";
  316. param["ListInProfile"] = ListInProfile ? "1" : "0";
  317. XmlRpcCall(requestID, "groups.setAgentGroupInfo", param);
  318. }
  319. public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID)
  320. {
  321. Hashtable param = new Hashtable();
  322. param["InviteID"] = inviteID.ToString();
  323. param["AgentID"] = agentID.ToString();
  324. param["RoleID"] = roleID.ToString();
  325. param["GroupID"] = groupID.ToString();
  326. XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param);
  327. }
  328. public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID)
  329. {
  330. Hashtable param = new Hashtable();
  331. param["InviteID"] = inviteID.ToString();
  332. Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param);
  333. if (respData.Contains("error"))
  334. {
  335. return null;
  336. }
  337. GroupInviteInfo inviteInfo = new GroupInviteInfo();
  338. inviteInfo.InviteID = inviteID;
  339. inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]);
  340. inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]);
  341. inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]);
  342. return inviteInfo;
  343. }
  344. public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID)
  345. {
  346. Hashtable param = new Hashtable();
  347. param["InviteID"] = inviteID.ToString();
  348. XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param);
  349. }
  350. public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID)
  351. {
  352. Hashtable param = new Hashtable();
  353. param["AgentID"] = AgentID.ToString();
  354. param["GroupID"] = GroupID.ToString();
  355. param["RoleID"] = RoleID.ToString();
  356. XmlRpcCall(requestID, "groups.addAgentToGroup", param);
  357. }
  358. public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID)
  359. {
  360. Hashtable param = new Hashtable();
  361. param["AgentID"] = AgentID.ToString();
  362. param["GroupID"] = GroupID.ToString();
  363. XmlRpcCall(requestID, "groups.removeAgentFromGroup", param);
  364. }
  365. public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID)
  366. {
  367. Hashtable param = new Hashtable();
  368. param["AgentID"] = AgentID.ToString();
  369. param["GroupID"] = GroupID.ToString();
  370. param["RoleID"] = RoleID.ToString();
  371. XmlRpcCall(requestID, "groups.addAgentToGroupRole", param);
  372. }
  373. public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID)
  374. {
  375. Hashtable param = new Hashtable();
  376. param["AgentID"] = AgentID.ToString();
  377. param["GroupID"] = GroupID.ToString();
  378. param["RoleID"] = RoleID.ToString();
  379. XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param);
  380. }
  381. public List<DirGroupsReplyData> FindGroups(GroupRequestID requestID, string search)
  382. {
  383. Hashtable param = new Hashtable();
  384. param["Search"] = search;
  385. Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param);
  386. List<DirGroupsReplyData> findings = new List<DirGroupsReplyData>();
  387. if (!respData.Contains("error"))
  388. {
  389. Hashtable results = (Hashtable)respData["results"];
  390. foreach (Hashtable groupFind in results.Values)
  391. {
  392. DirGroupsReplyData data = new DirGroupsReplyData();
  393. data.groupID = new UUID((string)groupFind["GroupID"]); ;
  394. data.groupName = (string)groupFind["Name"];
  395. data.members = int.Parse((string)groupFind["Members"]);
  396. // data.searchOrder = order;
  397. findings.Add(data);
  398. }
  399. }
  400. return findings;
  401. }
  402. public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID)
  403. {
  404. Hashtable param = new Hashtable();
  405. param["AgentID"] = AgentID.ToString();
  406. param["GroupID"] = GroupID.ToString();
  407. Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param);
  408. if (respData.Contains("error"))
  409. {
  410. return null;
  411. }
  412. GroupMembershipData data = HashTableToGroupMembershipData(respData);
  413. return data;
  414. }
  415. public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID)
  416. {
  417. Hashtable param = new Hashtable();
  418. param["AgentID"] = AgentID.ToString();
  419. Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param);
  420. if (respData.Contains("error"))
  421. {
  422. return null;
  423. }
  424. return HashTableToGroupMembershipData(respData);
  425. }
  426. public List<GroupMembershipData> GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID)
  427. {
  428. Hashtable param = new Hashtable();
  429. param["AgentID"] = AgentID.ToString();
  430. Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param);
  431. List<GroupMembershipData> memberships = new List<GroupMembershipData>();
  432. if (!respData.Contains("error"))
  433. {
  434. foreach (object membership in respData.Values)
  435. {
  436. memberships.Add(HashTableToGroupMembershipData((Hashtable)membership));
  437. }
  438. }
  439. return memberships;
  440. }
  441. public List<GroupRolesData> GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID)
  442. {
  443. Hashtable param = new Hashtable();
  444. param["AgentID"] = AgentID.ToString();
  445. param["GroupID"] = GroupID.ToString();
  446. Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param);
  447. List<GroupRolesData> Roles = new List<GroupRolesData>();
  448. if (respData.Contains("error"))
  449. {
  450. return Roles;
  451. }
  452. foreach (Hashtable role in respData.Values)
  453. {
  454. GroupRolesData data = new GroupRolesData();
  455. data.RoleID = new UUID((string)role["RoleID"]);
  456. data.Name = (string)role["Name"];
  457. data.Description = (string)role["Description"];
  458. data.Powers = ulong.Parse((string)role["Powers"]);
  459. data.Title = (string)role["Title"];
  460. Roles.Add(data);
  461. }
  462. return Roles;
  463. }
  464. public List<GroupRolesData> GetGroupRoles(GroupRequestID requestID, UUID GroupID)
  465. {
  466. Hashtable param = new Hashtable();
  467. param["GroupID"] = GroupID.ToString();
  468. Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param);
  469. List<GroupRolesData> Roles = new List<GroupRolesData>();
  470. if (respData.Contains("error"))
  471. {
  472. return Roles;
  473. }
  474. foreach (Hashtable role in respData.Values)
  475. {
  476. GroupRolesData data = new GroupRolesData();
  477. data.Description = (string)role["Description"];
  478. data.Members = int.Parse((string)role["Members"]);
  479. data.Name = (string)role["Name"];
  480. data.Powers = ulong.Parse((string)role["Powers"]);
  481. data.RoleID = new UUID((string)role["RoleID"]);
  482. data.Title = (string)role["Title"];
  483. Roles.Add(data);
  484. }
  485. return Roles;
  486. }
  487. public List<GroupMembersData> GetGroupMembers(GroupRequestID requestID, UUID GroupID)
  488. {
  489. Hashtable param = new Hashtable();
  490. param["GroupID"] = GroupID.ToString();
  491. Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param);
  492. List<GroupMembersData> members = new List<GroupMembersData>();
  493. if (respData.Contains("error"))
  494. {
  495. return members;
  496. }
  497. foreach (Hashtable membership in respData.Values)
  498. {
  499. GroupMembersData data = new GroupMembersData();
  500. data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1";
  501. data.AgentID = new UUID((string)membership["AgentID"]);
  502. data.Contribution = int.Parse((string)membership["Contribution"]);
  503. data.IsOwner = ((string)membership["IsOwner"]) == "1";
  504. data.ListInProfile = ((string)membership["ListInProfile"]) == "1";
  505. data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]);
  506. data.Title = (string)membership["Title"];
  507. members.Add(data);
  508. }
  509. return members;
  510. }
  511. public List<GroupRoleMembersData> GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID)
  512. {
  513. Hashtable param = new Hashtable();
  514. param["GroupID"] = GroupID.ToString();
  515. Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param);
  516. List<GroupRoleMembersData> members = new List<GroupRoleMembersData>();
  517. if (!respData.Contains("error"))
  518. {
  519. foreach (Hashtable membership in respData.Values)
  520. {
  521. GroupRoleMembersData data = new GroupRoleMembersData();
  522. data.MemberID = new UUID((string)membership["AgentID"]);
  523. data.RoleID = new UUID((string)membership["RoleID"]);
  524. members.Add(data);
  525. }
  526. }
  527. return members;
  528. }
  529. public List<GroupNoticeData> GetGroupNotices(GroupRequestID requestID, UUID GroupID)
  530. {
  531. Hashtable param = new Hashtable();
  532. param["GroupID"] = GroupID.ToString();
  533. Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param);
  534. List<GroupNoticeData> values = new List<GroupNoticeData>();
  535. if (!respData.Contains("error"))
  536. {
  537. foreach (Hashtable value in respData.Values)
  538. {
  539. GroupNoticeData data = new GroupNoticeData();
  540. data.NoticeID = UUID.Parse((string)value["NoticeID"]);
  541. data.Timestamp = uint.Parse((string)value["Timestamp"]);
  542. data.FromName = (string)value["FromName"];
  543. data.Subject = (string)value["Subject"];
  544. data.HasAttachment = false;
  545. data.AssetType = 0;
  546. values.Add(data);
  547. }
  548. }
  549. return values;
  550. }
  551. public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID)
  552. {
  553. Hashtable param = new Hashtable();
  554. param["NoticeID"] = noticeID.ToString();
  555. Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param);
  556. if (respData.Contains("error"))
  557. {
  558. return null;
  559. }
  560. GroupNoticeInfo data = new GroupNoticeInfo();
  561. data.GroupID = UUID.Parse((string)respData["GroupID"]);
  562. data.Message = (string)respData["Message"];
  563. data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true);
  564. data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]);
  565. data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]);
  566. data.noticeData.FromName = (string)respData["FromName"];
  567. data.noticeData.Subject = (string)respData["Subject"];
  568. data.noticeData.HasAttachment = false;
  569. data.noticeData.AssetType = 0;
  570. if (data.Message == null)
  571. {
  572. data.Message = string.Empty;
  573. }
  574. return data;
  575. }
  576. public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket)
  577. {
  578. string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, "");
  579. Hashtable param = new Hashtable();
  580. param["GroupID"] = groupID.ToString();
  581. param["NoticeID"] = noticeID.ToString();
  582. param["FromName"] = fromName;
  583. param["Subject"] = subject;
  584. param["Message"] = message;
  585. param["BinaryBucket"] = binBucket;
  586. param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString();
  587. XmlRpcCall(requestID, "groups.addGroupNotice", param);
  588. }
  589. #endregion
  590. #region XmlRpcHashtableMarshalling
  591. private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile)
  592. {
  593. GroupProfileData group = new GroupProfileData();
  594. group.GroupID = UUID.Parse((string)groupProfile["GroupID"]);
  595. group.Name = (string)groupProfile["Name"];
  596. if (groupProfile["Charter"] != null)
  597. {
  598. group.Charter = (string)groupProfile["Charter"];
  599. }
  600. group.ShowInList = ((string)groupProfile["ShowInList"]) == "1";
  601. group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]);
  602. group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]);
  603. group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1";
  604. group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1";
  605. group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1";
  606. group.FounderID = UUID.Parse((string)groupProfile["FounderID"]);
  607. group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]);
  608. group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]);
  609. group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]);
  610. return group;
  611. }
  612. private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile)
  613. {
  614. GroupRecord group = new GroupRecord();
  615. group.GroupID = UUID.Parse((string)groupProfile["GroupID"]);
  616. group.GroupName = groupProfile["Name"].ToString();
  617. if (groupProfile["Charter"] != null)
  618. {
  619. group.Charter = (string)groupProfile["Charter"];
  620. }
  621. group.ShowInList = ((string)groupProfile["ShowInList"]) == "1";
  622. group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]);
  623. group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]);
  624. group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1";
  625. group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1";
  626. group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1";
  627. group.FounderID = UUID.Parse((string)groupProfile["FounderID"]);
  628. group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]);
  629. return group;
  630. }
  631. private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData)
  632. {
  633. GroupMembershipData data = new GroupMembershipData();
  634. data.AcceptNotices = ((string)respData["AcceptNotices"] == "1");
  635. data.Contribution = int.Parse((string)respData["Contribution"]);
  636. data.ListInProfile = ((string)respData["ListInProfile"] == "1");
  637. data.ActiveRole = new UUID((string)respData["SelectedRoleID"]);
  638. data.GroupTitle = (string)respData["Title"];
  639. data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]);
  640. // Is this group the agent's active group
  641. data.GroupID = new UUID((string)respData["GroupID"]);
  642. UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]);
  643. data.Active = data.GroupID.Equals(ActiveGroup);
  644. data.AllowPublish = ((string)respData["AllowPublish"] == "1");
  645. if (respData["Charter"] != null)
  646. {
  647. data.Charter = (string)respData["Charter"];
  648. }
  649. data.FounderID = new UUID((string)respData["FounderID"]);
  650. data.GroupID = new UUID((string)respData["GroupID"]);
  651. data.GroupName = (string)respData["GroupName"];
  652. data.GroupPicture = new UUID((string)respData["InsigniaID"]);
  653. data.MaturePublish = ((string)respData["MaturePublish"] == "1");
  654. data.MembershipFee = int.Parse((string)respData["MembershipFee"]);
  655. data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1");
  656. data.ShowInList = ((string)respData["ShowInList"] == "1");
  657. return data;
  658. }
  659. #endregion
  660. /// <summary>
  661. /// Encapsulate the XmlRpc call to standardize security and error handling.
  662. /// </summary>
  663. private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param)
  664. {
  665. if (requestID == null)
  666. {
  667. requestID = new GroupRequestID();
  668. }
  669. param.Add("RequestingAgentID", requestID.AgentID.ToString());
  670. param.Add("RequestingAgentUserService", requestID.UserServiceURL);
  671. param.Add("RequestingSessionID", requestID.SessionID.ToString());
  672. param.Add("ReadKey", m_groupReadKey);
  673. param.Add("WriteKey", m_groupWriteKey);
  674. IList parameters = new ArrayList();
  675. parameters.Add(param);
  676. ConfigurableKeepAliveXmlRpcRequest req;
  677. req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive);
  678. XmlRpcResponse resp = null;
  679. try
  680. {
  681. resp = req.Send(m_serviceURL, 10000);
  682. }
  683. catch (Exception e)
  684. {
  685. m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function);
  686. m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString());
  687. foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None))
  688. {
  689. m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine);
  690. }
  691. foreach (string key in param.Keys)
  692. {
  693. m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString());
  694. }
  695. Hashtable respData = new Hashtable();
  696. respData.Add("error", e.ToString());
  697. return respData;
  698. }
  699. if (resp.Value is Hashtable)
  700. {
  701. Hashtable respData = (Hashtable)resp.Value;
  702. if (respData.Contains("error") && !respData.Contains("succeed"))
  703. {
  704. LogRespDataToConsoleError(respData);
  705. }
  706. return respData;
  707. }
  708. m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString());
  709. if (resp.Value is ArrayList)
  710. {
  711. ArrayList al = (ArrayList)resp.Value;
  712. m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count);
  713. foreach (object o in al)
  714. {
  715. m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString());
  716. }
  717. }
  718. else
  719. {
  720. m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString());
  721. }
  722. Hashtable error = new Hashtable();
  723. error.Add("error", "invalid return value");
  724. return error;
  725. }
  726. private void LogRespDataToConsoleError(Hashtable respData)
  727. {
  728. m_log.Error("[XMLRPCGROUPDATA]: Error:");
  729. foreach (string key in respData.Keys)
  730. {
  731. m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key);
  732. string[] lines = respData[key].ToString().Split(new char[] { '\n' });
  733. foreach (string line in lines)
  734. {
  735. m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line);
  736. }
  737. }
  738. }
  739. }
  740. public class GroupNoticeInfo
  741. {
  742. public GroupNoticeData noticeData = new GroupNoticeData();
  743. public UUID GroupID = UUID.Zero;
  744. public string Message = string.Empty;
  745. public byte[] BinaryBucket = new byte[0];
  746. }
  747. }
  748. namespace Nwc.XmlRpc
  749. {
  750. using System;
  751. using System.Collections;
  752. using System.IO;
  753. using System.Xml;
  754. using System.Net;
  755. using System.Text;
  756. using System.Reflection;
  757. /// <summary>Class supporting the request side of an XML-RPC transaction.</summary>
  758. public class ConfigurableKeepAliveXmlRpcRequest : XmlRpcRequest
  759. {
  760. private Encoding _encoding = new ASCIIEncoding();
  761. private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer();
  762. private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer();
  763. private bool _disableKeepAlive = true;
  764. public string RequestResponse = String.Empty;
  765. /// <summary>Instantiate an <c>XmlRpcRequest</c> for a specified method and parameters.</summary>
  766. /// <param name="methodName"><c>String</c> designating the <i>object.method</i> on the server the request
  767. /// should be directed to.</param>
  768. /// <param name="parameters"><c>ArrayList</c> of XML-RPC type parameters to invoke the request with.</param>
  769. public ConfigurableKeepAliveXmlRpcRequest(String methodName, IList parameters, bool disableKeepAlive)
  770. {
  771. MethodName = methodName;
  772. _params = parameters;
  773. _disableKeepAlive = disableKeepAlive;
  774. }
  775. /// <summary>Send the request to the server.</summary>
  776. /// <param name="url"><c>String</c> The url of the XML-RPC server.</param>
  777. /// <returns><c>XmlRpcResponse</c> The response generated.</returns>
  778. public XmlRpcResponse Send(String url)
  779. {
  780. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  781. if (request == null)
  782. throw new XmlRpcException(XmlRpcErrorCodes.TRANSPORT_ERROR,
  783. XmlRpcErrorCodes.TRANSPORT_ERROR_MSG + ": Could not create request with " + url);
  784. request.Method = "POST";
  785. request.ContentType = "text/xml";
  786. request.AllowWriteStreamBuffering = true;
  787. request.KeepAlive = !_disableKeepAlive;
  788. Stream stream = request.GetRequestStream();
  789. XmlTextWriter xml = new XmlTextWriter(stream, _encoding);
  790. _serializer.Serialize(xml, this);
  791. xml.Flush();
  792. xml.Close();
  793. HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  794. StreamReader input = new StreamReader(response.GetResponseStream());
  795. string inputXml = input.ReadToEnd();
  796. XmlRpcResponse resp;
  797. try
  798. {
  799. resp = (XmlRpcResponse)_deserializer.Deserialize(inputXml);
  800. }
  801. catch (Exception e)
  802. {
  803. RequestResponse = inputXml;
  804. throw e;
  805. }
  806. input.Close();
  807. response.Close();
  808. return resp;
  809. }
  810. }
  811. }