Ejemplo n.º 1
0
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString());

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
                if (scene.Entities.ContainsKey(toAgentID) &&
                    scene.Entities[toAgentID] is ScenePresence)
                {
                    m_log.DebugFormat("[INSTANT MESSAGE]: Looking for {0} in {1}", toAgentID.ToString(), scene.RegionInfo.RegionName);
                    // Local message
                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];
                    if (!user.IsChildAgent)
                    {
                        m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
                        user.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        return;
                    }
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                if (scene.Entities.ContainsKey(toAgentID) &&
                    scene.Entities[toAgentID] is ScenePresence)
                {
                    // Local message
                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];

                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
                    user.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            if (m_Gridmode)
            {
                //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering via grid");
                // Still here, try send via Grid
                SendGridInstantMessageViaXMLRPC(im, result);
                return;
            }

            HandleUndeliveredMessage(im, result);

            return;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Internal SendGridInstantMessage over XMLRPC method.
        /// </summary>

        /// <param name="prevRegionHandle">
        /// Pass in 0 the first time this method is called.  It will be called recursively with the last
        /// regionhandle tried
        /// </param>
        private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
        {
            GIM gim;

            do
            {
                try
                {
                    SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
                }
                catch (Exception e)
                {
                    m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
                }
                lock (pendingInstantMessages)
                {
                    if (pendingInstantMessages.Count > 0)
                    {
                        gim    = pendingInstantMessages.Dequeue();
                        im     = gim.im;
                        result = gim.result;
                    }
                    else
                    {
                        gim = null;
                        --numInstantMessageThreads;
                        //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
                    }
                }
            } while (gim != null);
        }
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            try
            {
                // Try root avatar only first
                m_Scenes.ForEach(delegate(Scene scene)
                {
                    //                m_log.DebugFormat(
                    //                    "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
                    //                    toAgentID.ToString(), scene.RegionInfo.RegionName);

                    ScenePresence sp = scene.GetScenePresence(toAgentID);
                    if (sp != null && !sp.IsChildAgent)
                    {
                        // Local message
                        //                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);

                        sp.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        throw new ThreadedClasses.ReturnValueException <bool>(true);
                    }
                });

                // try child avatar second
                m_Scenes.ForEach(delegate(Scene scene)
                {
                    //                m_log.DebugFormat(
                    //                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                    ScenePresence sp = scene.GetScenePresence(toAgentID);
                    if (sp != null)
                    {
                        // Local message
                        //                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID);

                        sp.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        throw new ThreadedClasses.ReturnValueException <bool>(true);
                    }
                });
            }
            catch (ThreadedClasses.ReturnValueException <bool> )
            {
                return;
            }

//            m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);

            SendGridInstantMessageViaXMLRPC(im, result);
        }
Ejemplo n.º 4
0
        private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
        {
            GIMData gim = new GIMData()
            {
                im     = im,
                result = result
            };

            IMXMLRPCSendWorkers.Enqueue(gim);
        }
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
                if (scene.Entities.ContainsKey(toAgentID) &&
                    scene.Entities[toAgentID] is ScenePresence)
                {
//                    m_log.DebugFormat(
//                        "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
//                        toAgentID.ToString(), scene.RegionInfo.RegionName);

                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];
                    if (!user.IsChildAgent)
                    {
                        // Local message
                        m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
                        user.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        return;
                    }
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                if (scene.Entities.ContainsKey(toAgentID) &&
                    scene.Entities[toAgentID] is ScenePresence)
                {
                    // Local message
                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];

                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
                    user.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
            SendGridInstantMessageViaXMLRPC(im, result);

            return;
        }
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            if (toAgentID == UUID.Zero)
            {
                return;
            }

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
//                    toAgentID.ToString(), scene.RegionInfo.RegionName);

                ScenePresence sp = scene.GetScenePresence(toAgentID);
                if (sp != null && !sp.IsChildAgent)
                {
                    // Local message
//                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);

                    sp.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                ScenePresence sp = scene.GetScenePresence(toAgentID);
                if (sp != null)
                {
                    // Local message
//                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID);

                    sp.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

//            m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);

            SendGridInstantMessageViaXMLRPC(im, result);
        }
Ejemplo n.º 7
0
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            if (toAgentID == UUID.Zero)
            {
                return;
            }

            IClientAPI client = null;

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
                ScenePresence sp = scene.GetScenePresence(toAgentID);
                if (sp != null && !sp.IsDeleted && sp.ControllingClient.IsActive)
                {
                    // actualy don't send via child agents
                    // ims can be complex things, and not sure viewers will not mess up
                    if (sp.IsChildAgent)
                    {
                        continue;
                    }

                    client = sp.ControllingClient;
                    if (!sp.IsChildAgent)
                    {
                        break;
                    }
                }
            }

            if (client != null)
            {
                // Local message
                //                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);

                client.SendInstantMessage(im);

                // Message sent
                result(true);
                return;
            }
            //            m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);

            SendGridInstantMessageViaXMLRPC(im, result);
        }
Ejemplo n.º 8
0
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            // Try root avatar only first - incorrect now, see below
            foreach (Scene scene in m_Scenes)
            {
                IScenePresence user;
                if (scene.TryGetScenePresence(toAgentID, out user))
                {
                    user.ControllingClient.SendInstantMessage(im);
                    return;
                }
            }
            //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
            SendGridInstantMessageViaXMLRPC(im, result);
        }
        private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;

            // If this event has handlers, then the IM will be considered
            // delivered. This will suppress the error message.
            //
            if (handlerUndeliveredMessage != null)
            {
                handlerUndeliveredMessage(im);
                result(true);
                return;
            }

            m_log.WarnFormat("[INSTANT MESSAGE]: Message undeliverable and no undeliverable message handler for message from {0} to {1}", im.fromAgentID, im.toAgentID);
            result(false);
        }
Ejemplo n.º 10
0
        private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;

            // If this event has handlers, then the IM will be considered
            // delivered. This will suppress the error message.
            //
            if (handlerUndeliveredMessage != null)
            {
                handlerUndeliveredMessage(im);
                result(true);
                return;
            }

            //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
            result(false);
        }
Ejemplo n.º 11
0
 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
 {
     lock (pendingInstantMessages) {
         if (numInstantMessageThreads >= 4)
         {
             GIM gim = new GIM();
             gim.im     = im;
             gim.result = result;
             pendingInstantMessages.Enqueue(gim);
         }
         else
         {
             ++numInstantMessageThreads;
             //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
             GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
             d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
         }
     }
 }
        private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
        {
            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);
                if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
                {
                    result(true);
                }
                else
                {
                    result(false);
                }
                return;
            }

            //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
            result(false);
        }
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result,
                                                                    ulong prevRegionHandle, int tries)
        {
            UserAgentData upd         = null;
            bool          lookupAgent = false;
            UUID          toAgentID   = new UUID(im.toAgentID);

            if (tries > 5)
            {
                m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Retries exhausted - Unable to deliver an instant message to {0}", toAgentID.ToString());
                return;
            }

            if (m_DebugLevel >= 2)
            {
                m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1}", prevRegionHandle, tries);
            }

            lock (m_UserRegionMap)
            {
                if (m_UserRegionMap.ContainsKey(toAgentID))
                {
                    upd             = new UserAgentData();
                    upd.AgentOnline = true;
                    upd.Handle      = m_UserRegionMap[toAgentID];

                    // We need to compare the current regionhandle with the previous region handle
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (prevRegionHandle == upd.Handle)
                    {
                        lookupAgent = true;
                        if (m_DebugLevel >= 2)
                        {
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1} in region map, same region, requires lookup", prevRegionHandle, tries);
                        }
                    }
                    else
                    if (prevRegionHandle == 0)
                    {
                        if (m_DebugLevel >= 1)
                        {
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1} in region map, using {2}, no lookup", prevRegionHandle, tries, upd.Handle);
                        }
                    }
                    else
                    {
                        if (m_DebugLevel >= 1)
                        {
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1} in region map, different region, no lookup", prevRegionHandle, tries);
                        }
                    }
                }
                else
                {
                    lookupAgent = true;
                    if (m_DebugLevel >= 2)
                    {
                        m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1} not in region map, requires lookup", prevRegionHandle, tries);
                    }
                }
            }

            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                // Non-cached user agent lookup.
                upd = m_Scenes[0].CommsManager.UserService.GetUserAgent(toAgentID, true);

                if (upd != null)
                {
                    // check if we've tried this before..
                    // This is one way to end the recursive loop
                    //
                    if (upd.Handle == prevRegionHandle)
                    {
                        if (m_DebugLevel >= 1)
                        {
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} still, tries={1}", upd.Handle, tries);
                        }
                        HandleUndeliveredMessage(im, result);
                        return;
                    }
                    else
                    {
                        if (m_DebugLevel >= 1)
                        {
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} now, tries={1} lookup success", upd.Handle, tries);
                        }
                    }
                }
                else
                {
                    m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Unable to deliver an instant message to {0} (user lookup failed).", toAgentID.ToString());
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            if (upd != null)
            {
                if (upd.AgentOnline)
                {
                    RegionInfo reginfo = m_Scenes[0].SceneGridService.RequestNeighbouringRegionInfo(upd.Handle);
                    if (reginfo != null)
                    {
                        if (m_DebugLevel >= 2)
                        {
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} now, sending grid IM", upd.Handle);
                        }
                        Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                        // Not actually used anymore, left in for compatibility
                        // Remove at next interface change
                        //
                        msgdata["region_handle"] = 0;
                        bool imresult = doIMSending(reginfo, msgdata);
                        if (imresult)
                        {
                            // IM delivery successful, so store the Agent's location in our local cache.
                            lock (m_UserRegionMap)
                            {
                                if (m_UserRegionMap.ContainsKey(toAgentID))
                                {
                                    m_UserRegionMap[toAgentID] = upd.Handle;
                                    if (m_DebugLevel >= 1)
                                    {
                                        m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} success, updating map", upd.Handle);
                                    }
                                }
                                else
                                {
                                    m_UserRegionMap.Add(toAgentID, upd.Handle);
                                    if (m_DebugLevel >= 1)
                                    {
                                        m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} success, adding to map", upd.Handle);
                                    }
                                }
                            }
                            result(true);
                        }
                        else
                        {
                            // try again, but lookup user this time.
                            // Warning, this must call the Async version
                            // of this method or we'll be making thousands of threads
                            // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                            // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                            // This is recursive!!!!!
                            if (m_DebugLevel >= 2)
                            {
                                m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} failed, retrying recursively", upd.Handle);
                            }
                            SendGridInstantMessageViaXMLRPCAsync(im, result, upd.Handle, ++tries);
                        }
                    }
                    else
                    {
                        if (m_DebugLevel >= 2)
                        {
                            m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}, will retry", upd.Handle);
                        }
                        SendGridInstantMessageViaXMLRPCAsync(im, result, upd.Handle, ++tries);
                    }
                }
                else
                {
                    if (m_DebugLevel >= 1)
                    {
                        m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} user offline.", upd.Handle);
                    }
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                if (m_DebugLevel >= 1)
                {
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find user {0}", toAgentID);
                }
                HandleUndeliveredMessage(im, result);
            }
        }
        private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;

            // If this event has handlers, then the IM will be considered
            // delivered. This will suppress the error message.
            //
            if (handlerUndeliveredMessage != null)
            {
                handlerUndeliveredMessage(im);
                result(true);
                return;
            }

            //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
            result(false);
        }
Ejemplo n.º 15
0
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID fromAgentID = new UUID(im.fromAgentID);
            UUID toAgentID = new UUID(im.toAgentID);

            foreach (Scene scene in m_Scenes)
            {
                if (!scene.EventManager.TriggerOnBeforeSendInstantMessage(im))
                {
                    m_log.WarnFormat("[INSTANT MESSAGE]: Outbound IM blocked by module");
                    return;
                }

                // Check for muted senders in specific IM cases.
                if (m_muteListModule == null)
                    m_muteListModule = scene.RequestModuleInterface<IMuteListModule>();
                if (m_muteListModule != null)
                    if ((im.dialog == (int)InstantMessageDialog.MessageFromAgent) || (im.dialog == (int)InstantMessageDialog.MessageFromObject))
                        if (m_muteListModule.IsMuted(fromAgentID, toAgentID))   // owner ID is in fromAgentID in case of IMs from objects
                            return; // recipient has sender muted.
            }

            //m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString());

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
                if (scene.Entities.ContainsKey(toAgentID) &&
                        scene.Entities[toAgentID] is ScenePresence)
                {
                    //m_log.DebugFormat("[INSTANT MESSAGE]: Looking for {0} in {1}", toAgentID.ToString(), scene.RegionInfo.RegionName);
                    // Local message
                    ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
                    if (!user.IsChildAgent)
                    {
                        //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
                        user.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        return;
                    }
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                if (scene.Entities.ContainsKey(toAgentID) &&
                        scene.Entities[toAgentID] is ScenePresence)
                {
                    // Local message
                    ScenePresence user = (ScenePresence) scene.Entities[toAgentID];

                    //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
                    user.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            if (m_Gridmode)
            {
                //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering via grid");
                // Still here, try send via Grid
                SendGridInstantMessageViaXMLRPC(im, result);
                return;
            }

            HandleUndeliveredMessage(im, result);

            return;
        }
Ejemplo n.º 16
0
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            // Try root avatar only first - incorrect now, see below
            foreach (Scene scene in m_Scenes)
            {
                if (scene.Entities.ContainsKey(toAgentID) &&
                        scene.Entities[toAgentID] is ScenePresence)
                {
                    // Local message
                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];
                    user.ControllingClient.SendInstantMessage(im);
                    return;
                }
            }
            //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
            SendGridInstantMessageViaXMLRPC(im, result);
        }
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString());

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
                if (scene.Entities.ContainsKey(toAgentID) &&
                        scene.Entities[toAgentID] is ScenePresence)
                {
                    m_log.DebugFormat("[INSTANT MESSAGE]: Looking for {0} in {1}", toAgentID.ToString(), scene.RegionInfo.RegionName);
                    // Local message
                    ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
                    if (!user.IsChildAgent)
                    {
                        m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
                        user.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        return;
                    }
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                if (scene.Entities.ContainsKey(toAgentID) &&
                        scene.Entities[toAgentID] is ScenePresence)
                {
                    // Local message
                    ScenePresence user = (ScenePresence) scene.Entities[toAgentID];

                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
                    user.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            SendGridInstantMessageViaXMLRPC(im, result);

            return;
        }
        protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
        {
            GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;

            d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d);
        }
Ejemplo n.º 19
0
        private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;

            // If this event has handlers, then the IM will be considered
            // delivered. This will suppress the error message.
            //
            if (handlerUndeliveredMessage != null)
            {
                handlerUndeliveredMessage(im);
                result(true);
                return;
            }

            m_log.WarnFormat("[INSTANT MESSAGE]: Message undeliverable and no undeliverable message handler for message from {0} to {1}", im.fromAgentID, im.toAgentID);
            result(false);
        }
Ejemplo n.º 20
0
        protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
        {
            GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;

            d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d);
        }
Ejemplo n.º 21
0
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result,
            ulong prevRegionHandle, int tries)
        {
            UserAgentData upd = null;
            bool lookupAgent = false;
            UUID toAgentID = new UUID(im.toAgentID);

            if (tries > 5)
            {
                m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Retries exhausted - Unable to deliver an instant message to {0}", toAgentID.ToString());
                return;
            }

            if (m_DebugLevel >= 2)
                m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1}", prevRegionHandle, tries);

            lock (m_UserRegionMap)
            {
                if (m_UserRegionMap.ContainsKey(toAgentID))
                {
                    upd = new UserAgentData();
                    upd.AgentOnline = true;
                    upd.Handle = m_UserRegionMap[toAgentID];

                    // We need to compare the current regionhandle with the previous region handle
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (prevRegionHandle == upd.Handle)
                    {
                        lookupAgent = true;
                        if (m_DebugLevel >= 2)
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1} in region map, same region, requires lookup", prevRegionHandle, tries);
                    }
                    else
                    if (prevRegionHandle == 0)
                    {
                        if (m_DebugLevel >= 1)
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1} in region map, using {2}, no lookup", prevRegionHandle, tries, upd.Handle);
                    }
                    else
                    {
                        if (m_DebugLevel >= 1)
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1} in region map, different region, no lookup", prevRegionHandle, tries);
                    }
                }
                else
                {
                    lookupAgent = true;
                    if (m_DebugLevel >= 2)
                        m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} tries={1} not in region map, requires lookup", prevRegionHandle, tries);
                }
            }

            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                // Non-cached user agent lookup.
                upd = m_Scenes[0].CommsManager.UserService.GetUserAgent(toAgentID,true);

                if (upd != null)
                {
                    // check if we've tried this before..
                    // This is one way to end the recursive loop
                    //
                    if (upd.Handle == prevRegionHandle)
                    {
                        if (m_DebugLevel >= 1)
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} still, tries={1}", upd.Handle, tries);
                        HandleUndeliveredMessage(im, result);
                        return;
                    }
                    else
                    {
                        if (m_DebugLevel >= 1)
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} now, tries={1} lookup success", upd.Handle, tries);
                    }
                }
                else
                {
                    m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Unable to deliver an instant message to {0} (user lookup failed).", toAgentID.ToString());
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            if (upd != null)
            {
                if (upd.AgentOnline)
                {
                    RegionInfo reginfo = m_Scenes[0].SceneGridService.RequestNeighbouringRegionInfo(upd.Handle);
                    if (reginfo != null)
                    {
                        if (m_DebugLevel >= 2)
                            m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} now, sending grid IM", upd.Handle);
                        Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                        // Not actually used anymore, left in for compatibility
                        // Remove at next interface change
                        //
                        msgdata["region_handle"] = 0;
                        bool imresult = doIMSending(reginfo, msgdata);
                        if (imresult)
                        {
                            // IM delivery successful, so store the Agent's location in our local cache.
                            lock (m_UserRegionMap)
                            {
                                if (m_UserRegionMap.ContainsKey(toAgentID))
                                {
                                    m_UserRegionMap[toAgentID] = upd.Handle;
                                    if (m_DebugLevel >= 1)
                                        m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} success, updating map", upd.Handle);
                                }
                                else
                                {
                                    m_UserRegionMap.Add(toAgentID, upd.Handle);
                                    if (m_DebugLevel >= 1)
                                        m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} success, adding to map", upd.Handle);
                                }
                            }
                            result(true);
                        }
                        else
                        {
                            // try again, but lookup user this time.
                            // Warning, this must call the Async version
                            // of this method or we'll be making thousands of threads
                            // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                            // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                            // This is recursive!!!!!
                            if (m_DebugLevel >= 2)
                                m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} failed, retrying recursively", upd.Handle);
                            SendGridInstantMessageViaXMLRPCAsync(im, result, upd.Handle, ++tries);
                        }
                    }
                    else
                    {
                        if (m_DebugLevel >= 2)
                            m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}, will retry", upd.Handle);
                        SendGridInstantMessageViaXMLRPCAsync(im, result, upd.Handle, ++tries);
                    }
                }
                else
                {
                    if (m_DebugLevel >= 1)
                        m_log.ErrorFormat("[GRID INSTANT MESSAGE]: region={0} user offline.", upd.Handle);
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                if (m_DebugLevel >= 1)
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find user {0}", toAgentID);
                HandleUndeliveredMessage(im, result);
            }
        }
Ejemplo n.º 22
0
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, GridRegion prevRegion)
        {
            UUID toAgentID = im.toAgentID;
            string HTTPPath = "";

            Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);

            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, msgdata))
                {
                    //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
                    result(true);
                    return;
                }
            }

            //Now query the grid server for the agent

            //Ask for the user new style first
            string[] AgentLocations = m_Scenes[0].RequestModuleInterface<IAgentInfoService>().GetAgentsLocations(new string[] { toAgentID.ToString() });
            //If this is false, this doesn't exist on the presence server and we use the legacy way
            if (AgentLocations.Length > 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);
                    }
                    m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
                else //Found the agent, use this location
                    HTTPPath = AgentLocations[0];
            }

            //We found the agent's location, now ask them about the user
            if (HTTPPath != "")
            {
                if (!doIMSending(HTTPPath, msgdata))
                {
                    //It failed, stop now
                    lock (IMUsersCache)
                    {
                        //Remove them so we keep testing against the db
                        IMUsersCache.Remove(toAgentID);
                    }
                    m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message as the region could not be found");
                    HandleUndeliveredMessage(im, result);
                    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
                    result(true);
                    return;
                }
            }
            else
            {
                //Couldn't find them, stop for now
                lock (IMUsersCache)
                {
                    //Remove them so we keep testing against the db
                    IMUsersCache.Remove(toAgentID);
                }
                m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message as the region could not be found");
                HandleUndeliveredMessage(im, result);
            }
        }
Ejemplo n.º 23
0
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for root agent {0} in {1}", 
//                    toAgentID.ToString(), scene.RegionInfo.RegionName);
                ScenePresence sp = scene.GetScenePresence(toAgentID);
                if (sp != null && !sp.IsChildAgent)
                {
                    // Local message
//                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
                    sp.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
                ScenePresence sp = scene.GetScenePresence(toAgentID);
                if (sp != null)
                {
                    // Local message
//                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
                    sp.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

//            m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
            SendGridInstantMessageViaXMLRPC(im, result);

            return;
        }
Ejemplo n.º 24
0
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, UUID prevRegionID)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            PresenceInfo upd = null;

            bool lookupAgent = false;

            lock (m_UserRegionMap)
            {
                if (m_UserRegionMap.ContainsKey(toAgentID))
                {
                    upd          = new PresenceInfo();
                    upd.RegionID = m_UserRegionMap[toAgentID];

                    // We need to compare the current regionhandle with the previous region handle
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (prevRegionID == upd.RegionID)
                    {
                        m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: agentInRegionMap. prevRegion==upd.Region settingLookupAgentTrue, agentID={1}, regionID={2}",
                                          LogHeader, toAgentID, prevRegionID);
                        lookupAgent = true;
                    }
                }
                else
                {
                    m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: agentNOTInRegionMap. setting LookupAgentTrue", LogHeader);
                    lookupAgent = true;
                }
            }


            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: lookupAgent IS TRUE", LogHeader);
                // Non-cached user agent lookup.
                PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
                if (presences != null && presences.Length > 0)
                {
                    foreach (PresenceInfo p in presences)
                    {
                        m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: got presences. p.RegionID={1}", LogHeader, p.RegionID);
                        // Sometimes we get more than 1 session querying a single agent ID! Filter for the correct agent ID.
                        if (p.UserID == toAgentID.ToString() && p.RegionID != UUID.Zero)
                        {
                            upd = p;
                            break;
                        }
                    }
                }

                if (upd != null)
                {
                    // check if we've tried this before..
                    // This is one way to end the recursive loop
                    //
                    if (upd.RegionID == prevRegionID)
                    {
                        // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                        m_log.DebugFormat("{0} Unable to deliver instant message: regionID==prevRegionID: regionID={1}, agentID={2}", LogHeader, prevRegionID, toAgentID);
                        HandleUndeliveredMessage(im, result);
                        return;
                    }
                }
                else
                {
                    // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    m_log.DebugFormat("{0} Unable to deliver instant message: lookupAgent=true, upd==null, agentID={1}", LogHeader, toAgentID);
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            if (upd != null)
            {
                GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, upd.RegionID);
                if (reginfo != null)
                {
                    m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: regInfoNotNull, regID={1}, regNam={2}, regURI={3}, regPort={4}",
                                      LogHeader, reginfo.RegionID, reginfo.RegionName, reginfo.ServerURI, reginfo.HttpPort);
                    Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                    // Not actually used anymore, left in for compatibility
                    // Remove at next interface change
                    //
                    msgdata["region_handle"] = 0;
                    bool imresult = doIMSending(reginfo, msgdata);
                    if (imresult)
                    {
                        // IM delivery successful, so store the Agent's location in our local cache.
                        lock (m_UserRegionMap)
                        {
                            if (m_UserRegionMap.ContainsKey(toAgentID))
                            {
                                m_log.DebugFormat("{0} SendGridInstMgsViaXMLRPCAsync: Updating RegionMap: agent={1}, reg={2}", LogHeader, toAgentID, upd.RegionID);
                                m_UserRegionMap[toAgentID] = upd.RegionID;
                            }
                            else
                            {
                                m_log.DebugFormat("{0} SendGridInstMgsViaXMLRPCAsync: Add RegionMap: agent={1}, reg={2}", LogHeader, toAgentID, upd.RegionID);
                                m_UserRegionMap.Add(toAgentID, upd.RegionID);
                            }
                        }
                        result(true);
                    }
                    else
                    {
                        // try again, but lookup user this time.
                        // Warning, this must call the Async version
                        // of this method or we'll be making thousands of threads
                        // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                        // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                        // This is recursive!!!!!
                        m_log.DebugFormat("{0} SendGridInstMgsViaXMLRPCAsync: Calling me recursively. region={1}", LogHeader, upd.RegionID);
                        SendGridInstantMessageViaXMLRPCAsync(im, result, upd.RegionID);
                    }
                }
                else
                {
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
                    m_log.DebugFormat("{0} Unable to deliver instant message: regionInfo==null, lookupAgent={1}, agentid={2}, region={3}", LogHeader, lookupAgent, toAgentID, upd.RegionID);
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                m_log.DebugFormat("{0} Unable to deliver instant message: upd==null, lookupAgent={1}, agentid={2}", LogHeader, lookupAgent, toAgentID);
                HandleUndeliveredMessage(im, result);
            }
        }
Ejemplo n.º 25
0
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, GridRegion prevRegion)
        {
            UUID   toAgentID = new UUID(im.toAgentID);
            string HTTPPath  = "";

            Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);

            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, msgdata))
                {
                    //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
                    result(true);
                    return;
                }
            }

            //Now query the grid server for the agent

            //Ask for the user new style first
            string[] AgentLocations = m_Scenes[0].RequestModuleInterface <IAgentInfoService>().GetAgentsLocations(new string[] { toAgentID.ToString() });
            //If this is false, this doesn't exist on the presence server and we use the legacy way
            if (AgentLocations.Length > 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);
                    }
                    m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
                else //Found the agent, use this location
                {
                    HTTPPath = AgentLocations[0];
                }
            }

            //We found the agent's location, now ask them about the user
            if (HTTPPath != "")
            {
                if (!doIMSending(HTTPPath, msgdata))
                {
                    //It failed, stop now
                    lock (IMUsersCache)
                    {
                        //Remove them so we keep testing against the db
                        IMUsersCache.Remove(toAgentID);
                    }
                    m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message as the region could not be found");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
                else
                {
                    //Send the IM, and it made it to the user, return true
                    result(true);
                    return;
                }
            }
            else
            {
                //Couldn't find them, stop for now
                lock (IMUsersCache)
                {
                    //Remove them so we keep testing against the db
                    IMUsersCache.Remove(toAgentID);
                }
                m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message as the region could not be found");
                HandleUndeliveredMessage(im, result);
            }
        }
Ejemplo n.º 26
0
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, ulong prevRegionHandle)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            UserAgentData upd = null;

            bool lookupAgent = false;

            lock (m_UserRegionMap)
            {
                if (m_UserRegionMap.ContainsKey(toAgentID))
                {
                    upd             = new UserAgentData();
                    upd.AgentOnline = true;
                    upd.Handle      = m_UserRegionMap[toAgentID];

                    // We need to compare the current regionhandle with the previous region handle
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (prevRegionHandle == upd.Handle)
                    {
                        lookupAgent = true;
                    }
                }
                else
                {
                    lookupAgent = true;
                }
            }


            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                // Non-cached user agent lookup.
                upd = m_Scenes[0].CommsManager.UserService.GetAgentByUUID(toAgentID);

                if (upd != null)
                {
                    // check if we've tried this before..
                    // This is one way to end the recursive loop
                    //
                    if (upd.Handle == prevRegionHandle)
                    {
                        m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                        HandleUndeliveredMessage(im, result);
                        return;
                    }
                }
                else
                {
                    m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            if (upd != null)
            {
                if (upd.AgentOnline)
                {
                    RegionInfo reginfo = m_Scenes[0].SceneGridService.RequestNeighbouringRegionInfo(upd.Handle);
                    if (reginfo != null)
                    {
                        Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                        // Not actually used anymore, left in for compatibility
                        // Remove at next interface change
                        //
                        msgdata["region_handle"] = 0;
                        bool imresult = doIMSending(reginfo, msgdata);
                        if (imresult)
                        {
                            // IM delivery successful, so store the Agent's location in our local cache.
                            lock (m_UserRegionMap)
                            {
                                if (m_UserRegionMap.ContainsKey(toAgentID))
                                {
                                    m_UserRegionMap[toAgentID] = upd.Handle;
                                }
                                else
                                {
                                    m_UserRegionMap.Add(toAgentID, upd.Handle);
                                }
                            }
                            result(true);
                        }
                        else
                        {
                            // try again, but lookup user this time.
                            // Warning, this must call the Async version
                            // of this method or we'll be making thousands of threads
                            // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                            // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                            // This is recursive!!!!!
                            SendGridInstantMessageViaXMLRPCAsync(im, result,
                                                                 upd.Handle);
                        }
                    }
                    else
                    {
                        m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.Handle);
                        HandleUndeliveredMessage(im, result);
                    }
                }
                else
                {
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find user {0}", toAgentID);
                HandleUndeliveredMessage(im, result);
            }
        }
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, ulong prevRegionHandle)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            UserAgentData  upd = null;

            bool lookupAgent = false;

            lock (m_UserRegionMap)
            {
                if (m_UserRegionMap.ContainsKey(toAgentID))
                {
                    upd = new UserAgentData();
                    upd.AgentOnline = true;
                    upd.Handle = m_UserRegionMap[toAgentID];

                    // We need to compare the current regionhandle with the previous region handle
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (prevRegionHandle == upd.Handle)
                    {
                        lookupAgent = true;
                    }
                }
                else
                {
                    lookupAgent = true;
                }
            }
            

            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                // Non-cached user agent lookup.
                upd = m_Scenes[0].CommsManager.UserService.GetAgentByUUID(toAgentID);

                if (upd != null)
                {
                    // check if we've tried this before..
                    // This is one way to end the recursive loop
                    //
                    if (upd.Handle == prevRegionHandle)
                    {
                        m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                        HandleUndeliveredMessage(im, result);
                        return;
                    }
                }
                else
                {
                    m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            if (upd != null)
            {
                if (upd.AgentOnline)
                {
                    RegionInfo reginfo = m_Scenes[0].SceneGridService.RequestNeighbouringRegionInfo(upd.Handle);
                    if (reginfo != null)
                    {
                        Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                        // Not actually used anymore, left in for compatibility
                        // Remove at next interface change
                        //
                        msgdata["region_handle"] = 0;
                        bool imresult = doIMSending(reginfo, msgdata);
                        if (imresult)
                        {
                            // IM delivery successful, so store the Agent's location in our local cache.
                            lock (m_UserRegionMap)
                            {
                                if (m_UserRegionMap.ContainsKey(toAgentID))
                                {
                                    m_UserRegionMap[toAgentID] = upd.Handle;
                                }
                                else
                                {
                                    m_UserRegionMap.Add(toAgentID, upd.Handle);
                                }
                            }
                            result(true);
                        }
                        else
                        {
                            // try again, but lookup user this time.
                            // Warning, this must call the Async version
                            // of this method or we'll be making thousands of threads
                            // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                            // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                            // This is recursive!!!!!
                            SendGridInstantMessageViaXMLRPCAsync(im, result,
                                    upd.Handle);
                        }
                    }
                    else
                    {
                        m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.Handle);
                        HandleUndeliveredMessage(im, result);
                    }
                }
                else
                {
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find user {0}", toAgentID);
                HandleUndeliveredMessage(im, result);
            }
        }
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID fromAgentID = new UUID(im.fromAgentID);
            UUID toAgentID   = new UUID(im.toAgentID);

            foreach (Scene scene in m_Scenes)
            {
                if (!scene.EventManager.TriggerOnBeforeSendInstantMessage(im))
                {
                    m_log.WarnFormat("[INSTANT MESSAGE]: Outbound IM blocked by module");
                    return;
                }

                // Check for muted senders in specific IM cases.
                if (m_muteListModule == null)
                {
                    m_muteListModule = scene.RequestModuleInterface <IMuteListModule>();
                }
                if (m_muteListModule != null)
                {
                    if ((im.dialog == (int)InstantMessageDialog.MessageFromAgent) || (im.dialog == (int)InstantMessageDialog.MessageFromObject))
                    {
                        if (m_muteListModule.IsMuted(fromAgentID, toAgentID)) // owner ID is in fromAgentID in case of IMs from objects
                        {
                            return;                                           // recipient has sender muted.
                        }
                    }
                }
            }

            //m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString());

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
                if (scene.Entities.ContainsKey(toAgentID) &&
                    scene.Entities[toAgentID] is ScenePresence)
                {
                    //m_log.DebugFormat("[INSTANT MESSAGE]: Looking for {0} in {1}", toAgentID.ToString(), scene.RegionInfo.RegionName);
                    // Local message
                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];
                    if (!user.IsChildAgent)
                    {
                        //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
                        user.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        return;
                    }
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                if (scene.Entities.ContainsKey(toAgentID) &&
                    scene.Entities[toAgentID] is ScenePresence)
                {
                    // Local message
                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];

                    //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
                    user.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            if (m_Gridmode)
            {
                //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering via grid");
                // Still here, try send via Grid
                SendGridInstantMessageViaXMLRPC(im, result);
                return;
            }

            HandleUndeliveredMessage(im, result);

            return;
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Internal SendGridInstantMessage over XMLRPC method.
        /// </summary>
        /// <remarks>
        /// This is called from within a dedicated thread.
        /// </remarks>
        private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);
            UUID regionID;
            bool needToLookupAgent;

            lock (m_UserRegionMap)
                needToLookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID);

            while (true)
            {
                if (needToLookupAgent)
                {
                    PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });

                    UUID foundRegionID = UUID.Zero;

                    if (presences != null)
                    {
                        foreach (PresenceInfo p in presences)
                        {
                            if (p.RegionID != UUID.Zero)
                            {
                                foundRegionID = p.RegionID;
                                break;
                            }
                        }
                    }

                    // If not found or the found region is the same as the last lookup, then message is undeliverable
                    if (foundRegionID == UUID.Zero || foundRegionID == regionID)
                    {
                        break;
                    }
                    else
                    {
                        regionID = foundRegionID;
                    }
                }

                GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
                if (reginfo == null)
                {
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID);
                    break;
                }

                // Try to send the message to the agent via the retrieved region.
                Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                msgdata["region_handle"] = 0;
                bool imresult = doIMSending(reginfo, msgdata);

                // If the message delivery was successful, then cache the entry.
                if (imresult)
                {
                    lock (m_UserRegionMap)
                    {
                        m_UserRegionMap[toAgentID] = regionID;
                    }
                    result(true);
                    return;
                }

                // If we reach this point in the first iteration of the while, then we may have unsuccessfully tried
                // to use a locally cached region ID.  All subsequent attempts need to lookup agent details from
                // the presence service.
                needToLookupAgent = true;
            }

            // If we reached this point then the message was not deliverable.  Remove the bad cache entry and
            // signal the delivery failure.
            lock (m_UserRegionMap)
                m_UserRegionMap.Remove(toAgentID);

            // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
            HandleUndeliverableMessage(im, result);
        }
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            if (toAgentID == UUID.Zero)
                return;

            IClientAPI client = null;

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
                ScenePresence sp = scene.GetScenePresence(toAgentID);
                if (sp != null && !sp.IsDeleted && sp.ControllingClient.IsActive)
                {
                    // actualy don't send via child agents
                    // ims can be complex things, and not sure viewers will not mess up
                    if(sp.IsChildAgent)
                        continue;

                    client = sp.ControllingClient;
                    if(!sp.IsChildAgent)
                        break;
                }
            }

            if(client != null)
            {
                // Local message
//                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);

                client.SendInstantMessage(im);

                    // Message sent
                result(true);
                return;
            }
//            m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);

            SendGridInstantMessageViaXMLRPC(im, result);
        }
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            try
            {
                // Try root avatar only first
                m_Scenes.ForEach(delegate(Scene scene)
                {
                    //                m_log.DebugFormat(
                    //                    "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
                    //                    toAgentID.ToString(), scene.RegionInfo.RegionName);

                    ScenePresence sp = scene.GetScenePresence(toAgentID);
                    if (sp != null && !sp.IsChildAgent)
                    {
                        // Local message
                        //                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", sp.Name, toAgentID);

                        sp.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        throw new ThreadedClasses.ReturnValueException<bool>(true);
                    }
                });

                // try child avatar second
                m_Scenes.ForEach(delegate(Scene scene)
                {
                    //                m_log.DebugFormat(
                    //                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                    ScenePresence sp = scene.GetScenePresence(toAgentID);
                    if (sp != null)
                    {
                        // Local message
                        //                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", sp.Name, toAgentID);

                        sp.ControllingClient.SendInstantMessage(im);

                        // Message sent
                        result(true);
                        throw new ThreadedClasses.ReturnValueException<bool>(true);
                    }
                });
            }
            catch(ThreadedClasses.ReturnValueException<bool>)
            {
                return;
            }

//            m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);

            SendGridInstantMessageViaXMLRPC(im, result);
        }
 private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
 {
     lock (pendingInstantMessages) {
         if (numInstantMessageThreads >= 4) {
             GIM gim = new GIM();
             gim.im = im;
             gim.result = result;
             pendingInstantMessages.Enqueue(gim);
         } else {
             ++ numInstantMessageThreads;
             //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
             GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
             d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
         }
     }
 }
Ejemplo n.º 33
0
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = im.toAgentID;

            // Try root avatar only first - incorrect now, see below
            foreach (Scene scene in m_Scenes)
            {
                IScenePresence user;
                if (scene.TryGetScenePresence (toAgentID, out user))
                {
                    user.ControllingClient.SendInstantMessage (im);
                    return;
                }
            }
            //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
            SendGridInstantMessageViaXMLRPC(im, result);
        }
        /// <summary>
        /// Internal SendGridInstantMessage over XMLRPC method.
        /// </summary>

        /// <param name="prevRegionHandle">
        /// Pass in 0 the first time this method is called.  It will be called recursively with the last 
        /// regionhandle tried
        /// </param>
        private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
        {
            GIM gim;
            do {
                try {
                    SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
                } catch (Exception e) {
                    m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
                }
                lock (pendingInstantMessages) {
                    if (pendingInstantMessages.Count > 0) {
                        gim = pendingInstantMessages.Dequeue();
                        im = gim.im;
                        result = gim.result;
                    } else {
                        gim = null;
                        -- numInstantMessageThreads;
                        //m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
                    }
                }
            } while (gim != null);
        }
Ejemplo n.º 35
0
        public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}",
//                    toAgentID.ToString(), scene.RegionInfo.RegionName);
                ScenePresence sp = scene.GetScenePresence(toAgentID);
                if (sp != null && !sp.IsChildAgent)
                {
                    // Local message
//                  m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
                    sp.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}",
//                    toAgentID, scene.RegionInfo.RegionName);
                ScenePresence sp = scene.GetScenePresence(toAgentID);
                if (sp != null)
                {
                    // Local message
//                    m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
                    sp.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

//            m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
            // Is the user a local user?
            string url       = string.Empty;
            bool   foreigner = false;

            if (UserManagementModule != null && !UserManagementModule.IsLocalGridUser(toAgentID)) // foreign user
            {
                url       = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
                foreigner = true;
            }

            Util.FireAndForget(delegate
            {
                bool success = false;
                if (foreigner && url == string.Empty) // we don't know about this user
                {
                    string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
                    m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
                    if (recipientUUI != string.Empty)
                    {
                        UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
                        if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
                        {
                            success = m_IMService.OutgoingInstantMessage(im, u, true);
                            if (success)
                            {
                                UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
                            }
                        }
                    }
                }
                else
                {
                    success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
                }

                if (!success && !foreigner)
                {
                    HandleUndeliveredMessage(im, result);
                }
                else
                {
                    result(success);
                }
            });

            return;
        }
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, UUID prevRegionID)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            PresenceInfo upd = null;

            bool lookupAgent = false;

            lock (m_UserRegionMap)
            {
                if (m_UserRegionMap.ContainsKey(toAgentID))
                {
                    upd = new PresenceInfo();
                    upd.RegionID = m_UserRegionMap[toAgentID];

                    // We need to compare the current regionhandle with the previous region handle
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (prevRegionID == upd.RegionID)
                    {
                        m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: agentInRegionMap. prevRegion==upd.Region settingLookupAgentTrue, agentID={1}, regionID={2}",
                                                    LogHeader, toAgentID, prevRegionID);
                        lookupAgent = true;
                    }
                }
                else
                {
                    m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: agentNOTInRegionMap. setting LookupAgentTrue", LogHeader);
                    lookupAgent = true;
                }
            }

            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: lookupAgent IS TRUE", LogHeader);
                // Non-cached user agent lookup.
                PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
                if (presences != null && presences.Length > 0)
                {
                    foreach (PresenceInfo p in presences)
                    {
                        m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: got presences. p.RegionID={1}", LogHeader, p.RegionID);
                        // Sometimes we get more than 1 session querying a single agent ID! Filter for the correct agent ID.
                        if (p.UserID == toAgentID.ToString() && p.RegionID != UUID.Zero)
                        {
                            upd = p;
                            break;
                        }
                    }
                }

                if (upd != null)
                {
                    // check if we've tried this before..
                    // This is one way to end the recursive loop
                    //
                    if (upd.RegionID == prevRegionID)
                    {
                        // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                        m_log.DebugFormat("{0} Unable to deliver instant message: regionID==prevRegionID: regionID={1}, agentID={2}", LogHeader, prevRegionID, toAgentID);
                        HandleUndeliveredMessage(im, result);
                        return;
                    }
                }
                else
                {
                    // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    m_log.DebugFormat("{0} Unable to deliver instant message: lookupAgent=true, upd==null, agentID={1}", LogHeader, toAgentID);
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            if (upd != null)
            {
                GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, upd.RegionID);
                if (reginfo != null)
                {
                    m_log.DebugFormat("{0} SendGridInstMsgViaXMLRPCAsync: regInfoNotNull, regID={1}, regNam={2}, regURI={3}, regPort={4}",
                        LogHeader, reginfo.RegionID, reginfo.RegionName, reginfo.ServerURI, reginfo.HttpPort);
                    Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                    // Not actually used anymore, left in for compatibility
                    // Remove at next interface change
                    //
                    msgdata["region_handle"] = 0;
                    bool imresult = doIMSending(reginfo, msgdata);
                    if (imresult)
                    {
                        // IM delivery successful, so store the Agent's location in our local cache.
                        lock (m_UserRegionMap)
                        {
                            if (m_UserRegionMap.ContainsKey(toAgentID))
                            {
                                m_log.DebugFormat("{0} SendGridInstMgsViaXMLRPCAsync: Updating RegionMap: agent={1}, reg={2}", LogHeader, toAgentID, upd.RegionID);
                                m_UserRegionMap[toAgentID] = upd.RegionID;
                            }
                            else
                            {
                                m_log.DebugFormat("{0} SendGridInstMgsViaXMLRPCAsync: Add RegionMap: agent={1}, reg={2}", LogHeader, toAgentID, upd.RegionID);
                                m_UserRegionMap.Add(toAgentID, upd.RegionID);
                            }
                        }
                        result(true);
                    }
                    else
                    {
                        // try again, but lookup user this time.
                        // Warning, this must call the Async version
                        // of this method or we'll be making thousands of threads
                        // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                        // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                        // This is recursive!!!!!
                        m_log.DebugFormat("{0} SendGridInstMgsViaXMLRPCAsync: Calling me recursively. region={1}", LogHeader, upd.RegionID);
                        SendGridInstantMessageViaXMLRPCAsync(im, result, upd.RegionID);
                    }
                }
                else
                {
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
                    m_log.DebugFormat("{0} Unable to deliver instant message: regionInfo==null, lookupAgent={1}, agentid={2}, region={3}", LogHeader, lookupAgent, toAgentID, upd.RegionID);
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                m_log.DebugFormat("{0} Unable to deliver instant message: upd==null, lookupAgent={1}, agentid={2}", LogHeader, lookupAgent, toAgentID);
                HandleUndeliveredMessage(im, result);
            }
        }
Ejemplo n.º 37
0
        private void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
        {
            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);
                if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
                    result(true);
                else
                    result(false);
                return;
            }

            //m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
            result(false);
        }
Ejemplo n.º 38
0
        public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            // Try root avatar only first - incorrect now, see below
            foreach (Scene scene in m_Scenes)
            {
                if (scene.Entities.ContainsKey(toAgentID) &&
                        scene.Entities[toAgentID] is ScenePresence)
                {
                    // Local message
                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];
                    user.ControllingClient.SendInstantMessage(im);
                    return;
                }
            }
            //Note: Why??? This is completely unnesessary!
            /*// try child avatar second
            foreach (Scene scene in m_Scenes)
            {
                //                m_log.DebugFormat(
                //                    "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);

                if (scene.Entities.ContainsKey(toAgentID) &&
                        scene.Entities[toAgentID] is ScenePresence)
                {
                    // Local message
                    ScenePresence user = (ScenePresence)scene.Entities[toAgentID];

                    m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
                    user.ControllingClient.SendInstantMessage(im);

                    return;
                }
            }*/

            //m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
            SendGridInstantMessageViaXMLRPC(im, result);
        }
Ejemplo n.º 39
0
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, UUID prevRegionID)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            PresenceInfo upd = null;

            bool lookupAgent = false;

            lock (m_UserRegionMap)
            {
                if (m_UserRegionMap.ContainsKey(toAgentID))
                {
                    upd = new PresenceInfo();
                    upd.RegionID = m_UserRegionMap[toAgentID];

                    // We need to compare the current regionhandle with the previous region handle
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (prevRegionID == upd.RegionID)
                    {
                        lookupAgent = true;
                    }
                }
                else
                {
                    lookupAgent = true;
                }
            }
            

            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                // Non-cached user agent lookup.
                PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); 
                if (presences != null && presences.Length > 0)
                {
                    foreach (PresenceInfo p in presences)
                    {
                        if (p.RegionID != UUID.Zero)
                        {
                            upd = p;
                            break;
                        }
                    }
                }

                if (upd != null)
                {
                    // check if we've tried this before..
                    // This is one way to end the recursive loop
                    //
                    if (upd.RegionID == prevRegionID)
                    {
                        // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                        HandleUndeliveredMessage(im, result);
                        return;
                    }
                }
                else
                {
                    // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            if (upd != null)
            {
                GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
                    upd.RegionID);
                if (reginfo != null)
                {
                    Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                    // Not actually used anymore, left in for compatibility
                    // Remove at next interface change
                    //
                    msgdata["region_handle"] = 0;
                    bool imresult = doIMSending(reginfo, msgdata);
                    if (imresult)
                    {
                        // IM delivery successful, so store the Agent's location in our local cache.
                        lock (m_UserRegionMap)
                        {
                            if (m_UserRegionMap.ContainsKey(toAgentID))
                            {
                                m_UserRegionMap[toAgentID] = upd.RegionID;
                            }
                            else
                            {
                                m_UserRegionMap.Add(toAgentID, upd.RegionID);
                            }
                        }
                        result(true);
                    }
                    else
                    {
                        // try again, but lookup user this time.
                        // Warning, this must call the Async version
                        // of this method or we'll be making thousands of threads
                        // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                        // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                        // This is recursive!!!!!
                        SendGridInstantMessageViaXMLRPCAsync(im, result,
                                upd.RegionID);
                    }
                }
                else
                {
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                HandleUndeliveredMessage(im, result);
            }
        }
Ejemplo n.º 40
0
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, GridRegion prevRegion)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            PresenceInfo upd = null;
            GridRegion cachedRegion = null;

            bool lookupAgent = false;

            lock (m_UserRegionMap)
            {
                if (m_UserRegionMap.ContainsKey(toAgentID))
                {
                    //They have been IMed before, look up in the cache
                    upd = new PresenceInfo();
                    upd.RegionID = m_UserRegionMap[toAgentID].Region.RegionID;
                    cachedRegion = m_UserRegionMap[toAgentID].Region;
                    // We need to compare the current regionhandle with the previous region handle
                    // or the recursive loop will never end because it will never try to lookup the agent again
                    if (prevRegion != null && prevRegion.RegionID == upd.RegionID)
                    {
                        //If prevRegion is the same as the cache, look them up, someone moved
                        lookupAgent = true;
                    }
                }
                else
                {
                    //Havn't IMed this person before, get their presence info
                    lookupAgent = true;
                }
            }
            

            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                //Find the regions http address where the agent is
                string[] AgentLocations = PresenceService.GetAgentsLocations(new string[] { toAgentID.ToString() });

                if (AgentLocations == null || (AgentLocations.Length == 1 && AgentLocations[0] == "Failure")) //If this is true, this doesn't exist on the presence server and we use the legacy way
                {
                    // Non-cached user agent lookup.
                    PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
                    if (presences != null && presences.Length > 0)
                        upd = presences[0];

                    if (upd != null)
                    {
                        // check if we've tried this region before..
                        // This is one way to end the recursive loop
                        if ((upd.RegionID == UUID.Zero) || (prevRegion != null && upd.RegionID == prevRegion.RegionID))
                        {
                            m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                            HandleUndeliveredMessage(im, result);
                            return;
                        }
                    }
                }
                else
                {
                    Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);

                    bool imresult = doIMSending("http://" + cachedRegion.ExternalHostName + ":" + cachedRegion.HttpPort, msgdata);
                    if (imresult)
                    {
                        // IM delivery successful, so store the Agent's location in our local cache.
                        lock (m_UserRegionMap)
                        {
                            m_UserRegionMap[toAgentID] = new IMPresenceInfo();
                            m_UserRegionMap[toAgentID].HTTPPath = "http://" + cachedRegion.ExternalHostName + ":" + cachedRegion.HttpPort;
                        }
                        result(true);
                        return;
                    }
                    else
                    {
                        // This happens when the agent moves out of the last known region

                        // try again, but lookup user this time.
                        // Warning, this must call the Async version
                        // of this method or we'll be making thousands of threads
                        // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                        // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                        // This is recursive!!!!!
                        SendGridInstantMessageViaXMLRPCAsync(im, result,
                                cachedRegion);
                    }
                    return; //If this isn't here, infinite loop occurs
                }
            }

            if (upd != null)
            {
                if(cachedRegion == null)
                    cachedRegion = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
                        upd.RegionID);

                if (cachedRegion != null)
                {
                    Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);

                    bool imresult = doIMSending("http://" + cachedRegion.ExternalHostName + ":" + cachedRegion.HttpPort, msgdata);
                    if (imresult)
                    {
                        // IM delivery successful, so store the Agent's location in our local cache.
                        lock (m_UserRegionMap)
                        {
                            m_UserRegionMap[toAgentID] = new IMPresenceInfo();
                            m_UserRegionMap[toAgentID].Region = cachedRegion;
                            m_UserRegionMap[toAgentID].HTTPPath = "http://" + cachedRegion.ExternalHostName + ":" + cachedRegion.HttpPort;
                        }
                        result(true);
                    }
                    else
                    {
                        // This happens when the agent moves out of the last known region

                        // try again, but lookup user this time.
                        // Warning, this must call the Async version
                        // of this method or we'll be making thousands of threads
                        // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                        // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                        // This is recursive!!!!!
                        SendGridInstantMessageViaXMLRPCAsync(im, result,
                                cachedRegion);
                    }
                }
                else
                {
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                HandleUndeliveredMessage(im, result);
            }
        }
        public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);

            // Try root avatar only first
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}", 
//                    toAgentID.ToString(), scene.RegionInfo.RegionName);
                ScenePresence sp = scene.GetScenePresence(toAgentID); 
                if (sp != null && !sp.IsChildAgent)
                {                                        
                    // Local message
//                  m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
                    sp.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

            // try child avatar second
            foreach (Scene scene in m_Scenes)
            {
//                m_log.DebugFormat(
//                    "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}", 
//                    toAgentID, scene.RegionInfo.RegionName);
                ScenePresence sp = scene.GetScenePresence(toAgentID); 
                if (sp != null)
                {                   
                    // Local message
//                    m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
                    sp.ControllingClient.SendInstantMessage(im);

                    // Message sent
                    result(true);
                    return;
                }
            }

//            m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
            // Is the user a local user?
            string url = string.Empty;
            bool foreigner = false;
            if (UserManagementModule != null && !UserManagementModule.IsLocalGridUser(toAgentID)) // foreign user
            {
                url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
                foreigner = true;
            }

            Util.FireAndForget(delegate
            {
                bool success = false;
                if (foreigner && url == string.Empty) // we don't know about this user
                {
                    string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
                    m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
                    if (recipientUUI != string.Empty)
                    {
                        UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
                        if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
                        {
                            success = m_IMService.OutgoingInstantMessage(im, u, true);
                            if (success)
                                UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
                        }
                    }
                }
                else
                    success = m_IMService.OutgoingInstantMessage(im, url, foreigner);

                if (!success && !foreigner)
                    HandleUndeliveredMessage(im, result);
                else
                    result(success);
            });

            return;
        }
Ejemplo n.º 42
0
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, GridRegion prevRegion)
        {
            UUID toAgentID = new UUID(im.toAgentID);
            string HTTPPath = "";

            Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);

            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, msgdata))
                {
                    //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
                    result(true);
                    return;
                }
            }

            //Now query the grid server for the agent

            //Ask for the user new style first
            string[] AgentLocations = PresenceService.GetAgentsLocations(new string[] { toAgentID.ToString() });
            //If this is false, this doesn't exist on the presence server and we use the legacy way
            if (AgentLocations != null && (AgentLocations.Length != 0 && AgentLocations[0] != "Failure")) 
            {
                //No agents, so this user is offline
                if (AgentLocations[0] == "NoAgents")
                {
                    lock (IMUsersCache)
                    {
                        //Remove them so we keep testing against the db
                        IMUsersCache.Remove(toAgentID);
                    }
                    m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
                else //Found the agent, use this location
                    HTTPPath = AgentLocations[0];
            }
            else
            {
                //Query the legacy way
                PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
                if (presences != null && presences.Length > 0)
                {
                    Services.Interfaces.GridRegion r = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
                        presences[0].RegionID);
                    if (r != null)
                    {
                        HTTPPath = "http://" + r.ExternalHostName + ":" + r.HttpPort;
                    }
                    else
                    {
                        //Can't find their region, so stop here
                        lock (IMUsersCache)
                        {
                            //Remove them so we keep testing against the db
                            IMUsersCache.Remove(toAgentID);
                        }
                        m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                        result(false);
                        return;
                    }
                }
                else
                {
                    //The user is offline
                    lock (IMUsersCache)
                    {
                        //Remove them so we keep testing against the db
                        IMUsersCache.Remove(toAgentID);
                    }
                    m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            //We found the agent's location, now ask them about the user
            if (HTTPPath != "")
            {
                if (!doIMSending(HTTPPath, msgdata))
                {
                    //It failed, stop now
                    lock (IMUsersCache)
                    {
                        //Remove them so we keep testing against the db
                        IMUsersCache.Remove(toAgentID);
                    }
                    m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message as the region could not be found");
                    result(false);
                    return;
                }
                else
                {
                    //Send the IM, and it made it to the user, return true
                    result(true);
                    return;
                }
            }
            else
            {
                //Couldn't find them, stop for now
                lock (IMUsersCache)
                {
                    //Remove them so we keep testing against the db
                    IMUsersCache.Remove(toAgentID);
                }
                m_log.Info("[GRID INSTANT MESSAGE]: Unable to deliver an instant message as the region could not be found");
                result(false);
            }
        }
        /// <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="prevRegionHandle">
        /// 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, MessageResultNotification result, UUID prevRegionID)
        {
            uint restartloopcount = 100;

restart:
            UUID toAgentID = new UUID(im.toAgentID);

            PresenceInfo upd = null;
            UUID         _regionID;

            bool lookupAgent = false;

            if (m_UserRegionMap.TryGetValue(toAgentID, out _regionID))
            {
                upd          = new PresenceInfo();
                upd.RegionID = _regionID;

                // We need to compare the current regionhandle with the previous region handle
                // or the recursive loop will never end because it will never try to lookup the agent again
                if (prevRegionID == upd.RegionID)
                {
                    lookupAgent = true;
                }
            }
            else
            {
                lookupAgent = true;
            }


            // Are we needing to look-up an agent?
            if (lookupAgent)
            {
                // Non-cached user agent lookup.
                PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
                if (presences != null && presences.Length > 0)
                {
                    foreach (PresenceInfo p in presences)
                    {
                        if (p.RegionID != UUID.Zero)
                        {
                            upd = p;
                            break;
                        }
                    }
                }

                if (upd != null)
                {
                    // check if we've tried this before..
                    // This is one way to end the recursive loop
                    //
                    if (upd.RegionID == prevRegionID)
                    {
                        // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                        HandleUndeliveredMessage(im, result);
                        return;
                    }
                }
                else
                {
                    // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
                    HandleUndeliveredMessage(im, result);
                    return;
                }
            }

            if (upd != null)
            {
                GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
                                                                             upd.RegionID);
                if (reginfo != null)
                {
                    Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                    // Not actually used anymore, left in for compatibility
                    // Remove at next interface change
                    //
                    msgdata["region_handle"] = 0;
                    bool imresult = doIMSending(reginfo, msgdata);
                    if (imresult)
                    {
                        // IM delivery successful, so store the Agent's location in our local cache.
                        m_UserRegionMap[toAgentID] = upd.RegionID;
                        result(true);
                    }
                    else
                    {
                        // try again, but lookup user this time.
                        // Warning, this must call the Async version
                        // of this method or we'll be making thousands of threads
                        // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
                        // The version that spawns the thread is SendGridInstantMessageViaXMLRPC

                        // This may end up in an endless loop. However, that is still nicer than the endless recursion that was previously possible.
                        prevRegionID = upd.RegionID;
                        if (restartloopcount-- == 0)
                        {
                            m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to locate user after several tries (loop count exceeded)");
                            HandleUndeliveredMessage(im, result);
                        }
                        goto restart;
                    }
                }
                else
                {
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
                    HandleUndeliveredMessage(im, result);
                }
            }
            else
            {
                HandleUndeliveredMessage(im, result);
            }
        }
Ejemplo n.º 44
0
        /// <summary>
        /// Internal SendGridInstantMessage over XMLRPC method.
        /// </summary>
        /// <remarks>
        /// This is called from within a dedicated thread.
        /// </remarks>
        private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result)
        {
            UUID toAgentID = new UUID(im.toAgentID);
            UUID regionID;
            bool needToLookupAgent;

            lock (m_UserRegionMap)
                needToLookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID);

            while (true)
            {
                if (needToLookupAgent)
                {
                    PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); 

                    UUID foundRegionID = UUID.Zero;

                    if (presences != null)
                    {
                        foreach (PresenceInfo p in presences)
                        {
                            if (p.RegionID != UUID.Zero)
                            {
                                foundRegionID = p.RegionID;
                                break;
                            }
                        }
                    }

                    // If not found or the found region is the same as the last lookup, then message is undeliverable
                    if (foundRegionID == UUID.Zero || foundRegionID == regionID)
                        break;
                    else
                        regionID = foundRegionID;
                }

                GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
                if (reginfo == null)
                {
                    m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID);
                    break;
                }

                // Try to send the message to the agent via the retrieved region.
                Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im);
                msgdata["region_handle"] = 0;
                bool imresult = doIMSending(reginfo, msgdata);

                // If the message delivery was successful, then cache the entry.
                if (imresult)
                {
                    lock (m_UserRegionMap)
                    {
                        m_UserRegionMap[toAgentID] = regionID;
                    }
                    result(true);
                    return;
                }

                // If we reach this point in the first iteration of the while, then we may have unsuccessfully tried
                // to use a locally cached region ID.  All subsequent attempts need to lookup agent details from
                // the presence service.
                needToLookupAgent = true;
            }

            // If we reached this point then the message was not deliverable.  Remove the bad cache entry and 
            // signal the delivery failure.
            lock (m_UserRegionMap)
                m_UserRegionMap.Remove(toAgentID);

            // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
            HandleUndeliverableMessage(im, result);
        }