public bool AddOfflineMessage(GridInstantMessage message) { object remoteValue = DoRemote(message); if (remoteValue != null || m_doRemoteOnly) return remoteValue == null ? false : (bool) remoteValue; if (m_maxOfflineMessages <= 0 || GenericUtils.GetGenericCount(message.ToAgentID, "OfflineMessages", GD) < m_maxOfflineMessages) { GenericUtils.AddGeneric(message.ToAgentID, "OfflineMessages", UUID.Random().ToString(), message.ToOSD(), GD); return true; } return false; }
public virtual void SendInstantMessages (GridInstantMessage im, List<UUID> AgentsToSendTo) { //Check for local users first List<UUID> RemoveUsers = new List<UUID> (); foreach (UUID t in AgentsToSendTo) { IScenePresence user; foreach (IScene scene in m_scenes) { if (!RemoveUsers.Contains (t) && scene.TryGetScenePresence (t, out user)) { // Local message user.ControllingClient.SendInstantMessage (im); RemoveUsers.Add (t); } } } //Clear the local users out foreach (UUID agentID in RemoveUsers) { AgentsToSendTo.Remove (agentID); } SendMultipleGridInstantMessageViaXMLRPC (im, AgentsToSendTo); }
/// <summary> /// If its a message we deal with, pull it from the client here /// </summary> /// <param name="client"></param> /// <param name="im"></param> private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { byte dialog = im.Dialog; switch (dialog) { case (byte) InstantMessageDialog.SessionGroupStart: m_imService.CreateGroupChat(client.AgentId, im); break; case (byte) InstantMessageDialog.SessionSend: m_imService.SendChatToSession(client.AgentId, im); break; case (byte) InstantMessageDialog.SessionDrop: m_imService.DropMemberFromSession(client.AgentId, im); break; } }
public void SendChatToSession(UUID agentID, GridInstantMessage im) { if (m_doRemoteOnly) { DoRemoteCallPost(true, "InstantMessageServerURI", agentID, im); return; } Util.FireAndForget((o) => { ChatSession session; ChatSessions.TryGetValue(im.SessionID, out session); if (session == null) return; if (agentID != UUID.Zero) //Not system { ChatSessionMember sender = FindMember(im.SessionID, agentID); if (sender.MuteText) return; //They have been admin muted, don't allow them to send anything } Dictionary<string, List<GridInstantMessage>> messagesToSend = new Dictionary<string, List<GridInstantMessage>>(); foreach (ChatSessionMember member in session.Members) { if (member.HasBeenAdded) { im.ToAgentID = member.AvatarKey; im.BinaryBucket = Utils.StringToBytes(session.Name); im.RegionID = UUID.Zero; im.ParentEstateID = 0; im.Offline = 0; GridInstantMessage message = new GridInstantMessage(); message.FromOSD(im.ToOSD()); //im.timestamp = 0; string uri = FindRegionURI(member.AvatarKey); if (uri != "") //Check if they are online { //Bulk send all of the instant messages to the same region, so that we don't send them one-by-one over and over if (messagesToSend.ContainsKey(uri)) messagesToSend[uri].Add(message); else messagesToSend.Add(uri, new List<GridInstantMessage>() {message}); } } else if (!member.RequestedRemoval) //If they're requested to leave, don't recontact them { UUID regionID = FindRegionID(member.AvatarKey); if (regionID != UUID.Zero) { im.ToAgentID = member.AvatarKey; m_eventQueueService.ChatterboxInvitation( session.SessionID , session.Name , im.FromAgentID , im.Message , im.ToAgentID , im.FromAgentName , im.Dialog , im.Timestamp , im.Offline == 1 , (int) im.ParentEstateID , im.Position , 1 , im.SessionID , false , Utils.StringToBytes(session.Name) , regionID ); } } } foreach (KeyValuePair<string, List<GridInstantMessage>> kvp in messagesToSend) { SendInstantMessages(kvp.Key, kvp.Value); } }); }
public void CreateGroupChat(UUID AgentID, GridInstantMessage im) { if (m_doRemoteOnly) { DoRemoteCallPost(true, "InstantMessageServerURI", AgentID, im); return; } UUID GroupID = im.SessionID; GroupRecord groupInfo = m_groupData.GetGroupRecord(AgentID, GroupID, null); if (groupInfo != null) { if (!GroupPermissionCheck(AgentID, GroupID, GroupPowers.JoinChat)) return; //They have to be able to join to create a group chat //Create the session. if (!SessionExists(GroupID)) { CreateSession(new ChatSession { Members = new List<ChatSessionMember>(), SessionID = GroupID, Name = groupInfo.GroupName }); AddMemberToGroup(new ChatSessionMember { AvatarKey = AgentID, CanVoiceChat = false, IsModerator = GroupPermissionCheck(AgentID, GroupID, GroupPowers.ModerateChat), MuteText = false, MuteVoice = false, HasBeenAdded = true }, GroupID); foreach ( GroupMembersData gmd in m_groupData.GetGroupMembers(AgentID, GroupID) .Where(gmd => gmd.AgentID != AgentID) .Where( gmd => (gmd.AgentPowers & (ulong) GroupPowers.JoinChat) == (ulong) GroupPowers.JoinChat)) { AddMemberToGroup(new ChatSessionMember { AvatarKey = gmd.AgentID, CanVoiceChat = false, IsModerator = GroupPermissionCheck(gmd.AgentID, GroupID, GroupPowers.ModerateChat), MuteText = false, MuteVoice = false, HasBeenAdded = false }, GroupID); } //Tell us that it was made successfully m_eventQueueService.ChatterBoxSessionStartReply(groupInfo.GroupName, GroupID, AgentID, FindRegionID(AgentID)); } else { ChatSession thisSession = GetSession(GroupID); //A session already exists //Add us AddMemberToGroup(new ChatSessionMember { AvatarKey = AgentID, CanVoiceChat = false, IsModerator = GroupPermissionCheck(AgentID, GroupID, GroupPowers.ModerateChat), MuteText = false, MuteVoice = false, HasBeenAdded = true }, GroupID); //Tell us that we entered successfully m_eventQueueService.ChatterBoxSessionStartReply(groupInfo.GroupName, GroupID, AgentID, FindRegionID(AgentID)); List<ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock> Us = new List<ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock>(); List<ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock> NotUsAgents = new List<ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock>(); foreach (ChatSessionMember sessionMember in thisSession.Members) { ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock block = new ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock { AgentID = sessionMember.AvatarKey, CanVoiceChat = sessionMember.CanVoiceChat, IsModerator = sessionMember.IsModerator, MuteText = sessionMember.MuteText, MuteVoice = sessionMember.MuteVoice, Transition = "ENTER" }; if (AgentID == sessionMember.AvatarKey) Us.Add(block); if (sessionMember.HasBeenAdded) // Don't add not joined yet agents. They don't want to be here. NotUsAgents.Add(block); } foreach (ChatSessionMember member in thisSession.Members) { if (member.HasBeenAdded) //Only send to those in the group { UUID regionID = FindRegionID(member.AvatarKey); if (regionID != UUID.Zero) { if (member.AvatarKey == AgentID) { //Tell 'us' about all the other agents in the group m_eventQueueService.ChatterBoxSessionAgentListUpdates(GroupID, NotUsAgents.ToArray(), member.AvatarKey, "ENTER", regionID); } else { //Tell 'other' agents about the new agent ('us') m_eventQueueService.ChatterBoxSessionAgentListUpdates(GroupID, Us.ToArray(), member.AvatarKey, "ENTER", regionID); } } } } } ChatSessionMember agentMember = FindMember(GroupID, AgentID); //Tell us that we entered ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock ourblock = new ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock { AgentID = AgentID, CanVoiceChat = agentMember.CanVoiceChat, IsModerator = agentMember.IsModerator, MuteText = agentMember.MuteText, MuteVoice = agentMember.MuteVoice, Transition = "ENTER" }; m_eventQueueService.ChatterBoxSessionAgentListUpdates(GroupID, new[] {ourblock}, AgentID, "ENTER", FindRegionID(AgentID)); } }
/// <summary> /// Recursive SendGridInstantMessage over XMLRPC method. /// This is called from within a dedicated thread. /// The first time this is called, prevRegionHandle will be 0 Subsequent times this is called from /// itself, prevRegionHandle will be the last region handle that we tried to send. /// If the handles are the same, we look up the user's location using the grid. /// If the handles are still the same, we end. The send failed. /// </summary> /// <param name="im"></param> /// <param name="prevRegion"> /// Pass in 0 the first time this method is called. It will be called recursively with the last /// regionhandle tried /// </param> protected virtual void SendGridInstantMessageViaXMLRPCAsync (GridInstantMessage im, GridRegion prevRegion) { UUID toAgentID = im.ToAgentID; string HTTPPath = ""; lock (IMUsersCache) { if (!IMUsersCache.TryGetValue (toAgentID, out HTTPPath)) HTTPPath = ""; } if (HTTPPath != "") { //We've tried to send an IM to them before, pull out their info //Send the IM to their last location if (!doIMSending (HTTPPath, im)) { //If this fails, the user has either moved from their stored location or logged out //Since it failed, let it look them up again and rerun lock (IMUsersCache) { IMUsersCache.Remove (toAgentID); } //Clear the path and let it continue trying again. HTTPPath = ""; } else { //Send the IM, and it made it to the user, return true return; } } //Now query the grid server for the agent List<string> AgentLocations = m_agentInfoService.GetAgentsLocations (im.FromAgentID.ToString (), new List<string> (new [] { toAgentID.ToString () })); if (AgentLocations != null && AgentLocations.Count > 0) { //No agents, so this user is offline if (AgentLocations [0] == "NotOnline") { lock (IMUsersCache) { //Remove them so we keep testing against the db IMUsersCache.Remove (toAgentID); } MainConsole.Instance.Debug ("[GRID INSTANT MESSAGE]: Unable to deliver an instant message as user is not online"); HandleUndeliveredMessage (im, "User is not online."); return; } if (AgentLocations [0] == "NonExistant") { IMUsersCache.Remove (toAgentID); MainConsole.Instance.Info ("[GRID INSTANT MESSAGE]: Unable to deliver an instant message to " + toAgentID + ", user does not exist"); HandleUndeliveredMessage (im, "User does not exist."); return; } HTTPPath = AgentLocations [0]; } //We found the agent's location, now ask them about the user if (HTTPPath != "") { if (!doIMSending (HTTPPath, im)) { //It failed, stop now lock (IMUsersCache) { //Remove them so we keep testing against the db IMUsersCache.Remove (toAgentID); } MainConsole.Instance.Info ( "[GRID INSTANT MESSAGE]: Unable to deliver an instant message as the region could not be found"); HandleUndeliveredMessage (im, "Failed to send IM to destination."); return; } else { //Add to the cache if (!IMUsersCache.ContainsKey (toAgentID)) IMUsersCache.Add (toAgentID, HTTPPath); //Send the IM, and it made it to the user, return true return; } } else { //Couldn't find them, stop for now lock (IMUsersCache) { //Remove them so we keep testing against the db IMUsersCache.Remove (toAgentID); } MainConsole.Instance.Info ( "[GRID INSTANT MESSAGE]: Unable to deliver an instant message as the region could not be found"); HandleUndeliveredMessage (im, "Agent Location was blank."); } }
protected virtual void SendGridInstantMessageViaXMLRPC (GridInstantMessage im) { GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; d.BeginInvoke (im, null, GridInstantMessageCompleted, d); }
public void OnInstantMessage(IClientAPI client, GridInstantMessage im) { byte dialog = im.Dialog; if (dialog != (byte) InstantMessageDialog.MessageFromAgent && dialog != (byte) InstantMessageDialog.StartTyping && dialog != (byte) InstantMessageDialog.StopTyping && dialog != (byte) InstantMessageDialog.BusyAutoResponse && dialog != (byte) InstantMessageDialog.MessageFromObject) { return; } if (m_TransferModule != null) { if (client == null) { UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.AllScopeIDs, im.FromAgentID); if (account != null) im.FromAgentName = account.Name; else im.FromAgentName = im.FromAgentName + "(No account found for this user)"; } else im.FromAgentName = client.Name; m_TransferModule.SendInstantMessage(im); } }
private void OnGridInstantMessage(GridInstantMessage msg) { if (m_debugEnabled) MainConsole.Instance.InfoFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name); // Trigger the above event handler OnInstantMessage(null, msg); // If a message from a group arrives here, it may need to be forwarded to a local client if (msg.FromGroup) { switch (msg.Dialog) { case (byte) InstantMessageDialog.GroupInvitation: case (byte) InstantMessageDialog.GroupNotice: UUID toAgentID = msg.ToAgentID; IClientAPI localClient = GetActiveClient(toAgentID); if (localClient != null) { localClient.SendInstantMessage(msg); } break; } } }
public GridInstantMessage BuildOfflineGroupNotice(GridInstantMessage msg) { msg.Dialog = 211; //We set this so that it isn't taken the wrong way later return msg; }
private void EventManager_OnClientLogin(IClientAPI client) { if (client.Scene.GetScenePresence(client.AgentId).IsChildAgent) return; List<GroupInviteInfo> inviteInfo = m_groupData.GetGroupInvites(client.AgentId); if (inviteInfo.Count != 0) { foreach (GroupInviteInfo Invite in inviteInfo) { if (m_msgTransferModule != null) { UUID inviteUUID = Invite.InviteID; GridInstantMessage msg = new GridInstantMessage { SessionID = inviteUUID, FromAgentID = Invite.GroupID, ToAgentID = Invite.AgentID, Timestamp = (uint) Util.UnixTimeSinceEpoch(), FromAgentName = Invite.FromAgentName, RegionID = client.Scene.RegionInfo.RegionID }; GroupRecord groupInfo = GetGroupRecord(Invite.GroupID); string MemberShipCost = ". There is no cost to join this group."; if (groupInfo.MembershipFee != 0) MemberShipCost = ". To join, you must pay " + groupInfo.MembershipFee.ToString() + "."; msg.Message = string.Format("{0} has invited you to join " + groupInfo.GroupName + MemberShipCost, Invite.FromAgentName); msg.Dialog = (byte) InstantMessageDialog.GroupInvitation; msg.FromGroup = true; msg.Offline = 0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero; msg.BinaryBucket = new byte[20]; OutgoingInstantMessage(msg, Invite.AgentID); } } } }
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, 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; }
public void TriggerIncomingInstantMessage(GridInstantMessage message) { IncomingInstantMessage handlerIncomingInstantMessage = OnIncomingInstantMessage; if (handlerIncomingInstantMessage != null) { foreach (IncomingInstantMessage d in handlerIncomingInstantMessage.GetInvocationList()) { try { d(message); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[EVENT MANAGER]: Delegate for TriggerIncomingInstantMessage failed - continuing. {0} {1}", e, e.StackTrace); } } } }
void UndeliveredMessage (GridInstantMessage im, string reason) { if (OfflineMessagesConnector == null || im == null) return; IClientAPI client = FindClient (im.FromAgentID); if ((client == null) && (im.Dialog != 32)) return; if (!OfflineMessagesConnector.AddOfflineMessage (im)) { if ((!im.FromGroup) && (reason != "User does not exist.") && (client != null)) client.SendInstantMessage (new GridInstantMessage () { FromAgentID = im.ToAgentID, FromAgentName = "System", ToAgentID = im.FromAgentID, Dialog = (byte)InstantMessageDialog.MessageFromAgent, Message = "User has too many IMs already, please try again later.", Offline = 0, RegionID = im.RegionID }); else if (client == null) return; } else if ((im.Offline != 0) && (!im.FromGroup || im.FromGroup)) { if (im.Dialog == 32) //Group notice { IGroupsModule module = m_Scene.RequestModuleInterface<IGroupsModule> (); if (module != null) im = module.BuildOfflineGroupNotice (im); // TODO: This drops (supposedly) group messages and the logic above is interesting!! return; } if (client == null) return; IEmailModule emailModule = m_Scene.RequestModuleInterface<IEmailModule> (); if (emailModule != null && m_SendOfflineMessagesToEmail) { IUserProfileInfo profile = Framework.Utilities.DataManager.RequestPlugin<IProfileConnector> ().GetUserProfile (im.ToAgentID); if (profile != null && profile.IMViaEmail) { UserAccount account = m_Scene.UserAccountService.GetUserAccount (null, im.ToAgentID); if (account != null && !string.IsNullOrEmpty (account.Email)) { emailModule.SendEmail (UUID.Zero, account.Email, string.Format ("Offline Message from {0}", im.FromAgentName), string.Format ("Time: {0}\n", Util.ToDateTime (im.Timestamp).ToShortDateString ()) + string.Format ("From: {0}\n", im.FromAgentName) + string.Format ("Message: {0}\n", im.Message), m_Scene); } } } if (im.Dialog == (byte)InstantMessageDialog.MessageFromAgent && !im.FromGroup) { client.SendInstantMessage (new GridInstantMessage () { FromAgentID = im.ToAgentID, FromAgentName = "System", ToAgentID = im.FromAgentID, Dialog = (byte)InstantMessageDialog.MessageFromAgent, Message = "Message saved, reason: " + reason, Offline = 0, RegionID = im.RegionID }); } if (im.Dialog == (byte)InstantMessageDialog.InventoryOffered) client.SendAlertMessage ("User is not online. Inventory has been saved"); } else if (im.Offline == 0) { if (client == null) return; if (im.Dialog == (byte)InstantMessageDialog.MessageFromAgent && !im.FromGroup) { client.SendInstantMessage (new GridInstantMessage () { FromAgentID = im.ToAgentID, FromAgentName = "System", ToAgentID = im.FromAgentID, Dialog = (byte)InstantMessageDialog.MessageFromAgent, Message = "Message saved, reason: " + reason, Offline = 0, RegionID = im.RegionID }); } if (im.Dialog == (byte)InstantMessageDialog.InventoryOffered) client.SendAlertMessage ("User not able to be found. Inventory has been saved"); } }
public void SendInstantMessage(GridInstantMessage im) { IMessageTransferModule m_TransferModule = m_object.Scene.RequestModuleInterface<IMessageTransferModule>(); if (m_TransferModule != null) m_TransferModule.SendInstantMessage(im); }
void OnGridInstantMessage (GridInstantMessage im) { if (im.Dialog == (byte)InstantMessageDialog.RequestTeleport) { MainConsole.Instance.DebugFormat ( "[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.SessionID, im.RegionID, im.Message); // Forward. We do this, because the IM module explicitly rejects // IMs of this type if (m_TransferModule != null) m_TransferModule.SendInstantMessage (im); } }
/// <summary> /// </summary> /// <param name="msg"></param> void OnGridInstantMessage(GridInstantMessage msg) { byte dialog = msg.Dialog; if (dialog != (byte) InstantMessageDialog.MessageFromAgent && dialog != (byte) InstantMessageDialog.StartTyping && dialog != (byte) InstantMessageDialog.StopTyping && dialog != (byte) InstantMessageDialog.MessageFromObject) { return; } if (m_TransferModule != null) { UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.AllScopeIDs, msg.FromAgentID); if (account != null) msg.FromAgentName = account.Name; else msg.FromAgentName = msg.FromAgentName + "(No account found for this user)"; IScenePresence presence = null; if (m_Scene.TryGetScenePresence(msg.ToAgentID, out presence)) { presence.ControllingClient.SendInstantMessage(msg); return; } } }
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.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; } }
void HandleUndeliveredMessage (GridInstantMessage im, string reason) { UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage; // If this event has handlers, then an IM from an agent will be // considered delivered. This will suppress the error message. // if (handlerUndeliveredMessage != null) { handlerUndeliveredMessage (im, reason); return; } //MainConsole.Instance.DebugFormat("[INSTANT MESSAGE]: Undeliverable"); }
private void OutgoingInstantMessage(GridInstantMessage msg, UUID msgTo, bool localOnly) { if (m_debugEnabled) MainConsole.Instance.InfoFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name); IClientAPI localClient = GetActiveClient(msgTo); if (localClient != null) { if (m_debugEnabled) MainConsole.Instance.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); localClient.SendInstantMessage(msg); } else if (!localOnly) { if (m_debugEnabled) MainConsole.Instance.InfoFormat( "[GROUPS]: MsgTo ({0}) is not local, delivering via TransferModule", msgTo); m_msgTransferModule.SendInstantMessage(msg); } }
protected virtual void SendMultipleGridInstantMessageViaXMLRPC (GridInstantMessage im, List<UUID> users) { Dictionary<UUID, string> HTTPPaths = new Dictionary<UUID, string> (); foreach (UUID agentID in users) { lock (IMUsersCache) { string HTTPPath = ""; if (!IMUsersCache.TryGetValue (agentID, out HTTPPath)) HTTPPath = ""; else HTTPPaths.Add (agentID, HTTPPath); } } List<UUID> CompletedUsers = new List<UUID> (); foreach (KeyValuePair<UUID, string> kvp in HTTPPaths) { //Fix the agentID im.ToAgentID = kvp.Key; //We've tried to send an IM to them before, pull out their info //Send the IM to their last location if (!doIMSending (kvp.Value, im)) { //If this fails, the user has either moved from their stored location or logged out //Since it failed, let it look them up again and rerun lock (IMUsersCache) { IMUsersCache.Remove (kvp.Key); } } else { //Send the IM, and it made it to the user, return true CompletedUsers.Add (kvp.Key); } } //Remove the finished users foreach (UUID agentID in CompletedUsers) { users.Remove (agentID); } HTTPPaths.Clear (); //Now query the grid server for the agents List<string> Queries = users.Select (agentID => agentID.ToString ()).ToList (); if (Queries.Count == 0) return; //All done //Ask for the user new style first List<string> AgentLocations = m_agentInfoService.GetAgentsLocations (im.FromAgentID.ToString (), Queries); //If this is false, this doesn't exist on the presence server and we use the legacy way if (AgentLocations != null && AgentLocations.Count != 0) { for (int i = 0; i < users.Count; i++) { //No agents, so this user is offline if (AgentLocations [i] == "NotOnline") { IMUsersCache.Remove (users [i]); MainConsole.Instance.Debug ("[GRID INSTANT MESSAGE]: Unable to deliver an instant message to " + users [i] + ", user was not online"); im.ToAgentID = users [i]; HandleUndeliveredMessage (im, "User is not online."); continue; } if (AgentLocations [i] == "NonExistant") { IMUsersCache.Remove (users [i]); MainConsole.Instance.Info ("[GRID INSTANT MESSAGE]: Unable to deliver an instant message to " + users [i] + ", user does not exist"); im.ToAgentID = users [i]; HandleUndeliveredMessage (im, "User does not exist."); continue; } HTTPPaths.Add (users [i], AgentLocations [i]); } } else { MainConsole.Instance.Info ( "[GRID INSTANT MESSAGE]: Unable to deliver an instant message, no users found."); return; } //We found the agent's location, now ask them about the user foreach (KeyValuePair<UUID, string> kvp in HTTPPaths) { if (kvp.Value != "") { im.ToAgentID = kvp.Key; if (!doIMSending (kvp.Value, im)) { //It failed lock (IMUsersCache) { //Remove them so we keep testing against the db IMUsersCache.Remove (kvp.Key); } HandleUndeliveredMessage (im, "Failed to send IM to destination."); } else { //Add to the cache if (!IMUsersCache.ContainsKey (kvp.Key)) IMUsersCache.Add (kvp.Key, kvp.Value); //Send the IM, and it made it to the user, return true continue; } } else { lock (IMUsersCache) { //Remove them so we keep testing against the db IMUsersCache.Remove (kvp.Key); } HandleUndeliveredMessage (im, "Agent Location was blank."); } } }
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; }
/// <summary> /// This actually does the XMLRPC Request /// </summary> /// <param name="httpInfo">RegionInfo we pull the data out of to send the request to</param> /// <param name="xmlrpcdata">The Instant Message data Hashtable</param> /// <returns>Bool if the message was successfully delivered at the other side.</returns> protected virtual bool doIMSending (string httpInfo, GridInstantMessage message) { MemoryStream stream = new MemoryStream (); ProtoBuf.Serializer.Serialize (stream, message); byte [] data = WebUtils.PostToService (httpInfo + "/gridinstantmessages/", stream.ToArray ()); return data == null || data.Length == 0 || data [0] == 0 ? false : true; }
public void EjectGroupMember(IClientAPI remoteClient, UUID agentID, UUID groupID, UUID ejecteeID) { if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name); if (!m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), ejecteeID, groupID)) return; m_cachedGroupMemberships.Remove(ejecteeID); string agentName; RegionInfo regionInfo; // remoteClient provided or just agentID? if (remoteClient != null) { agentName = remoteClient.Name; regionInfo = remoteClient.Scene.RegionInfo; remoteClient.SendEjectGroupMemberReply(agentID, groupID, true); } else { IClientAPI client = GetActiveClient(agentID); if (client != null) { agentName = client.Name; regionInfo = client.Scene.RegionInfo; client.SendEjectGroupMemberReply(agentID, groupID, true); } else { regionInfo = m_scene.RegionInfo; UserAccount acc = m_scene.UserAccountService.GetUserAccount(regionInfo.AllScopeIDs, agentID); if (acc != null) agentName = acc.FirstName + " " + acc.LastName; else agentName = "Unknown member"; } } GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); UserAccount account = m_scene.UserAccountService.GetUserAccount(regionInfo.AllScopeIDs, ejecteeID); if ((groupInfo == null) || (account == null)) return; // Send Message to avatar being ejected from the group GridInstantMessage msg = new GridInstantMessage { SessionID = UUID.Zero, FromAgentID = UUID.Zero, ToAgentID = ejecteeID, Timestamp = 0, FromAgentName = "System", Message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName), Dialog = 210, FromGroup = false, Offline = 0, ParentEstateID = 0, Position = Vector3.Zero, RegionID = remoteClient.Scene.RegionInfo.RegionID, BinaryBucket = new byte[0] }; OutgoingInstantMessage(msg, ejecteeID); //Do this here for local agents, otherwise it never gets done IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { msg.Dialog = (byte) InstantMessageDialog.MessageFromAgent; OutgoingInstantMessage(msg, ejecteeID); ejectee.SendAgentDropGroup(groupID); } // Message to ejected person // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid m_cachedGroupTitles[ejecteeID] = null; RemoveFromGroupPowersCache(ejecteeID, groupID); UpdateAllClientsWithGroupInfo(ejecteeID, ""); if (m_imService != null) { // SL sends out notifcations to the group messaging session that the person has left GridInstantMessage im = new GridInstantMessage { FromAgentID = groupID, Dialog = (byte) InstantMessageDialog.SessionSend, BinaryBucket = new byte[0], FromAgentName = "System", FromGroup = true, SessionID = groupID, Message = account.Name + " has been ejected from the group by " + remoteClient.Name + ".", Offline = 1, RegionID = remoteClient.Scene.RegionInfo.RegionID, Timestamp = (uint) Util.UnixTimeSinceEpoch(), ToAgentID = UUID.Zero }; m_imService.EnsureSessionIsStarted(groupID); m_imService.SendChatToSession(groupID, im); } }
public virtual void SendInstantMessage (GridInstantMessage im) { UUID toAgentID = im.ToAgentID; //Look locally first IScenePresence user; foreach (IScene scene in m_scenes) { if (scene.TryGetScenePresence (toAgentID, out user)) { user.ControllingClient.SendInstantMessage (im); return; } } ISceneChildEntity childPrim = null; foreach (IScene scene in m_scenes) { if ((childPrim = scene.GetSceneObjectPart (toAgentID)) != null) { im.ToAgentID = childPrim.OwnerID; SendInstantMessage (im); return; } } //MainConsole.Instance.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); SendGridInstantMessageViaXMLRPC (im); }
public void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID groupID, UUID invitedAgentID, UUID roleID) { if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name); string agentName; RegionInfo regionInfo; // remoteClient provided or just agentID? if (remoteClient != null) { agentName = remoteClient.Name; regionInfo = remoteClient.Scene.RegionInfo; } else { IClientAPI client = GetActiveClient(agentID); if (client != null) { agentName = client.Name; regionInfo = client.Scene.RegionInfo; } else { regionInfo = m_scene.RegionInfo; UserAccount account = m_scene.UserAccountService.GetUserAccount(regionInfo.AllScopeIDs, agentID); if (account != null) agentName = account.FirstName + " " + account.LastName; else agentName = "Unknown member"; } } UUID InviteID = UUID.Random(); m_groupData.AddAgentGroupInvite(GetRequestingAgentID(remoteClient), InviteID, groupID, roleID, invitedAgentID, remoteClient.Name); // Check to see if the invite went through, if it did not then it's possible // the remoteClient did not validate or did not have permission to invite. GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(invitedAgentID, InviteID); if (inviteInfo != null) { if (m_msgTransferModule != null) { UUID inviteUUID = InviteID; GridInstantMessage msg = new GridInstantMessage { SessionID = inviteUUID, FromAgentID = groupID, ToAgentID = invitedAgentID, Timestamp = 0, FromAgentName = agentName }; // msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; // msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); GroupRecord groupInfo = GetGroupRecord(groupID); string MemberShipCost = ". There is no cost to join this group."; if (groupInfo.MembershipFee != 0) { MemberShipCost = ". To join, you must pay " + groupInfo.MembershipFee.ToString() + "."; } msg.Message = string.Format("{0} has invited you to join " + groupInfo.GroupName + MemberShipCost, remoteClient.Name); msg.Dialog = (byte) InstantMessageDialog.GroupInvitation; msg.FromGroup = true; msg.Offline = 0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID; msg.BinaryBucket = new byte[20]; OutgoingInstantMessage(msg, invitedAgentID); } } }
public void DropMemberFromSession(UUID agentID, GridInstantMessage im) { if (m_doRemoteOnly) { DoRemoteCallPost(true, "InstantMessageServerURI", agentID, im); return; } ChatSession session; ChatSessions.TryGetValue(im.SessionID, out session); if (session == null) return; ChatSessionMember member = null; foreach ( ChatSessionMember testmember in session.Members.Where(testmember => testmember.AvatarKey == im.FromAgentID)) member = testmember; if (member == null) return; member.HasBeenAdded = false; member.RequestedRemoval = true; if (session.Members.Count(mem => mem.HasBeenAdded) == 0) //If a member hasn't been added, kill this anyway { ChatSessions.Remove(session.SessionID); return; } ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock block = new ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock { AgentID = member.AvatarKey, CanVoiceChat = member.CanVoiceChat, IsModerator = member.IsModerator, MuteText = member.MuteText, MuteVoice = member.MuteVoice, Transition = "LEAVE" }; foreach (ChatSessionMember sessionMember in session.Members) { if (sessionMember.HasBeenAdded) //Only send to those in the group { UUID regionID = FindRegionID(sessionMember.AvatarKey); if (regionID != UUID.Zero) { m_eventQueueService.ChatterBoxSessionAgentListUpdates(session.SessionID, new[] {block}, sessionMember.AvatarKey, "LEAVE", regionID); } } } }
public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) MainConsole.Instance.DebugFormat("[GROUPS]: {0} called", MethodBase.GetCurrentMethod().Name); if ( !m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID)) return; m_cachedGroupMemberships.Remove(remoteClient.AgentId); remoteClient.SendLeaveGroupReply(groupID, true); remoteClient.SendAgentDropGroup(groupID); RemoveFromGroupPowersCache(remoteClient.AgentId, groupID); if (remoteClient.ActiveGroupId == groupID) GroupTitleUpdate(remoteClient, UUID.Zero, UUID.Zero); SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); if (m_imService != null) { // SL sends out notifications to the group messaging session that the person has left GridInstantMessage im = new GridInstantMessage { FromAgentID = groupID, Dialog = (byte) InstantMessageDialog.SessionSend, BinaryBucket = new byte[0], FromAgentName = "System", FromGroup = true, SessionID = groupID, Message = remoteClient.Name + " has left the group.", Offline = 1, RegionID = remoteClient.Scene.RegionInfo.RegionID, Timestamp = (uint) Util.UnixTimeSinceEpoch(), ToAgentID = UUID.Zero }; m_imService.EnsureSessionIsStarted(groupID); m_imService.SendChatToSession(UUID.Zero, im); } }
private OSDMap syncRecievedService_OnMessageReceived(OSDMap message) { string method = message["Method"]; if (method == "SendInstantMessages") { List<GridInstantMessage> messages = ((OSDArray) message["Messages"]).ConvertAll<GridInstantMessage>((o) => { GridInstantMessage im = new GridInstantMessage(); im.FromOSD((OSDMap) o); return im; }); ISceneManager manager = m_registry.RequestModuleInterface<ISceneManager>(); if (manager != null) { foreach (GridInstantMessage im in messages) { Framework.PresenceInfo.IScenePresence UserPresence; foreach (IScene scene in manager.Scenes) { UserPresence = scene.GetScenePresence(im.ToAgentID); //AR: Do not fire for child agents or group messages are sent for every region if (UserPresence != null && UserPresence.IsChildAgent == false) { IMessageTransferModule messageTransfer = scene.RequestModuleInterface<IMessageTransferModule>(); if (messageTransfer != null) { messageTransfer.SendInstantMessage(im); } } } } } } return null; }
public void OnStartLure (byte lureType, string message, UUID targetid, IClientAPI client) { IScenePresence presence = client.Scene.GetScenePresence (client.AgentId); Vector3 position = presence.AbsolutePosition + new Vector3 (2, 0, 0) * presence.Rotation; UUID dest = Util.BuildFakeParcelID ( client.Scene.RegionInfo.RegionHandle, (uint)position.X, (uint)position.Y, (uint)position.Z); var m = new GridInstantMessage () { FromAgentID = client.AgentId, FromAgentName = client.Name, ToAgentID = targetid, Dialog = (byte)InstantMessageDialog.RequestTeleport, Message = message, SessionID = dest, Offline = 0, Position = presence.AbsolutePosition, BinaryBucket = new Byte [0], RegionID = client.Scene.RegionInfo.RegionID }; // if we are an admin and are in god mode if (m_allowGodTeleports && client.Scene.Permissions.CanGodTeleport (client.AgentId, targetid)) { //God tp them m.Dialog = (byte)InstantMessageDialog.GodLikeRequestTeleport; } if (m_TransferModule != null) m_TransferModule.SendInstantMessage (m); }