/OpenMetaverse/Modules/GroupManager.cs
C# | 2165 lines | 1300 code | 280 blank | 585 comment | 101 complexity | 07afd5a540832efd83ff1b997a820131 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /*
- * Copyright (c) 2007-2009, openmetaverse.org
- * All rights reserved.
- *
- * - Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * - Neither the name of the openmetaverse.org nor the names
- * of its contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using OpenMetaverse.Packets;
- using OpenMetaverse.StructuredData;
- using OpenMetaverse.Messages.Linden;
- using OpenMetaverse.Interfaces;
- namespace OpenMetaverse
- {
- #region Structs
- /// <summary>
- /// Avatar group management
- /// </summary>
- public struct GroupMember
- {
- /// <summary>Key of Group Member</summary>
- public UUID ID;
- /// <summary>Total land contribution</summary>
- public int Contribution;
- /// <summary>Online status information</summary>
- public string OnlineStatus;
- /// <summary>Abilities that the Group Member has</summary>
- public GroupPowers Powers;
- /// <summary>Current group title</summary>
- public string Title;
- /// <summary>Is a group owner</summary>
- public bool IsOwner;
- }
- /// <summary>
- /// Role manager for a group
- /// </summary>
- public struct GroupRole
- {
- /// <summary>Key of the group</summary>
- public UUID GroupID;
- /// <summary>Key of Role</summary>
- public UUID ID;
- /// <summary>Name of Role</summary>
- public string Name;
- /// <summary>Group Title associated with Role</summary>
- public string Title;
- /// <summary>Description of Role</summary>
- public string Description;
- /// <summary>Abilities Associated with Role</summary>
- public GroupPowers Powers;
- /// <summary>Returns the role's title</summary>
- /// <returns>The role's title</returns>
- public override string ToString()
- {
- return Name;
- }
- }
- /// <summary>
- /// Class to represent Group Title
- /// </summary>
- public struct GroupTitle
- {
- /// <summary>Key of the group</summary>
- public UUID GroupID;
- /// <summary>ID of the role title belongs to</summary>
- public UUID RoleID;
- /// <summary>Group Title</summary>
- public string Title;
- /// <summary>Whether title is Active</summary>
- public bool Selected;
- /// <summary>Returns group title</summary>
- public override string ToString()
- {
- return Title;
- }
- }
- /// <summary>
- /// Represents a group on the grid
- /// </summary>
- public struct Group
- {
- /// <summary>Key of Group</summary>
- public UUID ID;
- /// <summary>Key of Group Insignia</summary>
- public UUID InsigniaID;
- /// <summary>Key of Group Founder</summary>
- public UUID FounderID;
- /// <summary>Key of Group Role for Owners</summary>
- public UUID OwnerRole;
- /// <summary>Name of Group</summary>
- public string Name;
- /// <summary>Text of Group Charter</summary>
- public string Charter;
- /// <summary>Title of "everyone" role</summary>
- public string MemberTitle;
- /// <summary>Is the group open for enrolement to everyone</summary>
- public bool OpenEnrollment;
- /// <summary>Will group show up in search</summary>
- public bool ShowInList;
- /// <summary></summary>
- public GroupPowers Powers;
- /// <summary></summary>
- public bool AcceptNotices;
- /// <summary></summary>
- public bool AllowPublish;
- /// <summary>Is the group Mature</summary>
- public bool MaturePublish;
- /// <summary>Cost of group membership</summary>
- public int MembershipFee;
- /// <summary></summary>
- public int Money;
- /// <summary></summary>
- public int Contribution;
- /// <summary>The total number of current members this group has</summary>
- public int GroupMembershipCount;
- /// <summary>The number of roles this group has configured</summary>
- public int GroupRolesCount;
- /// <summary>Show this group in agent's profile</summary>
- public bool ListInProfile;
- /// <summary>Returns the name of the group</summary>
- /// <returns>A string containing the name of the group</returns>
- public override string ToString()
- {
- return Name;
- }
- }
- /// <summary>
- /// A group Vote
- /// </summary>
- public struct Vote
- {
- /// <summary>Key of Avatar who created Vote</summary>
- public UUID Candidate;
- /// <summary>Text of the Vote proposal</summary>
- public string VoteString;
- /// <summary>Total number of votes</summary>
- public int NumVotes;
- }
- /// <summary>
- /// A group proposal
- /// </summary>
- public struct GroupProposal
- {
- /// <summary>The Text of the proposal</summary>
- public string VoteText;
- /// <summary>The minimum number of members that must vote before proposal passes or failes</summary>
- public int Quorum;
- /// <summary>The required ration of yes/no votes required for vote to pass</summary>
- /// <remarks>The three options are Simple Majority, 2/3 Majority, and Unanimous</remarks>
- /// TODO: this should be an enum
- public float Majority;
- /// <summary>The duration in days votes are accepted</summary>
- public int Duration;
- }
- /// <summary>
- ///
- /// </summary>
- public struct GroupAccountSummary
- {
- /// <summary></summary>
- public int IntervalDays;
- /// <summary></summary>
- public int CurrentInterval;
- /// <summary></summary>
- public string StartDate;
- /// <summary></summary>
- public int Balance;
- /// <summary></summary>
- public int TotalCredits;
- /// <summary></summary>
- public int TotalDebits;
- /// <summary></summary>
- public int ObjectTaxCurrent;
- /// <summary></summary>
- public int LightTaxCurrent;
- /// <summary></summary>
- public int LandTaxCurrent;
- /// <summary></summary>
- public int GroupTaxCurrent;
- /// <summary></summary>
- public int ParcelDirFeeCurrent;
- /// <summary></summary>
- public int ObjectTaxEstimate;
- /// <summary></summary>
- public int LightTaxEstimate;
- /// <summary></summary>
- public int LandTaxEstimate;
- /// <summary></summary>
- public int GroupTaxEstimate;
- /// <summary></summary>
- public int ParcelDirFeeEstimate;
- /// <summary></summary>
- public int NonExemptMembers;
- /// <summary></summary>
- public string LastTaxDate;
- /// <summary></summary>
- public string TaxDate;
- }
- /// <summary>
- /// Struct representing a group notice
- /// </summary>
- public struct GroupNotice
- {
- /// <summary></summary>
- public string Subject;
- /// <summary></summary>
- public string Message;
- /// <summary></summary>
- public UUID AttachmentID;
- /// <summary></summary>
- public UUID OwnerID;
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public byte[] SerializeAttachment()
- {
- if (OwnerID == UUID.Zero || AttachmentID == UUID.Zero)
- return Utils.EmptyBytes;
- OpenMetaverse.StructuredData.OSDMap att = new OpenMetaverse.StructuredData.OSDMap();
- att.Add("item_id", OpenMetaverse.StructuredData.OSD.FromUUID(AttachmentID));
- att.Add("owner_id", OpenMetaverse.StructuredData.OSD.FromUUID(OwnerID));
- return OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlBytes(att);
- /*
- //I guess this is how this works, no gaurentees
- string lsd = "<llsd><item_id>" + AttachmentID.ToString() + "</item_id><owner_id>"
- + OwnerID.ToString() + "</owner_id></llsd>";
- return Utils.StringToBytes(lsd);
- */
- }
- }
- /// <summary>
- /// Struct representing a group notice list entry
- /// </summary>
- public struct GroupNoticesListEntry
- {
- /// <summary>Notice ID</summary>
- public UUID NoticeID;
- /// <summary>Creation timestamp of notice</summary>
- public uint Timestamp;
- /// <summary>Agent name who created notice</summary>
- public string FromName;
- /// <summary>Notice subject</summary>
- public string Subject;
- /// <summary>Is there an attachment?</summary>
- public bool HasAttachment;
- /// <summary>Attachment Type</summary>
- public AssetType AssetType;
- }
- /// <summary>
- /// Struct representing a member of a group chat session and their settings
- /// </summary>
- public struct ChatSessionMember
- {
- /// <summary>The <see cref="UUID"/> of the Avatar</summary>
- public UUID AvatarKey;
- /// <summary>True if user has voice chat enabled</summary>
- public bool CanVoiceChat;
- /// <summary>True of Avatar has moderator abilities</summary>
- public bool IsModerator;
- /// <summary>True if a moderator has muted this avatars chat</summary>
- public bool MuteText;
- /// <summary>True if a moderator has muted this avatars voice</summary>
- public bool MuteVoice;
- }
- #endregion Structs
- #region Enums
- /// <summary>
- /// Role update flags
- /// </summary>
- public enum GroupRoleUpdate : uint
- {
- /// <summary></summary>
- NoUpdate,
- /// <summary></summary>
- UpdateData,
- /// <summary></summary>
- UpdatePowers,
- /// <summary></summary>
- UpdateAll,
- /// <summary></summary>
- Create,
- /// <summary></summary>
- Delete
- }
- [Flags]
- public enum GroupPowers : ulong
- {
- /// <summary></summary>
- None = 0,
- // Membership
- /// <summary>Can send invitations to groups default role</summary>
- Invite = 1UL << 1,
- /// <summary>Can eject members from group</summary>
- Eject = 1UL << 2,
- /// <summary>Can toggle 'Open Enrollment' and change 'Signup fee'</summary>
- ChangeOptions = 1UL << 3,
- /// <summary>Member is visible in the public member list</summary>
- MemberVisible = 1UL << 47,
- // Roles
- /// <summary>Can create new roles</summary>
- CreateRole = 1UL << 4,
- /// <summary>Can delete existing roles</summary>
- DeleteRole = 1UL << 5,
- /// <summary>Can change Role names, titles and descriptions</summary>
- RoleProperties = 1UL << 6,
- /// <summary>Can assign other members to assigners role</summary>
- AssignMemberLimited = 1UL << 7,
- /// <summary>Can assign other members to any role</summary>
- AssignMember = 1UL << 8,
- /// <summary>Can remove members from roles</summary>
- RemoveMember = 1UL << 9,
- /// <summary>Can assign and remove abilities in roles</summary>
- ChangeActions = 1UL << 10,
- // Identity
- /// <summary>Can change group Charter, Insignia, 'Publish on the web' and which
- /// members are publicly visible in group member listings</summary>
- ChangeIdentity = 1UL << 11,
- // Parcel management
- /// <summary>Can buy land or deed land to group</summary>
- LandDeed = 1UL << 12,
- /// <summary>Can abandon group owned land to Governor Linden on mainland, or Estate owner for
- /// private estates</summary>
- LandRelease = 1UL << 13,
- /// <summary>Can set land for-sale information on group owned parcels</summary>
- LandSetSale = 1UL << 14,
- /// <summary>Can subdivide and join parcels</summary>
- LandDivideJoin = 1UL << 15,
- // Chat
- /// <summary>Can join group chat sessions</summary>
- JoinChat = 1UL << 16,
- /// <summary>Can use voice chat in Group Chat sessions</summary>
- AllowVoiceChat = 1UL << 27,
- /// <summary>Can moderate group chat sessions</summary>
- ModerateChat = 1UL << 37,
- // Parcel identity
- /// <summary>Can toggle "Show in Find Places" and set search category</summary>
- FindPlaces = 1UL << 17,
- /// <summary>Can change parcel name, description, and 'Publish on web' settings</summary>
- LandChangeIdentity = 1UL << 18,
- /// <summary>Can set the landing point and teleport routing on group land</summary>
- SetLandingPoint = 1UL << 19,
- // Parcel settings
- /// <summary>Can change music and media settings</summary>
- ChangeMedia = 1UL << 20,
- /// <summary>Can toggle 'Edit Terrain' option in Land settings</summary>
- LandEdit = 1UL << 21,
- /// <summary>Can toggle various About Land > Options settings</summary>
- LandOptions = 1UL << 22,
- // Parcel powers
- /// <summary>Can always terraform land, even if parcel settings have it turned off</summary>
- AllowEditLand = 1UL << 23,
- /// <summary>Can always fly while over group owned land</summary>
- AllowFly = 1UL << 24,
- /// <summary>Can always rez objects on group owned land</summary>
- AllowRez = 1UL << 25,
- /// <summary>Can always create landmarks for group owned parcels</summary>
- AllowLandmark = 1UL << 26,
- /// <summary>Can set home location on any group owned parcel</summary>
- AllowSetHome = 1UL << 28,
- // Parcel access
- /// <summary>Can modify public access settings for group owned parcels</summary>
- LandManageAllowed = 1UL << 29,
- /// <summary>Can manager parcel ban lists on group owned land</summary>
- LandManageBanned = 1UL << 30,
- /// <summary>Can manage pass list sales information</summary>
- LandManagePasses = 1UL << 31,
- /// <summary>Can eject and freeze other avatars on group owned land</summary>
- LandEjectAndFreeze = 1UL << 32,
- // Parcel content
- /// <summary>Can return objects set to group</summary>
- ReturnGroupSet = 1UL << 33,
- /// <summary>Can return non-group owned/set objects</summary>
- ReturnNonGroup = 1UL << 34,
- /// <summary>Can return group owned objects</summary>
- ReturnGroupOwned = 1UL << 48,
- /// <summary>Can landscape using Linden plants</summary>
- LandGardening = 1UL << 35,
- // Objects
- /// <summary>Can deed objects to group</summary>
- DeedObject = 1UL << 36,
- /// <summary>Can move group owned objects</summary>
- ObjectManipulate = 1UL << 38,
- /// <summary>Can set group owned objects for-sale</summary>
- ObjectSetForSale = 1UL << 39,
- /// <summary>Pay group liabilities and receive group dividends</summary>
- Accountable = 1UL << 40,
- /// <summary>List and Host group events</summary>
- HostEvent = 1UL << 41,
- // Notices and proposals
- /// <summary>Can send group notices</summary>
- SendNotices = 1UL << 42,
- /// <summary>Can receive group notices</summary>
- ReceiveNotices = 1UL << 43,
- /// <summary>Can create group proposals</summary>
- StartProposal = 1UL << 44,
- /// <summary>Can vote on group proposals</summary>
- VoteOnProposal = 1UL << 45
- }
- #endregion Enums
- /// <summary>
- /// Handles all network traffic related to reading and writing group
- /// information
- /// </summary>
- public class GroupManager
- {
- #region Delegates
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<CurrentGroupsEventArgs> m_CurrentGroups;
- /// <summary>Raises the CurrentGroups event</summary>
- /// <param name="e">A CurrentGroupsEventArgs object containing the
- /// data sent from the simulator</param>
- protected virtual void OnCurrentGroups(CurrentGroupsEventArgs e)
- {
- EventHandler<CurrentGroupsEventArgs> handler = m_CurrentGroups;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_CurrentGroupsLock = new object();
- /// <summary>Raised when the simulator sends us data containing
- /// our current group membership</summary>
- public event EventHandler<CurrentGroupsEventArgs> CurrentGroups
- {
- add { lock (m_CurrentGroupsLock) { m_CurrentGroups += value; } }
- remove { lock (m_CurrentGroupsLock) { m_CurrentGroups -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupNamesEventArgs> m_GroupNames;
- /// <summary>Raises the GroupNamesReply event</summary>
- /// <param name="e">A GroupNamesEventArgs object containing the
- /// data response from the simulator</param>
- protected virtual void OnGroupNamesReply(GroupNamesEventArgs e)
- {
- EventHandler<GroupNamesEventArgs> handler = m_GroupNames;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupNamesLock = new object();
- /// <summary>Raised when the simulator responds to a RequestGroupName
- /// or RequestGroupNames request</summary>
- public event EventHandler<GroupNamesEventArgs> GroupNamesReply
- {
- add { lock (m_GroupNamesLock) { m_GroupNames += value; } }
- remove { lock (m_GroupNamesLock) { m_GroupNames -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupProfileEventArgs> m_GroupProfile;
- /// <summary>Raises the GroupProfile event</summary>
- /// <param name="e">An GroupProfileEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupProfile(GroupProfileEventArgs e)
- {
- EventHandler<GroupProfileEventArgs> handler = m_GroupProfile;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupProfileLock = new object();
- /// <summary>Raised when the simulator responds to a <see cref="RequestGroupProfile"/> request</summary>
- public event EventHandler<GroupProfileEventArgs> GroupProfile
- {
- add { lock (m_GroupProfileLock) { m_GroupProfile += value; } }
- remove { lock (m_GroupProfileLock) { m_GroupProfile -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupMembersReplyEventArgs> m_GroupMembers;
- /// <summary>Raises the GroupMembers event</summary>
- /// <param name="e">A GroupMembersEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupMembersReply(GroupMembersReplyEventArgs e)
- {
- EventHandler<GroupMembersReplyEventArgs> handler = m_GroupMembers;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupMembersLock = new object();
- /// <summary>Raised when the simulator responds to a <see cref="RequestGroupMembers"/> request</summary>
- public event EventHandler<GroupMembersReplyEventArgs> GroupMembersReply
- {
- add { lock (m_GroupMembersLock) { m_GroupMembers += value; } }
- remove { lock (m_GroupMembersLock) { m_GroupMembers -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupRolesDataReplyEventArgs> m_GroupRoles;
- /// <summary>Raises the GroupRolesDataReply event</summary>
- /// <param name="e">A GroupRolesDataReplyEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupRoleDataReply(GroupRolesDataReplyEventArgs e)
- {
- EventHandler<GroupRolesDataReplyEventArgs> handler = m_GroupRoles;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupRolesLock = new object();
- /// <summary>Raised when the simulator responds to a <see cref="RequestGroupRoleData"/> request</summary>
- public event EventHandler<GroupRolesDataReplyEventArgs> GroupRoleDataReply
- {
- add { lock (m_GroupRolesLock) { m_GroupRoles += value; } }
- remove { lock (m_GroupRolesLock) { m_GroupRoles -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupRolesMembersReplyEventArgs> m_GroupRoleMembers;
- /// <summary>Raises the GroupRoleMembersReply event</summary>
- /// <param name="e">A GroupRolesRoleMembersReplyEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupRoleMembers(GroupRolesMembersReplyEventArgs e)
- {
- EventHandler<GroupRolesMembersReplyEventArgs> handler = m_GroupRoleMembers;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupRolesMembersLock = new object();
- /// <summary>Raised when the simulator responds to a <see cref="RequestGroupRolesMembers"/> request</summary>
- public event EventHandler<GroupRolesMembersReplyEventArgs> GroupRoleMembersReply
- {
- add { lock (m_GroupRolesMembersLock) { m_GroupRoleMembers += value; } }
- remove { lock (m_GroupRolesMembersLock) { m_GroupRoleMembers -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupTitlesReplyEventArgs> m_GroupTitles;
- /// <summary>Raises the GroupTitlesReply event</summary>
- /// <param name="e">A GroupTitlesReplyEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupTitles(GroupTitlesReplyEventArgs e)
- {
- EventHandler<GroupTitlesReplyEventArgs> handler = m_GroupTitles;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupTitlesLock = new object();
- /// <summary>Raised when the simulator responds to a <see cref="RequestGroupTitles"/> request</summary>
- public event EventHandler<GroupTitlesReplyEventArgs> GroupTitlesReply
- {
- add { lock (m_GroupTitlesLock) { m_GroupTitles += value; } }
- remove { lock (m_GroupTitlesLock) { m_GroupTitles -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupAccountSummaryReplyEventArgs> m_GroupAccountSummary;
- /// <summary>Raises the GroupAccountSummary event</summary>
- /// <param name="e">A GroupAccountSummaryReplyEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupAccountSummaryReply(GroupAccountSummaryReplyEventArgs e)
- {
- EventHandler<GroupAccountSummaryReplyEventArgs> handler = m_GroupAccountSummary;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupAccountSummaryLock = new object();
- /// <summary>Raised when a response to a RequestGroupAccountSummary is returned
- /// by the simulator</summary>
- public event EventHandler<GroupAccountSummaryReplyEventArgs> GroupAccountSummaryReply
- {
- add { lock (m_GroupAccountSummaryLock) { m_GroupAccountSummary += value; } }
- remove { lock (m_GroupAccountSummaryLock) { m_GroupAccountSummary -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupCreatedReplyEventArgs> m_GroupCreated;
- /// <summary>Raises the GroupCreated event</summary>
- /// <param name="e">An GroupCreatedEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupCreatedReply(GroupCreatedReplyEventArgs e)
- {
- EventHandler<GroupCreatedReplyEventArgs> handler = m_GroupCreated;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupCreatedLock = new object();
- /// <summary>Raised when a request to create a group is successful</summary>
- public event EventHandler<GroupCreatedReplyEventArgs> GroupCreatedReply
- {
- add { lock (m_GroupCreatedLock) { m_GroupCreated += value; } }
- remove { lock (m_GroupCreatedLock) { m_GroupCreated -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupOperationEventArgs> m_GroupJoined;
- /// <summary>Raises the GroupJoined event</summary>
- /// <param name="e">A GroupOperationEventArgs object containing the
- /// result of the operation returned from the simulator</param>
- protected virtual void OnGroupJoinedReply(GroupOperationEventArgs e)
- {
- EventHandler<GroupOperationEventArgs> handler = m_GroupJoined;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupJoinedLock = new object();
- /// <summary>Raised when a request to join a group either
- /// fails or succeeds</summary>
- public event EventHandler<GroupOperationEventArgs> GroupJoinedReply
- {
- add { lock (m_GroupJoinedLock) { m_GroupJoined += value; } }
- remove { lock (m_GroupJoinedLock) { m_GroupJoined -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupOperationEventArgs> m_GroupLeft;
- /// <summary>Raises the GroupLeft event</summary>
- /// <param name="e">A GroupOperationEventArgs object containing the
- /// result of the operation returned from the simulator</param>
- protected virtual void OnGroupLeaveReply(GroupOperationEventArgs e)
- {
- EventHandler<GroupOperationEventArgs> handler = m_GroupLeft;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupLeftLock = new object();
- /// <summary>Raised when a request to leave a group either
- /// fails or succeeds</summary>
- public event EventHandler<GroupOperationEventArgs> GroupLeaveReply
- {
- add { lock (m_GroupLeftLock) { m_GroupLeft += value; } }
- remove { lock (m_GroupLeftLock) { m_GroupLeft -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupDroppedEventArgs> m_GroupDropped;
- /// <summary>Raises the GroupDropped event</summary>
- /// <param name="e">An GroupDroppedEventArgs object containing the
- /// the group your agent left</param>
- protected virtual void OnGroupDropped(GroupDroppedEventArgs e)
- {
- EventHandler<GroupDroppedEventArgs> handler = m_GroupDropped;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupDroppedLock = new object();
- /// <summary>Raised when A group is removed from the group server</summary>
- public event EventHandler<GroupDroppedEventArgs> GroupDropped
- {
- add { lock (m_GroupDroppedLock) { m_GroupDropped += value; } }
- remove { lock (m_GroupDroppedLock) { m_GroupDropped -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupOperationEventArgs> m_GroupMemberEjected;
- /// <summary>Raises the GroupMemberEjected event</summary>
- /// <param name="e">An GroupMemberEjectedEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupMemberEjected(GroupOperationEventArgs e)
- {
- EventHandler<GroupOperationEventArgs> handler = m_GroupMemberEjected;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupMemberEjectedLock = new object();
- /// <summary>Raised when a request to eject a member from a group either
- /// fails or succeeds</summary>
- public event EventHandler<GroupOperationEventArgs> GroupMemberEjected
- {
- add { lock (m_GroupMemberEjectedLock) { m_GroupMemberEjected += value; } }
- remove { lock (m_GroupMemberEjectedLock) { m_GroupMemberEjected -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupNoticesListReplyEventArgs> m_GroupNoticesListReply;
- /// <summary>Raises the GroupNoticesListReply event</summary>
- /// <param name="e">An GroupNoticesListReplyEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupNoticesListReply(GroupNoticesListReplyEventArgs e)
- {
- EventHandler<GroupNoticesListReplyEventArgs> handler = m_GroupNoticesListReply;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupNoticesListReplyLock = new object();
- /// <summary>Raised when the simulator sends us group notices</summary>
- /// <seealso cref="RequestGroupNoticesList"/>
- public event EventHandler<GroupNoticesListReplyEventArgs> GroupNoticesListReply
- {
- add { lock (m_GroupNoticesListReplyLock) { m_GroupNoticesListReply += value; } }
- remove { lock (m_GroupNoticesListReplyLock) { m_GroupNoticesListReply -= value; } }
- }
- /// <summary>The event subscribers. null if no subcribers</summary>
- private EventHandler<GroupInvitationEventArgs> m_GroupInvitation;
- /// <summary>Raises the GroupInvitation event</summary>
- /// <param name="e">An GroupInvitationEventArgs object containing the
- /// data returned from the simulator</param>
- protected virtual void OnGroupInvitation(GroupInvitationEventArgs e)
- {
- EventHandler<GroupInvitationEventArgs> handler = m_GroupInvitation;
- if (handler != null)
- handler(this, e);
- }
- /// <summary>Thread sync lock object</summary>
- private readonly object m_GroupInvitationLock = new object();
- /// <summary>Raised when another agent invites our avatar to join a group</summary>
- public event EventHandler<GroupInvitationEventArgs> GroupInvitation
- {
- add { lock (m_GroupInvitationLock) { m_GroupInvitation += value; } }
- remove { lock (m_GroupInvitationLock) { m_GroupInvitation -= value; } }
- }
- #endregion Delegates
- #region Events
- #endregion Events
- /// <summary>A reference to the current <seealso cref="GridClient"/> instance</summary>
- private GridClient Client;
- /// <summary>Currently-active group members requests</summary>
- private List<UUID> GroupMembersRequests;
- /// <summary>Currently-active group roles requests</summary>
- private List<UUID> GroupRolesRequests;
- /// <summary>Currently-active group role-member requests</summary>
- private List<UUID> GroupRolesMembersRequests;
- /// <summary>Dictionary keeping group members while request is in progress</summary>
- private InternalDictionary<UUID, Dictionary<UUID, GroupMember>> TempGroupMembers;
- /// <summary>Dictionary keeping mebmer/role mapping while request is in progress</summary>
- private InternalDictionary<UUID, List<KeyValuePair<UUID, UUID>>> TempGroupRolesMembers;
- /// <summary>Dictionary keeping GroupRole information while request is in progress</summary>
- private InternalDictionary<UUID, Dictionary<UUID, GroupRole>> TempGroupRoles;
- /// <summary>Caches group name lookups</summary>
- public InternalDictionary<UUID, string> GroupName2KeyCache;
- /// <summary>
- /// Construct a new instance of the GroupManager class
- /// </summary>
- /// <param name="client">A reference to the current <seealso cref="GridClient"/> instance</param>
- public GroupManager(GridClient client)
- {
- Client = client;
- TempGroupMembers = new InternalDictionary<UUID, Dictionary<UUID, GroupMember>>();
- GroupMembersRequests = new List<UUID>();
- TempGroupRoles = new InternalDictionary<UUID, Dictionary<UUID, GroupRole>>();
- GroupRolesRequests = new List<UUID>();
- TempGroupRolesMembers = new InternalDictionary<UUID, List<KeyValuePair<UUID, UUID>>>();
- GroupRolesMembersRequests = new List<UUID>();
- GroupName2KeyCache = new InternalDictionary<UUID, string>();
- Client.Self.IM += Self_IM;
- Client.Network.RegisterEventCallback("AgentGroupDataUpdate", new Caps.EventQueueCallback(AgentGroupDataUpdateMessageHandler));
- // deprecated in simulator v1.27
- Client.Network.RegisterCallback(PacketType.AgentDropGroup, AgentDropGroupHandler);
- Client.Network.RegisterCallback(PacketType.GroupTitlesReply, GroupTitlesReplyHandler);
- Client.Network.RegisterCallback(PacketType.GroupProfileReply, GroupProfileReplyHandler);
- Client.Network.RegisterCallback(PacketType.GroupMembersReply, GroupMembersHandler);
- Client.Network.RegisterCallback(PacketType.GroupRoleDataReply, GroupRoleDataReplyHandler);
- Client.Network.RegisterCallback(PacketType.GroupRoleMembersReply, GroupRoleMembersReplyHandler);
- Client.Network.RegisterCallback(PacketType.GroupActiveProposalItemReply, GroupActiveProposalItemHandler);
- Client.Network.RegisterCallback(PacketType.GroupVoteHistoryItemReply, GroupVoteHistoryItemHandler);
- Client.Network.RegisterCallback(PacketType.GroupAccountSummaryReply, GroupAccountSummaryReplyHandler);
- Client.Network.RegisterCallback(PacketType.CreateGroupReply, CreateGroupReplyHandler);
- Client.Network.RegisterCallback(PacketType.JoinGroupReply, JoinGroupReplyHandler);
- Client.Network.RegisterCallback(PacketType.LeaveGroupReply, LeaveGroupReplyHandler);
- Client.Network.RegisterCallback(PacketType.UUIDGroupNameReply, UUIDGroupNameReplyHandler);
- Client.Network.RegisterCallback(PacketType.EjectGroupMemberReply, EjectGroupMemberReplyHandler);
- Client.Network.RegisterCallback(PacketType.GroupNoticesListReply, GroupNoticesListReplyHandler);
- Client.Network.RegisterEventCallback("AgentDropGroup", new Caps.EventQueueCallback(AgentDropGroupMessageHandler));
- }
- void Self_IM(object sender, InstantMessageEventArgs e)
- {
- if(m_GroupInvitation != null && e.IM.Dialog == InstantMessageDialog.GroupInvitation)
- {
- GroupInvitationEventArgs args = new GroupInvitationEventArgs(e.Simulator, e.IM.FromAgentID, e.IM.FromAgentName, e.IM.Message);
- OnGroupInvitation(args);
- if (args.Accept)
- {
- Client.Self.InstantMessage("name", e.IM.FromAgentID, "message", e.IM.IMSessionID, InstantMessageDialog.GroupInvitationAccept,
- InstantMessageOnline.Online, Client.Self.SimPosition, UUID.Zero, Utils.EmptyBytes);
- }
- else
- {
- Client.Self.InstantMessage("name", e.IM.FromAgentID, "message", e.IM.IMSessionID, InstantMessageDialog.GroupInvitationDecline,
- InstantMessageOnline.Online, Client.Self.SimPosition, UUID.Zero, new byte[1] { 0 });
- }
- }
- }
- #region Public Methods
- /// <summary>
- /// Request a current list of groups the avatar is a member of.
- /// </summary>
- /// <remarks>CAPS Event Queue must be running for this to work since the results
- /// come across CAPS.</remarks>
- public void RequestCurrentGroups()
- {
- AgentDataUpdateRequestPacket request = new AgentDataUpdateRequestPacket();
- request.AgentData.AgentID = Client.Self.AgentID;
- request.AgentData.SessionID = Client.Self.SessionID;
- Client.Network.SendPacket(request);
- }
- /// <summary>
- /// Lookup name of group based on groupID
- /// </summary>
- /// <param name="groupID">groupID of group to lookup name for.</param>
- public void RequestGroupName(UUID groupID)
- {
- // if we already have this in the cache, return from cache instead of making a request
- if (GroupName2KeyCache.ContainsKey(groupID))
- {
- Dictionary<UUID, string> groupNames = new Dictionary<UUID, string>();
- lock (GroupName2KeyCache.Dictionary)
- groupNames.Add(groupID, GroupName2KeyCache.Dictionary[groupID]);
- if (m_GroupNames != null)
- {
- OnGroupNamesReply(new GroupNamesEventArgs(groupNames));
- }
- }
- else
- {
- UUIDGroupNameRequestPacket req = new UUIDGroupNameRequestPacket();
- UUIDGroupNameRequestPacket.UUIDNameBlockBlock[] block = new UUIDGroupNameRequestPacket.UUIDNameBlockBlock[1];
- block[0] = new UUIDGroupNameRequestPacket.UUIDNameBlockBlock();
- block[0].ID = groupID;
- req.UUIDNameBlock = block;
- Client.Network.SendPacket(req);
- }
- }
- /// <summary>
- /// Request lookup of multiple group names
- /// </summary>
- /// <param name="groupIDs">List of group IDs to request.</param>
- public void RequestGroupNames(List<UUID> groupIDs)
- {
- Dictionary<UUID, string> groupNames = new Dictionary<UUID, string>();
- lock (GroupName2KeyCache.Dictionary)
- {
- foreach (UUID groupID in groupIDs)
- {
- if (GroupName2KeyCache.ContainsKey(groupID))
- groupNames[groupID] = GroupName2KeyCache.Dictionary[groupID];
- }
- }
- if (groupIDs.Count > 0)
- {
- UUIDGroupNameRequestPacket req = new UUIDGroupNameRequestPacket();
- UUIDGroupNameRequestPacket.UUIDNameBlockBlock[] block = new UUIDGroupNameRequestPacket.UUIDNameBlockBlock[groupIDs.Count];
- for (int i = 0; i < groupIDs.Count; i++)
- {
- block[i] = new UUIDGroupNameRequestPacket.UUIDNameBlockBlock();
- block[i].ID = groupIDs[i];
- }
- req.UUIDNameBlock = block;
- Client.Network.SendPacket(req);
- }
- // fire handler from cache
- if (groupNames.Count > 0 && m_GroupNames != null)
- {
- OnGroupNamesReply(new GroupNamesEventArgs(groupNames));
- }
- }
- /// <summary>Lookup group profile data such as name, enrollment, founder, logo, etc</summary>
- /// <remarks>Subscribe to <code>OnGroupProfile</code> event to receive the results.</remarks>
- /// <param name="group">group ID (UUID)</param>
- public void RequestGroupProfile(UUID group)
- {
- GroupProfileRequestPacket request = new GroupProfileRequestPacket();
- request.AgentData.AgentID = Client.Self.AgentID;
- request.AgentData.SessionID = Client.Self.SessionID;
- request.GroupData.GroupID = group;
- Client.Network.SendPacket(request);
- }
- /// <summary>Request a list of group members.</summary>
- /// <remarks>Subscribe to <code>OnGroupMembers</code> event to receive the results.</remarks>
- /// <param name="group">group ID (UUID)</param>
- /// <returns>UUID of the request, use to index into cache</returns>
- public UUID RequestGroupMembers(UUID group)
- {
- UUID requestID = UUID.Random();
- lock (GroupMembersRequests) GroupMembersRequests.Add(requestID);
- GroupMembersRequestPacket request = new GroupMembersRequestPacket();
- request.AgentData.AgentID = Client.Self.AgentID;
- request.AgentData.SessionID = Client.Self.SessionID;
- request.GroupData.GroupID = group;
- request.GroupData.RequestID = requestID;
- Client.Network.SendPacket(request);
- return requestID;
- }
- /// <summary>Request group roles</summary>
- /// <remarks>Subscribe to <code>OnGroupRoles</code> event to receive the results.</remarks>
- /// <param name="group">group ID (UUID)</param>
- /// <returns>UUID of the request, use to index into cache</returns>
- public UUID RequestGroupRoles(UUID group)
- {
- UUID requestID = UUID.Random();
- lock (GroupRolesRequests) GroupRolesRequests.Add(requestID);
- GroupRoleDataRequestPacket request = new GroupRoleDataRequestPacket();
- request.AgentData.AgentID = Client.Self.AgentID;
- request.AgentData.SessionID = Client.Self.SessionID;
- request.GroupData.GroupID = group;
- request.GroupData.RequestID = requestID;
- Client.Network.SendPacket(request);
- return requestID;
- }
- /// <summary>Request members (members,role) role mapping for a group.</summary>
- /// <remarks>Subscribe to <code>OnGroupRolesMembers</code> event to receive the results.</remarks>
- /// <param name="group">group ID (UUID)</param>
- /// <returns>UUID of the request, use to index into cache</returns>
- public UUID RequestGroupRolesMembers(UUID group)
- {
- UUID requestID = UUID.Random();
- lock (GroupRolesRequests) GroupRolesMembersRequests.Add(requestID);
- GroupRoleMembersRequestPacket request = new GroupRoleMembersRequestPacket();
- request.AgentData.AgentID = Client.Self.AgentID;
- request.AgentData.SessionID = Client.Self.SessionID;
- request.GroupData.GroupID = group;
- request.GroupData.RequestID = requestID;
- Client.Network.SendPacket(request);
- return requestID;
- }
- /// <summary>Request a groups Titles</summary>
- /// <remarks>Subscribe to <code>OnGroupTitles</code> event to receive the results.</remarks>
- /// <param name="group">group ID (UUID)</param>
- /// <returns>UUID of the request, use to index into cache</returns>
- public UUID RequestGroupTitles(UUID group)
- {
- UUID requestID = UUID.Random();
- GroupTitlesRequestPacket request = new GroupTitlesRequestPacket();
- request.AgentData.AgentID = Client.Self.AgentID;
- request.AgentData.SessionID = Client.Self.SessionID;
- request.AgentData.GroupID = group;
- request.AgentData.RequestID = requestID;
- Client.Network.SendPacket(request);
- return requestID;
- }
- /// <summary>Begin to get the group account summary</summary>
- /// <remarks>Subscribe to the <code>OnGroupAccountSummary</code> event to receive the results.</remarks>
- /// <param name="group">group ID (UUID)</param>
- /// <param name="intervalDays">How long of an interval</param>
- /// <param name="currentInterval">Which interval (0 for current, 1 for last)</param>
- public void RequestGroupAccountSummary(UUID group, int intervalDays, int currentInterval)
- {
- GroupAccountSummaryRequestPacket p = new GroupAccountSummaryRequestPacket();
- p.AgentData.AgentID = Client.Self.AgentID;
- p.AgentData.SessionID = Client.Self.SessionID;
- p.AgentData.GroupID = group;
- p.MoneyData.RequestID = UUID.Random();
- p.MoneyData.CurrentInterval = currentInterval;
- p.MoneyData.IntervalDays = intervalDays;
- Client.Network.SendPacket(p);
- }
- /// <summary>Invites a user to a group</summary>
- /// <param name="group">The group to invite to</param>
- /// <param name="roles">A list of roles to invite a person to</param>
- /// <param name="personkey">Key of person to invite</param>
- public void Invite(UUID group, List<UUID> roles, UUID personkey)
- {
- InviteGroupRequestPacket igp = new InviteGroupRequestPacket();
- igp.AgentData = new InviteGroupRequestPacket.AgentDataBlock();
- igp.AgentData.AgentID = Client.Self.AgentID;
- igp.AgentData.SessionID = Client.Self.SessionID;
- igp.GroupData = new InviteGroupRequestPacket.GroupDataBlock();
- igp.GroupData.GroupID = group;
- igp.InviteData = new InviteGroupRequestPacket.InviteDataBlock[roles.Count];
- for (int i = 0; i < roles.Count; i++)
- {
- igp.InviteData[i] = new InviteGroupRequestPacket.InviteDataBlock();
- igp.InviteData[i].InviteeID = personkey;
- igp.InviteData[i].RoleID = roles[i];
- }
- Client.Network.SendPacket(igp);
- }
- /// <summary>Set a group as the current active group</summary>
- /// <param name="id">group ID (UUID)</param>
- public void ActivateGroup(UUID id)
- {
- ActivateGroupPacket activate = new ActivateGroupPacket();
- activate.AgentData.AgentID = Client.Self.AgentID;
- activate.AgentData.SessionID = Client.Self.SessionID;
- activate.AgentData.GroupID = id;
- Client.Network.SendPacket(activate);
- }
- /// <summary>Change the role that determines your active title</summary>
- /// <param name="group">Group ID to use</param>
- /// <param name="role">Role ID to change to</param>
- public void ActivateTitle(UUID group, UUID role)
- {
- GroupTitleUpdatePacket gtu = new GroupTitleUpdatePacket();
- gtu.AgentData.AgentID = Client.Self.AgentID;
- gtu.AgentData.SessionID = Client.Self.SessionID;
- gtu.AgentData.TitleRoleID = role;
- gtu.AgentData.GroupID = group;
- Client.Network.SendPacket(gtu);
- }
- /// <summary>Set this avatar's tier contribution</summary>
- /// <param name="group">Group ID to change tier in</param>
- /// <param name="contribution">amount of tier to donate</param>
- public void SetGroupContribution(UUID group, int contribution)
- {
- SetGroupContributionPacket sgp = new SetGroupContributionPacket();
- sgp.AgentData.AgentID = Client.Self.AgentID;
- sgp.AgentData.SessionID = Client.Self.SessionID;
- sgp.Data.GroupID = group;
- sgp.Data.Contribution = contribution;
- Client.Network.SendPacket(sgp);
- }
- /// <summary>
- /// Save wheather agent wants to accept group notices and list this group in their profile
- /// </summary>
- /// <param name="groupID">Group <see cref="UUID"/></param>
- /// <param name="acceptNotices">Accept notices from this group</param>
- /// <param name="listInProfile">List this group in the profile</param>
- public void SetGroupAcceptNotices(UUID groupID, bool acceptNotices, bool listInProfile)
- {
- SetGrou…
Large files files are truncated, but you can click here to view the full file