private 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, imSessionID = 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.imSessionID = data.noticeData.ItemID; //GroupAttachmentCache[msg.imSessionID] = 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; }
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, imSessionID = 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.imSessionID = info.noticeData.ItemID; //GroupAttachmentCache[msg.imSessionID] = 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; }
private 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.imSessionID; 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_sceneList[0].UserAccountService.GetUserAccount(remoteClient.AllScopeIDs, inviteInfo.FromAgentName); if (account != null) { m_groupData.AddAgentToGroup(account.PrincipalID, inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); GridInstantMessage msg = new GridInstantMessage { imSessionID = 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); //WTH??? noone but the invitee needs to know //The other client wants to know too... GroupMembershipData gmd = AttemptFindGroupMembershipData(inviteInfo.AgentID, inviteInfo.AgentID, inviteInfo.GroupID); m_cachedGroupTitles[inviteInfo.AgentID] = gmd; m_cachedGroupMemberships.Remove(remoteClient.AgentId); UpdateAllClientsWithGroupInfo(inviteInfo.AgentID, gmd.GroupTitle); SendAgentGroupDataUpdate(remoteClient); // XTODO: If the inviter is still online, they need an agent dataupdate // and maybe group membership updates for the invitee // Reply: why do they need that? they will get told about the new user when they reopen the groups panel m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } } // Reject if (im.dialog == (byte) InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: Received a reject invite notice."); m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } } } // Group notices if ((im.dialog == (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_sceneList[0].InventoryService.GetItem(new InventoryItemBase(ItemID, GetRequestingAgentID(remoteClient))); 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); } } else if ((im.dialog == (byte) InstantMessageDialog.GroupNoticeInventoryDeclined) || (im.dialog == (byte) InstantMessageDialog.GroupNoticeInventoryDeclined)) { //GroupAttachmentCache.Remove(im.imSessionID); } else if ((im.dialog == (byte) InstantMessageDialog.GroupNoticeInventoryAccepted) || (im.dialog == (byte) InstantMessageDialog.GroupNoticeInventoryAccepted)) { UUID FolderID = new UUID(im.binaryBucket, 0); remoteClient.Scene.InventoryService.GiveInventoryItemAsync(remoteClient.AgentId, im.imSessionID, im.imSessionID, FolderID, false, (item) => { if (item != null) remoteClient.SendBulkUpdateInventory(item); }); //GroupAttachmentCache.Remove(im.imSessionID); } else if ((im.dialog == 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.imSessionID; ejectee.SendAgentDropGroup(groupID); if (ejectee.ActiveGroupId == groupID) GroupTitleUpdate(ejectee, UUID.Zero, UUID.Zero); } } // Interop, received special 211 code for offline group notice else if ((im.dialog == 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.imSessionID); //We reset the ID so that if this was set before, it won't be misadded or anything to the cache im.imSessionID = UUID.Random(); //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.imSessionID = GND.noticeData.ItemID; //GroupAttachmentCache[im.imSessionID] = 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; } }
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_sceneList[0].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); } } }
public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { object remoteValue = DoRemote(requestingAgentID, noticeID); if (remoteValue != null || m_doRemoteOnly) return (GroupNoticeInfo)remoteValue; 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 = data.Query(fields, "osgroupnotice", 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 GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { Dictionary<string, object> sendData = new Dictionary<string, object>(); sendData["METHOD"] = "GetGroupNotice"; sendData["requestingAgentID"] = requestingAgentID; sendData["noticeID"] = noticeID; string reqString = WebUtils.BuildXmlResponse(sendData); try { List<string> m_ServerURIs = m_registry.RequestModuleInterface<IConfigurationService>().FindValueOf( requestingAgentID.ToString(), "RemoteServerURI", false); foreach (string m_ServerURI in m_ServerURIs) { string reply = SynchronousRestFormsRequester.MakeRequest("POST", m_ServerURI, reqString); if (reply != string.Empty) { Dictionary<string, object> replyData = WebUtils.ParseXmlResponse(reply); if (replyData != null) { Dictionary<string, object>.ValueCollection replyvalues = replyData.Values; GroupNoticeInfo group = null; #if (!ISWIN) foreach (object replyvalue in replyvalues) { Dictionary<string, object> f = replyvalue as Dictionary<string, object>; if (f != null) { group = new GroupNoticeInfo(f); } } #else foreach (Dictionary<string, object> f in replyvalues.OfType<Dictionary<string, object>>()) { group = new GroupNoticeInfo(f); } #endif // Success return group; } } } } catch (Exception e) { MainConsole.Instance.DebugFormat("[AuroraRemoteGroupsServiceConnector]: Exception when contacting server: {0}", e); } return null; }
public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { Hashtable param = new Hashtable(); param["NoticeID"] = noticeID.ToString(); Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); if (respData.Contains("error")) { return null; } GroupNoticeInfo data = new GroupNoticeInfo { GroupID = UUID.Parse((string) respData["GroupID"]), Message = (string) respData["Message"], BinaryBucket = Utils.HexStringToBytes((string) respData["BinaryBucket"], true), noticeData = { NoticeID = UUID.Parse((string) respData["NoticeID"]), Timestamp = uint.Parse((string) respData["Timestamp"]), FromName = (string) respData["FromName"], Subject = (string) respData["Subject"], HasAttachment = false, AssetType = 0 } }; if (data.Message == null) { data.Message = string.Empty; } return data; }
public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { if (m_debugEnabled) MainConsole.Instance.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", MethodBase.GetCurrentMethod().Name); OSDMap GroupNotice; UUID GroupID; if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice)) { GroupNoticeInfo data = new GroupNoticeInfo { GroupID = GroupID, Message = GroupNotice["Message"].AsString(), BinaryBucket = GroupNotice["BinaryBucket"].AsBinary(), noticeData = { NoticeID = noticeID, Timestamp = GroupNotice["TimeStamp"].AsUInteger(), FromName = GroupNotice["FromName"].AsString(), Subject = GroupNotice["Subject"].AsString(), HasAttachment = GroupNotice["BinaryBucket"].AsBinary().Length > 0 } }; if (data.noticeData.HasAttachment) { data.noticeData.ItemID = GroupNotice["ItemID"].AsUUID(); data.noticeData.AssetType = (byte) GroupNotice["AssetType"].AsInteger(); data.noticeData.ItemName = GroupNotice["ItemName"].AsString(); } if (data.Message == null) { data.Message = string.Empty; } return data; } return null; }
protected OSDMap OnMessageReceived(OSDMap message) { //We need to check and see if this is an GroupSessionAgentUpdate if (message.ContainsKey("Method") && message["Method"] == "GroupSessionAgentUpdate") { //COMES IN ON AURORA.SERVER SIDE //Send it on to whomever it concerns OSDMap innerMessage = (OSDMap) message["Message"]; if (innerMessage["message"] == "ChatterBoxSessionAgentListUpdates") //ONLY forward on this type of message { UUID agentID = message["AgentID"]; IEventQueueService eqs = m_registry.RequestModuleInterface<IEventQueueService>(); ICapsService caps = m_registry.RequestModuleInterface<ICapsService>(); if (caps != null) { IClientCapsService clientCaps = caps.GetClientCapsService(agentID); if (clientCaps != null && clientCaps.GetRootCapsService() != null) eqs.Enqueue(innerMessage, agentID, clientCaps.GetRootCapsService().RegionHandle); } } } else if (message.ContainsKey("Method") && message["Method"] == "FixGroupRoleTitles") { //COMES IN ON AURORA.SERVER SIDE FROM REGION UUID groupID = message["GroupID"].AsUUID(); UUID agentID = message["AgentID"].AsUUID(); UUID roleID = message["RoleID"].AsUUID(); byte type = (byte) message["Type"].AsInteger(); IGroupsServiceConnector con = DataManager.RequestPlugin<IGroupsServiceConnector>(); List<GroupRoleMembersData> members = con.GetGroupRoleMembers(agentID, groupID); List<GroupRolesData> roles = con.GetGroupRoles(agentID, groupID); GroupRolesData everyone = null; #if (!ISWIN) foreach (GroupRolesData role in roles) { if (role.Name == "Everyone") everyone = role; } #else foreach (GroupRolesData role in roles.Where(role => role.Name == "Everyone")) everyone = role; #endif List<Interfaces.GridRegion> regionsToBeUpdated = new List<Interfaces.GridRegion>(); foreach (GroupRoleMembersData data in members) { if (data.RoleID == roleID) { //They were affected by the change switch ((GroupRoleUpdate) type) { case GroupRoleUpdate.Create: case GroupRoleUpdate.NoUpdate: //No changes... break; case GroupRoleUpdate.UpdatePowers: //Possible we don't need to send this? case GroupRoleUpdate.UpdateAll: case GroupRoleUpdate.UpdateData: case GroupRoleUpdate.Delete: if (type == (byte) GroupRoleUpdate.Delete) //Set them to the most limited role since their role is gone con.SetAgentGroupSelectedRole(data.MemberID, groupID, everyone.RoleID); //Need to update their title inworld ICapsService caps = m_registry.RequestModuleInterface<ICapsService>(); if (caps != null) { IClientCapsService clientCaps = caps.GetClientCapsService(agentID); if (clientCaps != null && clientCaps.GetRootCapsService() != null) regionsToBeUpdated.Add(clientCaps.GetRootCapsService().Region); } break; } } } if (regionsToBeUpdated.Count != 0) { ISyncMessagePosterService messagePost = m_registry.RequestModuleInterface<ISyncMessagePosterService>(); if (messagePost != null) { foreach (Interfaces.GridRegion region in regionsToBeUpdated) { OSDMap outgoingMessage = new OSDMap(); outgoingMessage["Method"] = "ForceUpdateGroupTitles"; outgoingMessage["GroupID"] = groupID; outgoingMessage["RoleID"] = roleID; outgoingMessage["RegionID"] = region.RegionID; messagePost.Post(region.ServerURI, outgoingMessage); } } } } else if (message.ContainsKey("Method") && message["Method"] == "ForceUpdateGroupTitles") { //COMES IN ON REGION SIDE FROM AURORA.SERVER UUID groupID = message["GroupID"].AsUUID(); UUID roleID = message["RoleID"].AsUUID(); UUID regionID = message["RegionID"].AsUUID(); IGroupsModule gm = m_registry.RequestModuleInterface<IGroupsModule>(); if (gm != null) gm.UpdateUsersForExternalRoleUpdate(groupID, roleID, regionID); } else if (message.ContainsKey("Method") && message["Method"] == "SendGroupNoticeToUsers") { //COMES IN ON REGION SIDE FROM AURORA.SERVER GroupNoticeInfo notice = new GroupNoticeInfo(); notice.FromOSD((OSDMap)message["Notice"]); IGroupsModule gm = m_registry.RequestModuleInterface<IGroupsModule>(); if (gm != null) gm.SendGroupNoticeToUsers(null, notice, true); } return null; }