PageRenderTime 63ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/OpenMetaverse/Modules/GroupManager.cs

https://bitbucket.org/VirtualReality/3rdparty-addon-modules
C# | 2165 lines | 1300 code | 280 blank | 585 comment | 101 complexity | 07afd5a540832efd83ff1b997a820131 MD5 | raw file
  1. /*
  2. * Copyright (c) 2007-2009, openmetaverse.org
  3. * All rights reserved.
  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. *
  8. * - Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. * - Neither the name of the openmetaverse.org nor the names
  11. * of its contributors may be used to endorse or promote products derived from
  12. * this software without specific prior written permission.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  18. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  19. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  20. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  21. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  22. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  23. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24. * POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. using System;
  27. using System.Collections.Generic;
  28. using OpenMetaverse.Packets;
  29. using OpenMetaverse.StructuredData;
  30. using OpenMetaverse.Messages.Linden;
  31. using OpenMetaverse.Interfaces;
  32. namespace OpenMetaverse
  33. {
  34. #region Structs
  35. /// <summary>
  36. /// Avatar group management
  37. /// </summary>
  38. public struct GroupMember
  39. {
  40. /// <summary>Key of Group Member</summary>
  41. public UUID ID;
  42. /// <summary>Total land contribution</summary>
  43. public int Contribution;
  44. /// <summary>Online status information</summary>
  45. public string OnlineStatus;
  46. /// <summary>Abilities that the Group Member has</summary>
  47. public GroupPowers Powers;
  48. /// <summary>Current group title</summary>
  49. public string Title;
  50. /// <summary>Is a group owner</summary>
  51. public bool IsOwner;
  52. }
  53. /// <summary>
  54. /// Role manager for a group
  55. /// </summary>
  56. public struct GroupRole
  57. {
  58. /// <summary>Key of the group</summary>
  59. public UUID GroupID;
  60. /// <summary>Key of Role</summary>
  61. public UUID ID;
  62. /// <summary>Name of Role</summary>
  63. public string Name;
  64. /// <summary>Group Title associated with Role</summary>
  65. public string Title;
  66. /// <summary>Description of Role</summary>
  67. public string Description;
  68. /// <summary>Abilities Associated with Role</summary>
  69. public GroupPowers Powers;
  70. /// <summary>Returns the role's title</summary>
  71. /// <returns>The role's title</returns>
  72. public override string ToString()
  73. {
  74. return Name;
  75. }
  76. }
  77. /// <summary>
  78. /// Class to represent Group Title
  79. /// </summary>
  80. public struct GroupTitle
  81. {
  82. /// <summary>Key of the group</summary>
  83. public UUID GroupID;
  84. /// <summary>ID of the role title belongs to</summary>
  85. public UUID RoleID;
  86. /// <summary>Group Title</summary>
  87. public string Title;
  88. /// <summary>Whether title is Active</summary>
  89. public bool Selected;
  90. /// <summary>Returns group title</summary>
  91. public override string ToString()
  92. {
  93. return Title;
  94. }
  95. }
  96. /// <summary>
  97. /// Represents a group on the grid
  98. /// </summary>
  99. public struct Group
  100. {
  101. /// <summary>Key of Group</summary>
  102. public UUID ID;
  103. /// <summary>Key of Group Insignia</summary>
  104. public UUID InsigniaID;
  105. /// <summary>Key of Group Founder</summary>
  106. public UUID FounderID;
  107. /// <summary>Key of Group Role for Owners</summary>
  108. public UUID OwnerRole;
  109. /// <summary>Name of Group</summary>
  110. public string Name;
  111. /// <summary>Text of Group Charter</summary>
  112. public string Charter;
  113. /// <summary>Title of "everyone" role</summary>
  114. public string MemberTitle;
  115. /// <summary>Is the group open for enrolement to everyone</summary>
  116. public bool OpenEnrollment;
  117. /// <summary>Will group show up in search</summary>
  118. public bool ShowInList;
  119. /// <summary></summary>
  120. public GroupPowers Powers;
  121. /// <summary></summary>
  122. public bool AcceptNotices;
  123. /// <summary></summary>
  124. public bool AllowPublish;
  125. /// <summary>Is the group Mature</summary>
  126. public bool MaturePublish;
  127. /// <summary>Cost of group membership</summary>
  128. public int MembershipFee;
  129. /// <summary></summary>
  130. public int Money;
  131. /// <summary></summary>
  132. public int Contribution;
  133. /// <summary>The total number of current members this group has</summary>
  134. public int GroupMembershipCount;
  135. /// <summary>The number of roles this group has configured</summary>
  136. public int GroupRolesCount;
  137. /// <summary>Show this group in agent's profile</summary>
  138. public bool ListInProfile;
  139. /// <summary>Returns the name of the group</summary>
  140. /// <returns>A string containing the name of the group</returns>
  141. public override string ToString()
  142. {
  143. return Name;
  144. }
  145. }
  146. /// <summary>
  147. /// A group Vote
  148. /// </summary>
  149. public struct Vote
  150. {
  151. /// <summary>Key of Avatar who created Vote</summary>
  152. public UUID Candidate;
  153. /// <summary>Text of the Vote proposal</summary>
  154. public string VoteString;
  155. /// <summary>Total number of votes</summary>
  156. public int NumVotes;
  157. }
  158. /// <summary>
  159. /// A group proposal
  160. /// </summary>
  161. public struct GroupProposal
  162. {
  163. /// <summary>The Text of the proposal</summary>
  164. public string VoteText;
  165. /// <summary>The minimum number of members that must vote before proposal passes or failes</summary>
  166. public int Quorum;
  167. /// <summary>The required ration of yes/no votes required for vote to pass</summary>
  168. /// <remarks>The three options are Simple Majority, 2/3 Majority, and Unanimous</remarks>
  169. /// TODO: this should be an enum
  170. public float Majority;
  171. /// <summary>The duration in days votes are accepted</summary>
  172. public int Duration;
  173. }
  174. /// <summary>
  175. ///
  176. /// </summary>
  177. public struct GroupAccountSummary
  178. {
  179. /// <summary></summary>
  180. public int IntervalDays;
  181. /// <summary></summary>
  182. public int CurrentInterval;
  183. /// <summary></summary>
  184. public string StartDate;
  185. /// <summary></summary>
  186. public int Balance;
  187. /// <summary></summary>
  188. public int TotalCredits;
  189. /// <summary></summary>
  190. public int TotalDebits;
  191. /// <summary></summary>
  192. public int ObjectTaxCurrent;
  193. /// <summary></summary>
  194. public int LightTaxCurrent;
  195. /// <summary></summary>
  196. public int LandTaxCurrent;
  197. /// <summary></summary>
  198. public int GroupTaxCurrent;
  199. /// <summary></summary>
  200. public int ParcelDirFeeCurrent;
  201. /// <summary></summary>
  202. public int ObjectTaxEstimate;
  203. /// <summary></summary>
  204. public int LightTaxEstimate;
  205. /// <summary></summary>
  206. public int LandTaxEstimate;
  207. /// <summary></summary>
  208. public int GroupTaxEstimate;
  209. /// <summary></summary>
  210. public int ParcelDirFeeEstimate;
  211. /// <summary></summary>
  212. public int NonExemptMembers;
  213. /// <summary></summary>
  214. public string LastTaxDate;
  215. /// <summary></summary>
  216. public string TaxDate;
  217. }
  218. /// <summary>
  219. /// Struct representing a group notice
  220. /// </summary>
  221. public struct GroupNotice
  222. {
  223. /// <summary></summary>
  224. public string Subject;
  225. /// <summary></summary>
  226. public string Message;
  227. /// <summary></summary>
  228. public UUID AttachmentID;
  229. /// <summary></summary>
  230. public UUID OwnerID;
  231. /// <summary>
  232. ///
  233. /// </summary>
  234. /// <returns></returns>
  235. public byte[] SerializeAttachment()
  236. {
  237. if (OwnerID == UUID.Zero || AttachmentID == UUID.Zero)
  238. return Utils.EmptyBytes;
  239. OpenMetaverse.StructuredData.OSDMap att = new OpenMetaverse.StructuredData.OSDMap();
  240. att.Add("item_id", OpenMetaverse.StructuredData.OSD.FromUUID(AttachmentID));
  241. att.Add("owner_id", OpenMetaverse.StructuredData.OSD.FromUUID(OwnerID));
  242. return OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlBytes(att);
  243. /*
  244. //I guess this is how this works, no gaurentees
  245. string lsd = "<llsd><item_id>" + AttachmentID.ToString() + "</item_id><owner_id>"
  246. + OwnerID.ToString() + "</owner_id></llsd>";
  247. return Utils.StringToBytes(lsd);
  248. */
  249. }
  250. }
  251. /// <summary>
  252. /// Struct representing a group notice list entry
  253. /// </summary>
  254. public struct GroupNoticesListEntry
  255. {
  256. /// <summary>Notice ID</summary>
  257. public UUID NoticeID;
  258. /// <summary>Creation timestamp of notice</summary>
  259. public uint Timestamp;
  260. /// <summary>Agent name who created notice</summary>
  261. public string FromName;
  262. /// <summary>Notice subject</summary>
  263. public string Subject;
  264. /// <summary>Is there an attachment?</summary>
  265. public bool HasAttachment;
  266. /// <summary>Attachment Type</summary>
  267. public AssetType AssetType;
  268. }
  269. /// <summary>
  270. /// Struct representing a member of a group chat session and their settings
  271. /// </summary>
  272. public struct ChatSessionMember
  273. {
  274. /// <summary>The <see cref="UUID"/> of the Avatar</summary>
  275. public UUID AvatarKey;
  276. /// <summary>True if user has voice chat enabled</summary>
  277. public bool CanVoiceChat;
  278. /// <summary>True of Avatar has moderator abilities</summary>
  279. public bool IsModerator;
  280. /// <summary>True if a moderator has muted this avatars chat</summary>
  281. public bool MuteText;
  282. /// <summary>True if a moderator has muted this avatars voice</summary>
  283. public bool MuteVoice;
  284. }
  285. #endregion Structs
  286. #region Enums
  287. /// <summary>
  288. /// Role update flags
  289. /// </summary>
  290. public enum GroupRoleUpdate : uint
  291. {
  292. /// <summary></summary>
  293. NoUpdate,
  294. /// <summary></summary>
  295. UpdateData,
  296. /// <summary></summary>
  297. UpdatePowers,
  298. /// <summary></summary>
  299. UpdateAll,
  300. /// <summary></summary>
  301. Create,
  302. /// <summary></summary>
  303. Delete
  304. }
  305. [Flags]
  306. public enum GroupPowers : ulong
  307. {
  308. /// <summary></summary>
  309. None = 0,
  310. // Membership
  311. /// <summary>Can send invitations to groups default role</summary>
  312. Invite = 1UL << 1,
  313. /// <summary>Can eject members from group</summary>
  314. Eject = 1UL << 2,
  315. /// <summary>Can toggle 'Open Enrollment' and change 'Signup fee'</summary>
  316. ChangeOptions = 1UL << 3,
  317. /// <summary>Member is visible in the public member list</summary>
  318. MemberVisible = 1UL << 47,
  319. // Roles
  320. /// <summary>Can create new roles</summary>
  321. CreateRole = 1UL << 4,
  322. /// <summary>Can delete existing roles</summary>
  323. DeleteRole = 1UL << 5,
  324. /// <summary>Can change Role names, titles and descriptions</summary>
  325. RoleProperties = 1UL << 6,
  326. /// <summary>Can assign other members to assigners role</summary>
  327. AssignMemberLimited = 1UL << 7,
  328. /// <summary>Can assign other members to any role</summary>
  329. AssignMember = 1UL << 8,
  330. /// <summary>Can remove members from roles</summary>
  331. RemoveMember = 1UL << 9,
  332. /// <summary>Can assign and remove abilities in roles</summary>
  333. ChangeActions = 1UL << 10,
  334. // Identity
  335. /// <summary>Can change group Charter, Insignia, 'Publish on the web' and which
  336. /// members are publicly visible in group member listings</summary>
  337. ChangeIdentity = 1UL << 11,
  338. // Parcel management
  339. /// <summary>Can buy land or deed land to group</summary>
  340. LandDeed = 1UL << 12,
  341. /// <summary>Can abandon group owned land to Governor Linden on mainland, or Estate owner for
  342. /// private estates</summary>
  343. LandRelease = 1UL << 13,
  344. /// <summary>Can set land for-sale information on group owned parcels</summary>
  345. LandSetSale = 1UL << 14,
  346. /// <summary>Can subdivide and join parcels</summary>
  347. LandDivideJoin = 1UL << 15,
  348. // Chat
  349. /// <summary>Can join group chat sessions</summary>
  350. JoinChat = 1UL << 16,
  351. /// <summary>Can use voice chat in Group Chat sessions</summary>
  352. AllowVoiceChat = 1UL << 27,
  353. /// <summary>Can moderate group chat sessions</summary>
  354. ModerateChat = 1UL << 37,
  355. // Parcel identity
  356. /// <summary>Can toggle "Show in Find Places" and set search category</summary>
  357. FindPlaces = 1UL << 17,
  358. /// <summary>Can change parcel name, description, and 'Publish on web' settings</summary>
  359. LandChangeIdentity = 1UL << 18,
  360. /// <summary>Can set the landing point and teleport routing on group land</summary>
  361. SetLandingPoint = 1UL << 19,
  362. // Parcel settings
  363. /// <summary>Can change music and media settings</summary>
  364. ChangeMedia = 1UL << 20,
  365. /// <summary>Can toggle 'Edit Terrain' option in Land settings</summary>
  366. LandEdit = 1UL << 21,
  367. /// <summary>Can toggle various About Land > Options settings</summary>
  368. LandOptions = 1UL << 22,
  369. // Parcel powers
  370. /// <summary>Can always terraform land, even if parcel settings have it turned off</summary>
  371. AllowEditLand = 1UL << 23,
  372. /// <summary>Can always fly while over group owned land</summary>
  373. AllowFly = 1UL << 24,
  374. /// <summary>Can always rez objects on group owned land</summary>
  375. AllowRez = 1UL << 25,
  376. /// <summary>Can always create landmarks for group owned parcels</summary>
  377. AllowLandmark = 1UL << 26,
  378. /// <summary>Can set home location on any group owned parcel</summary>
  379. AllowSetHome = 1UL << 28,
  380. // Parcel access
  381. /// <summary>Can modify public access settings for group owned parcels</summary>
  382. LandManageAllowed = 1UL << 29,
  383. /// <summary>Can manager parcel ban lists on group owned land</summary>
  384. LandManageBanned = 1UL << 30,
  385. /// <summary>Can manage pass list sales information</summary>
  386. LandManagePasses = 1UL << 31,
  387. /// <summary>Can eject and freeze other avatars on group owned land</summary>
  388. LandEjectAndFreeze = 1UL << 32,
  389. // Parcel content
  390. /// <summary>Can return objects set to group</summary>
  391. ReturnGroupSet = 1UL << 33,
  392. /// <summary>Can return non-group owned/set objects</summary>
  393. ReturnNonGroup = 1UL << 34,
  394. /// <summary>Can return group owned objects</summary>
  395. ReturnGroupOwned = 1UL << 48,
  396. /// <summary>Can landscape using Linden plants</summary>
  397. LandGardening = 1UL << 35,
  398. // Objects
  399. /// <summary>Can deed objects to group</summary>
  400. DeedObject = 1UL << 36,
  401. /// <summary>Can move group owned objects</summary>
  402. ObjectManipulate = 1UL << 38,
  403. /// <summary>Can set group owned objects for-sale</summary>
  404. ObjectSetForSale = 1UL << 39,
  405. /// <summary>Pay group liabilities and receive group dividends</summary>
  406. Accountable = 1UL << 40,
  407. /// <summary>List and Host group events</summary>
  408. HostEvent = 1UL << 41,
  409. // Notices and proposals
  410. /// <summary>Can send group notices</summary>
  411. SendNotices = 1UL << 42,
  412. /// <summary>Can receive group notices</summary>
  413. ReceiveNotices = 1UL << 43,
  414. /// <summary>Can create group proposals</summary>
  415. StartProposal = 1UL << 44,
  416. /// <summary>Can vote on group proposals</summary>
  417. VoteOnProposal = 1UL << 45
  418. }
  419. #endregion Enums
  420. /// <summary>
  421. /// Handles all network traffic related to reading and writing group
  422. /// information
  423. /// </summary>
  424. public class GroupManager
  425. {
  426. #region Delegates
  427. /// <summary>The event subscribers. null if no subcribers</summary>
  428. private EventHandler<CurrentGroupsEventArgs> m_CurrentGroups;
  429. /// <summary>Raises the CurrentGroups event</summary>
  430. /// <param name="e">A CurrentGroupsEventArgs object containing the
  431. /// data sent from the simulator</param>
  432. protected virtual void OnCurrentGroups(CurrentGroupsEventArgs e)
  433. {
  434. EventHandler<CurrentGroupsEventArgs> handler = m_CurrentGroups;
  435. if (handler != null)
  436. handler(this, e);
  437. }
  438. /// <summary>Thread sync lock object</summary>
  439. private readonly object m_CurrentGroupsLock = new object();
  440. /// <summary>Raised when the simulator sends us data containing
  441. /// our current group membership</summary>
  442. public event EventHandler<CurrentGroupsEventArgs> CurrentGroups
  443. {
  444. add { lock (m_CurrentGroupsLock) { m_CurrentGroups += value; } }
  445. remove { lock (m_CurrentGroupsLock) { m_CurrentGroups -= value; } }
  446. }
  447. /// <summary>The event subscribers. null if no subcribers</summary>
  448. private EventHandler<GroupNamesEventArgs> m_GroupNames;
  449. /// <summary>Raises the GroupNamesReply event</summary>
  450. /// <param name="e">A GroupNamesEventArgs object containing the
  451. /// data response from the simulator</param>
  452. protected virtual void OnGroupNamesReply(GroupNamesEventArgs e)
  453. {
  454. EventHandler<GroupNamesEventArgs> handler = m_GroupNames;
  455. if (handler != null)
  456. handler(this, e);
  457. }
  458. /// <summary>Thread sync lock object</summary>
  459. private readonly object m_GroupNamesLock = new object();
  460. /// <summary>Raised when the simulator responds to a RequestGroupName
  461. /// or RequestGroupNames request</summary>
  462. public event EventHandler<GroupNamesEventArgs> GroupNamesReply
  463. {
  464. add { lock (m_GroupNamesLock) { m_GroupNames += value; } }
  465. remove { lock (m_GroupNamesLock) { m_GroupNames -= value; } }
  466. }
  467. /// <summary>The event subscribers. null if no subcribers</summary>
  468. private EventHandler<GroupProfileEventArgs> m_GroupProfile;
  469. /// <summary>Raises the GroupProfile event</summary>
  470. /// <param name="e">An GroupProfileEventArgs object containing the
  471. /// data returned from the simulator</param>
  472. protected virtual void OnGroupProfile(GroupProfileEventArgs e)
  473. {
  474. EventHandler<GroupProfileEventArgs> handler = m_GroupProfile;
  475. if (handler != null)
  476. handler(this, e);
  477. }
  478. /// <summary>Thread sync lock object</summary>
  479. private readonly object m_GroupProfileLock = new object();
  480. /// <summary>Raised when the simulator responds to a <see cref="RequestGroupProfile"/> request</summary>
  481. public event EventHandler<GroupProfileEventArgs> GroupProfile
  482. {
  483. add { lock (m_GroupProfileLock) { m_GroupProfile += value; } }
  484. remove { lock (m_GroupProfileLock) { m_GroupProfile -= value; } }
  485. }
  486. /// <summary>The event subscribers. null if no subcribers</summary>
  487. private EventHandler<GroupMembersReplyEventArgs> m_GroupMembers;
  488. /// <summary>Raises the GroupMembers event</summary>
  489. /// <param name="e">A GroupMembersEventArgs object containing the
  490. /// data returned from the simulator</param>
  491. protected virtual void OnGroupMembersReply(GroupMembersReplyEventArgs e)
  492. {
  493. EventHandler<GroupMembersReplyEventArgs> handler = m_GroupMembers;
  494. if (handler != null)
  495. handler(this, e);
  496. }
  497. /// <summary>Thread sync lock object</summary>
  498. private readonly object m_GroupMembersLock = new object();
  499. /// <summary>Raised when the simulator responds to a <see cref="RequestGroupMembers"/> request</summary>
  500. public event EventHandler<GroupMembersReplyEventArgs> GroupMembersReply
  501. {
  502. add { lock (m_GroupMembersLock) { m_GroupMembers += value; } }
  503. remove { lock (m_GroupMembersLock) { m_GroupMembers -= value; } }
  504. }
  505. /// <summary>The event subscribers. null if no subcribers</summary>
  506. private EventHandler<GroupRolesDataReplyEventArgs> m_GroupRoles;
  507. /// <summary>Raises the GroupRolesDataReply event</summary>
  508. /// <param name="e">A GroupRolesDataReplyEventArgs object containing the
  509. /// data returned from the simulator</param>
  510. protected virtual void OnGroupRoleDataReply(GroupRolesDataReplyEventArgs e)
  511. {
  512. EventHandler<GroupRolesDataReplyEventArgs> handler = m_GroupRoles;
  513. if (handler != null)
  514. handler(this, e);
  515. }
  516. /// <summary>Thread sync lock object</summary>
  517. private readonly object m_GroupRolesLock = new object();
  518. /// <summary>Raised when the simulator responds to a <see cref="RequestGroupRoleData"/> request</summary>
  519. public event EventHandler<GroupRolesDataReplyEventArgs> GroupRoleDataReply
  520. {
  521. add { lock (m_GroupRolesLock) { m_GroupRoles += value; } }
  522. remove { lock (m_GroupRolesLock) { m_GroupRoles -= value; } }
  523. }
  524. /// <summary>The event subscribers. null if no subcribers</summary>
  525. private EventHandler<GroupRolesMembersReplyEventArgs> m_GroupRoleMembers;
  526. /// <summary>Raises the GroupRoleMembersReply event</summary>
  527. /// <param name="e">A GroupRolesRoleMembersReplyEventArgs object containing the
  528. /// data returned from the simulator</param>
  529. protected virtual void OnGroupRoleMembers(GroupRolesMembersReplyEventArgs e)
  530. {
  531. EventHandler<GroupRolesMembersReplyEventArgs> handler = m_GroupRoleMembers;
  532. if (handler != null)
  533. handler(this, e);
  534. }
  535. /// <summary>Thread sync lock object</summary>
  536. private readonly object m_GroupRolesMembersLock = new object();
  537. /// <summary>Raised when the simulator responds to a <see cref="RequestGroupRolesMembers"/> request</summary>
  538. public event EventHandler<GroupRolesMembersReplyEventArgs> GroupRoleMembersReply
  539. {
  540. add { lock (m_GroupRolesMembersLock) { m_GroupRoleMembers += value; } }
  541. remove { lock (m_GroupRolesMembersLock) { m_GroupRoleMembers -= value; } }
  542. }
  543. /// <summary>The event subscribers. null if no subcribers</summary>
  544. private EventHandler<GroupTitlesReplyEventArgs> m_GroupTitles;
  545. /// <summary>Raises the GroupTitlesReply event</summary>
  546. /// <param name="e">A GroupTitlesReplyEventArgs object containing the
  547. /// data returned from the simulator</param>
  548. protected virtual void OnGroupTitles(GroupTitlesReplyEventArgs e)
  549. {
  550. EventHandler<GroupTitlesReplyEventArgs> handler = m_GroupTitles;
  551. if (handler != null)
  552. handler(this, e);
  553. }
  554. /// <summary>Thread sync lock object</summary>
  555. private readonly object m_GroupTitlesLock = new object();
  556. /// <summary>Raised when the simulator responds to a <see cref="RequestGroupTitles"/> request</summary>
  557. public event EventHandler<GroupTitlesReplyEventArgs> GroupTitlesReply
  558. {
  559. add { lock (m_GroupTitlesLock) { m_GroupTitles += value; } }
  560. remove { lock (m_GroupTitlesLock) { m_GroupTitles -= value; } }
  561. }
  562. /// <summary>The event subscribers. null if no subcribers</summary>
  563. private EventHandler<GroupAccountSummaryReplyEventArgs> m_GroupAccountSummary;
  564. /// <summary>Raises the GroupAccountSummary event</summary>
  565. /// <param name="e">A GroupAccountSummaryReplyEventArgs object containing the
  566. /// data returned from the simulator</param>
  567. protected virtual void OnGroupAccountSummaryReply(GroupAccountSummaryReplyEventArgs e)
  568. {
  569. EventHandler<GroupAccountSummaryReplyEventArgs> handler = m_GroupAccountSummary;
  570. if (handler != null)
  571. handler(this, e);
  572. }
  573. /// <summary>Thread sync lock object</summary>
  574. private readonly object m_GroupAccountSummaryLock = new object();
  575. /// <summary>Raised when a response to a RequestGroupAccountSummary is returned
  576. /// by the simulator</summary>
  577. public event EventHandler<GroupAccountSummaryReplyEventArgs> GroupAccountSummaryReply
  578. {
  579. add { lock (m_GroupAccountSummaryLock) { m_GroupAccountSummary += value; } }
  580. remove { lock (m_GroupAccountSummaryLock) { m_GroupAccountSummary -= value; } }
  581. }
  582. /// <summary>The event subscribers. null if no subcribers</summary>
  583. private EventHandler<GroupCreatedReplyEventArgs> m_GroupCreated;
  584. /// <summary>Raises the GroupCreated event</summary>
  585. /// <param name="e">An GroupCreatedEventArgs object containing the
  586. /// data returned from the simulator</param>
  587. protected virtual void OnGroupCreatedReply(GroupCreatedReplyEventArgs e)
  588. {
  589. EventHandler<GroupCreatedReplyEventArgs> handler = m_GroupCreated;
  590. if (handler != null)
  591. handler(this, e);
  592. }
  593. /// <summary>Thread sync lock object</summary>
  594. private readonly object m_GroupCreatedLock = new object();
  595. /// <summary>Raised when a request to create a group is successful</summary>
  596. public event EventHandler<GroupCreatedReplyEventArgs> GroupCreatedReply
  597. {
  598. add { lock (m_GroupCreatedLock) { m_GroupCreated += value; } }
  599. remove { lock (m_GroupCreatedLock) { m_GroupCreated -= value; } }
  600. }
  601. /// <summary>The event subscribers. null if no subcribers</summary>
  602. private EventHandler<GroupOperationEventArgs> m_GroupJoined;
  603. /// <summary>Raises the GroupJoined event</summary>
  604. /// <param name="e">A GroupOperationEventArgs object containing the
  605. /// result of the operation returned from the simulator</param>
  606. protected virtual void OnGroupJoinedReply(GroupOperationEventArgs e)
  607. {
  608. EventHandler<GroupOperationEventArgs> handler = m_GroupJoined;
  609. if (handler != null)
  610. handler(this, e);
  611. }
  612. /// <summary>Thread sync lock object</summary>
  613. private readonly object m_GroupJoinedLock = new object();
  614. /// <summary>Raised when a request to join a group either
  615. /// fails or succeeds</summary>
  616. public event EventHandler<GroupOperationEventArgs> GroupJoinedReply
  617. {
  618. add { lock (m_GroupJoinedLock) { m_GroupJoined += value; } }
  619. remove { lock (m_GroupJoinedLock) { m_GroupJoined -= value; } }
  620. }
  621. /// <summary>The event subscribers. null if no subcribers</summary>
  622. private EventHandler<GroupOperationEventArgs> m_GroupLeft;
  623. /// <summary>Raises the GroupLeft event</summary>
  624. /// <param name="e">A GroupOperationEventArgs object containing the
  625. /// result of the operation returned from the simulator</param>
  626. protected virtual void OnGroupLeaveReply(GroupOperationEventArgs e)
  627. {
  628. EventHandler<GroupOperationEventArgs> handler = m_GroupLeft;
  629. if (handler != null)
  630. handler(this, e);
  631. }
  632. /// <summary>Thread sync lock object</summary>
  633. private readonly object m_GroupLeftLock = new object();
  634. /// <summary>Raised when a request to leave a group either
  635. /// fails or succeeds</summary>
  636. public event EventHandler<GroupOperationEventArgs> GroupLeaveReply
  637. {
  638. add { lock (m_GroupLeftLock) { m_GroupLeft += value; } }
  639. remove { lock (m_GroupLeftLock) { m_GroupLeft -= value; } }
  640. }
  641. /// <summary>The event subscribers. null if no subcribers</summary>
  642. private EventHandler<GroupDroppedEventArgs> m_GroupDropped;
  643. /// <summary>Raises the GroupDropped event</summary>
  644. /// <param name="e">An GroupDroppedEventArgs object containing the
  645. /// the group your agent left</param>
  646. protected virtual void OnGroupDropped(GroupDroppedEventArgs e)
  647. {
  648. EventHandler<GroupDroppedEventArgs> handler = m_GroupDropped;
  649. if (handler != null)
  650. handler(this, e);
  651. }
  652. /// <summary>Thread sync lock object</summary>
  653. private readonly object m_GroupDroppedLock = new object();
  654. /// <summary>Raised when A group is removed from the group server</summary>
  655. public event EventHandler<GroupDroppedEventArgs> GroupDropped
  656. {
  657. add { lock (m_GroupDroppedLock) { m_GroupDropped += value; } }
  658. remove { lock (m_GroupDroppedLock) { m_GroupDropped -= value; } }
  659. }
  660. /// <summary>The event subscribers. null if no subcribers</summary>
  661. private EventHandler<GroupOperationEventArgs> m_GroupMemberEjected;
  662. /// <summary>Raises the GroupMemberEjected event</summary>
  663. /// <param name="e">An GroupMemberEjectedEventArgs object containing the
  664. /// data returned from the simulator</param>
  665. protected virtual void OnGroupMemberEjected(GroupOperationEventArgs e)
  666. {
  667. EventHandler<GroupOperationEventArgs> handler = m_GroupMemberEjected;
  668. if (handler != null)
  669. handler(this, e);
  670. }
  671. /// <summary>Thread sync lock object</summary>
  672. private readonly object m_GroupMemberEjectedLock = new object();
  673. /// <summary>Raised when a request to eject a member from a group either
  674. /// fails or succeeds</summary>
  675. public event EventHandler<GroupOperationEventArgs> GroupMemberEjected
  676. {
  677. add { lock (m_GroupMemberEjectedLock) { m_GroupMemberEjected += value; } }
  678. remove { lock (m_GroupMemberEjectedLock) { m_GroupMemberEjected -= value; } }
  679. }
  680. /// <summary>The event subscribers. null if no subcribers</summary>
  681. private EventHandler<GroupNoticesListReplyEventArgs> m_GroupNoticesListReply;
  682. /// <summary>Raises the GroupNoticesListReply event</summary>
  683. /// <param name="e">An GroupNoticesListReplyEventArgs object containing the
  684. /// data returned from the simulator</param>
  685. protected virtual void OnGroupNoticesListReply(GroupNoticesListReplyEventArgs e)
  686. {
  687. EventHandler<GroupNoticesListReplyEventArgs> handler = m_GroupNoticesListReply;
  688. if (handler != null)
  689. handler(this, e);
  690. }
  691. /// <summary>Thread sync lock object</summary>
  692. private readonly object m_GroupNoticesListReplyLock = new object();
  693. /// <summary>Raised when the simulator sends us group notices</summary>
  694. /// <seealso cref="RequestGroupNoticesList"/>
  695. public event EventHandler<GroupNoticesListReplyEventArgs> GroupNoticesListReply
  696. {
  697. add { lock (m_GroupNoticesListReplyLock) { m_GroupNoticesListReply += value; } }
  698. remove { lock (m_GroupNoticesListReplyLock) { m_GroupNoticesListReply -= value; } }
  699. }
  700. /// <summary>The event subscribers. null if no subcribers</summary>
  701. private EventHandler<GroupInvitationEventArgs> m_GroupInvitation;
  702. /// <summary>Raises the GroupInvitation event</summary>
  703. /// <param name="e">An GroupInvitationEventArgs object containing the
  704. /// data returned from the simulator</param>
  705. protected virtual void OnGroupInvitation(GroupInvitationEventArgs e)
  706. {
  707. EventHandler<GroupInvitationEventArgs> handler = m_GroupInvitation;
  708. if (handler != null)
  709. handler(this, e);
  710. }
  711. /// <summary>Thread sync lock object</summary>
  712. private readonly object m_GroupInvitationLock = new object();
  713. /// <summary>Raised when another agent invites our avatar to join a group</summary>
  714. public event EventHandler<GroupInvitationEventArgs> GroupInvitation
  715. {
  716. add { lock (m_GroupInvitationLock) { m_GroupInvitation += value; } }
  717. remove { lock (m_GroupInvitationLock) { m_GroupInvitation -= value; } }
  718. }
  719. #endregion Delegates
  720. #region Events
  721. #endregion Events
  722. /// <summary>A reference to the current <seealso cref="GridClient"/> instance</summary>
  723. private GridClient Client;
  724. /// <summary>Currently-active group members requests</summary>
  725. private List<UUID> GroupMembersRequests;
  726. /// <summary>Currently-active group roles requests</summary>
  727. private List<UUID> GroupRolesRequests;
  728. /// <summary>Currently-active group role-member requests</summary>
  729. private List<UUID> GroupRolesMembersRequests;
  730. /// <summary>Dictionary keeping group members while request is in progress</summary>
  731. private InternalDictionary<UUID, Dictionary<UUID, GroupMember>> TempGroupMembers;
  732. /// <summary>Dictionary keeping mebmer/role mapping while request is in progress</summary>
  733. private InternalDictionary<UUID, List<KeyValuePair<UUID, UUID>>> TempGroupRolesMembers;
  734. /// <summary>Dictionary keeping GroupRole information while request is in progress</summary>
  735. private InternalDictionary<UUID, Dictionary<UUID, GroupRole>> TempGroupRoles;
  736. /// <summary>Caches group name lookups</summary>
  737. public InternalDictionary<UUID, string> GroupName2KeyCache;
  738. /// <summary>
  739. /// Construct a new instance of the GroupManager class
  740. /// </summary>
  741. /// <param name="client">A reference to the current <seealso cref="GridClient"/> instance</param>
  742. public GroupManager(GridClient client)
  743. {
  744. Client = client;
  745. TempGroupMembers = new InternalDictionary<UUID, Dictionary<UUID, GroupMember>>();
  746. GroupMembersRequests = new List<UUID>();
  747. TempGroupRoles = new InternalDictionary<UUID, Dictionary<UUID, GroupRole>>();
  748. GroupRolesRequests = new List<UUID>();
  749. TempGroupRolesMembers = new InternalDictionary<UUID, List<KeyValuePair<UUID, UUID>>>();
  750. GroupRolesMembersRequests = new List<UUID>();
  751. GroupName2KeyCache = new InternalDictionary<UUID, string>();
  752. Client.Self.IM += Self_IM;
  753. Client.Network.RegisterEventCallback("AgentGroupDataUpdate", new Caps.EventQueueCallback(AgentGroupDataUpdateMessageHandler));
  754. // deprecated in simulator v1.27
  755. Client.Network.RegisterCallback(PacketType.AgentDropGroup, AgentDropGroupHandler);
  756. Client.Network.RegisterCallback(PacketType.GroupTitlesReply, GroupTitlesReplyHandler);
  757. Client.Network.RegisterCallback(PacketType.GroupProfileReply, GroupProfileReplyHandler);
  758. Client.Network.RegisterCallback(PacketType.GroupMembersReply, GroupMembersHandler);
  759. Client.Network.RegisterCallback(PacketType.GroupRoleDataReply, GroupRoleDataReplyHandler);
  760. Client.Network.RegisterCallback(PacketType.GroupRoleMembersReply, GroupRoleMembersReplyHandler);
  761. Client.Network.RegisterCallback(PacketType.GroupActiveProposalItemReply, GroupActiveProposalItemHandler);
  762. Client.Network.RegisterCallback(PacketType.GroupVoteHistoryItemReply, GroupVoteHistoryItemHandler);
  763. Client.Network.RegisterCallback(PacketType.GroupAccountSummaryReply, GroupAccountSummaryReplyHandler);
  764. Client.Network.RegisterCallback(PacketType.CreateGroupReply, CreateGroupReplyHandler);
  765. Client.Network.RegisterCallback(PacketType.JoinGroupReply, JoinGroupReplyHandler);
  766. Client.Network.RegisterCallback(PacketType.LeaveGroupReply, LeaveGroupReplyHandler);
  767. Client.Network.RegisterCallback(PacketType.UUIDGroupNameReply, UUIDGroupNameReplyHandler);
  768. Client.Network.RegisterCallback(PacketType.EjectGroupMemberReply, EjectGroupMemberReplyHandler);
  769. Client.Network.RegisterCallback(PacketType.GroupNoticesListReply, GroupNoticesListReplyHandler);
  770. Client.Network.RegisterEventCallback("AgentDropGroup", new Caps.EventQueueCallback(AgentDropGroupMessageHandler));
  771. }
  772. void Self_IM(object sender, InstantMessageEventArgs e)
  773. {
  774. if(m_GroupInvitation != null && e.IM.Dialog == InstantMessageDialog.GroupInvitation)
  775. {
  776. GroupInvitationEventArgs args = new GroupInvitationEventArgs(e.Simulator, e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);
  777. OnGroupInvitation(args);
  778. if (args.Accept)
  779. {
  780. Client.Self.InstantMessage("name", e.IM.FromAgentID, "message", e.IM.IMSessionID, InstantMessageDialog.GroupInvitationAccept,
  781. InstantMessageOnline.Online, Client.Self.SimPosition, UUID.Zero, Utils.EmptyBytes);
  782. }
  783. else
  784. {
  785. Client.Self.InstantMessage("name", e.IM.FromAgentID, "message", e.IM.IMSessionID, InstantMessageDialog.GroupInvitationDecline,
  786. InstantMessageOnline.Online, Client.Self.SimPosition, UUID.Zero, new byte[1] { 0 });
  787. }
  788. }
  789. }
  790. #region Public Methods
  791. /// <summary>
  792. /// Request a current list of groups the avatar is a member of.
  793. /// </summary>
  794. /// <remarks>CAPS Event Queue must be running for this to work since the results
  795. /// come across CAPS.</remarks>
  796. public void RequestCurrentGroups()
  797. {
  798. AgentDataUpdateRequestPacket request = new AgentDataUpdateRequestPacket();
  799. request.AgentData.AgentID = Client.Self.AgentID;
  800. request.AgentData.SessionID = Client.Self.SessionID;
  801. Client.Network.SendPacket(request);
  802. }
  803. /// <summary>
  804. /// Lookup name of group based on groupID
  805. /// </summary>
  806. /// <param name="groupID">groupID of group to lookup name for.</param>
  807. public void RequestGroupName(UUID groupID)
  808. {
  809. // if we already have this in the cache, return from cache instead of making a request
  810. if (GroupName2KeyCache.ContainsKey(groupID))
  811. {
  812. Dictionary<UUID, string> groupNames = new Dictionary<UUID, string>();
  813. lock (GroupName2KeyCache.Dictionary)
  814. groupNames.Add(groupID, GroupName2KeyCache.Dictionary[groupID]);
  815. if (m_GroupNames != null)
  816. {
  817. OnGroupNamesReply(new GroupNamesEventArgs(groupNames));
  818. }
  819. }
  820. else
  821. {
  822. UUIDGroupNameRequestPacket req = new UUIDGroupNameRequestPacket();
  823. UUIDGroupNameRequestPacket.UUIDNameBlockBlock[] block = new UUIDGroupNameRequestPacket.UUIDNameBlockBlock[1];
  824. block[0] = new UUIDGroupNameRequestPacket.UUIDNameBlockBlock();
  825. block[0].ID = groupID;
  826. req.UUIDNameBlock = block;
  827. Client.Network.SendPacket(req);
  828. }
  829. }
  830. /// <summary>
  831. /// Request lookup of multiple group names
  832. /// </summary>
  833. /// <param name="groupIDs">List of group IDs to request.</param>
  834. public void RequestGroupNames(List<UUID> groupIDs)
  835. {
  836. Dictionary<UUID, string> groupNames = new Dictionary<UUID, string>();
  837. lock (GroupName2KeyCache.Dictionary)
  838. {
  839. foreach (UUID groupID in groupIDs)
  840. {
  841. if (GroupName2KeyCache.ContainsKey(groupID))
  842. groupNames[groupID] = GroupName2KeyCache.Dictionary[groupID];
  843. }
  844. }
  845. if (groupIDs.Count > 0)
  846. {
  847. UUIDGroupNameRequestPacket req = new UUIDGroupNameRequestPacket();
  848. UUIDGroupNameRequestPacket.UUIDNameBlockBlock[] block = new UUIDGroupNameRequestPacket.UUIDNameBlockBlock[groupIDs.Count];
  849. for (int i = 0; i < groupIDs.Count; i++)
  850. {
  851. block[i] = new UUIDGroupNameRequestPacket.UUIDNameBlockBlock();
  852. block[i].ID = groupIDs[i];
  853. }
  854. req.UUIDNameBlock = block;
  855. Client.Network.SendPacket(req);
  856. }
  857. // fire handler from cache
  858. if (groupNames.Count > 0 && m_GroupNames != null)
  859. {
  860. OnGroupNamesReply(new GroupNamesEventArgs(groupNames));
  861. }
  862. }
  863. /// <summary>Lookup group profile data such as name, enrollment, founder, logo, etc</summary>
  864. /// <remarks>Subscribe to <code>OnGroupProfile</code> event to receive the results.</remarks>
  865. /// <param name="group">group ID (UUID)</param>
  866. public void RequestGroupProfile(UUID group)
  867. {
  868. GroupProfileRequestPacket request = new GroupProfileRequestPacket();
  869. request.AgentData.AgentID = Client.Self.AgentID;
  870. request.AgentData.SessionID = Client.Self.SessionID;
  871. request.GroupData.GroupID = group;
  872. Client.Network.SendPacket(request);
  873. }
  874. /// <summary>Request a list of group members.</summary>
  875. /// <remarks>Subscribe to <code>OnGroupMembers</code> event to receive the results.</remarks>
  876. /// <param name="group">group ID (UUID)</param>
  877. /// <returns>UUID of the request, use to index into cache</returns>
  878. public UUID RequestGroupMembers(UUID group)
  879. {
  880. UUID requestID = UUID.Random();
  881. lock (GroupMembersRequests) GroupMembersRequests.Add(requestID);
  882. GroupMembersRequestPacket request = new GroupMembersRequestPacket();
  883. request.AgentData.AgentID = Client.Self.AgentID;
  884. request.AgentData.SessionID = Client.Self.SessionID;
  885. request.GroupData.GroupID = group;
  886. request.GroupData.RequestID = requestID;
  887. Client.Network.SendPacket(request);
  888. return requestID;
  889. }
  890. /// <summary>Request group roles</summary>
  891. /// <remarks>Subscribe to <code>OnGroupRoles</code> event to receive the results.</remarks>
  892. /// <param name="group">group ID (UUID)</param>
  893. /// <returns>UUID of the request, use to index into cache</returns>
  894. public UUID RequestGroupRoles(UUID group)
  895. {
  896. UUID requestID = UUID.Random();
  897. lock (GroupRolesRequests) GroupRolesRequests.Add(requestID);
  898. GroupRoleDataRequestPacket request = new GroupRoleDataRequestPacket();
  899. request.AgentData.AgentID = Client.Self.AgentID;
  900. request.AgentData.SessionID = Client.Self.SessionID;
  901. request.GroupData.GroupID = group;
  902. request.GroupData.RequestID = requestID;
  903. Client.Network.SendPacket(request);
  904. return requestID;
  905. }
  906. /// <summary>Request members (members,role) role mapping for a group.</summary>
  907. /// <remarks>Subscribe to <code>OnGroupRolesMembers</code> event to receive the results.</remarks>
  908. /// <param name="group">group ID (UUID)</param>
  909. /// <returns>UUID of the request, use to index into cache</returns>
  910. public UUID RequestGroupRolesMembers(UUID group)
  911. {
  912. UUID requestID = UUID.Random();
  913. lock (GroupRolesRequests) GroupRolesMembersRequests.Add(requestID);
  914. GroupRoleMembersRequestPacket request = new GroupRoleMembersRequestPacket();
  915. request.AgentData.AgentID = Client.Self.AgentID;
  916. request.AgentData.SessionID = Client.Self.SessionID;
  917. request.GroupData.GroupID = group;
  918. request.GroupData.RequestID = requestID;
  919. Client.Network.SendPacket(request);
  920. return requestID;
  921. }
  922. /// <summary>Request a groups Titles</summary>
  923. /// <remarks>Subscribe to <code>OnGroupTitles</code> event to receive the results.</remarks>
  924. /// <param name="group">group ID (UUID)</param>
  925. /// <returns>UUID of the request, use to index into cache</returns>
  926. public UUID RequestGroupTitles(UUID group)
  927. {
  928. UUID requestID = UUID.Random();
  929. GroupTitlesRequestPacket request = new GroupTitlesRequestPacket();
  930. request.AgentData.AgentID = Client.Self.AgentID;
  931. request.AgentData.SessionID = Client.Self.SessionID;
  932. request.AgentData.GroupID = group;
  933. request.AgentData.RequestID = requestID;
  934. Client.Network.SendPacket(request);
  935. return requestID;
  936. }
  937. /// <summary>Begin to get the group account summary</summary>
  938. /// <remarks>Subscribe to the <code>OnGroupAccountSummary</code> event to receive the results.</remarks>
  939. /// <param name="group">group ID (UUID)</param>
  940. /// <param name="intervalDays">How long of an interval</param>
  941. /// <param name="currentInterval">Which interval (0 for current, 1 for last)</param>
  942. public void RequestGroupAccountSummary(UUID group, int intervalDays, int currentInterval)
  943. {
  944. GroupAccountSummaryRequestPacket p = new GroupAccountSummaryRequestPacket();
  945. p.AgentData.AgentID = Client.Self.AgentID;
  946. p.AgentData.SessionID = Client.Self.SessionID;
  947. p.AgentData.GroupID = group;
  948. p.MoneyData.RequestID = UUID.Random();
  949. p.MoneyData.CurrentInterval = currentInterval;
  950. p.MoneyData.IntervalDays = intervalDays;
  951. Client.Network.SendPacket(p);
  952. }
  953. /// <summary>Invites a user to a group</summary>
  954. /// <param name="group">The group to invite to</param>
  955. /// <param name="roles">A list of roles to invite a person to</param>
  956. /// <param name="personkey">Key of person to invite</param>
  957. public void Invite(UUID group, List<UUID> roles, UUID personkey)
  958. {
  959. InviteGroupRequestPacket igp = new InviteGroupRequestPacket();
  960. igp.AgentData = new InviteGroupRequestPacket.AgentDataBlock();
  961. igp.AgentData.AgentID = Client.Self.AgentID;
  962. igp.AgentData.SessionID = Client.Self.SessionID;
  963. igp.GroupData = new InviteGroupRequestPacket.GroupDataBlock();
  964. igp.GroupData.GroupID = group;
  965. igp.InviteData = new InviteGroupRequestPacket.InviteDataBlock[roles.Count];
  966. for (int i = 0; i < roles.Count; i++)
  967. {
  968. igp.InviteData[i] = new InviteGroupRequestPacket.InviteDataBlock();
  969. igp.InviteData[i].InviteeID = personkey;
  970. igp.InviteData[i].RoleID = roles[i];
  971. }
  972. Client.Network.SendPacket(igp);
  973. }
  974. /// <summary>Set a group as the current active group</summary>
  975. /// <param name="id">group ID (UUID)</param>
  976. public void ActivateGroup(UUID id)
  977. {
  978. ActivateGroupPacket activate = new ActivateGroupPacket();
  979. activate.AgentData.AgentID = Client.Self.AgentID;
  980. activate.AgentData.SessionID = Client.Self.SessionID;
  981. activate.AgentData.GroupID = id;
  982. Client.Network.SendPacket(activate);
  983. }
  984. /// <summary>Change the role that determines your active title</summary>
  985. /// <param name="group">Group ID to use</param>
  986. /// <param name="role">Role ID to change to</param>
  987. public void ActivateTitle(UUID group, UUID role)
  988. {
  989. GroupTitleUpdatePacket gtu = new GroupTitleUpdatePacket();
  990. gtu.AgentData.AgentID = Client.Self.AgentID;
  991. gtu.AgentData.SessionID = Client.Self.SessionID;
  992. gtu.AgentData.TitleRoleID = role;
  993. gtu.AgentData.GroupID = group;
  994. Client.Network.SendPacket(gtu);
  995. }
  996. /// <summary>Set this avatar's tier contribution</summary>
  997. /// <param name="group">Group ID to change tier in</param>
  998. /// <param name="contribution">amount of tier to donate</param>
  999. public void SetGroupContribution(UUID group, int contribution)
  1000. {
  1001. SetGroupContributionPacket sgp = new SetGroupContributionPacket();
  1002. sgp.AgentData.AgentID = Client.Self.AgentID;
  1003. sgp.AgentData.SessionID = Client.Self.SessionID;
  1004. sgp.Data.GroupID = group;
  1005. sgp.Data.Contribution = contribution;
  1006. Client.Network.SendPacket(sgp);
  1007. }
  1008. /// <summary>
  1009. /// Save wheather agent wants to accept group notices and list this group in their profile
  1010. /// </summary>
  1011. /// <param name="groupID">Group <see cref="UUID"/></param>
  1012. /// <param name="acceptNotices">Accept notices from this group</param>
  1013. /// <param name="listInProfile">List this group in the profile</param>
  1014. public void SetGroupAcceptNotices(UUID groupID, bool acceptNotices, bool listInProfile)
  1015. {
  1016. SetGroupAcceptNoticesPacket p = new SetGroupAcceptNoticesPacket();
  1017. p.AgentData.AgentID = Client.Self.AgentID;
  1018. p.AgentData.SessionID = Client.Self.SessionID;
  1019. p.Data.GroupID = groupID;
  1020. p.Data.AcceptNotices = acceptNotices;
  1021. p.NewData.ListInProfile = listInProfile;
  1022. Client.Network.SendPacket(p);
  1023. }
  1024. /// <summary>Request to join a group</summary>
  1025. /// <remarks>Subscribe to <code>OnGroupJoined</code> event for confirmation.</remarks>
  1026. /// <param name="id">group ID (UUID) to join.</param>
  1027. public void RequestJoinGroup(UUID id)
  1028. {
  1029. JoinGroupRequestPacket join = new JoinGroupRequestPacket();
  1030. join.AgentData.AgentID = Client.Self.AgentID;
  1031. join.AgentData.SessionID = Client.Self.SessionID;
  1032. join.GroupData.GroupID = id;
  1033. Client.Network.SendPacket(join);
  1034. }
  1035. /// <summary>
  1036. /// Request to create a new group. If the group is successfully
  1037. /// created, L$100 will automatically be deducted
  1038. /// </summary>
  1039. /// <remarks>Subscribe to <code>OnGroupCreated</code> event to receive confirmation.</remarks>
  1040. /// <param name="group">Group struct containing the new group info</param>
  1041. public void RequestCreateGroup(Group group)
  1042. {
  1043. OpenMetaverse.Packets.CreateGroupRequestPacket cgrp = new CreateGroupRequestPacket();
  1044. cgrp.AgentData = new CreateGroupRequestPacket.AgentDataBlock();
  1045. cgrp.AgentData.AgentID = Client.Self.AgentID;
  1046. cgrp.AgentData.SessionID = Client.Self.SessionID;
  1047. cgrp.GroupData = new CreateGroupRequestPacket.GroupDataBlock();
  1048. cgrp.GroupData.AllowPublish = group.AllowPublish;
  1049. cgrp.GroupData.Charter = Utils.StringToBytes(group.Charter);
  1050. cgrp.GroupData.InsigniaID = group.InsigniaID;
  1051. cgrp.GroupData.MaturePublish = group.MaturePublish;
  1052. cgrp.GroupData.MembershipFee = group.MembershipFee;
  1053. cgrp.GroupData.Name = Utils.StringToBytes(group.Name);
  1054. cgrp.GroupData.OpenEnrollment = group.OpenEnrollment;
  1055. cgrp.GroupData.ShowInList = group.ShowInList;
  1056. Client.Network.SendPacket(cgrp);
  1057. }
  1058. /// <summary>Update a group's profile and other information</summary>
  1059. /// <param name="id">Groups ID (UUID) to update.</param>
  1060. /// <param name="group">Group struct to update.</param>
  1061. public void UpdateGroup(UUID id, Group group)
  1062. {
  1063. OpenMetaverse.Packets.UpdateGroupInfoPacket cgrp = new UpdateGroupInfoPacket();
  1064. cgrp.AgentData = new UpdateGroupInfoPacket.AgentDataBlock();
  1065. cgrp.AgentData.AgentID = Client.Self.AgentID;
  1066. cgrp.AgentData.SessionID = Client.Self.SessionID;
  1067. cgrp.GroupData = new UpdateGroupInfoPacket.GroupDataBlock();
  1068. cgrp.GroupData.GroupID = id;
  1069. cgrp.GroupData.AllowPublish = group.AllowPublish;
  1070. cgrp.GroupData.Charter = Utils.StringToBytes(group.Charter);
  1071. cgrp.GroupData.InsigniaID = group.InsigniaID;
  1072. cgrp.GroupData.MaturePublish = group.MaturePublish;
  1073. cgrp.GroupData.MembershipFee = group.MembershipFee;
  1074. cgrp.GroupData.OpenEnrollment = group.OpenEnrollment;
  1075. cgrp.GroupData.ShowInList = group.ShowInList;
  1076. Client.Network.SendPacket(cgrp);
  1077. }
  1078. /// <summary>Eject a user from a group</summary>
  1079. /// <param name="group">Group ID to eject the user from</param>
  1080. /// <param name="member">Avatar's key to eject</param>
  1081. public void EjectUser(UUID group, UUID member)
  1082. {
  1083. OpenMetaverse.Packets.EjectGroupMemberRequestPacket eject = new EjectGroupMemberRequestPacket();
  1084. eject.AgentData = new EjectGroupMemberRequestPacket.AgentDataBlock();
  1085. eject.AgentData.AgentID = Client.Self.AgentID;
  1086. eject.AgentData.SessionID = Client.Self.SessionID;
  1087. eject.GroupData = new EjectGroupMemberRequestPacket.GroupDataBlock();
  1088. eject.GroupData.GroupID = group;
  1089. eject.EjectData = new EjectGroupMemberRequestPacket.EjectDataBlock[1];
  1090. eject.EjectData[0] = new EjectGroupMemberRequestPacket.EjectDataBlock();
  1091. eject.EjectData[0].EjecteeID = member;
  1092. Client.Network.SendPacket(eject);
  1093. }
  1094. /// <summary>Update role information</summary>
  1095. /// <param name="role">Modified role to be updated</param>
  1096. public void UpdateRole(GroupRole role)
  1097. {
  1098. OpenMetaverse.Packets.GroupRoleUpdatePacket gru = new GroupRoleUpdatePacket();
  1099. gru.AgentData.AgentID = Client.Self.AgentID;
  1100. gru.AgentData.SessionID = Client.Self.SessionID;
  1101. gru.AgentData.GroupID = role.GroupID;
  1102. gru.RoleData = new GroupRoleUpdatePacket.RoleDataBlock[1];
  1103. gru.RoleData[0] = new GroupRoleUpdatePacket.RoleDataBlock();
  1104. gru.RoleData[0].Name = Utils.StringToBytes(role.Name);
  1105. gru.RoleData[0].Description = Utils.StringToBytes(role.Description);
  1106. gru.RoleData[0].Powers = (ulong)role.Powers;
  1107. gru.RoleData[0].RoleID = role.ID;
  1108. gru.RoleData[0].Title = Utils.StringToBytes(role.Title);
  1109. gru.RoleData[0].UpdateType = (byte)GroupRoleUpdate.UpdateAll;
  1110. Client.Network.SendPacket(gru);
  1111. }
  1112. /// <summary>Create a new group role</summary>
  1113. /// <param name="group">Group ID to update</param>
  1114. /// <param name="role">Role to create</param>
  1115. public void CreateRole(UUID group, GroupRole role)
  1116. {
  1117. OpenMetaverse.Packets.GroupRoleUpdatePacket gru = new GroupRoleUpdatePacket();
  1118. gru.AgentData.AgentID = Client.Self.AgentID;
  1119. gru.AgentData.SessionID = Client.Self.SessionID;
  1120. gru.AgentData.GroupID = group;
  1121. gru.RoleData = new GroupRoleUpdatePacket.RoleDataBlock[1];
  1122. gru.RoleData[0] = new GroupRoleUpdatePacket.RoleDataBlock();
  1123. gru.RoleData[0].RoleID = UUID.Random();
  1124. gru.RoleData[0].Name = Utils.StringToBytes(role.Name);
  1125. gru.RoleData[0].Description = Utils.StringToBytes(role.Description);
  1126. gru.RoleData[0].Powers = (ulong)role.Powers;
  1127. gru.RoleData[0].Title = Utils.StringToBytes(role.Title);
  1128. gru.RoleData[0].UpdateType = (byte)GroupRoleUpdate.Create;
  1129. Client.Network.SendPacket(gru);
  1130. }
  1131. /// <summary>Delete a group role</summary>
  1132. /// <param name="group">Group ID to update</param>
  1133. /// <param name="roleID">Role to delete</param>
  1134. public void DeleteRole(UUID group, UUID roleID)
  1135. {
  1136. OpenMetaverse.Packets.GroupRoleUpdatePacket gru = new GroupRoleUpdatePacket();
  1137. gru.AgentData.AgentID = Client.Self.AgentID;
  1138. gru.AgentData.SessionID = Client.Self.SessionID;
  1139. gru.AgentData.GroupID = group;
  1140. gru.RoleData = new GroupRoleUpdatePacket.RoleDataBlock[1];
  1141. gru.RoleData[0] = new GroupRoleUpdatePacket.RoleDataBlock();
  1142. gru.RoleData[0].RoleID = roleID;
  1143. gru.RoleData[0].Name = Utils.StringToBytes(string.Empty);
  1144. gru.RoleData[0].Description = Utils.StringToBytes(string.Empty);
  1145. gru.RoleData[0].Powers = 0u;
  1146. gru.RoleData[0].Title = Utils.StringToBytes(string.Empty);
  1147. gru.RoleData[0].UpdateType = (byte)GroupRoleUpdate.Delete;
  1148. Client.Network.SendPacket(gru);
  1149. }
  1150. /// <summary>Remove an avatar from a role</summary>
  1151. /// <param name="group">Group ID to update</param>
  1152. /// <param name="role">Role ID to be removed from</param>
  1153. /// <param name="member">Avatar's Key to remove</param>
  1154. public void RemoveFromRole(UUID group, UUID role, UUID member)
  1155. {
  1156. OpenMetaverse.Packets.GroupRoleChangesPacket grc = new GroupRoleChangesPacket();
  1157. grc.AgentData.AgentID = Client.Self.AgentID;
  1158. grc.AgentData.SessionID = Client.Self.SessionID;
  1159. grc.AgentData.GroupID = group;
  1160. grc.RoleChange = new GroupRoleChangesPacket.RoleChangeBlock[1];
  1161. grc.RoleChange[0] = new GroupRoleChangesPacket.RoleChangeBlock();
  1162. //Add to members and role
  1163. grc.RoleChange[0].MemberID = member;
  1164. grc.RoleChange[0].RoleID = role;
  1165. //1 = Remove From Role TODO: this should be in an enum
  1166. grc.RoleChange[0].Change = 1;
  1167. Client.Network.SendPacket(grc);
  1168. }
  1169. /// <summary>Assign an avatar to a role</summary>
  1170. /// <param name="group">Group ID to update</param>
  1171. /// <param name="role">Role ID to assign to</param>
  1172. /// <param name="member">Avatar's ID to assign to role</param>
  1173. public void AddToRole(UUID group, UUID role, UUID member)
  1174. {
  1175. OpenMetaverse.Packets.GroupRoleChangesPacket grc = new GroupRoleChangesPacket();
  1176. grc.AgentData.AgentID = Client.Self.AgentID;
  1177. grc.AgentData.SessionID = Client.Self.SessionID;
  1178. grc.AgentData.GroupID = group;
  1179. grc.RoleChange = new GroupRoleChangesPacket.RoleChangeBlock[1];
  1180. grc.RoleChange[0] = new GroupRoleChangesPacket.RoleChangeBlock();
  1181. //Add to members and role
  1182. grc.RoleChange[0].MemberID = member;
  1183. grc.RoleChange[0].RoleID = role;
  1184. //0 = Add to Role TODO: this should be in an enum
  1185. grc.RoleChange[0].Change = 0;
  1186. Client.Network.SendPacket(grc);
  1187. }
  1188. /// <summary>Request the group notices list</summary>
  1189. /// <param name="group">Group ID to fetch notices for</param>
  1190. public void RequestGroupNoticesList(UUID group)
  1191. {
  1192. OpenMetaverse.Packets.GroupNoticesListRequestPacket gnl = new GroupNoticesListRequestPacket();
  1193. gnl.AgentData.AgentID = Client.Self.AgentID;
  1194. gnl.AgentData.SessionID = Client.Self.SessionID;
  1195. gnl.Data.GroupID = group;
  1196. Client.Network.SendPacket(gnl);
  1197. }
  1198. /// <summary>Request a group notice by key</summary>
  1199. /// <param name="noticeID">ID of group notice</param>
  1200. public void RequestGroupNotice(UUID noticeID)
  1201. {
  1202. OpenMetaverse.Packets.GroupNoticeRequestPacket gnr = new GroupNoticeRequestPacket();
  1203. gnr.AgentData.AgentID = Client.Self.AgentID;
  1204. gnr.AgentData.SessionID = Client.Self.SessionID;
  1205. gnr.Data.GroupNoticeID = noticeID;
  1206. Client.Network.SendPacket(gnr);
  1207. }
  1208. /// <summary>Send out a group notice</summary>
  1209. /// <param name="group">Group ID to update</param>
  1210. /// <param name="notice"><code>GroupNotice</code> structure containing notice data</param>
  1211. public void SendGroupNotice(UUID group, GroupNotice notice)
  1212. {
  1213. Client.Self.InstantMessage(Client.Self.Name, group, notice.Subject + "|" + notice.Message,
  1214. UUID.Zero, InstantMessageDialog.GroupNotice, InstantMessageOnline.Online,
  1215. Vector3.Zero, UUID.Zero, notice.SerializeAttachment());
  1216. }
  1217. /// <summary>Start a group proposal (vote)</summary>
  1218. /// <param name="group">The Group ID to send proposal to</param>
  1219. /// <param name="prop"><code>GroupProposal</code> structure containing the proposal</param>
  1220. public void StartProposal(UUID group, GroupProposal prop)
  1221. {
  1222. StartGroupProposalPacket p = new StartGroupProposalPacket();
  1223. p.AgentData.AgentID = Client.Self.AgentID;
  1224. p.AgentData.SessionID = Client.Self.SessionID;
  1225. p.ProposalData.GroupID = group;
  1226. p.ProposalData.ProposalText = Utils.StringToBytes(prop.VoteText);
  1227. p.ProposalData.Quorum = prop.Quorum;
  1228. p.ProposalData.Majority = prop.Majority;
  1229. p.ProposalData.Duration = prop.Duration;
  1230. Client.Network.SendPacket(p);
  1231. }
  1232. /// <summary>Request to leave a group</summary>
  1233. /// <remarks>Subscribe to <code>OnGroupLeft</code> event to receive confirmation</remarks>
  1234. /// <param name="groupID">The group to leave</param>
  1235. public void LeaveGroup(UUID groupID)
  1236. {
  1237. LeaveGroupRequestPacket p = new LeaveGroupRequestPacket();
  1238. p.AgentData.AgentID = Client.Self.AgentID;
  1239. p.AgentData.SessionID = Client.Self.SessionID;
  1240. p.GroupData.GroupID = groupID;
  1241. Client.Network.SendPacket(p);
  1242. }
  1243. #endregion
  1244. #region Packet Handlers
  1245. protected void AgentGroupDataUpdateMessageHandler(string capsKey, IMessage message, Simulator simulator)
  1246. {
  1247. if (m_CurrentGroups != null)
  1248. {
  1249. AgentGroupDataUpdateMessage msg = (AgentGroupDataUpdateMessage)message;
  1250. Dictionary<UUID, Group> currentGroups = new Dictionary<UUID, Group>();
  1251. for (int i = 0; i < msg.GroupDataBlock.Length; i++)
  1252. {
  1253. Group group = new Group();
  1254. group.ID = msg.GroupDataBlock[i].GroupID;
  1255. group.InsigniaID = msg.GroupDataBlock[i].GroupInsigniaID;
  1256. group.Name = msg.GroupDataBlock[i].GroupName;
  1257. group.Contribution = msg.GroupDataBlock[i].Contribution;
  1258. group.AcceptNotices = msg.GroupDataBlock[i].AcceptNotices;
  1259. group.Powers = msg.GroupDataBlock[i].GroupPowers;
  1260. group.ListInProfile = msg.NewGroupDataBlock[i].ListInProfile;
  1261. currentGroups.Add(group.ID, group);
  1262. lock (GroupName2KeyCache.Dictionary)
  1263. {
  1264. if (!GroupName2KeyCache.Dictionary.ContainsKey(group.ID))
  1265. GroupName2KeyCache.Dictionary.Add(group.ID, group.Name);
  1266. }
  1267. }
  1268. OnCurrentGroups(new CurrentGroupsEventArgs(currentGroups));
  1269. }
  1270. }
  1271. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1272. /// <param name="sender">The sender</param>
  1273. /// <param name="e">The EventArgs object containing the packet data</param>
  1274. protected void AgentDropGroupHandler(object sender, PacketReceivedEventArgs e)
  1275. {
  1276. if (m_GroupDropped != null)
  1277. {
  1278. Packet packet = e.Packet;
  1279. OnGroupDropped(new GroupDroppedEventArgs(((AgentDropGroupPacket)packet).AgentData.GroupID));
  1280. }
  1281. }
  1282. protected void AgentDropGroupMessageHandler(string capsKey, IMessage message, Simulator simulator)
  1283. {
  1284. if (m_GroupDropped != null)
  1285. {
  1286. AgentDropGroupMessage msg = (AgentDropGroupMessage)message;
  1287. for (int i = 0; i < msg.AgentDataBlock.Length; i++)
  1288. {
  1289. OnGroupDropped(new GroupDroppedEventArgs(msg.AgentDataBlock[i].GroupID));
  1290. }
  1291. }
  1292. }
  1293. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1294. /// <param name="sender">The sender</param>
  1295. /// <param name="e">The EventArgs object containing the packet data</param>
  1296. protected void GroupProfileReplyHandler(object sender, PacketReceivedEventArgs e)
  1297. {
  1298. if (m_GroupProfile != null)
  1299. {
  1300. Packet packet = e.Packet;
  1301. GroupProfileReplyPacket profile = (GroupProfileReplyPacket)packet;
  1302. Group group = new Group();
  1303. group.ID = profile.GroupData.GroupID;
  1304. group.AllowPublish = profile.GroupData.AllowPublish;
  1305. group.Charter = Utils.BytesToString(profile.GroupData.Charter);
  1306. group.FounderID = profile.GroupData.FounderID;
  1307. group.GroupMembershipCount = profile.GroupData.GroupMembershipCount;
  1308. group.GroupRolesCount = profile.GroupData.GroupRolesCount;
  1309. group.InsigniaID = profile.GroupData.InsigniaID;
  1310. group.MaturePublish = profile.GroupData.MaturePublish;
  1311. group.MembershipFee = profile.GroupData.MembershipFee;
  1312. group.MemberTitle = Utils.BytesToString(profile.GroupData.MemberTitle);
  1313. group.Money = profile.GroupData.Money;
  1314. group.Name = Utils.BytesToString(profile.GroupData.Name);
  1315. group.OpenEnrollment = profile.GroupData.OpenEnrollment;
  1316. group.OwnerRole = profile.GroupData.OwnerRole;
  1317. group.Powers = (GroupPowers)profile.GroupData.PowersMask;
  1318. group.ShowInList = profile.GroupData.ShowInList;
  1319. OnGroupProfile(new GroupProfileEventArgs(group));
  1320. }
  1321. }
  1322. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1323. /// <param name="sender">The sender</param>
  1324. /// <param name="e">The EventArgs object containing the packet data</param>
  1325. protected void GroupNoticesListReplyHandler(object sender, PacketReceivedEventArgs e)
  1326. {
  1327. if (m_GroupNoticesListReply != null)
  1328. {
  1329. Packet packet = e.Packet;
  1330. GroupNoticesListReplyPacket reply = (GroupNoticesListReplyPacket)packet;
  1331. List<GroupNoticesListEntry> notices = new List<GroupNoticesListEntry>();
  1332. foreach (GroupNoticesListReplyPacket.DataBlock entry in reply.Data)
  1333. {
  1334. GroupNoticesListEntry notice = new GroupNoticesListEntry();
  1335. notice.FromName = Utils.BytesToString(entry.FromName);
  1336. notice.Subject = Utils.BytesToString(entry.Subject);
  1337. notice.NoticeID = entry.NoticeID;
  1338. notice.Timestamp = entry.Timestamp;
  1339. notice.HasAttachment = entry.HasAttachment;
  1340. notice.AssetType = (AssetType)entry.AssetType;
  1341. notices.Add(notice);
  1342. }
  1343. OnGroupNoticesListReply(new GroupNoticesListReplyEventArgs(reply.AgentData.GroupID, notices));
  1344. }
  1345. }
  1346. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1347. /// <param name="sender">The sender</param>
  1348. /// <param name="e">The EventArgs object containing the packet data</param>
  1349. protected void GroupTitlesReplyHandler(object sender, PacketReceivedEventArgs e)
  1350. {
  1351. if (m_GroupTitles != null)
  1352. {
  1353. Packet packet = e.Packet;
  1354. GroupTitlesReplyPacket titles = (GroupTitlesReplyPacket)packet;
  1355. Dictionary<UUID, GroupTitle> groupTitleCache = new Dictionary<UUID, GroupTitle>();
  1356. foreach (GroupTitlesReplyPacket.GroupDataBlock block in titles.GroupData)
  1357. {
  1358. GroupTitle groupTitle = new GroupTitle();
  1359. groupTitle.GroupID = titles.AgentData.GroupID;
  1360. groupTitle.RoleID = block.RoleID;
  1361. groupTitle.Title = Utils.BytesToString(block.Title);
  1362. groupTitle.Selected = block.Selected;
  1363. groupTitleCache[block.RoleID] = groupTitle;
  1364. }
  1365. OnGroupTitles(new GroupTitlesReplyEventArgs(titles.AgentData.RequestID, titles.AgentData.GroupID, groupTitleCache));
  1366. }
  1367. }
  1368. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1369. /// <param name="sender">The sender</param>
  1370. /// <param name="e">The EventArgs object containing the packet data</param>
  1371. protected void GroupMembersHandler(object sender, PacketReceivedEventArgs e)
  1372. {
  1373. Packet packet = e.Packet;
  1374. GroupMembersReplyPacket members = (GroupMembersReplyPacket)packet;
  1375. Dictionary<UUID, GroupMember> groupMemberCache = null;
  1376. lock (GroupMembersRequests)
  1377. {
  1378. // If nothing is registered to receive this RequestID drop the data
  1379. if (GroupMembersRequests.Contains(members.GroupData.RequestID))
  1380. {
  1381. lock (TempGroupMembers.Dictionary)
  1382. {
  1383. if (!TempGroupMembers.TryGetValue(members.GroupData.RequestID, out groupMemberCache))
  1384. {
  1385. groupMemberCache = new Dictionary<UUID, GroupMember>();
  1386. TempGroupMembers[members.GroupData.RequestID] = groupMemberCache;
  1387. }
  1388. foreach (GroupMembersReplyPacket.MemberDataBlock block in members.MemberData)
  1389. {
  1390. GroupMember groupMember = new GroupMember();
  1391. groupMember.ID = block.AgentID;
  1392. groupMember.Contribution = block.Contribution;
  1393. groupMember.IsOwner = block.IsOwner;
  1394. groupMember.OnlineStatus = Utils.BytesToString(block.OnlineStatus);
  1395. groupMember.Powers = (GroupPowers)block.AgentPowers;
  1396. groupMember.Title = Utils.BytesToString(block.Title);
  1397. groupMemberCache[block.AgentID] = groupMember;
  1398. }
  1399. if (groupMemberCache.Count >= members.GroupData.MemberCount)
  1400. {
  1401. GroupMembersRequests.Remove(members.GroupData.RequestID);
  1402. TempGroupMembers.Remove(members.GroupData.RequestID);
  1403. }
  1404. }
  1405. }
  1406. }
  1407. if (m_GroupMembers != null && groupMemberCache != null && groupMemberCache.Count >= members.GroupData.MemberCount)
  1408. {
  1409. OnGroupMembersReply(new GroupMembersReplyEventArgs(members.GroupData.RequestID, members.GroupData.GroupID, groupMemberCache));
  1410. }
  1411. }
  1412. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1413. /// <param name="sender">The sender</param>
  1414. /// <param name="e">The EventArgs object containing the packet data</param>
  1415. protected void GroupRoleDataReplyHandler(object sender, PacketReceivedEventArgs e)
  1416. {
  1417. Packet packet = e.Packet;
  1418. GroupRoleDataReplyPacket roles = (GroupRoleDataReplyPacket)packet;
  1419. Dictionary<UUID, GroupRole> groupRoleCache = null;
  1420. lock (GroupRolesRequests)
  1421. {
  1422. // If nothing is registered to receive this RequestID drop the data
  1423. if (GroupRolesRequests.Contains(roles.GroupData.RequestID))
  1424. {
  1425. GroupRolesRequests.Remove(roles.GroupData.RequestID);
  1426. lock (TempGroupRoles.Dictionary)
  1427. {
  1428. if (!TempGroupRoles.TryGetValue(roles.GroupData.RequestID, out groupRoleCache))
  1429. {
  1430. groupRoleCache = new Dictionary<UUID, GroupRole>();
  1431. TempGroupRoles[roles.GroupData.RequestID] = groupRoleCache;
  1432. }
  1433. foreach (GroupRoleDataReplyPacket.RoleDataBlock block in roles.RoleData)
  1434. {
  1435. GroupRole groupRole = new GroupRole();
  1436. groupRole.GroupID = roles.GroupData.GroupID;
  1437. groupRole.ID = block.RoleID;
  1438. groupRole.Description = Utils.BytesToString(block.Description);
  1439. groupRole.Name = Utils.BytesToString(block.Name);
  1440. groupRole.Powers = (GroupPowers)block.Powers;
  1441. groupRole.Title = Utils.BytesToString(block.Title);
  1442. groupRoleCache[block.RoleID] = groupRole;
  1443. }
  1444. if (groupRoleCache.Count >= roles.GroupData.RoleCount)
  1445. {
  1446. GroupRolesRequests.Remove(roles.GroupData.RequestID);
  1447. TempGroupRoles.Remove(roles.GroupData.RequestID);
  1448. }
  1449. }
  1450. }
  1451. }
  1452. if (m_GroupRoles != null && groupRoleCache != null && groupRoleCache.Count >= roles.GroupData.RoleCount)
  1453. {
  1454. OnGroupRoleDataReply(new GroupRolesDataReplyEventArgs(roles.GroupData.RequestID, roles.GroupData.GroupID, groupRoleCache));
  1455. }
  1456. }
  1457. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1458. /// <param name="sender">The sender</param>
  1459. /// <param name="e">The EventArgs object containing the packet data</param>
  1460. protected void GroupRoleMembersReplyHandler(object sender, PacketReceivedEventArgs e)
  1461. {
  1462. Packet packet = e.Packet;
  1463. GroupRoleMembersReplyPacket members = (GroupRoleMembersReplyPacket)packet;
  1464. List<KeyValuePair<UUID, UUID>> groupRoleMemberCache = null;
  1465. try
  1466. {
  1467. lock (GroupRolesMembersRequests)
  1468. {
  1469. // If nothing is registered to receive this RequestID drop the data
  1470. if (GroupRolesMembersRequests.Contains(members.AgentData.RequestID))
  1471. {
  1472. lock (TempGroupRolesMembers.Dictionary)
  1473. {
  1474. if (!TempGroupRolesMembers.TryGetValue(members.AgentData.RequestID, out groupRoleMemberCache))
  1475. {
  1476. groupRoleMemberCache = new List<KeyValuePair<UUID, UUID>>();
  1477. TempGroupRolesMembers[members.AgentData.RequestID] = groupRoleMemberCache;
  1478. }
  1479. foreach (GroupRoleMembersReplyPacket.MemberDataBlock block in members.MemberData)
  1480. {
  1481. KeyValuePair<UUID, UUID> rolemember =
  1482. new KeyValuePair<UUID, UUID>(block.RoleID, block.MemberID);
  1483. groupRoleMemberCache.Add(rolemember);
  1484. }
  1485. if (groupRoleMemberCache.Count >= members.AgentData.TotalPairs)
  1486. {
  1487. GroupRolesMembersRequests.Remove(members.AgentData.RequestID);
  1488. TempGroupRolesMembers.Remove(members.AgentData.RequestID);
  1489. }
  1490. }
  1491. }
  1492. }
  1493. }
  1494. catch (Exception ex)
  1495. {
  1496. Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex);
  1497. }
  1498. if (m_GroupRoleMembers != null && groupRoleMemberCache != null && groupRoleMemberCache.Count >= members.AgentData.TotalPairs)
  1499. {
  1500. OnGroupRoleMembers(new GroupRolesMembersReplyEventArgs(members.AgentData.RequestID, members.AgentData.GroupID, groupRoleMemberCache));
  1501. }
  1502. }
  1503. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1504. /// <param name="sender">The sender</param>
  1505. /// <param name="e">The EventArgs object containing the packet data</param>
  1506. protected void GroupActiveProposalItemHandler(object sender, PacketReceivedEventArgs e)
  1507. {
  1508. //GroupActiveProposalItemReplyPacket proposal = (GroupActiveProposalItemReplyPacket)packet;
  1509. // TODO: Create a proposal struct to represent the fields in a proposal item
  1510. }
  1511. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1512. /// <param name="sender">The sender</param>
  1513. /// <param name="e">The EventArgs object containing the packet data</param>
  1514. protected void GroupVoteHistoryItemHandler(object sender, PacketReceivedEventArgs e)
  1515. {
  1516. //GroupVoteHistoryItemReplyPacket history = (GroupVoteHistoryItemReplyPacket)packet;
  1517. // TODO: This was broken in the official viewer when I was last trying to work on it
  1518. }
  1519. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1520. /// <param name="sender">The sender</param>
  1521. /// <param name="e">The EventArgs object containing the packet data</param>
  1522. protected void GroupAccountSummaryReplyHandler(object sender, PacketReceivedEventArgs e)
  1523. {
  1524. if (m_GroupAccountSummary != null)
  1525. {
  1526. Packet packet = e.Packet;
  1527. GroupAccountSummaryReplyPacket summary = (GroupAccountSummaryReplyPacket)packet;
  1528. GroupAccountSummary account = new GroupAccountSummary();
  1529. account.Balance = summary.MoneyData.Balance;
  1530. account.CurrentInterval = summary.MoneyData.CurrentInterval;
  1531. account.GroupTaxCurrent = summary.MoneyData.GroupTaxCurrent;
  1532. account.GroupTaxEstimate = summary.MoneyData.GroupTaxEstimate;
  1533. account.IntervalDays = summary.MoneyData.IntervalDays;
  1534. account.LandTaxCurrent = summary.MoneyData.LandTaxCurrent;
  1535. account.LandTaxEstimate = summary.MoneyData.LandTaxEstimate;
  1536. account.LastTaxDate = Utils.BytesToString(summary.MoneyData.LastTaxDate);
  1537. account.LightTaxCurrent = summary.MoneyData.LightTaxCurrent;
  1538. account.LightTaxEstimate = summary.MoneyData.LightTaxEstimate;
  1539. account.NonExemptMembers = summary.MoneyData.NonExemptMembers;
  1540. account.ObjectTaxCurrent = summary.MoneyData.ObjectTaxCurrent;
  1541. account.ObjectTaxEstimate = summary.MoneyData.ObjectTaxEstimate;
  1542. account.ParcelDirFeeCurrent = summary.MoneyData.ParcelDirFeeCurrent;
  1543. account.ParcelDirFeeEstimate = summary.MoneyData.ParcelDirFeeEstimate;
  1544. account.StartDate = Utils.BytesToString(summary.MoneyData.StartDate);
  1545. account.TaxDate = Utils.BytesToString(summary.MoneyData.TaxDate);
  1546. account.TotalCredits = summary.MoneyData.TotalCredits;
  1547. account.TotalDebits = summary.MoneyData.TotalDebits;
  1548. OnGroupAccountSummaryReply(new GroupAccountSummaryReplyEventArgs(summary.AgentData.GroupID, account));
  1549. }
  1550. }
  1551. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1552. /// <param name="sender">The sender</param>
  1553. /// <param name="e">The EventArgs object containing the packet data</param>
  1554. protected void CreateGroupReplyHandler(object sender, PacketReceivedEventArgs e)
  1555. {
  1556. if (m_GroupCreated != null)
  1557. {
  1558. Packet packet = e.Packet;
  1559. CreateGroupReplyPacket reply = (CreateGroupReplyPacket)packet;
  1560. string message = Utils.BytesToString(reply.ReplyData.Message);
  1561. OnGroupCreatedReply(new GroupCreatedReplyEventArgs(reply.ReplyData.GroupID, reply.ReplyData.Success, message));
  1562. }
  1563. }
  1564. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1565. /// <param name="sender">The sender</param>
  1566. /// <param name="e">The EventArgs object containing the packet data</param>
  1567. protected void JoinGroupReplyHandler(object sender, PacketReceivedEventArgs e)
  1568. {
  1569. if (m_GroupJoined != null)
  1570. {
  1571. Packet packet = e.Packet;
  1572. JoinGroupReplyPacket reply = (JoinGroupReplyPacket)packet;
  1573. OnGroupJoinedReply(new GroupOperationEventArgs(reply.GroupData.GroupID, reply.GroupData.Success));
  1574. }
  1575. }
  1576. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1577. /// <param name="sender">The sender</param>
  1578. /// <param name="e">The EventArgs object containing the packet data</param>
  1579. protected void LeaveGroupReplyHandler(object sender, PacketReceivedEventArgs e)
  1580. {
  1581. if (m_GroupLeft != null)
  1582. {
  1583. Packet packet = e.Packet;
  1584. LeaveGroupReplyPacket reply = (LeaveGroupReplyPacket)packet;
  1585. OnGroupLeaveReply(new GroupOperationEventArgs(reply.GroupData.GroupID, reply.GroupData.Success));
  1586. }
  1587. }
  1588. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1589. /// <param name="sender">The sender</param>
  1590. /// <param name="e">The EventArgs object containing the packet data</param>
  1591. private void UUIDGroupNameReplyHandler(object sender, PacketReceivedEventArgs e)
  1592. {
  1593. Packet packet = e.Packet;
  1594. UUIDGroupNameReplyPacket reply = (UUIDGroupNameReplyPacket)packet;
  1595. UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] blocks = reply.UUIDNameBlock;
  1596. Dictionary<UUID, string> groupNames = new Dictionary<UUID, string>();
  1597. foreach (UUIDGroupNameReplyPacket.UUIDNameBlockBlock block in blocks)
  1598. {
  1599. groupNames.Add(block.ID, Utils.BytesToString(block.GroupName));
  1600. if (!GroupName2KeyCache.ContainsKey(block.ID))
  1601. GroupName2KeyCache.Add(block.ID, Utils.BytesToString(block.GroupName));
  1602. }
  1603. if (m_GroupNames != null)
  1604. {
  1605. OnGroupNamesReply(new GroupNamesEventArgs(groupNames));
  1606. }
  1607. }
  1608. /// <summary>Process an incoming packet and raise the appropriate events</summary>
  1609. /// <param name="sender">The sender</param>
  1610. /// <param name="e">The EventArgs object containing the packet data</param>
  1611. protected void EjectGroupMemberReplyHandler(object sender, PacketReceivedEventArgs e)
  1612. {
  1613. Packet packet = e.Packet;
  1614. EjectGroupMemberReplyPacket reply = (EjectGroupMemberReplyPacket)packet;
  1615. // TODO: On Success remove the member from the cache(s)
  1616. if (m_GroupMemberEjected != null)
  1617. {
  1618. OnGroupMemberEjected(new GroupOperationEventArgs(reply.GroupData.GroupID, reply.EjectData.Success));
  1619. }
  1620. }
  1621. #endregion Packet Handlers
  1622. }
  1623. #region EventArgs
  1624. /// <summary>Contains the current groups your agent is a member of</summary>
  1625. public class CurrentGroupsEventArgs : EventArgs
  1626. {
  1627. private readonly Dictionary<UUID, Group> m_Groups;
  1628. /// <summary>Get the current groups your agent is a member of</summary>
  1629. public Dictionary<UUID, Group> Groups { get { return m_Groups; } }
  1630. /// <summary>Construct a new instance of the CurrentGroupsEventArgs class</summary>
  1631. /// <param name="groups">The current groups your agent is a member of</param>
  1632. public CurrentGroupsEventArgs(Dictionary<UUID, Group> groups)
  1633. {
  1634. this.m_Groups = groups;
  1635. }
  1636. }
  1637. /// <summary>A Dictionary of group names, where the Key is the groups ID and the value is the groups name</summary>
  1638. public class GroupNamesEventArgs : EventArgs
  1639. {
  1640. private readonly Dictionary<UUID, string> m_GroupNames;
  1641. /// <summary>Get the Group Names dictionary</summary>
  1642. public Dictionary<UUID, string> GroupNames { get { return m_GroupNames; } }
  1643. /// <summary>Construct a new instance of the GroupNamesEventArgs class</summary>
  1644. /// <param name="groupNames">The Group names dictionary</param>
  1645. public GroupNamesEventArgs(Dictionary<UUID, string> groupNames)
  1646. {
  1647. this.m_GroupNames = groupNames;
  1648. }
  1649. }
  1650. /// <summary>Represents the members of a group</summary>
  1651. public class GroupMembersReplyEventArgs : EventArgs
  1652. {
  1653. private readonly UUID m_RequestID;
  1654. private readonly UUID m_GroupID;
  1655. private readonly Dictionary<UUID, GroupMember> m_Members;
  1656. /// <summary>Get the ID as returned by the request to correlate
  1657. /// this result set and the request</summary>
  1658. public UUID RequestID { get { return m_RequestID; } }
  1659. /// <summary>Get the ID of the group</summary>
  1660. public UUID GroupID { get { return m_GroupID; } }
  1661. /// <summary>Get the dictionary of members</summary>
  1662. public Dictionary<UUID, GroupMember> Members { get { return m_Members; } }
  1663. /// <summary>
  1664. /// Construct a new instance of the GroupMembersReplyEventArgs class
  1665. /// </summary>
  1666. /// <param name="requestID">The ID of the request</param>
  1667. /// <param name="groupID">The ID of the group</param>
  1668. /// <param name="members">The membership list of the group</param>
  1669. public GroupMembersReplyEventArgs(UUID requestID, UUID groupID, Dictionary<UUID, GroupMember> members)
  1670. {
  1671. this.m_RequestID = requestID;
  1672. this.m_GroupID = groupID;
  1673. this.m_Members = members;
  1674. }
  1675. }
  1676. /// <summary>Represents the roles associated with a group</summary>
  1677. public class GroupRolesDataReplyEventArgs : EventArgs
  1678. {
  1679. private readonly UUID m_RequestID;
  1680. private readonly UUID m_GroupID;
  1681. private readonly Dictionary<UUID, GroupRole> m_Roles;
  1682. /// <summary>Get the ID as returned by the request to correlate
  1683. /// this result set and the request</summary>
  1684. public UUID RequestID { get { return m_RequestID; } }
  1685. /// <summary>Get the ID of the group</summary>
  1686. public UUID GroupID { get { return m_GroupID; } }
  1687. /// <summary>Get the dictionary containing the roles</summary>
  1688. public Dictionary<UUID, GroupRole> Roles { get { return m_Roles; } }
  1689. /// <summary>Construct a new instance of the GroupRolesDataReplyEventArgs class</summary>
  1690. /// <param name="requestID">The ID as returned by the request to correlate
  1691. /// this result set and the request</param>
  1692. /// <param name="groupID">The ID of the group</param>
  1693. /// <param name="roles">The dictionary containing the roles</param>
  1694. public GroupRolesDataReplyEventArgs(UUID requestID, UUID groupID, Dictionary<UUID, GroupRole> roles)
  1695. {
  1696. this.m_RequestID = requestID;
  1697. this.m_GroupID = groupID;
  1698. this.m_Roles = roles;
  1699. }
  1700. }
  1701. /// <summary>Represents the Role to Member mappings for a group</summary>
  1702. public class GroupRolesMembersReplyEventArgs : EventArgs
  1703. {
  1704. private readonly UUID m_RequestID;
  1705. private readonly UUID m_GroupID;
  1706. private readonly List<KeyValuePair<UUID, UUID>> m_RolesMembers;
  1707. /// <summary>Get the ID as returned by the request to correlate
  1708. /// this result set and the request</summary>
  1709. public UUID RequestID { get { return m_RequestID; } }
  1710. /// <summary>Get the ID of the group</summary>
  1711. public UUID GroupID { get { return m_GroupID; } }
  1712. /// <summary>Get the member to roles map</summary>
  1713. public List<KeyValuePair<UUID, UUID>> RolesMembers { get { return m_RolesMembers; } }
  1714. /// <summary>Construct a new instance of the GroupRolesMembersReplyEventArgs class</summary>
  1715. /// <param name="requestID">The ID as returned by the request to correlate
  1716. /// this result set and the request</param>
  1717. /// <param name="groupID">The ID of the group</param>
  1718. /// <param name="rolesMembers">The member to roles map</param>
  1719. public GroupRolesMembersReplyEventArgs(UUID requestID, UUID groupID, List<KeyValuePair<UUID, UUID>> rolesMembers)
  1720. {
  1721. this.m_RequestID = requestID;
  1722. this.m_GroupID = groupID;
  1723. this.m_RolesMembers = rolesMembers;
  1724. }
  1725. }
  1726. /// <summary>Represents the titles for a group</summary>
  1727. public class GroupTitlesReplyEventArgs : EventArgs
  1728. {
  1729. private readonly UUID m_RequestID;
  1730. private readonly UUID m_GroupID;
  1731. private readonly Dictionary<UUID, GroupTitle> m_Titles;
  1732. /// <summary>Get the ID as returned by the request to correlate
  1733. /// this result set and the request</summary>
  1734. public UUID RequestID { get { return m_RequestID; } }
  1735. /// <summary>Get the ID of the group</summary>
  1736. public UUID GroupID { get { return m_GroupID; } }
  1737. /// <summary>Get the titles</summary>
  1738. public Dictionary<UUID, GroupTitle> Titles { get { return m_Titles; } }
  1739. /// <summary>Construct a new instance of the GroupTitlesReplyEventArgs class</summary>
  1740. /// <param name="requestID">The ID as returned by the request to correlate
  1741. /// this result set and the request</param>
  1742. /// <param name="groupID">The ID of the group</param>
  1743. /// <param name="titles">The titles</param>
  1744. public GroupTitlesReplyEventArgs(UUID requestID, UUID groupID, Dictionary<UUID, GroupTitle> titles)
  1745. {
  1746. this.m_RequestID = requestID;
  1747. this.m_GroupID = groupID;
  1748. this.m_Titles = titles;
  1749. }
  1750. }
  1751. /// <summary>Represents the summary data for a group</summary>
  1752. public class GroupAccountSummaryReplyEventArgs : EventArgs
  1753. {
  1754. private readonly UUID m_GroupID;
  1755. private readonly GroupAccountSummary m_Summary;
  1756. /// <summary>Get the ID of the group</summary>
  1757. public UUID GroupID { get { return m_GroupID; } }
  1758. /// <summary>Get the summary data</summary>
  1759. public GroupAccountSummary Summary { get { return m_Summary; } }
  1760. /// <summary>Construct a new instance of the GroupAccountSummaryReplyEventArgs class</summary>
  1761. /// <param name="groupID">The ID of the group</param>
  1762. /// <param name="summary">The summary data</param>
  1763. public GroupAccountSummaryReplyEventArgs(UUID groupID, GroupAccountSummary summary)
  1764. {
  1765. this.m_GroupID = groupID;
  1766. this.m_Summary = summary;
  1767. }
  1768. }
  1769. /// <summary>A response to a group create request</summary>
  1770. public class GroupCreatedReplyEventArgs : EventArgs
  1771. {
  1772. private readonly UUID m_GroupID;
  1773. private readonly bool m_Success;
  1774. private readonly string m_Message;
  1775. /// <summary>Get the ID of the group</summary>
  1776. public UUID GroupID { get { return m_GroupID; } }
  1777. /// <summary>true of the group was created successfully</summary>
  1778. public bool Success { get { return m_Success; } }
  1779. /// <summary>A string containing the message</summary>
  1780. public string Message { get { return m_Message; } }
  1781. /// <summary>Construct a new instance of the GroupCreatedReplyEventArgs class</summary>
  1782. /// <param name="groupID">The ID of the group</param>
  1783. /// <param name="success">the success or faulure of the request</param>
  1784. /// <param name="messsage">A string containing additional information</param>
  1785. public GroupCreatedReplyEventArgs(UUID groupID, bool success, string messsage)
  1786. {
  1787. this.m_GroupID = groupID;
  1788. this.m_Success = success;
  1789. this.m_Message = messsage;
  1790. }
  1791. }
  1792. /// <summary>Represents a response to a request</summary>
  1793. public class GroupOperationEventArgs : EventArgs
  1794. {
  1795. private readonly UUID m_GroupID;
  1796. private readonly bool m_Success;
  1797. /// <summary>Get the ID of the group</summary>
  1798. public UUID GroupID { get { return m_GroupID; } }
  1799. /// <summary>true of the request was successful</summary>
  1800. public bool Success { get { return m_Success; } }
  1801. /// <summary>Construct a new instance of the GroupOperationEventArgs class</summary>
  1802. /// <param name="groupID">The ID of the group</param>
  1803. /// <param name="success">true of the request was successful</param>
  1804. public GroupOperationEventArgs(UUID groupID, bool success)
  1805. {
  1806. this.m_GroupID = groupID;
  1807. this.m_Success = success;
  1808. }
  1809. }
  1810. /// <summary>Represents your agent leaving a group</summary>
  1811. public class GroupDroppedEventArgs : EventArgs
  1812. {
  1813. private readonly UUID m_GroupID;
  1814. /// <summary>Get the ID of the group</summary>
  1815. public UUID GroupID { get { return m_GroupID; } }
  1816. /// <summary>Construct a new instance of the GroupDroppedEventArgs class</summary>
  1817. /// <param name="groupID">The ID of the group</param>
  1818. public GroupDroppedEventArgs(UUID groupID)
  1819. {
  1820. m_GroupID = groupID;
  1821. }
  1822. }
  1823. /// <summary>Represents a list of active group notices</summary>
  1824. public class GroupNoticesListReplyEventArgs : EventArgs
  1825. {
  1826. private readonly UUID m_GroupID;
  1827. private readonly List<GroupNoticesListEntry> m_Notices;
  1828. /// <summary>Get the ID of the group</summary>
  1829. public UUID GroupID { get { return m_GroupID; } }
  1830. /// <summary>Get the notices list</summary>
  1831. public List<GroupNoticesListEntry> Notices { get { return m_Notices; } }
  1832. /// <summary>Construct a new instance of the GroupNoticesListReplyEventArgs class</summary>
  1833. /// <param name="groupID">The ID of the group</param>
  1834. /// <param name="notices">The list containing active notices</param>
  1835. public GroupNoticesListReplyEventArgs(UUID groupID, List<GroupNoticesListEntry> notices)
  1836. {
  1837. m_GroupID = groupID;
  1838. m_Notices = notices;
  1839. }
  1840. }
  1841. /// <summary>Represents the profile of a group</summary>
  1842. public class GroupProfileEventArgs : EventArgs
  1843. {
  1844. private readonly Group m_Group;
  1845. /// <summary>Get the group profile</summary>
  1846. public Group Group { get { return m_Group; } }
  1847. /// <summary>Construct a new instance of the GroupProfileEventArgs class</summary>
  1848. /// <param name="group">The group profile</param>
  1849. public GroupProfileEventArgs(Group group)
  1850. {
  1851. this.m_Group = group;
  1852. }
  1853. }
  1854. /// <summary>
  1855. /// Provides notification of a group invitation request sent by another Avatar
  1856. /// </summary>
  1857. /// <remarks>The <see cref="GroupInvitation"/> invitation is raised when another avatar makes an offer for our avatar
  1858. /// to join a group.</remarks>
  1859. public class GroupInvitationEventArgs : EventArgs
  1860. {
  1861. private readonly UUID m_FromAgentID;
  1862. private readonly string m_FromAgentName;
  1863. private readonly string m_Message;
  1864. private readonly Simulator m_Simulator;
  1865. /// <summary>The ID of the Avatar sending the group invitation</summary>
  1866. public UUID AgentID { get { return m_FromAgentID; } }
  1867. /// <summary>The name of the Avatar sending the group invitation</summary>
  1868. public string FromName { get { return m_FromAgentName; } }
  1869. /// <summary>A message containing the request information which includes
  1870. /// the name of the group, the groups charter and the fee to join details</summary>
  1871. public string Message { get { return m_Message; } }
  1872. /// <summary>The Simulator</summary>
  1873. public Simulator Simulator { get { return m_Simulator; } }
  1874. /// <summary>Set to true to accept invitation, false to decline</summary>
  1875. public bool Accept { get; set; }
  1876. public GroupInvitationEventArgs(Simulator simulator, UUID agentID, string agentName, string message)
  1877. {
  1878. this.m_Simulator = simulator;
  1879. this.m_FromAgentID = agentID;
  1880. this.m_FromAgentName = agentName;
  1881. this.m_Message = message;
  1882. }
  1883. }
  1884. #endregion
  1885. }