diff --git a/OpenMetaverse.GUI/GroupList.cs b/OpenMetaverse.GUI/GroupList.cs index 61684274..81362052 100644 --- a/OpenMetaverse.GUI/GroupList.cs +++ b/OpenMetaverse.GUI/GroupList.cs @@ -84,7 +84,12 @@ namespace OpenMetaverse.GUI private void InitializeClient(GridClient client) { _Client = client; - _Client.Groups.OnCurrentGroups += new GroupManager.CurrentGroupsCallback(Groups_OnCurrentGroups); + _Client.Groups.CurrentGroups += Groups_CurrentGroups; + } + + void Groups_CurrentGroups(object sender, CurrentGroupsEventArgs e) + { + RefreshGroups(e.Groups); } private void RefreshGroups(Dictionary groups) @@ -97,12 +102,7 @@ namespace OpenMetaverse.GUI this.Items.Add(group.Key.ToString(), group.Value.Name, null).Tag = group.Value; } } - - private void Groups_OnCurrentGroups(Dictionary groups) - { - RefreshGroups(groups); - } - + private void GroupList_ColumnClick(object sender, ColumnClickEventArgs e) { if ((_ColumnSorter.Ascending = (this.Sorting == SortOrder.Ascending))) this.Sorting = SortOrder.Descending; diff --git a/OpenMetaverse/GridManager.cs b/OpenMetaverse/GridManager.cs index d8e7f723..ca26bd1b 100644 --- a/OpenMetaverse/GridManager.cs +++ b/OpenMetaverse/GridManager.cs @@ -786,9 +786,9 @@ namespace OpenMetaverse sunPhase = time.TimeInfo.SunPhase; sunDirection = time.TimeInfo.SunDirection; sunAngVelocity = time.TimeInfo.SunAngVelocity; - + // TODO: Does anyone have a use for the time stuff? - } + } protected void CoarseLocationHandler(Packet packet, Simulator simulator) { diff --git a/OpenMetaverse/GroupManager.cs b/OpenMetaverse/GroupManager.cs index bf32cd14..bd6b938d 100644 --- a/OpenMetaverse/GroupManager.cs +++ b/OpenMetaverse/GroupManager.cs @@ -142,7 +142,7 @@ namespace OpenMetaverse public int GroupRolesCount; /// Show this group in agent's profile public bool ListInProfile; - + /// Returns the name of the group /// A string containing the name of the group public override string ToString() @@ -248,7 +248,7 @@ namespace OpenMetaverse { 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)); @@ -463,161 +463,332 @@ namespace OpenMetaverse { #region Delegates - /// - /// Callback for the list of groups the avatar is currently a member of - /// - /// A dictionary containing the groups an avatar is a member of, - /// where the Key is the group , and the values are the groups - public delegate void CurrentGroupsCallback(Dictionary groups); + /// The event subscribers. null if no subcribers + private EventHandler m_CurrentGroups; - /// - /// Callback for a list of group names - /// - /// A dictionary containing the the group names requested - /// where the Key is the group , and the values are the names - public delegate void GroupNamesCallback(Dictionary groupNames); + /// Raises the CurrentGroups event + /// A CurrentGroupsEventArgs object containing the + /// data sent from the simulator + protected virtual void OnCurrentGroups(CurrentGroupsEventArgs e) + { + EventHandler handler = m_CurrentGroups; + if (handler != null) + handler(this, e); + } - /// - /// Callback for the profile of a group - /// - /// The group profile - public delegate void GroupProfileCallback(Group group); + /// Thread sync lock object + private readonly object m_CurrentGroupsLock = new object(); - /// - /// Callback for the member list of a group - /// - /// returned by RequestGroupMembers - /// of the group - /// A dictionary containing the members of a group - /// where key is member and value is struct - public delegate void GroupMembersCallback(UUID requestID, UUID groupID, Dictionary members); + /// Raised when the simulator sends us data containing + /// our current group membership + public event EventHandler CurrentGroups + { + add { lock (m_CurrentGroupsLock) { m_CurrentGroups += value; } } + remove { lock (m_CurrentGroupsLock) { m_CurrentGroups -= value; } } + } - /// - /// Callback for retrieving group roles - /// - /// of the request returned from RequestGroupRoles - /// of the group - /// A dictionary containing role s as the key - /// and structs as values - public delegate void GroupRolesCallback(UUID requestID, UUID groupID, Dictionary roles); + /// The event subscribers. null if no subcribers + private EventHandler m_GroupNames; - /// - /// Callback for a pairing of roles to members - /// - /// of the request returned from RequestGroupRolesMembers - /// of the group - /// List containing role/member pairs - public delegate void GroupRolesMembersCallback(UUID requestID, UUID groupID, List> rolesMembers); + /// Raises the GroupNamesReply event + /// A GroupNamesEventArgs object containing the + /// data response from the simulator + protected virtual void OnGroupNamesReply(GroupNamesEventArgs e) + { + EventHandler handler = m_GroupNames; + if (handler != null) + handler(this, e); + } - /// - /// Callback for the title list of a group - /// - /// of the request returned from RequestGroupTitles - /// Group - /// A dictionary containing the titles of a group - /// where the Key is the role , and the values are the title details - public delegate void GroupTitlesCallback(UUID requestID, UUID groupID, Dictionary titles); + /// Thread sync lock object + private readonly object m_GroupNamesLock = new object(); - /// - /// Callback fired when group account summary information is received - /// - /// Group - /// The group account summary information - public delegate void GroupAccountSummaryCallback(UUID groupID, GroupAccountSummary summary); + /// Raised when the simulator responds to a RequestGroupName + /// or RequestGroupNames request + public event EventHandler GroupNamesReply + { + add { lock (m_GroupNamesLock) { m_GroupNames += value; } } + remove { lock (m_GroupNamesLock) { m_GroupNames -= value; } } + } - /// - /// Callback fired after an attempt to create a group - /// - /// The new groups - /// True of creation was successful - /// A string, containing a message from the simulator - public delegate void GroupCreatedCallback(UUID groupID, bool success, string message); + /// The event subscribers. null if no subcribers + private EventHandler m_GroupProfile; - /// - /// Callback fired when the avatar has joined a group - /// - /// The of the group joined - /// True if the join was successful - public delegate void GroupJoinedCallback(UUID groupID, bool success); + /// Raises the GroupProfile event + /// An GroupProfileEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupProfile(GroupProfileEventArgs e) + { + EventHandler handler = m_GroupProfile; + if (handler != null) + handler(this, e); + } - /// - /// Callback fired when the avatar leaves a group - /// - /// The of the group joined - /// True if the part was successful - public delegate void GroupLeftCallback(UUID groupID, bool success); + /// Thread sync lock object + private readonly object m_GroupProfileLock = new object(); - /// - /// Fired when a group is dropped, likely because it did not keep the required (2) avatar - /// minimum - /// - /// The of the group which was dropped - public delegate void GroupDroppedCallback(UUID groupID); + /// Raised when the simulator responds to a request + public event EventHandler GroupProfile + { + add { lock (m_GroupProfileLock) { m_GroupProfile += value; } } + remove { lock (m_GroupProfileLock) { m_GroupProfile -= value; } } + } - /// - /// Fired when a member of a group is ejected, - /// Does not provide member information, only - /// group ID and whether it was successful or not - /// - /// The Group UUID the member was ejected from - /// true of member was successfully ejected - public delegate void GroupMemberEjectedCallback(UUID groupID, bool success); + /// The event subscribers. null if no subcribers + private EventHandler m_GroupMembers; - /// - /// Fired when the list of group notices is recievied - /// - /// The of the group for which the notice list entry was recievied - /// The Notice list entry - public delegate void GroupNoticesListCallback(UUID groupID, GroupNoticeList notice); + /// Raises the GroupMembers event + /// A GroupMembersEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupMembersReply(GroupMembersReplyEventArgs e) + { + EventHandler handler = m_GroupMembers; + if (handler != null) + handler(this, e); + } + /// Thread sync lock object + private readonly object m_GroupMembersLock = new object(); + + /// Raised when the simulator responds to a request + public event EventHandler GroupMembersReply + { + add { lock (m_GroupMembersLock) { m_GroupMembers += value; } } + remove { lock (m_GroupMembersLock) { m_GroupMembers -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupRoles; + + /// Raises the GroupRolesDataReply event + /// A GroupRolesDataReplyEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupRoleDataReply(GroupRolesDataReplyEventArgs e) + { + EventHandler handler = m_GroupRoles; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_GroupRolesLock = new object(); + + /// Raised when the simulator responds to a request + public event EventHandler GroupRoleDataReply + { + add { lock (m_GroupRolesLock) { m_GroupRoles += value; } } + remove { lock (m_GroupRolesLock) { m_GroupRoles -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupRoleMembers; + + /// Raises the GroupRoleMembersReply event + /// A GroupRolesRoleMembersReplyEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupRoleMembers(GroupRolesMembersReplyEventArgs e) + { + EventHandler handler = m_GroupRoleMembers; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_GroupRolesMembersLock = new object(); + + /// Raised when the simulator responds to a request + public event EventHandler GroupRoleMembersReply + { + add { lock (m_GroupRolesMembersLock) { m_GroupRoleMembers += value; } } + remove { lock (m_GroupRolesMembersLock) { m_GroupRoleMembers -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupTitles; + + + /// Raises the GroupTitlesReply event + /// A GroupTitlesReplyEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupTitles(GroupTitlesReplyEventArgs e) + { + EventHandler handler = m_GroupTitles; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_GroupTitlesLock = new object(); + + /// Raised when the simulator responds to a request + public event EventHandler GroupTitlesReply + { + add { lock (m_GroupTitlesLock) { m_GroupTitles += value; } } + remove { lock (m_GroupTitlesLock) { m_GroupTitles -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupAccountSummary; + + /// Raises the GroupAccountSummary event + /// A GroupAccountSummaryReplyEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupAccountSummaryReply(GroupAccountSummaryReplyEventArgs e) + { + EventHandler handler = m_GroupAccountSummary; + if (handler != null) + handler(this, e); + } + + /// Thread sync lock object + private readonly object m_GroupAccountSummaryLock = new object(); + + /// Raised when a response to a RequestGroupAccountSummary is returned + /// by the simulator + public event EventHandler GroupAccountSummaryReply + { + add { lock (m_GroupAccountSummaryLock) { m_GroupAccountSummary += value; } } + remove { lock (m_GroupAccountSummaryLock) { m_GroupAccountSummary -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupCreated; + + /// Raises the GroupCreated event + /// An GroupCreatedEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupCreatedReply(GroupCreatedReplyEventArgs e) + { + EventHandler handler = m_GroupCreated; + if (handler != null) + handler(this, e); + } + /// Thread sync lock object + private readonly object m_GroupCreatedLock = new object(); + + /// Raised when a request to create a group is successful + public event EventHandler GroupCreatedReply + { + add { lock (m_GroupCreatedLock) { m_GroupCreated += value; } } + remove { lock (m_GroupCreatedLock) { m_GroupCreated -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupJoined; + + /// Raises the GroupJoined event + /// A GroupOperationEventArgs object containing the + /// result of the operation returned from the simulator + protected virtual void OnGroupJoinedReply(GroupOperationEventArgs e) + { + EventHandler handler = m_GroupJoined; + if (handler != null) + handler(this, e); + } + /// Thread sync lock object + private readonly object m_GroupJoinedLock = new object(); + + /// Raised when a request to join a group either + /// fails or succeeds + public event EventHandler GroupJoinedReply + { + add { lock (m_GroupJoinedLock) { m_GroupJoined += value; } } + remove { lock (m_GroupJoinedLock) { m_GroupJoined -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupLeft; + + /// Raises the GroupLeft event + /// A GroupOperationEventArgs object containing the + /// result of the operation returned from the simulator + protected virtual void OnGroupLeaveReply(GroupOperationEventArgs e) + { + EventHandler handler = m_GroupLeft; + if (handler != null) + handler(this, e); + } + /// Thread sync lock object + private readonly object m_GroupLeftLock = new object(); + + /// Raised when a request to leave a group either + /// fails or succeeds + public event EventHandler GroupLeaveReply + { + add { lock (m_GroupLeftLock) { m_GroupLeft += value; } } + remove { lock (m_GroupLeftLock) { m_GroupLeft -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupDropped; + + /// Raises the GroupDropped event + /// An GroupDroppedEventArgs object containing the + /// the group your agent left + protected virtual void OnGroupDropped(GroupDroppedEventArgs e) + { + EventHandler handler = m_GroupDropped; + if (handler != null) + handler(this, e); + } + /// Thread sync lock object + private readonly object m_GroupDroppedLock = new object(); + + /// Raised when A group is removed from the group server + public event EventHandler GroupDropped + { + add { lock (m_GroupDroppedLock) { m_GroupDropped += value; } } + remove { lock (m_GroupDroppedLock) { m_GroupDropped -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupMemberEjected; + + /// Raises the GroupMemberEjected event + /// An GroupMemberEjectedEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupMemberEjected(GroupOperationEventArgs e) + { + EventHandler handler = m_GroupMemberEjected; + if (handler != null) + handler(this, e); + } + /// Thread sync lock object + private readonly object m_GroupMemberEjectedLock = new object(); + + /// Raised when a request to eject a member from a group either + /// fails or succeeds + public event EventHandler GroupMemberEjected + { + add { lock (m_GroupMemberEjectedLock) { m_GroupMemberEjected += value; } } + remove { lock (m_GroupMemberEjectedLock) { m_GroupMemberEjected -= value; } } + } + + /// The event subscribers. null if no subcribers + private EventHandler m_GroupNoticesListReply; + + /// Raises the GroupNoticesListReply event + /// An GroupNoticesListReplyEventArgs object containing the + /// data returned from the simulator + protected virtual void OnGroupNoticesListReply(GroupNoticesListReplyEventArgs e) + { + EventHandler handler = m_GroupNoticesListReply; + if (handler != null) + handler(this, e); + } + /// Thread sync lock object + private readonly object m_GroupNoticesListReplyLock = new object(); + + /// Raised when ... + public event EventHandler GroupNoticesListReply + { + add { lock (m_GroupNoticesListReplyLock) { m_GroupNoticesListReply += value; } } + remove { lock (m_GroupNoticesListReplyLock) { m_GroupNoticesListReply -= value; } } + } #endregion Delegates #region Events - /// Fired when a is received, contains a list of - /// groups avatar is currently a member of - public event CurrentGroupsCallback OnCurrentGroups; - /// Fired when a UUIDGroupNameReply packet is receiived, - /// contains name of group requested - public event GroupNamesCallback OnGroupNames; - /// Fired when a GroupProfileReply packet is received, - /// contains group profile information for requested group. - public event GroupProfileCallback OnGroupProfile; - /// Fired when a GroupMembersReply packet is received, - /// contains a list of group members for requested group - public event GroupMembersCallback OnGroupMembers; - /// Fired when a GroupRoleDataReply packet is received, - /// contains details on roles for requested group - public event GroupRolesCallback OnGroupRoles; - /// Fired when a is received, - /// Contains group member to group role mappings - public event GroupRolesMembersCallback OnGroupRolesMembers; - /// Fired when a GroupTitlesReply packet is received, - /// sets the active role title for the current Agent - public event GroupTitlesCallback OnGroupTitles; - /// Fired when a GroupAccountSummaryReply packet is received, - /// Contains a summary of group financial information - public event GroupAccountSummaryCallback OnGroupAccountSummary; - /// Fired when a CreateGroupReply packet is received, indicates - /// the successful creation of a new group - public event GroupCreatedCallback OnGroupCreated; - /// Fired when a JoinGroupReply packet is received, indicates - /// the Avatar has successfully joined a new group either by - /// or by accepting a group join invitation with - public event GroupJoinedCallback OnGroupJoined; - /// Fired when a LeaveGroupReply packet is received, indicates - /// the Avatar has successfully left a group - /// - public event GroupLeftCallback OnGroupLeft; - /// Fired when a AgentDropGroup packet is received, contains - /// the of the group dropped - public event GroupDroppedCallback OnGroupDropped; - /// Fired when a GroupMemberEjected packet is received, - /// indicates a member of a group has been ejected - public event GroupMemberEjectedCallback OnGroupMemberEjected; - /// Fired when the list of group notices is recievied - public event GroupNoticesListCallback OnGroupNoticesList; - #endregion Events /// A reference to the current instance @@ -636,8 +807,9 @@ namespace OpenMetaverse private InternalDictionary> TempGroupRoles; /// Caches group name lookups public InternalDictionary GroupName2KeyCache; + /// - /// Group Management Routines, Methods and Packet Handlers + /// Construct a new instance of the GroupManager class /// /// A reference to the current instance public GroupManager(GridClient client) @@ -650,20 +822,19 @@ namespace OpenMetaverse GroupRolesRequests = new List(); TempGroupRolesMembers = new InternalDictionary>>(); GroupRolesMembersRequests = new List(); - GroupName2KeyCache = new InternalDictionary(); + GroupName2KeyCache = new InternalDictionary(); - Client.Network.RegisterEventCallback("AgentGroupDataUpdate", new Caps.EventQueueCallback(AgentGroupDataUpdateMessageHandler)); - Client.Network.RegisterCallback(PacketType.AgentGroupDataUpdate, new NetworkManager.PacketCallback(AgentGroupDataUpdateHandler)); + Client.Network.RegisterEventCallback("AgentGroupDataUpdate", new Caps.EventQueueCallback(AgentGroupDataUpdateMessageHandler)); // deprecated in simulator v1.27 Client.Network.RegisterCallback(PacketType.AgentDropGroup, new NetworkManager.PacketCallback(AgentDropGroupHandler)); - Client.Network.RegisterCallback(PacketType.GroupTitlesReply, new NetworkManager.PacketCallback(GroupTitlesHandler)); - Client.Network.RegisterCallback(PacketType.GroupProfileReply, new NetworkManager.PacketCallback(GroupProfileHandler)); + Client.Network.RegisterCallback(PacketType.GroupTitlesReply, new NetworkManager.PacketCallback(GroupTitlesReplyHandler)); + Client.Network.RegisterCallback(PacketType.GroupProfileReply, new NetworkManager.PacketCallback(GroupProfileReplyHandler)); Client.Network.RegisterCallback(PacketType.GroupMembersReply, new NetworkManager.PacketCallback(GroupMembersHandler)); - Client.Network.RegisterCallback(PacketType.GroupRoleDataReply, new NetworkManager.PacketCallback(GroupRoleDataHandler)); - Client.Network.RegisterCallback(PacketType.GroupRoleMembersReply, new NetworkManager.PacketCallback(GroupRoleMembersHandler)); + Client.Network.RegisterCallback(PacketType.GroupRoleDataReply, new NetworkManager.PacketCallback(GroupRoleDataReplyHandler)); + Client.Network.RegisterCallback(PacketType.GroupRoleMembersReply, new NetworkManager.PacketCallback(GroupRoleMembersReplyHandler)); Client.Network.RegisterCallback(PacketType.GroupActiveProposalItemReply, new NetworkManager.PacketCallback(GroupActiveProposalItemHandler)); Client.Network.RegisterCallback(PacketType.GroupVoteHistoryItemReply, new NetworkManager.PacketCallback(GroupVoteHistoryItemHandler)); - Client.Network.RegisterCallback(PacketType.GroupAccountSummaryReply, new NetworkManager.PacketCallback(GroupAccountSummaryHandler)); + Client.Network.RegisterCallback(PacketType.GroupAccountSummaryReply, new NetworkManager.PacketCallback(GroupAccountSummaryReplyHandler)); Client.Network.RegisterCallback(PacketType.CreateGroupReply, new NetworkManager.PacketCallback(CreateGroupReplyHandler)); Client.Network.RegisterCallback(PacketType.JoinGroupReply, new NetworkManager.PacketCallback(JoinGroupReplyHandler)); Client.Network.RegisterCallback(PacketType.LeaveGroupReply, new NetworkManager.PacketCallback(LeaveGroupReplyHandler)); @@ -674,6 +845,9 @@ namespace OpenMetaverse Client.Network.RegisterEventCallback("AgentDropGroup", new Caps.EventQueueCallback(AgentDropGroupMessageHandler)); } + + #region Public Methods + /// /// Request a current list of groups the avatar is a member of. /// @@ -685,7 +859,7 @@ namespace OpenMetaverse request.AgentData.AgentID = Client.Self.AgentID; request.AgentData.SessionID = Client.Self.SessionID; - + Client.Network.SendPacket(request); } @@ -696,28 +870,27 @@ namespace OpenMetaverse 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 groupNames = new Dictionary(); - lock(GroupName2KeyCache.Dictionary) + if (GroupName2KeyCache.ContainsKey(groupID)) + { + Dictionary groupNames = new Dictionary(); + lock (GroupName2KeyCache.Dictionary) groupNames.Add(groupID, GroupName2KeyCache.Dictionary[groupID]); - if (OnGroupNames != null) - { - - try { OnGroupNames(groupNames); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } - } - } - - else + + if (m_GroupNames != null) { - 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); + 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); + } } /// @@ -734,8 +907,8 @@ namespace OpenMetaverse if (GroupName2KeyCache.ContainsKey(groupID)) groupNames[groupID] = GroupName2KeyCache.Dictionary[groupID]; } - } - + } + if (groupIDs.Count > 0) { UUIDGroupNameRequestPacket req = new UUIDGroupNameRequestPacket(); @@ -752,9 +925,10 @@ namespace OpenMetaverse } // fire handler from cache - if(groupNames.Count > 0 && OnGroupNames != null) - try { OnGroupNames(groupNames); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + if (groupNames.Count > 0 && m_GroupNames != null) + { + OnGroupNamesReply(new GroupNamesEventArgs(groupNames)); + } } /// Lookup group profile data such as name, enrollment, founder, logo, etc @@ -815,7 +989,7 @@ namespace OpenMetaverse /// Subscribe to OnGroupRolesMembers event to receive the results. /// group ID (UUID) /// UUID of the request, use to index into cache - public UUID RequestGroupRoleMembers(UUID group) + public UUID RequestGroupRolesMembers(UUID group) { UUID requestID = UUID.Random(); lock (GroupRolesRequests) GroupRolesMembersRequests.Add(requestID); @@ -999,7 +1173,7 @@ namespace OpenMetaverse cgrp.AgentData = new UpdateGroupInfoPacket.AgentDataBlock(); cgrp.AgentData.AgentID = Client.Self.AgentID; cgrp.AgentData.SessionID = Client.Self.SessionID; - + cgrp.GroupData = new UpdateGroupInfoPacket.GroupDataBlock(); cgrp.GroupData.GroupID = id; cgrp.GroupData.AllowPublish = group.AllowPublish; @@ -1009,7 +1183,7 @@ namespace OpenMetaverse cgrp.GroupData.MembershipFee = group.MembershipFee; cgrp.GroupData.OpenEnrollment = group.OpenEnrollment; cgrp.GroupData.ShowInList = group.ShowInList; - + Client.Network.SendPacket(cgrp); } @@ -1022,14 +1196,14 @@ namespace OpenMetaverse eject.AgentData = new EjectGroupMemberRequestPacket.AgentDataBlock(); eject.AgentData.AgentID = Client.Self.AgentID; eject.AgentData.SessionID = Client.Self.SessionID; - + eject.GroupData = new EjectGroupMemberRequestPacket.GroupDataBlock(); eject.GroupData.GroupID = group; - + eject.EjectData = new EjectGroupMemberRequestPacket.EjectDataBlock[1]; eject.EjectData[0] = new EjectGroupMemberRequestPacket.EjectDataBlock(); eject.EjectData[0].EjecteeID = member; - + Client.Network.SendPacket(eject); } @@ -1112,7 +1286,7 @@ namespace OpenMetaverse /// Request the group notices list /// Group ID to fetch notices for - public void RequestGroupNoticeList(UUID group) + public void RequestGroupNoticesList(UUID group) { OpenMetaverse.Packets.GroupNoticesListRequestPacket gnl = new GroupNoticesListRequestPacket(); gnl.AgentData.AgentID = Client.Self.AgentID; @@ -1131,37 +1305,14 @@ namespace OpenMetaverse gnr.Data.GroupNoticeID = noticeID; Client.Network.SendPacket(gnr); } - - - private void GroupNoticesListReplyHandler(Packet packet, Simulator simulator) - { - GroupNoticesListReplyPacket reply = (GroupNoticesListReplyPacket)packet; - - foreach (GroupNoticesListReplyPacket.DataBlock entry in reply.Data) - { - GroupNoticeList notice = new GroupNoticeList(); - notice.FromName = Utils.BytesToString(entry.FromName); - notice.Subject = Utils.BytesToString(entry.Subject); - notice.NoticeID = entry.NoticeID; - notice.Timestamp = entry.Timestamp; - notice.HasAttachment = entry.HasAttachment; - notice.AssetType = (AssetType)entry.AssetType; - - if (OnGroupNoticesList != null) - { - try { OnGroupNoticesList(reply.AgentData.GroupID, notice); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } - } - } - } - + /// Send out a group notice /// Group ID to update /// GroupNotice structure containing notice data public void SendGroupNotice(UUID group, GroupNotice notice) { Client.Self.InstantMessage(Client.Self.Name, group, notice.Subject + "|" + notice.Message, - UUID.Zero, InstantMessageDialog.GroupNotice, InstantMessageOnline.Online, + UUID.Zero, InstantMessageDialog.GroupNotice, InstantMessageOnline.Online, Vector3.Zero, UUID.Zero, notice.SerializeAttachment()); } @@ -1190,47 +1341,22 @@ namespace OpenMetaverse p.AgentData.AgentID = Client.Self.AgentID; p.AgentData.SessionID = Client.Self.SessionID; p.GroupData.GroupID = groupID; + Client.Network.SendPacket(p); } +#endregion #region Packet Handlers - // When Arriving over UDP (OpenSim still sends it this way) - private void AgentGroupDataUpdateHandler(Packet packet, Simulator simulator) - { - if (OnCurrentGroups != null) - { - //AgentGroupDataUpdateMessage msg = (AgentGroupDataUpdateMessage)message; - AgentGroupDataUpdatePacket msg = (AgentGroupDataUpdatePacket)packet; - //AgentGroupDataUpdatePacket.GroupDataBlock groupDataBlock = msg.GroupData; - - Dictionary currentGroups = new Dictionary(); - foreach (AgentGroupDataUpdatePacket.GroupDataBlock block in msg.GroupData) - { - Group group = new Group(); - group.ID = block.GroupID; - group.Name = Utils.BytesToString(block.GroupName); - group.InsigniaID = block.GroupInsigniaID; - group.AcceptNotices = block.AcceptNotices; - group.Contribution = block.Contribution; - group.Powers = (GroupPowers)block.GroupPowers; - - currentGroups.Add(group.ID, group); - lock (GroupName2KeyCache.Dictionary) - { - if (!GroupName2KeyCache.Dictionary.ContainsKey(group.ID)) - GroupName2KeyCache.Dictionary.Add(group.ID, group.Name); - } - } - - try { OnCurrentGroups(currentGroups); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } - } - } - - // When Arriving via Capabilities - private void AgentGroupDataUpdateMessageHandler(string capsKey, IMessage message, Simulator simulator) - { - if (OnCurrentGroups != null) + + /// + /// + /// + /// + /// + /// + protected void AgentGroupDataUpdateMessageHandler(string capsKey, IMessage message, Simulator simulator) + { + if (m_CurrentGroups != null) { AgentGroupDataUpdateMessage msg = (AgentGroupDataUpdateMessage)message; @@ -1254,37 +1380,45 @@ namespace OpenMetaverse GroupName2KeyCache.Dictionary.Add(group.ID, group.Name); } } - - try { OnCurrentGroups(currentGroups); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnCurrentGroups(new CurrentGroupsEventArgs(currentGroups)); } } - private void AgentDropGroupHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to your agents request to leave a group + /// The packet containing the data + /// The simulator the packet originated from + /// Raises the event confirming the request to leave a group + /// was successful + protected void AgentDropGroupHandler(Packet packet, Simulator simulator) { - if (OnGroupDropped != null) + if (m_GroupDropped != null) { - try { OnGroupDropped(((AgentDropGroupPacket)packet).AgentData.GroupID); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupDropped(new GroupDroppedEventArgs(((AgentDropGroupPacket)packet).AgentData.GroupID)); } } - private void AgentDropGroupMessageHandler(string capsKey, IMessage message, Simulator simulator) + protected void AgentDropGroupMessageHandler(string capsKey, IMessage message, Simulator simulator) { - if (OnGroupDropped != null) + + if (m_GroupDropped != null) { AgentDropGroupMessage msg = (AgentDropGroupMessage)message; for (int i = 0; i < msg.AgentDataBlock.Length; i++) { - try { OnGroupDropped(msg.AgentDataBlock[i].GroupID); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupDropped(new GroupDroppedEventArgs(msg.AgentDataBlock[i].GroupID)); } } } - private void GroupProfileHandler(Packet packet, Simulator simulator) - { - if (OnGroupProfile != null) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void GroupProfileReplyHandler(Packet packet, Simulator simulator) + { + if (m_GroupProfile != null) { GroupProfileReplyPacket profile = (GroupProfileReplyPacket)packet; Group group = new Group(); @@ -1306,14 +1440,45 @@ namespace OpenMetaverse group.Powers = (GroupPowers)profile.GroupData.PowersMask; group.ShowInList = profile.GroupData.ShowInList; - try { OnGroupProfile(group); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupProfile(new GroupProfileEventArgs(group)); } } - private void GroupTitlesHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + /// + protected void GroupNoticesListReplyHandler(Packet packet, Simulator simulator) { - if (OnGroupTitles != null) + if (m_GroupNoticesListReply != null) + { + GroupNoticesListReplyPacket reply = (GroupNoticesListReplyPacket)packet; + + foreach (GroupNoticesListReplyPacket.DataBlock entry in reply.Data) + { + GroupNoticeList notice = new GroupNoticeList(); + notice.FromName = Utils.BytesToString(entry.FromName); + notice.Subject = Utils.BytesToString(entry.Subject); + notice.NoticeID = entry.NoticeID; + notice.Timestamp = entry.Timestamp; + notice.HasAttachment = entry.HasAttachment; + notice.AssetType = (AssetType)entry.AssetType; + + OnGroupNoticesListReply(new GroupNoticesListReplyEventArgs(reply.AgentData.GroupID, notice)); + } + } + } + + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void GroupTitlesReplyHandler(Packet packet, Simulator simulator) + { + if (m_GroupTitles != null) { GroupTitlesReplyPacket titles = (GroupTitlesReplyPacket)packet; Dictionary groupTitleCache = new Dictionary(); @@ -1329,13 +1494,16 @@ namespace OpenMetaverse groupTitleCache[block.RoleID] = groupTitle; } - - try { OnGroupTitles(titles.AgentData.RequestID, titles.AgentData.GroupID, groupTitleCache); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupTitles(new GroupTitlesReplyEventArgs(titles.AgentData.RequestID, titles.AgentData.GroupID, groupTitleCache)); } } - private void GroupMembersHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void GroupMembersHandler(Packet packet, Simulator simulator) { GroupMembersReplyPacket members = (GroupMembersReplyPacket)packet; Dictionary groupMemberCache = null; @@ -1376,14 +1544,18 @@ namespace OpenMetaverse } } - if (OnGroupMembers != null && groupMemberCache != null && groupMemberCache.Count >= members.GroupData.MemberCount) + if (m_GroupMembers != null && groupMemberCache != null && groupMemberCache.Count >= members.GroupData.MemberCount) { - try { OnGroupMembers(members.GroupData.RequestID, members.GroupData.GroupID, groupMemberCache); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupMembersReply(new GroupMembersReplyEventArgs(members.GroupData.RequestID, members.GroupData.GroupID, groupMemberCache)); } } - private void GroupRoleDataHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void GroupRoleDataReplyHandler(Packet packet, Simulator simulator) { GroupRoleDataReplyPacket roles = (GroupRoleDataReplyPacket)packet; Dictionary groupRoleCache = null; @@ -1426,14 +1598,18 @@ namespace OpenMetaverse } } - if (OnGroupRoles != null && groupRoleCache != null && groupRoleCache.Count >= roles.GroupData.RoleCount) + if (m_GroupRoles != null && groupRoleCache != null && groupRoleCache.Count >= roles.GroupData.RoleCount) { - try { OnGroupRoles(roles.GroupData.RequestID, roles.GroupData.GroupID, groupRoleCache); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupRoleDataReply(new GroupRolesDataReplyEventArgs(roles.GroupData.RequestID, roles.GroupData.GroupID, groupRoleCache)); } } - private void GroupRoleMembersHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void GroupRoleMembersReplyHandler(Packet packet, Simulator simulator) { GroupRoleMembersReplyPacket members = (GroupRoleMembersReplyPacket)packet; List> groupRoleMemberCache = null; @@ -1475,10 +1651,9 @@ namespace OpenMetaverse Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } - if (OnGroupRolesMembers != null && groupRoleMemberCache != null && groupRoleMemberCache.Count >= members.AgentData.TotalPairs) + if (m_GroupRoleMembers != null && groupRoleMemberCache != null && groupRoleMemberCache.Count >= members.AgentData.TotalPairs) { - try { OnGroupRolesMembers(members.AgentData.RequestID, members.AgentData.GroupID, groupRoleMemberCache); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupRoleMembers(new GroupRolesMembersReplyEventArgs(members.AgentData.RequestID, members.AgentData.GroupID, groupRoleMemberCache)); } } @@ -1496,9 +1671,14 @@ namespace OpenMetaverse // TODO: This was broken in the official viewer when I was last trying to work on it } - private void GroupAccountSummaryHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void GroupAccountSummaryReplyHandler(Packet packet, Simulator simulator) { - if (OnGroupAccountSummary != null) + if (m_GroupAccountSummary != null) { GroupAccountSummaryReplyPacket summary = (GroupAccountSummaryReplyPacket)packet; GroupAccountSummary account = new GroupAccountSummary(); @@ -1523,64 +1703,79 @@ namespace OpenMetaverse account.TotalCredits = summary.MoneyData.TotalCredits; account.TotalDebits = summary.MoneyData.TotalDebits; - try { OnGroupAccountSummary(summary.AgentData.GroupID, account); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupAccountSummaryReply(new GroupAccountSummaryReplyEventArgs(summary.AgentData.GroupID, account)); } } - private void CreateGroupReplyHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void CreateGroupReplyHandler(Packet packet, Simulator simulator) { - if (OnGroupCreated != null) + if (m_GroupCreated != null) { CreateGroupReplyPacket reply = (CreateGroupReplyPacket)packet; string message = Utils.BytesToString(reply.ReplyData.Message); - try { OnGroupCreated(reply.ReplyData.GroupID, reply.ReplyData.Success, message); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupCreatedReply(new GroupCreatedReplyEventArgs(reply.ReplyData.GroupID, reply.ReplyData.Success, message)); } } - private void JoinGroupReplyHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void JoinGroupReplyHandler(Packet packet, Simulator simulator) { - if (OnGroupJoined != null) + if (m_GroupJoined != null) { JoinGroupReplyPacket reply = (JoinGroupReplyPacket)packet; - try { OnGroupJoined(reply.GroupData.GroupID, reply.GroupData.Success); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupJoinedReply(new GroupOperationEventArgs(reply.GroupData.GroupID, reply.GroupData.Success)); } } - private void LeaveGroupReplyHandler(Packet packet, Simulator simulator) + /// Process an incoming packet sent + /// by the simulator in response to a + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data + protected void LeaveGroupReplyHandler(Packet packet, Simulator simulator) { - if (OnGroupLeft != null) + if (m_GroupLeft != null) { LeaveGroupReplyPacket reply = (LeaveGroupReplyPacket)packet; - try { OnGroupLeft(reply.GroupData.GroupID, reply.GroupData.Success); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupLeaveReply(new GroupOperationEventArgs(reply.GroupData.GroupID, reply.GroupData.Success)); } } + /// Process an incoming packet sent + /// by the simulator in response to a or request + /// The packet containing the reply data + /// The simulator the packet originated from + /// Raises the event with the response data private void UUIDGroupNameReplyHandler(Packet packet, Simulator simulator) { UUIDGroupNameReplyPacket reply = (UUIDGroupNameReplyPacket)packet; UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] blocks = reply.UUIDNameBlock; - + Dictionary groupNames = new Dictionary(); - foreach (UUIDGroupNameReplyPacket.UUIDNameBlockBlock block in blocks) + foreach (UUIDGroupNameReplyPacket.UUIDNameBlockBlock block in blocks) { groupNames.Add(block.ID, Utils.BytesToString(block.GroupName)); - if (!GroupName2KeyCache.ContainsKey(block.ID)) - GroupName2KeyCache.Add(block.ID, Utils.BytesToString(block.GroupName)); + if (!GroupName2KeyCache.ContainsKey(block.ID)) + GroupName2KeyCache.Add(block.ID, Utils.BytesToString(block.GroupName)); } - if (OnGroupNames != null) - { - try { OnGroupNames(groupNames); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + if (m_GroupNames != null) + { + OnGroupNamesReply(new GroupNamesEventArgs(groupNames)); } } @@ -1591,19 +1786,287 @@ namespace OpenMetaverse /// The EjectGroupMemberReply packet /// The simulator where the message originated /// This is a silly packet, it doesn't provide you with the ejectees UUID - private void EjectGroupMemberReplyHandler(Packet packet, Simulator simulator) + protected void EjectGroupMemberReplyHandler(Packet packet, Simulator simulator) { EjectGroupMemberReplyPacket reply = (EjectGroupMemberReplyPacket)packet; // TODO: On Success remove the member from the cache(s) - - if(OnGroupMemberEjected != null) + + if (m_GroupMemberEjected != null) { - try { OnGroupMemberEjected(reply.GroupData.GroupID, reply.EjectData.Success); } - catch (Exception e) { Logger.Log(e.Message, Helpers.LogLevel.Error, Client, e); } + OnGroupMemberEjected(new GroupOperationEventArgs(reply.GroupData.GroupID, reply.EjectData.Success)); } } #endregion Packet Handlers } + + #region EventArgs + + /// Contains the current groups your agent is a member of + public class CurrentGroupsEventArgs : EventArgs + { + private readonly Dictionary m_Groups; + + /// Get the current groups your agent is a member of + public Dictionary Groups { get { return m_Groups; } } + + /// Construct a new instance of the CurrentGroupsEventArgs class + /// The current groups your agent is a member of + public CurrentGroupsEventArgs(Dictionary groups) + { + this.m_Groups = groups; + } + } + + /// A Dictionary of group names, where the Key is the groups ID and the value is the groups name + public class GroupNamesEventArgs : EventArgs + { + private readonly Dictionary m_GroupNames; + + /// Get the Group Names dictionary + public Dictionary GroupNames { get { return m_GroupNames; } } + + /// Construct a new instance of the GroupNamesEventArgs class + /// The Group names dictionary + public GroupNamesEventArgs(Dictionary groupNames) + { + this.m_GroupNames = groupNames; + } + } + + /// Represents the members of a group + public class GroupMembersReplyEventArgs : EventArgs + { + private readonly UUID m_RequestID; + private readonly UUID m_GroupID; + private readonly Dictionary m_Members; + + /// Get the ID as returned by the request to correlate + /// this result set and the request + public UUID RequestID { get { return m_RequestID; } } + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + /// Get the dictionary of members + public Dictionary Members { get { return m_Members; } } + + /// + /// Construct a new instance of the GroupMembersReplyEventArgs class + /// + /// The ID of the request + /// The ID of the group + /// The membership list of the group + public GroupMembersReplyEventArgs(UUID requestID, UUID groupID, Dictionary members) + { + this.m_RequestID = requestID; + this.m_GroupID = groupID; + this.m_Members = members; + } + } + + /// Represents the roles associated with a group + public class GroupRolesDataReplyEventArgs : EventArgs + { + private readonly UUID m_RequestID; + private readonly UUID m_GroupID; + private readonly Dictionary m_Roles; + + /// Get the ID as returned by the request to correlate + /// this result set and the request + public UUID RequestID { get { return m_RequestID; } } + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + /// Get the dictionary containing the roles + public Dictionary Roles { get { return m_Roles; } } + + /// Construct a new instance of the GroupRolesDataReplyEventArgs class + /// The ID as returned by the request to correlate + /// this result set and the request + /// The ID of the group + /// The dictionary containing the roles + public GroupRolesDataReplyEventArgs(UUID requestID, UUID groupID, Dictionary roles) + { + this.m_RequestID = requestID; + this.m_GroupID = groupID; + this.m_Roles = roles; + } + } + + /// Represents the Role to Member mappings for a group + public class GroupRolesMembersReplyEventArgs : EventArgs + { + private readonly UUID m_RequestID; + private readonly UUID m_GroupID; + private readonly List> m_RolesMembers; + + /// Get the ID as returned by the request to correlate + /// this result set and the request + public UUID RequestID { get { return m_RequestID; } } + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + /// Get the member to roles map + public List> RolesMembers { get { return m_RolesMembers; } } + + /// Construct a new instance of the GroupRolesMembersReplyEventArgs class + /// The ID as returned by the request to correlate + /// this result set and the request + /// The ID of the group + /// The member to roles map + public GroupRolesMembersReplyEventArgs(UUID requestID, UUID groupID, List> rolesMembers) + { + this.m_RequestID = requestID; + this.m_GroupID = groupID; + this.m_RolesMembers = rolesMembers; + } + } + + /// Represents the titles for a group + public class GroupTitlesReplyEventArgs : EventArgs + { + private readonly UUID m_RequestID; + private readonly UUID m_GroupID; + private readonly Dictionary m_Titles; + + /// Get the ID as returned by the request to correlate + /// this result set and the request + public UUID RequestID { get { return m_RequestID; } } + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + /// Get the titles + public Dictionary Titles { get { return m_Titles; } } + + /// Construct a new instance of the GroupTitlesReplyEventArgs class + /// The ID as returned by the request to correlate + /// this result set and the request + /// The ID of the group + /// The titles + public GroupTitlesReplyEventArgs(UUID requestID, UUID groupID, Dictionary titles) + { + this.m_RequestID = requestID; + this.m_GroupID = groupID; + this.m_Titles = titles; + } + } + + /// Represents the summary data for a group + public class GroupAccountSummaryReplyEventArgs : EventArgs + { + private readonly UUID m_GroupID; + private readonly GroupAccountSummary m_Summary; + + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + /// Get the summary data + public GroupAccountSummary Summary { get { return m_Summary; } } + + /// Construct a new instance of the GroupAccountSummaryReplyEventArgs class + /// The ID of the group + /// The summary data + public GroupAccountSummaryReplyEventArgs(UUID groupID, GroupAccountSummary summary) + { + this.m_GroupID = groupID; + this.m_Summary = summary; + } + } + + /// A response to a group create request + public class GroupCreatedReplyEventArgs : EventArgs + { + private readonly UUID m_GroupID; + private readonly bool m_Success; + private readonly string m_Message; + + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + /// true of the group was created successfully + public bool Success { get { return m_Success; } } + /// A string containing the message + public string Message { get { return m_Message; } } + + /// Construct a new instance of the GroupCreatedReplyEventArgs class + /// The ID of the group + /// the success or faulure of the request + /// A string containing additional information + public GroupCreatedReplyEventArgs(UUID groupID, bool success, string messsage) + { + this.m_GroupID = groupID; + this.m_Success = success; + this.m_Message = messsage; + } + } + + /// Represents a response to a request + public class GroupOperationEventArgs : EventArgs + { + private readonly UUID m_GroupID; + private readonly bool m_Success; + + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + /// true of the request was successful + public bool Success { get { return m_Success; } } + + /// Construct a new instance of the GroupOperationEventArgs class + /// The ID of the group + /// true of the request was successful + public GroupOperationEventArgs(UUID groupID, bool success) + { + this.m_GroupID = groupID; + this.m_Success = success; + } + } + + /// Represents your agent leaving a group + public class GroupDroppedEventArgs : EventArgs + { + private readonly UUID m_GroupID; + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + + /// Construct a new instance of the GroupDroppedEventArgs class + /// The ID of the group + public GroupDroppedEventArgs(UUID groupID) + { + m_GroupID = groupID; + } + } + + /// Represents a list of active group notices + public class GroupNoticesListReplyEventArgs : EventArgs + { + private readonly UUID m_GroupID; + private readonly GroupNoticeList m_Notices; + + /// Get the ID of the group + public UUID GroupID { get { return m_GroupID; } } + /// Get the notices list + public GroupNoticeList Notices { get { return m_Notices; } } + + /// Construct a new instance of the GroupNoticesListReplyEventArgs class + /// The ID of the group + /// The list containing active notices + public GroupNoticesListReplyEventArgs(UUID groupID, GroupNoticeList notices) + { + m_GroupID = groupID; + m_Notices = notices; + } + } + + /// Represents the profile of a group + public class GroupProfileEventArgs : EventArgs + { + private readonly Group m_Group; + + /// Get the group profile + public Group Group { get { return m_Group; } } + + /// Construct a new instance of the GroupProfileEventArgs class + /// The group profile + public GroupProfileEventArgs(Group group) + { + this.m_Group = group; + } + } + + #endregion } diff --git a/Programs/examples/TestClient/Commands/Agent/CloneProfileCommand.cs b/Programs/examples/TestClient/Commands/Agent/CloneProfileCommand.cs index 2a70ef6a..c4b00d77 100644 --- a/Programs/examples/TestClient/Commands/Agent/CloneProfileCommand.cs +++ b/Programs/examples/TestClient/Commands/Agent/CloneProfileCommand.cs @@ -21,7 +21,8 @@ namespace OpenMetaverse.TestClient testClient.Avatars.OnAvatarInterests += new AvatarManager.AvatarInterestsCallback(Avatars_OnAvatarInterests); testClient.Avatars.OnAvatarProperties += new AvatarManager.AvatarPropertiesCallback(Avatars_OnAvatarProperties); testClient.Avatars.OnAvatarGroups += new AvatarManager.AvatarGroupsCallback(Avatars_OnAvatarGroups); - testClient.Groups.OnGroupJoined += new GroupManager.GroupJoinedCallback(Groups_OnGroupJoined); + testClient.Groups.GroupJoinedReply += new EventHandler(Groups_OnGroupJoined); + testClient.Avatars.OnAvatarPicks += new AvatarManager.AvatarPicksCallback(Avatars_OnAvatarPicks); testClient.Avatars.OnPickInfo += new AvatarManager.PickInfoCallback(Avatars_OnPickInfo); @@ -29,7 +30,7 @@ namespace OpenMetaverse.TestClient Description = "Clones another avatars profile as closely as possible. WARNING: This command will " + "destroy your existing profile! Usage: cloneprofile [targetuuid]"; Category = CommandCategory.Other; - } + } public override string Execute(string[] args, UUID fromAgentID) { @@ -141,16 +142,16 @@ namespace OpenMetaverse.TestClient } } - void Groups_OnGroupJoined(UUID groupID, bool success) + void Groups_OnGroupJoined(object sender, GroupOperationEventArgs e) { - Console.WriteLine(Client.ToString() + (success ? " joined " : " failed to join ") + - groupID.ToString()); + Console.WriteLine(Client.ToString() + (e.Success ? " joined " : " failed to join ") + + e.GroupID.ToString()); - if (success) + if (e.Success) { - Console.WriteLine(Client.ToString() + " setting " + groupID.ToString() + + Console.WriteLine(Client.ToString() + " setting " + e.GroupID.ToString() + " as the active group"); - Client.Groups.ActivateGroup(groupID); + Client.Groups.ActivateGroup(e.GroupID); } } } diff --git a/Programs/examples/TestClient/Commands/Directory/Key2NameCommand.cs b/Programs/examples/TestClient/Commands/Directory/Key2NameCommand.cs index ce3596a1..3df133b9 100644 --- a/Programs/examples/TestClient/Commands/Directory/Key2NameCommand.cs +++ b/Programs/examples/TestClient/Commands/Directory/Key2NameCommand.cs @@ -29,7 +29,7 @@ namespace OpenMetaverse.TestClient.Commands waitQuery.Reset(); Client.Avatars.OnAvatarNames += Avatars_OnAvatarNames; - Client.Groups.OnGroupProfile += Groups_OnGroupProfile; + Client.Groups.GroupProfile += Groups_OnGroupProfile; Client.Avatars.RequestAvatarName(key); Client.Groups.RequestGroupProfile(key); @@ -39,13 +39,13 @@ namespace OpenMetaverse.TestClient.Commands } Client.Avatars.OnAvatarNames -= Avatars_OnAvatarNames; - Client.Groups.OnGroupProfile -= Groups_OnGroupProfile; + Client.Groups.GroupProfile -= Groups_OnGroupProfile; return result.ToString(); } - void Groups_OnGroupProfile(Group group) + void Groups_OnGroupProfile(object sender, GroupProfileEventArgs e) { - result.AppendLine("Group: " + group.Name + " " + group.ID); + result.AppendLine("Group: " + e.Group.Name + " " + e.Group.ID); waitQuery.Set(); } diff --git a/Programs/examples/TestClient/Commands/Groups/GroupMembersCommand.cs b/Programs/examples/TestClient/Commands/Groups/GroupMembersCommand.cs index a0fa3605..bf0ef917 100644 --- a/Programs/examples/TestClient/Commands/Groups/GroupMembersCommand.cs +++ b/Programs/examples/TestClient/Commands/Groups/GroupMembersCommand.cs @@ -35,31 +35,29 @@ namespace OpenMetaverse.TestClient GroupName = GroupName.Trim(); GroupUUID = Client.GroupName2UUID(GroupName); - if (UUID.Zero != GroupUUID) { - GroupManager.GroupMembersCallback callback = - new GroupManager.GroupMembersCallback(GroupMembersHandler); - Client.Groups.OnGroupMembers += callback; + if (UUID.Zero != GroupUUID) { + Client.Groups.GroupMembersReply += GroupMembersHandler; GroupRequestID = Client.Groups.RequestGroupMembers(GroupUUID); GroupsEvent.WaitOne(30000, false); GroupsEvent.Reset(); - Client.Groups.OnGroupMembers -= callback; + Client.Groups.GroupMembersReply -= GroupMembersHandler; return Client.ToString() + " got group members"; } return Client.ToString() + " doesn't seem to be member of the group " + GroupName; } - private void GroupMembersHandler(UUID requestID, UUID groupID, Dictionary members) + private void GroupMembersHandler(object sender, GroupMembersReplyEventArgs e) { - if (requestID == GroupRequestID) { + if (e.RequestID == GroupRequestID) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); - sb.AppendFormat("GroupMembers: RequestID {0}", requestID).AppendLine(); + sb.AppendFormat("GroupMembers: RequestID {0}", e.RequestID).AppendLine(); sb.AppendFormat("GroupMembers: GroupUUID {0}", GroupUUID).AppendLine(); sb.AppendFormat("GroupMembers: GroupName {0}", GroupName).AppendLine(); - if (members.Count > 0) - foreach (KeyValuePair member in members) + if (e.Members.Count > 0) + foreach (KeyValuePair member in e.Members) sb.AppendFormat("GroupMembers: MemberUUID {0}", member.Key.ToString()).AppendLine(); - sb.AppendFormat("GroupMembers: MemberCount {0}", members.Count).AppendLine(); + sb.AppendFormat("GroupMembers: MemberCount {0}", e.Members.Count).AppendLine(); Console.WriteLine(sb.ToString()); GroupsEvent.Set(); } diff --git a/Programs/examples/TestClient/Commands/Groups/GroupRolesCommand.cs b/Programs/examples/TestClient/Commands/Groups/GroupRolesCommand.cs index 79d1e48a..e1618546 100644 --- a/Programs/examples/TestClient/Commands/Groups/GroupRolesCommand.cs +++ b/Programs/examples/TestClient/Commands/Groups/GroupRolesCommand.cs @@ -36,33 +36,32 @@ namespace OpenMetaverse.TestClient GroupUUID = Client.GroupName2UUID(GroupName); if (UUID.Zero != GroupUUID) { - GroupManager.GroupRolesCallback callback = - new GroupManager.GroupRolesCallback(GroupRolesHandler); - Client.Groups.OnGroupRoles += callback; + Client.Groups.GroupRoleDataReply += Groups_GroupRoles; GroupRequestID = Client.Groups.RequestGroupRoles(GroupUUID); GroupsEvent.WaitOne(30000, false); GroupsEvent.Reset(); - Client.Groups.OnGroupRoles -= callback; + Client.Groups.GroupRoleDataReply += Groups_GroupRoles; return Client.ToString() + " got group roles"; } return Client.ToString() + " doesn't seem to have any roles in the group " + GroupName; } - private void GroupRolesHandler(UUID requestID, UUID groupID, Dictionary roles) + void Groups_GroupRoles(object sender, GroupRolesDataReplyEventArgs e) { - if (requestID == GroupRequestID) { + if (e.RequestID == GroupRequestID) + { StringBuilder sb = new StringBuilder(); sb.AppendLine(); - sb.AppendFormat("GroupRole: RequestID {0}", requestID).AppendLine(); + sb.AppendFormat("GroupRole: RequestID {0}", e.RequestID).AppendLine(); sb.AppendFormat("GroupRole: GroupUUID {0}", GroupUUID).AppendLine(); sb.AppendFormat("GroupRole: GroupName {0}", GroupName).AppendLine(); - if (roles.Count > 0) - foreach (KeyValuePair role in roles) + if (e.Roles.Count > 0) + foreach (KeyValuePair role in e.Roles) sb.AppendFormat("GroupRole: Role {0} {1}|{2}", role.Value.ID, role.Value.Name, role.Value.Title).AppendLine(); - sb.AppendFormat("GroupRole: RoleCount {0}", roles.Count).AppendLine(); + sb.AppendFormat("GroupRole: RoleCount {0}", e.Roles.Count).AppendLine(); Console.WriteLine(sb.ToString()); GroupsEvent.Set(); } - } + } } } diff --git a/Programs/examples/TestClient/Commands/Groups/JoinGroupCommand.cs b/Programs/examples/TestClient/Commands/Groups/JoinGroupCommand.cs index fcbed773..b83e2fd8 100644 --- a/Programs/examples/TestClient/Commands/Groups/JoinGroupCommand.cs +++ b/Programs/examples/TestClient/Commands/Groups/JoinGroupCommand.cs @@ -64,9 +64,8 @@ namespace OpenMetaverse.TestClient else return resolvedGroupName; } - - GroupManager.GroupJoinedCallback gcallback = new GroupManager.GroupJoinedCallback(Groups_OnGroupJoined); - Client.Groups.OnGroupJoined += gcallback; + + Client.Groups.GroupJoinedReply += Groups_OnGroupJoined; Client.Groups.RequestJoinGroup(resolvedGroupID); /* A.Biondi @@ -75,7 +74,7 @@ namespace OpenMetaverse.TestClient GetGroupsSearchEvent.WaitOne(60000, false); - Client.Groups.OnGroupJoined -= gcallback; + Client.Groups.GroupJoinedReply -= Groups_GroupJoined; GetGroupsSearchEvent.Reset(); Client.ReloadGroupsCache(); @@ -84,6 +83,11 @@ namespace OpenMetaverse.TestClient return "Unable to join the group " + resolvedGroupName; } + void Groups_GroupJoined(object sender, GroupOperationEventArgs e) + { + throw new NotImplementedException(); + } + void Directory_DirGroups(object sender, DirGroupsReplyEventArgs e) { if (queryID == e.QueryID) @@ -126,9 +130,9 @@ namespace OpenMetaverse.TestClient } } - void Groups_OnGroupJoined(UUID groupID, bool success) + void Groups_OnGroupJoined(object sender, GroupOperationEventArgs e) { - Console.WriteLine(Client.ToString() + (success ? " joined " : " failed to join ") + groupID.ToString()); + Console.WriteLine(Client.ToString() + (e.Success ? " joined " : " failed to join ") + e.GroupID.ToString()); /* A.Biondi * This code is not necessary because it is yet present in the @@ -144,7 +148,7 @@ namespace OpenMetaverse.TestClient */ - joinedGroup = success; + joinedGroup = e.Success; GetGroupsSearchEvent.Set(); } } diff --git a/Programs/examples/TestClient/Commands/Groups/LeaveGroupCommand.cs b/Programs/examples/TestClient/Commands/Groups/LeaveGroupCommand.cs index a18006cb..f8798a6d 100644 --- a/Programs/examples/TestClient/Commands/Groups/LeaveGroupCommand.cs +++ b/Programs/examples/TestClient/Commands/Groups/LeaveGroupCommand.cs @@ -29,14 +29,13 @@ namespace OpenMetaverse.TestClient groupName = groupName.Trim(); UUID groupUUID = Client.GroupName2UUID(groupName); - if (UUID.Zero != groupUUID) { - GroupManager.GroupLeftCallback lcallback = new GroupManager.GroupLeftCallback(Groups_OnGroupLeft); - Client.Groups.OnGroupLeft += lcallback; + if (UUID.Zero != groupUUID) { + Client.Groups.GroupLeaveReply += Groups_GroupLeft; Client.Groups.LeaveGroup(groupUUID); GroupsEvent.WaitOne(30000, false); + Client.Groups.GroupLeaveReply -= Groups_GroupLeft; - Client.Groups.OnGroupLeft -= lcallback; GroupsEvent.Reset(); Client.ReloadGroupsCache(); @@ -47,13 +46,13 @@ namespace OpenMetaverse.TestClient return Client.ToString() + " doesn't seem to be member of the group " + groupName; } - - void Groups_OnGroupLeft(UUID groupID, bool success) + void Groups_GroupLeft(object sender, GroupOperationEventArgs e) { - Console.WriteLine(Client.ToString() + (success ? " has left group " : " failed to left group ") + groupID.ToString()); + Console.WriteLine(Client.ToString() + (e.Success ? " has left group " : " failed to left group ") + e.GroupID.ToString()); - leftGroup = success; + leftGroup = e.Success; GroupsEvent.Set(); } + } } diff --git a/Programs/examples/TestClient/TestClient.cs b/Programs/examples/TestClient/TestClient.cs index 7003f830..7ed15bee 100644 --- a/Programs/examples/TestClient/TestClient.cs +++ b/Programs/examples/TestClient/TestClient.cs @@ -53,7 +53,7 @@ namespace OpenMetaverse.TestClient Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler)); Network.OnLogin += new NetworkManager.LoginCallback(LoginHandler); Self.IM += Self_IM; - Groups.OnGroupMembers += new GroupManager.GroupMembersCallback(GroupMembersHandler); + Groups.GroupMembersReply += GroupMembersHandler; Inventory.OnObjectOffered += new InventoryManager.ObjectOfferedCallback(Inventory_OnInventoryObjectReceived); Network.RegisterCallback(PacketType.AvatarAppearance, new NetworkManager.PacketCallback(AvatarAppearanceHandler)); @@ -140,15 +140,22 @@ namespace OpenMetaverse.TestClient public void ReloadGroupsCache() { - GroupManager.CurrentGroupsCallback callback = - new GroupManager.CurrentGroupsCallback(Groups_OnCurrentGroups); - Groups.OnCurrentGroups += callback; + Groups.CurrentGroups += Groups_CurrentGroups; Groups.RequestCurrentGroups(); GroupsEvent.WaitOne(10000, false); - Groups.OnCurrentGroups -= callback; + Groups.CurrentGroups -= Groups_CurrentGroups; GroupsEvent.Reset(); } + void Groups_CurrentGroups(object sender, CurrentGroupsEventArgs e) + { + if (null == GroupsCache) + GroupsCache = e.Groups; + else + lock (GroupsCache) { GroupsCache = e.Groups; } + GroupsEvent.Set(); + } + public UUID GroupName2UUID(String groupName) { UUID tryUUID; @@ -167,17 +174,7 @@ namespace OpenMetaverse.TestClient } } return UUID.Zero; - } - - private void Groups_OnCurrentGroups(Dictionary pGroups) - { - if (null == GroupsCache) - GroupsCache = pGroups; - else - lock(GroupsCache) { GroupsCache = pGroups; } - GroupsEvent.Set(); - } - + } private void updateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { @@ -197,11 +194,11 @@ namespace OpenMetaverse.TestClient } } - private void GroupMembersHandler(UUID requestID, UUID groupID, Dictionary members) + private void GroupMembersHandler(object sender, GroupMembersReplyEventArgs e) { - if (requestID != GroupMembersRequestID) return; + if (e.RequestID != GroupMembersRequestID) return; - GroupMembers = members; + GroupMembers = e.Members; } private void AvatarAppearanceHandler(Packet packet, Simulator simulator) diff --git a/Programs/examples/groupmanager/frmGroupInfo.cs b/Programs/examples/groupmanager/frmGroupInfo.cs index c8677835..4d92147e 100644 --- a/Programs/examples/groupmanager/frmGroupInfo.cs +++ b/Programs/examples/groupmanager/frmGroupInfo.cs @@ -21,9 +21,9 @@ namespace groupmanager Dictionary Titles = new Dictionary(); Dictionary MemberData = new Dictionary(); Dictionary Names = new Dictionary(); - GroupManager.GroupProfileCallback GroupProfileCallback; - GroupManager.GroupMembersCallback GroupMembersCallback; - GroupManager.GroupTitlesCallback GroupTitlesCallback; + EventHandler GroupProfileCallback; + EventHandler GroupMembersCallback; + EventHandler GroupTitlesCallback; AvatarManager.AvatarNamesCallback AvatarNamesCallback; public frmGroupInfo(Group group, GridClient client) @@ -37,18 +37,18 @@ namespace groupmanager IntPtr temp = Handle; } - GroupProfileCallback = new GroupManager.GroupProfileCallback(GroupProfileHandler); - GroupMembersCallback = new GroupManager.GroupMembersCallback(GroupMembersHandler); - GroupTitlesCallback = new GroupManager.GroupTitlesCallback(GroupTitlesHandler); + GroupMembersCallback = new EventHandler(GroupMembersHandler); + GroupProfileCallback = new EventHandler(GroupProfileHandler); + GroupTitlesCallback = new EventHandler(GroupTitlesHandler); AvatarNamesCallback = new AvatarManager.AvatarNamesCallback(AvatarNamesHandler); Group = group; Client = client; // Register the callbacks for this form - Client.Groups.OnGroupProfile += GroupProfileCallback; - Client.Groups.OnGroupMembers += GroupMembersCallback; - Client.Groups.OnGroupTitles += GroupTitlesCallback; + Client.Groups.GroupProfile += GroupProfileCallback; + Client.Groups.GroupMembersReply += GroupMembersCallback; + Client.Groups.GroupTitlesReply += GroupTitlesCallback; Client.Avatars.OnAvatarNames += AvatarNamesCallback; // Request the group information @@ -60,15 +60,15 @@ namespace groupmanager ~frmGroupInfo() { // Unregister the callbacks for this form - Client.Groups.OnGroupProfile -= GroupProfileCallback; - Client.Groups.OnGroupMembers -= GroupMembersCallback; - Client.Groups.OnGroupTitles -= GroupTitlesCallback; + Client.Groups.GroupProfile -= GroupProfileCallback; + Client.Groups.GroupMembersReply -= GroupMembersCallback; + Client.Groups.GroupTitlesReply -= GroupTitlesCallback; Client.Avatars.OnAvatarNames -= AvatarNamesCallback; } - private void GroupProfileHandler(Group profile) + private void GroupProfileHandler(object sender, GroupProfileEventArgs e) { - Profile = profile; + Profile = e.Group; if (Group.InsigniaID != UUID.Zero) Client.Assets.RequestImage(Group.InsigniaID, ImageType.Normal, @@ -213,9 +213,9 @@ namespace groupmanager } } - private void GroupMembersHandler(UUID requestID, UUID groupID, Dictionary members) + private void GroupMembersHandler(object sender, GroupMembersReplyEventArgs e) { - Members = members; + Members = e.Members; UpdateMembers(); } @@ -256,9 +256,9 @@ namespace groupmanager } } - private void GroupTitlesHandler(UUID requestID, UUID groupID, Dictionary titles) + private void GroupTitlesHandler(object sender, GroupTitlesReplyEventArgs e) { - Titles = titles; + Titles = e.Titles; UpdateTitles(); } diff --git a/Programs/examples/groupmanager/frmGroupManager.cs b/Programs/examples/groupmanager/frmGroupManager.cs index 627045da..c3a1a761 100644 --- a/Programs/examples/groupmanager/frmGroupManager.cs +++ b/Programs/examples/groupmanager/frmGroupManager.cs @@ -28,11 +28,18 @@ namespace groupmanager Client.Network.OnLogin += new NetworkManager.LoginCallback(Network_OnLogin); Client.Network.OnEventQueueRunning += new NetworkManager.EventQueueRunningCallback(Network_OnEventQueueRunning); - Client.Groups.OnCurrentGroups += new GroupManager.CurrentGroupsCallback(Groups_OnCurrentGroups); + Client.Groups.CurrentGroups += Groups_CurrentGroups; InitializeComponent(); } + void Groups_CurrentGroups(object sender, CurrentGroupsEventArgs e) + { + Groups = e.Groups; + + Invoke(new MethodInvoker(UpdateGroups)); + } + private void UpdateGroups() { lock (lstGroups) @@ -131,14 +138,7 @@ namespace groupmanager }); } } - - private void Groups_OnCurrentGroups(Dictionary groups) - { - Groups = groups; - - Invoke(new MethodInvoker(UpdateGroups)); - } - + private void Network_OnEventQueueRunning(Simulator simulator) { if (simulator == Client.Network.CurrentSim)