From 404bfdc9a6828638b7b4f7851602e3fe77044025 Mon Sep 17 00:00:00 2001
From: Melanie Thielker
Date: Sun, 29 Mar 2009 00:48:34 +0000
Subject: Finish the offline IM module (still needs a server). Add rudimentary
 support for the mute list (no functionality yet, but allows the
 RetrieveInstantMessages event to fire now).

---
 OpenSim/Client/MXP/ClientStack/MXPClientView.cs    |   4 +
 OpenSim/Framework/IClientAPI.cs                    |   1 +
 .../Region/ClientStack/LindenUDP/LLClientView.cs   |  11 ++
 .../Avatar/InstantMessage/MuteListModule.cs        | 138 +++++++++++++++++++++
 .../Avatar/InstantMessage/OfflineMessageModule.cs  |  69 +++++++++--
 .../Region/Examples/SimpleModule/MyNpcCharacter.cs |   4 +
 .../Region/OptionalModules/World/NPC/NPCAvatar.cs  |   4 +
 OpenSim/Tests/Common/Mock/TestClient.cs            |   4 +
 bin/OpenSim.ini.example                            |   2 +
 9 files changed, 229 insertions(+), 8 deletions(-)
 create mode 100644 OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs

diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index 548c657..f3eb2b6 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -1601,5 +1601,9 @@ namespace OpenSim.Client.MXP.ClientStack
         public void SendUseCachedMuteList()
         {
         }
+
+        public void SendMuteListUpdate(string filename)
+        {
+        }
     }
 }
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 6d9ed79..bef1bfc 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -1133,6 +1133,7 @@ namespace OpenSim.Framework
         void SendUserInfoReply(bool imViaEmail, bool visible, string email);
         
         void SendUseCachedMuteList();
+        void SendMuteListUpdate(string filename);
 
         void KillEndDone();
 
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index b65b3f9..7d9efa6 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -8700,6 +8700,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             OutPacket(useCachedMuteList, ThrottleOutPacketType.Task);
         }
 
+        public void SendMuteListUpdate(string filename)
+        {
+            MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate);
+
+            muteListUpdate.MuteData = new MuteListUpdatePacket.MuteDataBlock();
+            muteListUpdate.MuteData.AgentID = AgentId;
+            muteListUpdate.MuteData.Filename = Utils.StringToBytes(filename);
+
+            OutPacket(muteListUpdate, ThrottleOutPacketType.Task);
+        }
+
         public string Report()
         {
             LLPacketHandler handler = (LLPacketHandler) m_PacketHandler;
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs
new file mode 100644
index 0000000..41441b3
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the OpenSim Project nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using log4net;
+using Nini.Config;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Servers;
+using OpenSim.Framework.Client;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Region.CoreModules.Avatar.MuteList
+{
+    public class MuteListModule : IRegionModule
+    {
+        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        private bool enabled = true;
+        private List<Scene> m_SceneList = new List<Scene>();
+        private string m_RestURL = String.Empty;
+
+        public void Initialise(Scene scene, IConfigSource config)
+        {
+            if (!enabled)
+                return;
+
+            IConfig cnf = config.Configs["Messaging"];
+            if (cnf != null && cnf.GetString(
+                    "MuteListModule", "None") !=
+                    "MuteListModule")
+            {
+                enabled = false;
+                return;
+            }
+
+            lock (m_SceneList)
+            {
+                if (m_SceneList.Count == 0)
+                {
+                    m_RestURL = cnf.GetString("MuteListURL", "");
+                    if (m_RestURL == "")
+                    {
+                        m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling");
+                        enabled = false;
+                        return;
+                    }
+                }
+                if (!m_SceneList.Contains(scene))
+                    m_SceneList.Add(scene);
+
+                scene.EventManager.OnNewClient += OnNewClient;
+            }
+        }
+
+        public void PostInitialise()
+        {
+            if (!enabled)
+                return;
+
+            if (m_SceneList.Count == 0)
+                return;
+
+            m_log.Debug("[MUTE LIST] Mute list enabled");
+        }
+
+        public string Name
+        {
+            get { return "MuteListModule"; }
+        }
+
+        public bool IsSharedModule
+        {
+            get { return true; }
+        }
+        
+        public void Close()
+        {
+        }
+
+        private IClientAPI FindClient(UUID agentID)
+        {
+            foreach (Scene s in m_SceneList)
+            {
+                ScenePresence presence = s.GetScenePresence(agentID);
+                if (presence != null && !presence.IsChildAgent)
+                    return presence.ControllingClient;
+            }
+            return null;
+        }
+
+        private void OnNewClient(IClientAPI client)
+        {
+            client.OnMuteListRequest += OnMuteListRequest;
+        }
+
+        private void OnMuteListRequest(IClientAPI client, uint crc)
+        {
+            m_log.DebugFormat("[MUTE LIST] Got mute list requestg for crc {0}", crc);
+            string filename = "mutes"+client.AgentId.ToString();
+
+            IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
+            if (xfer != null)
+            {
+                xfer.AddNewFile(filename, new Byte[0]);
+                client.SendMuteListUpdate(filename);
+            }
+        }
+    }
+}
+
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index 77bc9d7..814b2de 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -24,12 +24,15 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+using System;
 using System.Collections.Generic;
 using System.Reflection;
 using log4net;
 using Nini.Config;
 using OpenMetaverse;
 using OpenSim.Framework;
+using OpenSim.Framework.Communications;
+using OpenSim.Framework.Servers;
 using OpenSim.Framework.Client;
 using OpenSim.Region.Framework.Interfaces;
 using OpenSim.Region.Framework.Scenes;
@@ -40,21 +43,36 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
-        private bool enabled = false;
+        private bool enabled = true;
         private List<Scene> m_SceneList = new List<Scene>();
+        private string m_RestURL = String.Empty;
 
         public void Initialise(Scene scene, IConfigSource config)
         {
+            if (!enabled)
+                return;
+
             IConfig cnf = config.Configs["Messaging"];
             if (cnf != null && cnf.GetString(
                     "OfflineMessageModule", "None") !=
                     "OfflineMessageModule")
+            {
+                enabled = false;
                 return;
-
-            enabled = true;
+            }
 
             lock (m_SceneList)
             {
+                if (m_SceneList.Count == 0)
+                {
+                    m_RestURL = cnf.GetString("OfflineMessageURL", "");
+                    if (m_RestURL == "")
+                    {
+                        m_log.Error("[OFFLINE MESSAGING] Module was enabled, but no URL is given, disabling");
+                        enabled = false;
+                        return;
+                    }
+                }
                 if (!m_SceneList.Contains(scene))
                     m_SceneList.Add(scene);
 
@@ -64,6 +82,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
 
         public void PostInitialise()
         {
+            if (!enabled)
+                return;
+
             if (m_SceneList.Count == 0)
                 return;
 
@@ -80,6 +101,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
                     m_SceneList.Clear();
                 }
 
+                m_log.Error("[OFFLINE MESSAGING] No message transfer module is enabled. Diabling offline messages");
                 return;
             }
 
@@ -107,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
             foreach (Scene s in m_SceneList)
             {
                 ScenePresence presence = s.GetScenePresence(agentID);
-                if (!presence.IsChildAgent)
+                if (presence != null && !presence.IsChildAgent)
                     return presence.ControllingClient;
             }
             return null;
@@ -116,18 +138,49 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
         private void OnNewClient(IClientAPI client)
         {
             client.OnRetrieveInstantMessages += RetrieveInstantMessages;
+            // TODO:: Remove when mute lists are supported
+            //
+            //client.OnEconomyDataRequest += OnEconomyDataRequest;
         }
 
+        // TODO: Remove method when mute lists are supported
+        //
+        //private void OnEconomyDataRequest(UUID agentID)
+        //{
+        //    IClientAPI client = FindClient(agentID);
+        //    if (client == null)
+        //    {
+        //        m_log.ErrorFormat("[OFFLINE MESSAGING] Can't find client {0}", agentID.ToString());
+        //        return;
+        //    }
+        //    RetrieveInstantMessages(client);
+        //}
+
         private void RetrieveInstantMessages(IClientAPI client)
         {
-            m_log.Debug("[OFFLINE MESSAGING] RetrieveInstantMessages called");
+            m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId);
+
+            List<GridInstantMessage>msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
+                    "POST", m_RestURL+"/RetrieveMessages/", client.AgentId);
+
+            foreach (GridInstantMessage im in msglist)
+            {
+                DateTime saved = Util.ToDateTime((uint)im.timestamp);
+
+                client.SendInstantMessage(new UUID(im.toAgentID),
+                        "(saved " + saved.ToString() + ") " + im.message,
+                        new UUID(im.fromAgentID), im.fromAgentName,
+                        (byte)im.dialog,
+                        (uint)im.timestamp);
+            }
         }
 
         private void UndeliveredMessage(GridInstantMessage im)
         {
             if (im.offline != 0)
             {
-                // TODO: Actually save it
+                bool success = SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
+                        "POST", m_RestURL+"/SaveMessage/", im);
 
                 if(im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
                 {
@@ -137,9 +190,9 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
 
                     client.SendInstantMessage(new UUID(im.fromAgentID),
                             "User is not logged in. "+
-                            "Message saved.",
+                            (success ? "Message saved." : "Message not saved"),
                             new UUID(im.toAgentID), "System",
-                            (byte)InstantMessageDialog.BusyAutoResponse,
+                            (byte)InstantMessageDialog.MessageFromAgent,
                             (uint)Util.UnixTimeSinceEpoch());
                 }
             }
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index fa01a42..82d84fa 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -1068,6 +1068,10 @@ namespace OpenSim.Region.Examples.SimpleModule
         {
         }
 
+        public void SendMuteListUpdate(string filename)
+        {
+        }
+
         #endregion
     }
 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 4bf4341..415a24a 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -1068,6 +1068,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
         {
         }
 
+        public void SendMuteListUpdate(string filename)
+        {
+        }
+
         #endregion
     }
 }
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index f96057c..b2c1423 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -1109,5 +1109,9 @@ namespace OpenSim.Tests.Common.Mock
         public void SendUseCachedMuteList()
         {
         }
+
+        public void SendMuteListUpdate(string filename)
+        {
+        }
     }
 }
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 64cf4e5..47a3d3e 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -378,6 +378,8 @@ InterregionComms = "RESTComms"
     ; MessageTransferModule = MessageTransferModule
     ; OfflineMessageModule = OfflineMessageModule
     ; OfflineMessagesURL = http://yourserver/offlines.php
+    ; MuteListModule = MuteListModule
+    ; MuteListsURL = http://yourserver/mutes.php
 
 
 [ODEPhysicsSettings]
-- 
cgit v1.1