Inheritance: Universe.Framework.Modules.IDataTransferable
        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>
        ///     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.");
            }
        }
        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 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);
            }
        }
        void OnInstantMessage(IClientAPI client, GridInstantMessage im)
        {
            //MainConsole.Instance.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog);
            IScene clientScene = FindClientScene(client.AgentId);
            if (clientScene == null) // Something seriously wrong here.
            {
                MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Cannot find originating user scene");
                return;
            }

            if (im.Dialog == (byte) InstantMessageDialog.InventoryOffered)
            {
                //MainConsole.Instance.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0]));

                if (im.BinaryBucket.Length < 17) // Invalid
                {
                    MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Invalid length {0} for asset type {1}",
                        im.BinaryBucket.Length, ((AssetType)im.BinaryBucket[0]));
                    return;
                }

                UUID receipientID = im.ToAgentID;
                IScenePresence recipientUser = null;
                IScene recipientUserScene = FindClientScene(client.AgentId);
                if (recipientUserScene != null)
                    recipientUser = recipientUserScene.GetScenePresence(receipientID);
                UUID copyID;

                // user is online now...
                if (recipientUser != null)
                {

                    // First byte is the asset type
                    AssetType assetType = (AssetType)im.BinaryBucket [0];

                    if (assetType == AssetType.Folder)
                    {
                        UUID folderID = new UUID (im.BinaryBucket, 1);

                        MainConsole.Instance.DebugFormat (
                            "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory",
                            folderID, im.ToAgentID);


                        clientScene.InventoryService.GiveInventoryFolderAsync (
                            receipientID,
                            client.AgentId,
                            folderID,
                            UUID.Zero,
                            (folder) =>
                            {
                                if (folder == null)
                                {
                                    client.SendAgentAlertMessage ("Can't find folder to give. Nothing given.", false);
                                    return;
                                }

                                // The outgoing binary bucket should contain only the byte which signals an asset folder is
                                // being copied and the following bytes for the copied folder's UUID
                                copyID = folder.ID;
                                byte[] copyIDBytes = copyID.GetBytes ();
                                im.BinaryBucket = new byte[ 1 + copyIDBytes.Length ];
                                im.BinaryBucket [0] = (byte)AssetType.Folder;
                                Array.Copy (copyIDBytes, 0, im.BinaryBucket, 1, copyIDBytes.Length);

//                                m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0,
//                                    "Inworld inventory folder transfer", TransactionType.GiveInventory, UUID.Zero);
                            if (moneyService != null)
                                moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                "Inworld inventory folder transfer", TransactionType.GiveInventory);

                                if (recipientUser != null)
                                {
                                    recipientUser.ControllingClient.SendBulkUpdateInventory (folder);
                                    im.SessionID = copyID;
                                    recipientUser.ControllingClient.SendInstantMessage (im);
                                }
                            });

                    } else
                    {
                        // First byte of the array is probably the item type
                        // Next 16 bytes are the UUID

                        UUID itemID = new UUID (im.BinaryBucket, 1);

                        MainConsole.Instance.DebugFormat (
                            "[INVENTORY TRANSFER]: (giving) Inserting item {0} into agent {1}'s inventory",
                            itemID, im.ToAgentID);

                        clientScene.InventoryService.GiveInventoryItemAsync (
                            im.ToAgentID,
                            im.FromAgentID,
                            itemID,
                            UUID.Zero,
                            false,
                            (itemCopy) =>
                            {
                                if (itemCopy == null)
                                {
                                    MainConsole.Instance.DebugFormat (
                                        "[INVENTORY TRANSFER]: (giving) Unable to find item {0} to give to agent {1}'s inventory",
                                        itemID, im.ToAgentID);
                                    client.SendAgentAlertMessage ("Can't find item to give. Nothing given.", false);
                                    return;
                                }

                                copyID = itemCopy.ID;
                                Array.Copy (copyID.GetBytes (), 0, im.BinaryBucket, 1, 16);
                                
                               if (moneyService != null)
                                  moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                                          "Inworld inventory item transfer", TransactionType.GiveInventory);

                                if (recipientUser != null)
                                {
                                    recipientUser.ControllingClient.SendBulkUpdateInventory (itemCopy);
                                    im.SessionID = itemCopy.ID;
                                    recipientUser.ControllingClient.SendInstantMessage (im);
                                }
                            });
  
                    
                    }
                }  else
                {
                    // recipient is offline.
                    // Send the IM to the recipient. The item is already
                    // in their inventory, so it will not be lost if
                    // they are offline.
                    //
                     if (m_TransferModule != null)
                        m_TransferModule.SendInstantMessage(im);
                }
            }
            else if (im.Dialog == (byte) InstantMessageDialog.InventoryAccepted)
            {
                IScenePresence user = clientScene.GetScenePresence(im.ToAgentID);
                MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Acceptance message received");

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                        m_TransferModule.SendInstantMessage(im);
                }
            }
            else if (im.Dialog == (byte) InstantMessageDialog.InventoryDeclined)
            {
                // Here, the recipient is local and we can assume that the
                // inventory is loaded. Courtesy of the above bulk update,
                // It will have been pushed to the client, too
                //
                IInventoryService invService = clientScene.InventoryService;
                MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Declined message received");

                InventoryFolderBase trashFolder =
                    invService.GetFolderForType(client.AgentId, InventoryType.Unknown, FolderType.Trash);

                UUID inventoryID = im.SessionID; // The inventory item/folder, back from it's trip

                InventoryItemBase item = invService.GetItem(client.AgentId, inventoryID);
                InventoryFolderBase folder = null;

                if (item != null && trashFolder != null)
                {
                    item.Folder = trashFolder.ID;

                    // Diva comment: can't we just update this item???
                    List<UUID> uuids = new List<UUID> {item.ID};
                    invService.DeleteItems(item.Owner, uuids);
                    ILLClientInventory inventory = client.Scene.RequestModuleInterface<ILLClientInventory>();
                    if (inventory != null)
                        inventory.AddInventoryItemAsync(client, item);
                }
                else
                {
                    folder = new InventoryFolderBase(inventoryID, client.AgentId);
                    folder = invService.GetFolder(folder);

                    if (folder != null & trashFolder != null)
                    {
                        folder.ParentID = trashFolder.ID;
                        invService.MoveFolder(folder);
                        client.SendBulkUpdateInventory(folder);
                    }
                }

                if ((null == item && null == folder) | null == trashFolder)
                {
                    string reason = String.Empty;

                    if (trashFolder == null)
                        reason += " Trash folder not found.";
                    if (item == null)
                        reason += " Item not found.";
                    if (folder == null)
                        reason += " Folder not found.";

                    client.SendAgentAlertMessage("Unable to delete " +
                                                 "received inventory" + reason, false);
                }

                //m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0,
                //    "Inworld inventory transfer declined", TransactionType.GiveInventory, UUID.Zero);
                if (moneyService != null)
                    moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0,
                        "Inworld inventory transfer declined", TransactionType.GiveInventory);

                IScenePresence user = clientScene.GetScenePresence(im.ToAgentID);

                if (user != null) // Local
                {
                    user.ControllingClient.SendInstantMessage(im);
                }
                else
                {
                    if (m_TransferModule != null)
                        m_TransferModule.SendInstantMessage(im);
                }
            }
        }
        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);
            }
        }
        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);

                            //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;
        }
Exemple #10
0
        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);
        }
        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);
        }
Exemple #12
0
        public void llGiveInventoryList(string destination, string category, LSL_List inventory)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;

            UUID destID;
            if (!UUID.TryParse(destination, out destID))
                return;

            List<UUID> itemList = new List<UUID>();

            foreach (Object item in inventory.Data)
            {
                UUID itemID;
                if (UUID.TryParse(item.ToString(), out itemID))
                {
                    itemList.Add(itemID);
                }
                else
                {
                    itemID = GetTaskInventoryItem(item.ToString());
                    if (itemID != UUID.Zero)
                        itemList.Add(itemID);
                }
            }

            if (itemList.Count == 0)
                return;
            UUID folderID = UUID.Zero;
            ILLClientInventory inventoryModule = World.RequestModuleInterface<ILLClientInventory>();
            if (inventoryModule != null)
                folderID = inventoryModule.MoveTaskInventoryItemsToUserInventory(destID, category, m_host, itemList);

            if (folderID == UUID.Zero)
                return;

            byte[] bucket = new byte[17];
            bucket[0] = (byte)AssetType.Folder;
            byte[] objBytes = folderID.GetBytes();
            Array.Copy(objBytes, 0, bucket, 1, 16);

            GridInstantMessage msg = new GridInstantMessage()
                {
                    FromAgentID = m_host.UUID,
                    FromAgentName = m_host.Name + ", an object owned by " +
                                                                         resolveName(m_host.OwnerID) + ",",
                    ToAgentID = destID,
                    Dialog = (byte)InstantMessageDialog.InventoryOffered,
                    Message = category + "\n" + m_host.Name + " is located at " +
                                                                   World.RegionInfo.RegionName + " " +
                                                                   m_host.AbsolutePosition.ToString(),
                    SessionID = folderID,
                    Offline = 1,
                    Position = m_host.AbsolutePosition,
                    BinaryBucket = bucket,
                    RegionID = m_host.ParentEntity.Scene.RegionInfo.RegionID
                };

            if (m_TransferModule != null)
                m_TransferModule.SendInstantMessage(msg);
        }
Exemple #13
0
        public DateTime llInstantMessage(string user, string message)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return DateTime.Now;

            // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
            // InstantMessageModule.OnInstantMessage searches through a list of scenes for a client matching the toAgent,
            // but I don't think we have a list of scenes available from here.
            // (We also don't want to duplicate the code in OnInstantMessage if we can avoid it.)

            UUID friendTransactionID = UUID.Random();

            GridInstantMessage msg = new GridInstantMessage
                                         {
                                             FromAgentID = m_host.UUID,
                                             ToAgentID = UUID.Parse(user),
                                             SessionID = friendTransactionID,
                                             FromAgentName = m_host.Name,
                                             RegionID = m_host.ParentEntity.Scene.RegionInfo.RegionID
                                         };

            // This is the item we're mucking with here

            // Cap the message length at 1024.
            if (message != null && message.Length > 1024)
                msg.Message = message.Substring(0, 1024);
            else
                msg.Message = message;

            msg.Dialog = (byte)InstantMessageDialog.MessageFromObject;
            msg.FromGroup = false;
            msg.Offline = 0;
            msg.ParentEstateID = 0;
            msg.Position = m_host.AbsolutePosition;
            msg.RegionID = World.RegionInfo.RegionID;
            msg.BinaryBucket
                = Util.StringToBytes256(
                    "{0}/{1}/{2}/{3}",
                    World.RegionInfo.RegionName,
                    (int)Math.Floor(m_host.AbsolutePosition.X),
                    (int)Math.Floor(m_host.AbsolutePosition.Y),
                    (int)Math.Floor(m_host.AbsolutePosition.Z));

            if (m_TransferModule != null)
            {
                m_TransferModule.SendInstantMessage(msg);
            }
            return PScriptSleep(m_sleepMsOnInstantMessage);
        }
Exemple #14
0
        public DateTime llGiveInventory(string destination, string inventory)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return DateTime.Now;

            bool found = false;
            UUID destId = UUID.Zero;
            UUID objId = UUID.Zero;
            int assetType = 0;
            string objName = String.Empty;

            if (!UUID.TryParse(destination, out destId))
            {
                Error("llGiveInventory", "Could not parse key " + destination);
                return DateTime.Now;
            }

            // move the first object found with this inventory name
            lock (m_host.TaskInventory)
            {
                foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
                {
                    if (inv.Value.Name == inventory)
                    {
                        found = true;
                        objId = inv.Key;
                        assetType = inv.Value.Type;
                        objName = inv.Value.Name;
                        break;
                    }
                }
            }

            if (!found)
            {
                Error("llGiveInventory", "Can't find inventory object '" + inventory + "'");
            }

            // check if destination is an avatar
            if (World.GetScenePresence(destId) != null ||
                m_host.ParentEntity.Scene.RequestModuleInterface<IAgentInfoService>().GetUserInfo(destId.ToString()) !=
                null)
            {
                // destination is an avatar
                InventoryItemBase agentItem = null;
                ILLClientInventory inventoryModule = World.RequestModuleInterface<ILLClientInventory>();
                if (inventoryModule != null)
                    agentItem = inventoryModule.MoveTaskInventoryItemToUserInventory(destId, UUID.Zero, m_host, objId,
                                                                                     false);

                if (agentItem == null)
                    return DateTime.Now;

                byte[] bucket = new byte[17];
                bucket[0] = (byte)assetType;
                byte[] objBytes = agentItem.ID.GetBytes();
                Array.Copy(objBytes, 0, bucket, 1, 16);

                GridInstantMessage msg = new GridInstantMessage()
                    {
                        FromAgentID = m_host.UUID,
                        FromAgentName = m_host.Name + ", an object owned by " +
                                                                              resolveName(m_host.OwnerID) + ",",
                        ToAgentID = destId,
                        Dialog = (byte)InstantMessageDialog.InventoryOffered,
                        Message = objName + "'\n'" + m_host.Name + "' is located at " +
                                                                 m_host.AbsolutePosition.ToString() + " in '" +
                                                                 World.RegionInfo.RegionName,
                        SessionID = agentItem.ID,
                        Offline = 1,
                        Position = m_host.AbsolutePosition,
                        BinaryBucket = bucket,
                        RegionID = m_host.ParentEntity.Scene.RegionInfo.RegionID
                    };

                if (m_TransferModule != null)
                    m_TransferModule.SendInstantMessage(msg);
            }
            else
            {
                // destination is an object
                ILLClientInventory inventoryModule = World.RequestModuleInterface<ILLClientInventory>();
                if (inventoryModule != null)
                    inventoryModule.MoveTaskInventoryItemToObject(destId, m_host, objId);
            }
            return PScriptSleep(m_sleepMsOnGiveInventory);
        }
        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);
            }
        }
        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; // not required?
            }
            else
            {
                IClientAPI client = GetActiveClient(agentID);
                if (client != null)
                {
                    agentName = client.Name;
                    regionInfo = client.Scene.RegionInfo;   // not required?
                }

                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 + ".";
                    }
                    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);
                }
            }
        }
 /// <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 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);
                    }
                }
            }
        }
Exemple #19
0
        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);
            }
        }
        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;
        }
        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));
            }
        }
        public void SendInstantMessage(GridInstantMessage im)
        {
            IMessageTransferModule m_TransferModule =
                m_object.Scene.RequestModuleInterface<IMessageTransferModule>();

            if (m_TransferModule != null)
                m_TransferModule.SendInstantMessage(im);
        }
        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());
                                               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 override void FromOSD(OSDMap map)
        {
            AgentInfo = new IAgentInfo();
            AgentInfo.FromOSD((OSDMap) (map["AgentInfo"]));
            UserAccount = new UserAccount();
            UserAccount.FromOSD((OSDMap)(map["UserAccount"]));
            if (!map.ContainsKey("ActiveGroup"))
                ActiveGroup = null;
            else
            {
                ActiveGroup = new GroupMembershipData();
                ActiveGroup.FromOSD((OSDMap)(map["ActiveGroup"]));
            }
            GroupMemberships = ((OSDArray) map["GroupMemberships"]).ConvertAll<GroupMembershipData>((o) =>
                                                                                                        {
                                                                                                            GroupMembershipData
                                                                                                                group =
                                                                                                                    new GroupMembershipData
                                                                                                                        ();
                                                                                                            group
                                                                                                                .FromOSD
                                                                                                                ((OSDMap
                                                                                                                 ) o);
                                                                                                            return group;
                                                                                                        });
            OfflineMessages = ((OSDArray) map["OfflineMessages"]).ConvertAll<GridInstantMessage>((o) =>
                                                                                                     {
                                                                                                         GridInstantMessage
                                                                                                             group =
                                                                                                                 new GridInstantMessage
                                                                                                                     ();
                                                                                                         group.FromOSD(
                                                                                                             (OSDMap) o);
                                                                                                         return group;
                                                                                                     });
            MuteList = ((OSDArray) map["MuteList"]).ConvertAll<MuteList>((o) =>
                                                                             {
                                                                                 MuteList group = new MuteList();
                                                                                 group.FromOSD((OSDMap) o);
                                                                                 return group;
                                                                             });

            if (map.ContainsKey("Appearance"))
            {
                Appearance = new AvatarAppearance();
                Appearance.FromOSD((OSDMap)map["Appearance"]);
            }
            if (map.ContainsKey("FriendOnlineStatuses"))
                FriendOnlineStatuses = ((OSDArray)map["FriendOnlineStatuses"]).ConvertAll<UUID>((o) => { return o; });
            if (map.ContainsKey("Friends"))
                Friends = ((OSDArray)map["Friends"]).ConvertAll<FriendInfo>((o) =>
                {
                    FriendInfo f = new FriendInfo();
                    f.FromOSD((OSDMap)o);
                    return f;
                });
        }
 /// <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;
     }
 }
        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");
        }
        /// <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;
                }
            }
        }
        protected virtual void SendGridInstantMessageViaXMLRPC (GridInstantMessage im)
        {
            GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;

            d.BeginInvoke (im, null, GridInstantMessageCompleted, d);
        }
        /// <summary>
        /// </summary>
        /// <param name="msg"></param>
        void OnGridInstantMessage(GridInstantMessage msg)
        {
            // Check if this is ours to handle
            //
            IScene userScene = FindClientScene(msg.ToAgentID);
            if (userScene == null)
            {
                MainConsole.Instance.DebugFormat ("[INVENTORY TRANSFER]: Cannot find user scene for instant message");
                return;
            }

            // Find agent to deliver to
            //
            IScenePresence user = userScene.GetScenePresence(msg.ToAgentID);

            // Just forward to local handling
            OnInstantMessage(user.ControllingClient, msg);
        }
        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;
            }
        }