public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { if (m_doRemoteOnly) { object remoteValue = DoRemote (requestingAgentID, noticeID); return remoteValue != null ? (GroupNoticeInfo)remoteValue : null; } QueryFilter filter = new QueryFilter(); filter.andFilters["NoticeID"] = noticeID; string[] fields = new string[9] { "GroupID", "Timestamp", "FromName", "Subject", "ItemID", "HasAttachment", "Message", "AssetType", "ItemName" }; List<string> notice = GD.Query(fields, _NOTICEREALM, filter, null, null, null); if (notice.Count != fields.Length) return null; GroupNoticeData GND = new GroupNoticeData { NoticeID = noticeID, Timestamp = uint.Parse(notice[1]), FromName = notice[2], Subject = notice[3], HasAttachment = int.Parse(notice[5]) == 1 }; if (GND.HasAttachment) { GND.ItemID = UUID.Parse(notice[4]); GND.AssetType = (byte) int.Parse(notice[7]); GND.ItemName = notice[8]; } GroupNoticeInfo info = new GroupNoticeInfo { BinaryBucket = new byte[0], GroupID = UUID.Parse(notice[0]), Message = notice[6], noticeData = GND }; return (!agentsCanBypassGroupNoticePermsCheck.Contains(requestingAgentID) && !CheckGroupPermissions(requestingAgentID, info.GroupID, (ulong) GroupPowers.ReceiveNotices)) ? null : info; }
public void SendGroupNoticeToUsers(IClientAPI remoteClient, GroupNoticeInfo notice, bool localOnly) { // Send notice out to everyone that wants notices foreach ( GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), notice.GroupID)) { if (m_debugEnabled) { UserAccount targetUser = m_scene.UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.AllScopeIDs, member.AgentID); if (targetUser != null) { MainConsole.Instance.DebugFormat( "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", notice.noticeData.NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); } else { MainConsole.Instance.DebugFormat( "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", notice.noticeData.NoticeID, member.AgentID, member.AcceptNotices); } } if (member.AcceptNotices) { // Build notice IIM GridInstantMessage msg = CreateGroupNoticeIM(GetRequestingAgentID(remoteClient), notice, (byte) InstantMessageDialog.GroupNotice); msg.ToAgentID = member.AgentID; OutgoingInstantMessage(msg, member.AgentID, localOnly); } } }
void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name); // Group invitations if ((im.Dialog == (byte) InstantMessageDialog.GroupInvitationAccept) || (im.Dialog == (byte) InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = im.SessionID; GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); if (inviteInfo == null) { if (m_debugEnabled) MainConsole.Instance.WarnFormat( "[GROUPS]: Received an Invite IM for an invite that does not exist {0}.", inviteID); return; } if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); UUID fromAgentID = im.FromAgentID; if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) { // Accept if (im.Dialog == (byte) InstantMessageDialog.GroupInvitationAccept) { if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: Received an accept invite notice."); // and the sessionid is the role UserAccount account = m_scene.UserAccountService.GetUserAccount(remoteClient.AllScopeIDs, inviteInfo.FromAgentName); if (account != null) { m_groupData.AddAgentToGroup(account.PrincipalID, inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); GridInstantMessage msg = new GridInstantMessage { SessionID = UUID.Zero, FromAgentID = UUID.Zero, ToAgentID = inviteInfo.AgentID, Timestamp = (uint) Util.UnixTimeSinceEpoch(), FromAgentName = "Groups", Message = string.Format("You have been added to the group."), Dialog = (byte) InstantMessageDialog.MessageBox, FromGroup = false, Offline = 0, ParentEstateID = 0, Position = Vector3.Zero, RegionID = UUID.Zero, BinaryBucket = new byte[0] }; OutgoingInstantMessage(msg, inviteInfo.AgentID); GroupMembershipData gmd = AttemptFindGroupMembershipData(inviteInfo.AgentID, inviteInfo.AgentID, inviteInfo.GroupID); m_cachedGroupTitles[inviteInfo.AgentID] = gmd; m_cachedGroupMemberships.Remove(remoteClient.AgentId); RemoveFromGroupPowersCache(inviteInfo.AgentID, inviteInfo.GroupID); UpdateAllClientsWithGroupInfo(inviteInfo.AgentID, gmd.GroupTitle); SendAgentGroupDataUpdate(remoteClient); m_groupData.RemoveAgentInvite(GetRequestingAgentID(remoteClient), inviteID); } } // Reject if (im.Dialog == (byte) InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: Received a reject invite notice."); m_groupData.RemoveAgentInvite(GetRequestingAgentID(remoteClient), inviteID); } RemoveFromGroupPowersCache(remoteClient.AgentId, inviteInfo.GroupID); } } // Group notices switch (im.Dialog) { case (byte) InstantMessageDialog.GroupNotice: { if (!m_groupNoticesEnabled) return; UUID GroupID = im.ToAgentID; if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.Message.Substring(0, im.Message.IndexOf('|')); string Message = im.Message.Substring(Subject.Length + 1); byte[] bucket; UUID ItemID = UUID.Zero; int AssetType = 0; string ItemName = ""; if ((im.BinaryBucket.Length == 1) && (im.BinaryBucket[0] == 0)) { bucket = new byte[19]; bucket[0] = 0; bucket[1] = 0; GroupID.ToBytes(bucket, 2); bucket[18] = 0; } else { //bucket = im.BinaryBucket; string binBucket = Utils.BytesToString(im.BinaryBucket); binBucket = binBucket.Remove(0, 14).Trim(); OSDMap binBucketOSD = (OSDMap) OSDParser.DeserializeLLSDXml(binBucket); if (binBucketOSD.ContainsKey("item_id")) { ItemID = binBucketOSD["item_id"].AsUUID(); InventoryItemBase item = m_scene.InventoryService.GetItem(GetRequestingAgentID(remoteClient), ItemID); if (item != null) { AssetType = item.AssetType; ItemName = item.Name; } else ItemID = UUID.Zero; } } m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.FromAgentName, Subject, Message, ItemID, AssetType, ItemName); if (OnNewGroupNotice != null) OnNewGroupNotice(GroupID, NoticeID); GroupNoticeInfo notice = new GroupNoticeInfo() { BinaryBucket = im.BinaryBucket, GroupID = GroupID, Message = Message, noticeData = new GroupNoticeData() { AssetType = (byte) AssetType, FromName = im.FromAgentName, GroupID = GroupID, HasAttachment = ItemID != UUID.Zero, ItemID = ItemID, ItemName = ItemName, NoticeID = NoticeID, Subject = Subject, Timestamp = im.Timestamp } }; SendGroupNoticeToUsers(remoteClient, notice, false); } } break; case (byte) InstantMessageDialog.GroupNoticeInventoryDeclined: break; case (byte) InstantMessageDialog.GroupNoticeInventoryAccepted: { UUID FolderID = new UUID(im.BinaryBucket, 0); remoteClient.Scene.InventoryService.GiveInventoryItemAsync(remoteClient.AgentId, UUID.Zero, im.SessionID, FolderID, false, (item) => { if (item != null) remoteClient .SendBulkUpdateInventory (item); }); } break; case 210: { // This is sent from the region that the ejectee was ejected from // if it's being delivered here, then the ejectee is here // so we need to send local updates to the agent. UUID ejecteeID = im.ToAgentID; im.Dialog = (byte) InstantMessageDialog.MessageFromAgent; OutgoingInstantMessage(im, ejecteeID); IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { UUID groupID = im.SessionID; ejectee.SendAgentDropGroup(groupID); if (ejectee.ActiveGroupId == groupID) GroupTitleUpdate(ejectee, UUID.Zero, UUID.Zero); RemoveFromGroupPowersCache(ejecteeID, groupID); } } break; case 211: { im.Dialog = (byte) InstantMessageDialog.GroupNotice; //In offline group notices, imSessionID is replaced with the NoticeID so that we can rebuild the packet here GroupNoticeInfo GND = m_groupData.GetGroupNotice(im.ToAgentID, im.SessionID); //Rebuild the binary bucket if (GND.noticeData.HasAttachment) { im.BinaryBucket = CreateBitBucketForGroupAttachment(GND.noticeData, GND.GroupID); //Save the sessionID for the callback by the client (reject or accept) //Only save if has attachment im.SessionID = GND.noticeData.ItemID; } else { byte[] bucket = new byte[19]; bucket[0] = 0; //Attachment enabled == false so 0 bucket[1] = 0; //No attachment, so no asset type GND.GroupID.ToBytes(bucket, 2); bucket[18] = 0; //dunno im.BinaryBucket = bucket; } OutgoingInstantMessage(im, im.ToAgentID); //You MUST reset this, otherwise the client will get it twice, // as it goes through OnGridInstantMessage // which will check and then reresent the notice im.Dialog = 211; } break; } }
public GridInstantMessage CreateGroupNoticeIM(UUID agentID, GroupNoticeInfo info, byte dialog) { if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name); GridInstantMessage msg = new GridInstantMessage { ToAgentID = agentID, Dialog = dialog, FromGroup = true, Offline = 1, ParentEstateID = 0, Position = Vector3.Zero, RegionID = UUID.Zero, SessionID = UUID.Random() }; // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; // Allow this message to be stored for offline use msg.FromAgentID = info.GroupID; msg.Timestamp = info.noticeData.Timestamp; msg.FromAgentName = info.noticeData.FromName; msg.Message = info.noticeData.Subject + "|" + info.Message; if (info.noticeData.HasAttachment) { msg.BinaryBucket = CreateBitBucketForGroupAttachment(info.noticeData, info.GroupID); //Save the sessionID for the callback by the client (reject or accept) //Only save if has attachment msg.SessionID = info.noticeData.ItemID; } else { byte[] bucket = new byte[19]; bucket[0] = 0; //Attachment enabled == false so 0 bucket[1] = 0; //No attachment, so no asset type info.GroupID.ToBytes(bucket, 2); bucket[18] = 0; //dunno msg.BinaryBucket = bucket; } return msg; }
GridInstantMessage BuildGroupNoticeIM(GroupNoticeInfo data, UUID groupNoticeID, UUID AgentID) { GridInstantMessage msg = new GridInstantMessage { FromAgentID = data.GroupID, ToAgentID = AgentID, Timestamp = data.noticeData.Timestamp, FromAgentName = data.noticeData.FromName, Message = data.noticeData.Subject + "|" + data.Message, Dialog = (byte) InstantMessageDialog.GroupNoticeRequested, FromGroup = true, Offline = 1, ParentEstateID = 0, Position = Vector3.Zero, RegionID = UUID.Zero, SessionID = UUID.Random() }; //Allow offline if (data.noticeData.HasAttachment) { msg.BinaryBucket = CreateBitBucketForGroupAttachment(data.noticeData, data.GroupID); //Save the sessionID for the callback by the client (reject or accept) //Only save if has attachment msg.SessionID = data.noticeData.ItemID; } else { byte[] bucket = new byte[19]; bucket[0] = 0; //Attachment enabled == false so 0 bucket[1] = 0; //No attachment, so no asset type data.GroupID.ToBytes(bucket, 2); bucket[18] = 0; //dunno msg.BinaryBucket = bucket; } return msg; }