public virtual void SendInstantMessages(GridInstantMessage im, List<UUID> AgentsToSendTo)
        {
            //Check for local users first
            List<UUID> RemoveUsers = new List<UUID>();
            foreach (IScene scene in m_Scenes)
            {
                foreach (UUID t in AgentsToSendTo)
                {
                    IScenePresence user;
                    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);
        }
        public GridInstantMessage[] GetOfflineMessages(UUID PrincipalID)
        {
            OSDMap map = new OSDMap();

            map["PrincipalID"] = PrincipalID;
            map["Method"] = "getofflinemessages";

            List<GridInstantMessage> Messages = new List<GridInstantMessage>();
            try
            {
                List<string> urls =
                    m_registry.RequestModuleInterface<IConfigurationService>().FindValueOf(PrincipalID.ToString(),
                                                                                           "RemoteServerURI");
                foreach (string url in urls)
                {
                    OSDMap result = WebUtils.PostToService(url + "osd", map, true, false);
                    OSDArray array = (OSDArray) OSDParser.DeserializeJson(result["_RawResult"]);
                    foreach (OSD o in array)
                    {
                        GridInstantMessage message = new GridInstantMessage();
                        message.FromOSD((OSDMap) o);
                        Messages.Add(message);
                    }
                }
                return Messages.ToArray();
            }
            catch (Exception e)
            {
                MainConsole.Instance.DebugFormat("[AuroraRemoteOfflineMessagesConnector]: Exception when contacting server: {0}", e);
            }
            return Messages.ToArray();
        }
        public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
        {
            if (m_debugEnabled)
                MainConsole.Instance.DebugFormat("[GROUPS-MESSAGING]: {0} called", MethodBase.GetCurrentMethod().Name);

            // Copy Message

            GridInstantMessage msg = new GridInstantMessage
                                         {
                                             imSessionID = groupID,
                                             fromAgentName = im.fromAgentName,
                                             message = im.message,
                                             dialog = (byte) InstantMessageDialog.SessionSend,
                                             offline = 0,
                                             ParentEstateID = 0,
                                             Position = Vector3.Zero,
                                             RegionID = UUID.Zero
                                         };
            ChatSession session = m_groupData.GetSession(im.imSessionID);
            msg.binaryBucket = Utils.StringToBytes(session.Name);
            msg.timestamp = (uint) Util.UnixTimeSinceEpoch();

            msg.fromAgentID = im.fromAgentID;
            msg.fromGroup = true;

            Util.FireAndForget(SendInstantMessages, msg);
        }
 public bool AddOfflineMessage(GridInstantMessage message)
 {
     List<string> serverURIs =
         m_registry.RequestModuleInterface<IConfigurationService>().FindValueOf(message.toAgentID.ToString(),
                                                                                "FriendsServerURI");
     if (serverURIs.Count > 0) //Remote user... or should be
         return (bool)DoRemote(message);
     return m_localService.AddOfflineMessage(message);
 }
 public bool AddOfflineMessage(GridInstantMessage message)
 {
     foreach (string m_ServerURI in m_ServerURIs)
     {
         SimianUtils.AddGeneric(message.toAgentID, "OfflineMessages", UUID.Random().ToString(), message.ToOSD(),
                                m_ServerURI);
     }
     return true;
 }
 public GridInstantMessage[] GetOfflineMessages(UUID PrincipalID)
 {
     List<GridInstantMessage> Messages = new List<GridInstantMessage>();
     Dictionary<string, OSDMap> Maps = new Dictionary<string, OSDMap>();
     foreach (string m_ServerURI in m_ServerURIs)
     {
         if (SimianUtils.GetGenericEntries(PrincipalID, "OfflineMessages", m_ServerURI, out Maps))
         {
             GridInstantMessage baseMessage = new GridInstantMessage();
             foreach (OSDMap map in Maps.Values)
             {
                 baseMessage.FromOSD(map);
                 Messages.Add(baseMessage);
             }
         }
     }
     return Messages.ToArray();
 }
        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;
        }
        private void OnGridInstantMessage(GridInstantMessage msg)
        {
            // The instant message module will only deliver messages of dialog types:
            // MessageFromAgent, StartTyping, StopTyping, MessageFromObject
            //
            // Any other message type will not be delivered to a client by the 
            // Instant Message Module


            if (m_debugEnabled)
            {
                MainConsole.Instance.DebugFormat("[GROUPS-MESSAGING]: {0} called", MethodBase.GetCurrentMethod().Name);

                DebugGridInstantMessage(msg);
            }

            // Incoming message from a group
            if (msg.fromGroup &&
                ((msg.dialog == (byte) InstantMessageDialog.SessionSend)
                 || (msg.dialog == (byte) InstantMessageDialog.SessionAdd)
                 || (msg.dialog == (byte) InstantMessageDialog.SessionDrop)
                 || (msg.dialog == 212)
                 || (msg.dialog == 213)))
            {
                ProcessMessageFromGroupSession(msg);
            }
        }
        private void ProcessMessageFromGroupSession(GridInstantMessage msg)
        {
            if (m_debugEnabled)
                MainConsole.Instance.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName,
                                  msg.toAgentID);

            UUID AgentID = msg.toAgentID;
            UUID GroupID = msg.imSessionID;

            switch (msg.dialog)
            {
                case (byte) InstantMessageDialog.SessionAdd:
                    ChatSession chatSession = m_groupData.GetSession(msg.imSessionID);
                    if (chatSession != null)
                    {
                        chatSession.Members.Add(new ChatSessionMember
                                                    {
                                                        AvatarKey = AgentID,
                                                        CanVoiceChat = false,
                                                        HasBeenAdded = true,
                                                        IsModerator = GetIsModerator(AgentID, GroupID),
                                                        MuteVoice = false,
                                                        MuteText = false
                                                    });
                    }
                    break;

                case (byte) InstantMessageDialog.SessionDrop:
                case 212:
                    DropMemberFromSession(GetActiveClient(AgentID), msg, false);
                    break;

                case 213: //Special for muting/unmuting a user
                    IClientAPI client = GetActiveClient(AgentID);
                    IEventQueueService eq = client.Scene.RequestModuleInterface<IEventQueueService>();
                    ChatSessionMember thismember = m_groupData.FindMember(msg.imSessionID, AgentID);
                    if (thismember == null)
                        return;
                    string[] brokenMessage = msg.message.Split(',');
                    bool mutedText = false, mutedVoice = false;
                    bool.TryParse(brokenMessage[0], out mutedText);
                    bool.TryParse(brokenMessage[1], out mutedVoice);
                    thismember.MuteText = mutedText;
                    thismember.MuteVoice = mutedVoice;
                    MuteUser(msg.imSessionID, eq, AgentID, thismember, false);
                    break;

                case (byte) InstantMessageDialog.SessionSend:
                    EnsureGroupChatIsStarted(msg.imSessionID); //Make sure one exists
                    ChatSession session = m_groupData.GetSession(msg.imSessionID);
                    if (session != null)
                    {
                        ChatSessionMember member = m_groupData.FindMember(msg.imSessionID, AgentID);
                        if (member.AvatarKey == AgentID && !member.MuteText)
                        {
                            IClientAPI msgclient = GetActiveClient(msg.toAgentID);
                            if (msgclient != null)
                            {
                                if (!member.HasBeenAdded)
                                    msgclient.Scene.RequestModuleInterface<IEventQueueService>().ChatterboxInvitation(
                                        session.SessionID
                                        , session.Name
                                        , msg.fromAgentID
                                        , msg.message
                                        , member.AvatarKey
                                        , msg.fromAgentName
                                        , msg.dialog
                                        , msg.timestamp
                                        , msg.offline == 1
                                        , (int) msg.ParentEstateID
                                        , msg.Position
                                        , 1
                                        , msg.imSessionID
                                        , true
                                        , Utils.StringToBytes(session.Name)
                                        , msgclient.Scene.RegionInfo.RegionHandle
                                        );
                                // Deliver locally, directly
                                if (m_debugEnabled)
                                    MainConsole.Instance.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", msgclient.Name);
                                msgclient.SendInstantMessage(msg);
                            }
                        }
                    }
                    break;

                default:
                    MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: I don't know how to proccess a {0} message.",
                                     ((InstantMessageDialog) msg.dialog).ToString());
                    break;
            }
        }
Exemple #10
0
 public void TriggerUnhandledInstantMessage(GridInstantMessage message)
 {
     IncomingInstantMessage handlerUnhandledInstantMessage = OnUnhandledInstantMessage;
     if (handlerUnhandledInstantMessage != null)
     {
         foreach (IncomingInstantMessage d in handlerUnhandledInstantMessage.GetInvocationList())
         {
             try
             {
                 d(message);
             }
             catch (Exception e)
             {
                 MainConsole.Instance.ErrorFormat(
                     "[EVENT MANAGER]: Delegate for TriggerOnAttach failed - continuing.  {0} {1}",
                     e, e.StackTrace);
             }
         }
     }
 }
 private void DebugGridInstantMessage(GridInstantMessage im)
 {
     // Don't log any normal IMs (privacy!)
     if (m_debugEnabled && im.dialog != (byte) InstantMessageDialog.MessageFromAgent)
     {
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: fromGroup({0})", im.fromGroup ? "True" : "False");
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: Dialog({0})", ((InstantMessageDialog) im.dialog).ToString());
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentID({0})", im.fromAgentID.ToString());
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: fromAgentName({0})", im.fromAgentName);
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: imSessionID({0})", im.imSessionID.ToString());
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: message({0})", im.message);
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: offline({0})", im.offline.ToString());
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: toAgentID({0})", im.toAgentID.ToString());
         MainConsole.Instance.WarnFormat("[GROUPS-MESSAGING]: IM: binaryBucket({0})",
                          Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
     }
 }
        public bool LocalFriendshipApproved(UUID userID, string name, IClientAPI us, UUID friendID)
        {
            IClientAPI friendClient = LocateClientObject(friendID);
            if (friendClient != null)
            {
                //They are online, send the online message
                if (us != null)
                    us.SendAgentOnline(new[] {friendID});

                // the prospective friend in this sim as root agent
                GridInstantMessage im = new GridInstantMessage(m_Scenes[0], userID, name, friendID,
                                                               (byte) InstantMessageDialog.FriendshipAccepted,
                                                               userID.ToString(), false, Vector3.Zero);
                friendClient.SendInstantMessage(im);

                // Update the local cache
                UpdateFriendsCache(friendID);


                //
                // put a calling card into the inventory of the friend
                //
                ICallingCardModule ccmodule = friendClient.Scene.RequestModuleInterface<ICallingCardModule>();
                if (ccmodule != null)
                {
                    UserAccount account = friendClient.Scene.UserAccountService.GetUserAccount(UUID.Zero, userID);
                    UUID folderID =
                        friendClient.Scene.InventoryService.GetFolderForType(friendID, InventoryType.Unknown,
                                                                             AssetType.CallingCard).ID;
                    ccmodule.CreateCallingCard(friendClient, userID, folderID, account.Name);
                }
                // we're done
                return true;
            }

            return false;
        }
 public GridInstantMessage BuildOfflineGroupNotice(GridInstantMessage msg)
 {
     msg.dialog = 211; //We set this so that it isn't taken the wrong way later
     //Unknown what this did...
     //UUID NoticeID = GroupSessionIDCache[msg.imSessionID];
     //GroupSessionIDCache.Remove(msg.imSessionID);
     //msg.imSessionID = NoticeID;
     return msg;
 }
        /// <summary>
        ///   Remove the member from this session
        /// </summary>
        /// <param name = "client"></param>
        /// <param name = "im"></param>
        public void DropMemberFromSession(IClientAPI client, GridInstantMessage im)
        {
            ChatSession session;
            ChatSessions.TryGetValue(im.imSessionID, out session);
            if (session == null)
                return;
            ChatSessionMember member = new ChatSessionMember {AvatarKey = UUID.Zero};
#if (!ISWIN)
            foreach (ChatSessionMember testmember in session.Members)
            {
                if (testmember.AvatarKey == im.fromAgentID)
                {
                    member = testmember;
                }
            }
#else
            foreach (ChatSessionMember testmember in session.Members.Where(testmember => testmember.AvatarKey == im.fromAgentID))
            {
                member = testmember;
            }
#endif

            if (member.AvatarKey != UUID.Zero)
                session.Members.Remove(member);

            if (session.Members.Count == 0)
            {
                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"
                    };
            IEventQueueService eq = client.Scene.RequestModuleInterface<IEventQueueService>();
            foreach (ChatSessionMember sessionMember in session.Members)
            {
                eq.ChatterBoxSessionAgentListUpdates(session.SessionID, new[] {block}, sessionMember.AvatarKey, "LEAVE",
                                                     findScene(sessionMember.AvatarKey).RegionInfo.RegionHandle);
            }
        }
 private void OnGridInstantMessage(GridInstantMessage msg)
 {
     OnInstantMessage(findScenePresence(msg.toAgentID).ControllingClient, msg);
 }
 private void SendMutedUserIM(ChatSessionMember member, UUID GroupID)
 {
     GridInstantMessage img = new GridInstantMessage
                                  {
                                      toAgentID = member.AvatarKey,
                                      fromGroup = true,
                                      imSessionID = GroupID,
                                      dialog = 213,
                                      //Special mute one
                                      message = member.MuteText + "," + member.MuteVoice
                                  };
     m_msgTransferModule.SendInstantMessage(img);
 }
        /// <summary>
        ///   Remove the member from this session
        /// </summary>
        /// <param name = "client"></param>
        /// <param name = "im"></param>
        public void DropMemberFromSession(IClientAPI client, GridInstantMessage im, bool forwardOn)
        {
            ChatSession session = m_groupData.GetSession(im.imSessionID);
            if (session == null)
                return;
            ChatSessionMember member = new ChatSessionMember {AvatarKey = UUID.Zero};
#if (!ISWIN)
            foreach (ChatSessionMember testmember in session.Members)
            {
                if (testmember.AvatarKey == im.fromAgentID)
                {
                    member = testmember;
                }
            }
#else
            foreach (ChatSessionMember testmember in session.Members.Where(testmember => testmember.AvatarKey == im.fromAgentID))
            {
                member = testmember;
            }
#endif

            if (member.AvatarKey != UUID.Zero)
            {
                member.HasBeenAdded = false;
            }

            if (GetMemeberCount(session) == 0)
            {
                m_groupData.RemoveSession(session.SessionID); //Noone is left!
                return;
            }

            ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock block =
                new ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock
                    {
                        AgentID = member.AvatarKey,
                        CanVoiceChat = member.CanVoiceChat,
                        IsModerator = member.IsModerator,
                        MuteText = member.MuteText,
                        MuteVoice = member.MuteVoice,
                        Transition = "LEAVE"
                    };
            List<UUID> usersToForwardTo = new List<UUID>();
            IEventQueueService eq = client.Scene.RequestModuleInterface<IEventQueueService>();
            foreach (ChatSessionMember sessionMember in session.Members)
            {
                IClientAPI user = GetActiveClient(sessionMember.AvatarKey);
                if (user != null)
                    eq.ChatterBoxSessionAgentListUpdates(session.SessionID, new[] {block}, sessionMember.AvatarKey,
                                                         "LEAVE", user.Scene.RegionInfo.RegionHandle);
                else
                    usersToForwardTo.Add(sessionMember.AvatarKey);
            }
            if (forwardOn)
            {
                im.dialog = 212; //Don't keep forwarding on other sims
                m_msgTransferModule.SendInstantMessages(im, usersToForwardTo);
            }
        }
        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;
                }
            }
        }
        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;
            }
        }
        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
                                                     {
                                                         imSessionID = inviteUUID,
                                                         fromAgentID = Invite.GroupID,
                                                         toAgentID = Invite.AgentID,
                                                         timestamp = (uint) Util.UnixTimeSinceEpoch(),
                                                         fromAgentName = Invite.FromAgentName
                                                     };



                        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 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);
            }
        }
        public bool LocalFriendshipDenied(UUID userID, string userName, UUID friendID)
        {
            IClientAPI friendClient = LocateClientObject(friendID);
            if (friendClient != null)
            {
                // the prospective friend in this sim as root agent
                GridInstantMessage im = new GridInstantMessage(m_Scenes[0], userID, userName, friendID,
                                                               (byte) InstantMessageDialog.FriendshipDeclined,
                                                               userID.ToString(), false, Vector3.Zero);
                friendClient.SendInstantMessage(im);
                // we're done
                return true;
            }

            return false;
        }
        private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
        {
            IScenePresence presence;
            if ((presence = remoteClient.Scene.GetScenePresence(remoteClient.AgentId)) == null || presence.IsChildAgent)
                return; //Must exist and not be a child
            if (m_debugEnabled)
            {
                MainConsole.Instance.DebugFormat("[GROUPS-MESSAGING]: {0} called", MethodBase.GetCurrentMethod().Name);

                DebugGridInstantMessage(im);
            }

            // Start group IM session
            if ((im.dialog == (byte) InstantMessageDialog.SessionGroupStart))
            {
                if (m_debugEnabled)
                    MainConsole.Instance.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID);

                UUID GroupID = im.imSessionID;
                UUID AgentID = im.fromAgentID;

                GroupRecord groupInfo = m_groupData.GetGroupRecord(AgentID, GroupID, null);

                if (groupInfo != null)
                {
                    if (!m_groupsModule.GroupPermissionCheck(AgentID, GroupID, GroupPowers.JoinChat))
                        return; //They have to be able to join to create a group chat
                    //Create the session.
                    IEventQueueService queue = remoteClient.Scene.RequestModuleInterface<IEventQueueService>();
                    if (m_groupData.CreateSession(new ChatSession
                                                      {
                                                          Members = new List<ChatSessionMember>(),
                                                          SessionID = GroupID,
                                                          Name = groupInfo.GroupName
                                                      }))
                    {
                        m_groupData.AddMemberToGroup(new ChatSessionMember
                                                         {
                                                             AvatarKey = AgentID,
                                                             CanVoiceChat = false,
                                                             IsModerator = GetIsModerator(AgentID, GroupID),
                                                             MuteText = false,
                                                             MuteVoice = false,
                                                             HasBeenAdded = true
                                                         }, GroupID);

#if (!ISWIN)
                        foreach (GroupMembersData gmd in m_groupData.GetGroupMembers(AgentID, GroupID))
                        {
                            if (gmd.AgentID != AgentID)
                            {
                                if ((gmd.AgentPowers & (ulong) GroupPowers.JoinChat) == (ulong) GroupPowers.JoinChat)
                                {
                                    m_groupData.AddMemberToGroup(new ChatSessionMember
                                                                     {
                                                                         AvatarKey = gmd.AgentID,
                                                                         CanVoiceChat = false,
                                                                         IsModerator =
                                                                             GetIsModerator(gmd.AgentID, GroupID),
                                                                         MuteText = false,
                                                                         MuteVoice = false,
                                                                         HasBeenAdded = false
                                                                     }, GroupID);
                                }
                            }
                        }
#else
                        foreach (GroupMembersData gmd in m_groupData.GetGroupMembers(AgentID, GroupID).Where(gmd => gmd.AgentID != AgentID).Where(gmd => (gmd.AgentPowers & (ulong) GroupPowers.JoinChat) == (ulong) GroupPowers.JoinChat))
                        {
                            m_groupData.AddMemberToGroup(new ChatSessionMember
                                                             {
                                                                 AvatarKey = gmd.AgentID,
                                                                 CanVoiceChat = false,
                                                                 IsModerator =
                                                                     GetIsModerator(gmd.AgentID, GroupID),
                                                                 MuteText = false,
                                                                 MuteVoice = false,
                                                                 HasBeenAdded = false
                                                             }, GroupID);
                        }
#endif
                        //Tell us that it was made successfully
                        ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
                    }
                    else
                    {
                        ChatSession thisSession = m_groupData.GetSession(GroupID);
                        //A session already exists
                        //Add us
                        m_groupData.AddMemberToGroup(new ChatSessionMember
                                                         {
                                                             AvatarKey = AgentID,
                                                             CanVoiceChat = false,
                                                             IsModerator = GetIsModerator(AgentID, GroupID),
                                                             MuteText = false,
                                                             MuteVoice = false,
                                                             HasBeenAdded = true
                                                         }, GroupID);

                        //Tell us that we entered successfully
                        ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
                        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.AvatarKey == AgentID)
                            {
                                //Tell 'us' about all the other agents in the group
                                queue.ChatterBoxSessionAgentListUpdates(GroupID, NotUsAgents.ToArray(), member.AvatarKey,
                                                                        "ENTER",
                                                                        remoteClient.Scene.RegionInfo.RegionHandle);
                            }
                            else
                            {
                                //Tell 'other' agents about the new agent ('us')
                                IClientAPI otherAgent = GetActiveClient(member.AvatarKey);
                                if (otherAgent != null) //Local, so we can send it directly
                                    queue.ChatterBoxSessionAgentListUpdates(GroupID, Us.ToArray(), member.AvatarKey,
                                                                            "ENTER",
                                                                            otherAgent.Scene.RegionInfo.RegionHandle);
                                else
                                {
                                    ISyncMessagePosterService amps =
                                        m_sceneList[0].RequestModuleInterface<ISyncMessagePosterService>();
                                    if (amps != null)
                                    {
                                        OSDMap message = new OSDMap();
                                        message["Method"] = "GroupSessionAgentUpdate";
                                        message["AgentID"] = AgentID;
                                        message["Message"] = ChatterBoxSessionAgentListUpdates(GroupID, Us.ToArray(),
                                                                                               "ENTER");
                                        amps.PostToServer(message);
                                    }
                                }
                            }
                        }
                    }

                    //Tell us that we entered
                    ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock ourblock =
                        new ChatterBoxSessionAgentListUpdatesMessage.AgentUpdatesBlock
                            {
                                AgentID = AgentID,
                                CanVoiceChat = true,
                                IsModerator = true,
                                MuteText = false,
                                MuteVoice = false,
                                Transition = "ENTER"
                            };
                    queue.ChatterBoxSessionAgentListUpdates(GroupID, new[] {ourblock}, AgentID, "ENTER",
                                                            remoteClient.Scene.RegionInfo.RegionHandle);
                }
            }
                // Send a message from locally connected client to a group
            else if ((im.dialog == (byte) InstantMessageDialog.SessionSend) && im.message != "")
            {
                UUID GroupID = im.imSessionID;
                UUID AgentID = im.fromAgentID;

                if (m_debugEnabled)
                    MainConsole.Instance.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}",
                                      GroupID, im.imSessionID.ToString());

                ChatSessionMember memeber = m_groupData.FindMember(im.imSessionID, AgentID);
                if (memeber == null || memeber.MuteText)
                    return; //Not in the chat or muted
                SendMessageToGroup(im, GroupID);
            }
            else if (im.dialog == (byte) InstantMessageDialog.SessionDrop)
                DropMemberFromSession(remoteClient, im, true);
            else if (im.dialog == 212) //Forwarded sessionDrop
                DropMemberFromSession(remoteClient, im, false);
        }
        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 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(
                            null, im.toAgentID,
                            "System", im.fromAgentID,
                            (byte)InstantMessageDialog.MessageFromAgent,
                            "User has too many IMs already, please try again later.",
                            false, Vector3.Zero));
                else if (client == null)
                    return;
            }
            else if ((im.offline != 0)
                && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
            {
                if (im.dialog == 32) //Group notice
                {
                    IGroupsModule module = m_SceneList[0].RequestModuleInterface<IGroupsModule>();
                    if (module != null)
                        im = module.BuildOfflineGroupNotice(im);
                    return;
                }
                if (client == null) return;
                IEmailModule emailModule = m_SceneList[0].RequestModuleInterface<IEmailModule> ();
                if (emailModule != null && m_SendOfflineMessagesToEmail)
                {
                    IUserProfileInfo profile = DataManager.DataManager.RequestPlugin<IProfileConnector> ().GetUserProfile (im.toAgentID);
                    if (profile != null && profile.IMViaEmail)
                    {
                        UserAccount account = m_SceneList[0].UserAccountService.GetUserAccount(null, im.toAgentID.ToString());
                        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_SceneList[0]);
                        }
                    }
                }

                if(im.dialog == (byte)InstantMessageDialog.MessageFromAgent && !im.fromGroup)
                {
                    client.SendInstantMessage(new GridInstantMessage(
                            null, im.toAgentID,
                            "System", im.fromAgentID,
                            (byte)InstantMessageDialog.MessageFromAgent,
                            "Message saved, reason: " + reason,
                            false, new Vector3()));
                }

                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(
                            null, im.toAgentID,
                            "System", im.fromAgentID,
                            (byte)InstantMessageDialog.MessageFromAgent,
                            "Message saved, reason: " + reason,
                            false, new Vector3()));
                }

                if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
                    client.SendAlertMessage("User not able to be found. Inventory has been saved");
            }
        }
        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);

            if (remoteClient.ActiveGroupId == groupID)
                GroupTitleUpdate(remoteClient, UUID.Zero, UUID.Zero);

            SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));

            if (m_groupsMessagingModule != 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,
                                                imSessionID = groupID,
                                                message = remoteClient.Name + " has left the group.",
                                                offline = 1,
                                                RegionID = remoteClient.Scene.RegionInfo.RegionID,
                                                timestamp = (uint) Util.UnixTimeSinceEpoch(),
                                                toAgentID = UUID.Zero
                                            };

                m_groupsMessagingModule.EnsureGroupChatIsStarted(groupID);
                m_groupsMessagingModule.SendMessageToGroup(im, groupID);
            }
        }
 /// <summary>
 ///   Send chat to all the members of this friend conference
 /// </summary>
 /// <param name = "client"></param>
 /// <param name = "im"></param>
 public void SendChatToSession(IClientAPI client, GridInstantMessage im)
 {
     ChatSession session;
     ChatSessions.TryGetValue(im.imSessionID, out session);
     if (session == null)
         return;
     IEventQueueService eq = client.Scene.RequestModuleInterface<IEventQueueService>();
     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.timestamp = 0;
             m_TransferModule.SendInstantMessage(im);
         }
         else
         {
             im.toAgentID = member.AvatarKey;
             eq.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.imSessionID
                 , false
                 , Utils.StringToBytes(session.Name)
                 , findScene(member.AvatarKey).RegionInfo.RegionHandle
                 );
         }
     }
 }
        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_sceneList[0].RegionInfo;
                    UserAccount acc = m_sceneList[0].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_sceneList[0].UserAccountService.GetUserAccount(regionInfo.AllScopeIDs, ejecteeID);

            if ((groupInfo == null) || (account == null))
                return;

            // Send Message to avatar being ejected from the group
            GridInstantMessage msg = new GridInstantMessage
            {
                imSessionID = 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;
            UpdateAllClientsWithGroupInfo(ejecteeID, "");

            if (m_groupsMessagingModule != 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,
                    imSessionID = 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_groupsMessagingModule.EnsureGroupChatIsStarted(groupID);
                m_groupsMessagingModule.SendMessageToGroup(im, groupID);
            }
        }
        /// <summary>
        ///   If its a message we deal with, pull it from the client here
        /// </summary>
        /// <param name = "client"></param>
        /// <param name = "im"></param>
        public void OnInstantMessage(IClientAPI client, GridInstantMessage im)
        {
            byte dialog = im.dialog;
            //We only deal with friend IM sessions here, groups module handles group IM sessions
            if (dialog == (byte) InstantMessageDialog.SessionSend)
                SendChatToSession(client, im);

            if (dialog == (byte) InstantMessageDialog.SessionDrop)
                DropMemberFromSession(client, 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_sceneList[0].RegionInfo;
                    UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.AllScopeIDs, agentID);
                    if (account != null)
                    {
                        agentName = account.FirstName + " " + account.LastName;
                    }

                    else
                    {
                        agentName = "Unknown member";
                    }
                }
            }

            UUID InviteID = UUID.Random();

            m_groupData.AddAgentToGroupInvite(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
                                                 {
                                                     imSessionID = 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);
                }
            }
        }