From add42f5e9b2d58a4978d4aab4440d5cc2d255a12 Mon Sep 17 00:00:00 2001
From: Dr Scofield
Date: Mon, 3 Nov 2008 17:17:57 +0000
Subject: completing move to refactored multi-channel capable IRCBridgeModule

---
 .../Modules/Avatar/Chat/ChannelState.cs            |  12 +-
 .../Modules/Avatar/Chat/IRCBridgeModule.cs         | 280 +++++++
 .../Modules/Avatar/Chat/IRCConnector.cs            | 843 +++++++++++++++++++++
 .../Modules/Avatar/Chat/XIRCBridgeModule.cs        | 280 -------
 .../Modules/Avatar/Chat/XIRCConnector.cs           | 843 ---------------------
 5 files changed, 1129 insertions(+), 1129 deletions(-)
 create mode 100644 OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs
 create mode 100644 OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs
 delete mode 100644 OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs
 delete mode 100644 OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs

(limited to 'OpenSim/Region/Environment')

diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs
index f9089cb..4fc744b 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChannelState.cs
@@ -97,7 +97,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
 
         // IRC connector reference
 
-        internal XIRCConnector irc           = null;
+        internal IRCConnector irc           = null;
 
         internal int idn                     = _idk_++;
 
@@ -256,7 +256,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
             // values that, while independent of the IRC connetion, do still distinguish 
             // this region's behavior.
 
-            foreach (ChannelState xcs in XIRCBridgeModule.m_channels)
+            foreach (ChannelState xcs in IRCBridgeModule.m_channels)
             {
                 if (cs.IsAPerfectMatchFor(xcs))
                 {
@@ -279,9 +279,9 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
 
                 m_log.DebugFormat("[IRC-Channel-{0}]  New channel required", cs.idn);
 
-                if ((cs.irc = new XIRCConnector(cs)) != null)
+                if ((cs.irc = new IRCConnector(cs)) != null)
                 {
-                    XIRCBridgeModule.m_channels.Add(cs);
+                    IRCBridgeModule.m_channels.Add(cs);
 
                     m_log.InfoFormat("[IRC-Channel-{0}] New channel initialized for {1}, nick: {2}, commands {3}, private channels {4}", 
                                  cs.idn, rs.Region, cs.DefaultZone, 
@@ -554,7 +554,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
         // contains information that is not differentiating from an
         // IRC point-of-view.
 
-        public static void OSChat(XIRCConnector p_irc, OSChatMessage c, bool cmsg)
+        public static void OSChat(IRCConnector p_irc, OSChatMessage c, bool cmsg)
         {
 
             // m_log.DebugFormat("[IRC-OSCHAT] from {0}:{1}", p_irc.Server, p_irc.IrcChannel);
@@ -568,7 +568,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Chat
                 // Note that this code is responsible for completing some of the
                 // settings for the inbound OSChatMessage
 
-                foreach (ChannelState cs in XIRCBridgeModule.m_channels)
+                foreach (ChannelState cs in IRCBridgeModule.m_channels)
                 {
                     if ( p_irc == cs.irc)
                     {
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs
new file mode 100644
index 0000000..e413290
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs
@@ -0,0 +1,280 @@
+/*
+ * 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;
+using System.Collections.Generic;
+using System.Reflection;
+using log4net;
+using Nini.Config;
+using Nwc.XmlRpc;
+using OpenSim.Framework;
+using OpenSim.Region.Environment.Interfaces;
+using OpenSim.Region.Environment.Scenes;
+
+namespace OpenSim.Region.Environment.Modules.Avatar.Chat
+{
+
+    public class IRCBridgeModule : IRegionModule
+    {
+
+        private static readonly ILog m_log =
+            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        internal static bool   configured = false;
+        internal static bool   enabled    = false;
+        internal static IConfig m_config  = null;
+
+        internal static List<RegionState>  m_regions  = new List<RegionState>();
+        internal static List<ChannelState> m_channels = new List<ChannelState>();
+
+        internal static string password = String.Empty;
+
+        #region IRegionModule Members
+
+        public string Name
+        {
+            get { return "IRCBridgeModule"; }
+        }
+
+        public bool IsSharedModule
+        {
+            get { return true; }
+        }
+
+        public void Initialise(Scene scene, IConfigSource config)
+        {
+
+            // Do a once-only scan of the configuration file to make
+            // sure it's basically intact.
+
+            if (!configured)
+            {
+
+                configured = true;
+
+                try
+                {
+                    if ((m_config = config.Configs["IRC"]) == null)
+                    {
+                        m_log.InfoFormat("[IRC-Bridge] module not configured");
+                        return;
+                    }
+
+                    if (!m_config.GetBoolean("enabled", false))
+                    {
+                        m_log.InfoFormat("[IRC-Bridge] module disabled in configuration");
+                        return;
+                    }
+                }
+                catch (Exception e)
+                {
+                    m_log.ErrorFormat("[IRC-Bridge] configuration failed : {0}", e.Message);
+                    return;
+                }
+
+                enabled = true;
+
+                if (config.Configs["RemoteAdmin"] != null)
+                {
+                    password = config.Configs["RemoteAdmin"].GetString("access_password", password);
+                    scene.CommsManager.HttpServer.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false);
+                }
+
+            }
+
+            // Iff the IRC bridge is enabled, then each new region may be 
+            // connected to IRC. But it should NOT be obligatory (and it 
+            // is not).
+             
+            if (enabled)
+            {
+                try
+                {
+                    m_log.InfoFormat("[IRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName);
+                    m_regions.Add(new RegionState(scene, m_config));
+                }
+                catch (Exception e)
+                {
+                    m_log.WarnFormat("[IRC-Bridge] Region {0} not connected to IRC : {1}", scene.RegionInfo.RegionName, e.Message);
+                    m_log.Debug(e);
+                }
+            }
+            else
+            {
+                m_log.WarnFormat("[IRC-Bridge] Not enabled. Connect for region {0} ignored", scene.RegionInfo.RegionName);
+            }
+
+        }
+
+        // Called after all region modules have been loaded.
+        // Iff the IRC bridge is enabled, then start all of the
+        // configured channels. The set of channels is a side
+        // effect of RegionState creation.
+
+        public void PostInitialise()
+        {
+
+            if (!enabled)
+                return;
+
+            foreach (RegionState region in m_regions)
+            {
+                m_log.InfoFormat("[IRC-Bridge] Opening connection for {0}:{1} on IRC server {2}:{3}",
+                            region.Region, region.cs.BaseNickname, region.cs.Server, region.cs.IrcChannel);
+                try
+                {
+                    region.Open();
+                }
+                catch (Exception e)
+                {
+                    m_log.ErrorFormat("[IRC-Bridge] Open failed for {0}:{1} on IRC server {2}:{3} : {4}",
+                            region.Region, region.cs.BaseNickname, region.cs.Server, region.cs.IrcChannel,
+                            e.Message);
+                }
+            }
+
+        }
+
+        // Called immediately before the region module is unloaded. Close all
+        // associated channels.
+
+        public void Close()
+        {
+
+            if (!enabled)
+                return;
+
+            // Stop each of the region sessions
+
+            foreach (RegionState region in m_regions)
+            {
+                m_log.InfoFormat("[IRC-Bridge] Closing connection for {0}:{1} on IRC server {2}:{3}",
+                            region.Region, region.cs.BaseNickname, region.cs.Server, region.cs.IrcChannel);
+                try
+                {
+                    region.Close();
+                }
+                catch (Exception e)
+                {
+                    m_log.ErrorFormat("[IRC-Bridge] Close failed for {0}:{1} on IRC server {2}:{3} : {4}",
+                            region.Region, region.cs.BaseNickname, region.cs.Server, region.cs.IrcChannel,
+                            e.Message);
+                }
+            }
+
+            // Perform final cleanup of the channels (they now have no active clients)
+
+            foreach (ChannelState channel in m_channels)
+            {
+                m_log.InfoFormat("[IRC-Bridge] Closing connection for {0} on IRC server {1}:{2}",
+                            channel.BaseNickname, channel.Server, channel.IrcChannel);
+                try
+                {
+                    channel.Close();
+                }
+                catch (Exception e)
+                {
+                    m_log.ErrorFormat("[IRC-Bridge] Close failed for {0} on IRC server {1}:{2} : {3}",
+                            channel.BaseNickname, channel.Server, channel.IrcChannel,
+                            e.Message);
+                }
+            }
+
+        }
+
+        #endregion
+
+        public XmlRpcResponse XmlRpcAdminMethod(XmlRpcRequest request)
+        {
+
+            m_log.Info("[IRC-Bridge]: XML RPC Admin Entry");
+
+            XmlRpcResponse response = new XmlRpcResponse();
+            Hashtable  responseData = new Hashtable();
+
+            try
+            {
+
+                Hashtable requestData = (Hashtable)request.Params[0];
+                bool    found = false;
+                string region = String.Empty;
+
+                if (password != String.Empty)
+                {
+                    if (!requestData.ContainsKey("password"))
+                        throw new Exception("Invalid request");
+                    if ((string)requestData["password"] != password)
+                        throw new Exception("Invalid request");
+                }
+
+                if (!requestData.ContainsKey("region"))
+                    throw new Exception("No region name specified");
+                
+                foreach (RegionState rs in m_regions)
+                {
+                    if (rs.Region == region)
+                    {
+                        responseData["server"]    = rs.cs.Server;
+                        responseData["port"]      = rs.cs.Port;
+                        responseData["user"]      = rs.cs.User;
+                        responseData["channel"]   = rs.cs.IrcChannel;
+                        responseData["enabled"]   = rs.cs.irc.Enabled;
+                        responseData["connected"] = rs.cs.irc.Connected;
+                        responseData["nickname"]  = rs.cs.irc.Nick;
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (!found) throw new Exception(String.Format("Region <{0}> not found", region));
+
+                responseData["success"] = true;
+
+            }
+            catch (Exception e)
+            {
+                m_log.InfoFormat("[IRC-Bridge] XML RPC Admin request failed : {0}", e.Message);
+
+                responseData["success"] = "false";
+                responseData["error"]   = e.Message;
+
+            }
+            finally
+            {
+                response.Value = responseData;
+            }
+
+            m_log.Debug("[IRC-Bridge]: XML RPC Admin Exit");
+
+            return response;
+
+        }
+
+    }
+
+}
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs
new file mode 100644
index 0000000..b9422f3
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs
@@ -0,0 +1,843 @@
+/*
+ * 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.Timers;
+using System.Collections.Generic;
+using System.IO;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Threading;
+using OpenMetaverse;
+using log4net;
+using Nini.Config;
+using OpenSim.Framework;
+using OpenSim.Region.Environment.Interfaces;
+using OpenSim.Region.Environment.Scenes;
+
+namespace OpenSim.Region.Environment.Modules.Avatar.Chat
+{
+    public class IRCConnector
+    {
+
+        #region Global (static) state
+
+        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+        // Local constants
+ 
+        private static readonly Vector3 CenterOfRegion = new Vector3(128, 128, 20);
+        private static readonly char[]  CS_SPACE = { ' ' };
+
+        private const  int  WD_INTERVAL = 1000;     // base watchdog interval
+        private static int  PING_PERIOD = 15;       // WD intervals per PING
+        private static int  ICCD_PERIOD = 10;       // WD intervals between Connects
+
+        private static int _idk_        = 0;        // core connector identifier
+        private static int _pdk_        = 0;        // ping interval counter
+        private static int _icc_        = 0;        // IRC connect counter
+
+        // List of configured connectors
+
+        private static List<IRCConnector> m_connectors = new List<IRCConnector>();
+
+        // Watchdog state
+
+        private static System.Timers.Timer m_watchdog = null;
+
+        static IRCConnector()
+        {
+            m_log.DebugFormat("[IRC-Connector]: Static initialization started");
+            m_watchdog = new System.Timers.Timer(WD_INTERVAL);
+            m_watchdog.Elapsed += new ElapsedEventHandler(WatchdogHandler);
+            m_watchdog.AutoReset = true;
+            m_watchdog.Start();
+            m_log.DebugFormat("[IRC-Connector]: Static initialization complete");
+        }
+
+        #endregion
+
+        #region Instance state
+
+        // Connector identity
+
+        internal int idn = _idk_++;
+
+        // How many regions depend upon this connection
+        // This count is updated by the ChannelState object and reflects the sum
+        // of the region clients associated with the set of associated channel 
+        // state instances. That's why it cannot be managed here.
+
+        internal int depends = 0;
+
+        // Working threads
+
+        private Thread m_listener = null;
+
+        private Object msyncConnect = new Object();
+
+        internal bool   m_randomizeNick = true; // add random suffix
+        internal string m_baseNick = null;      // base name for randomizing
+        internal string m_nick = null;          // effective nickname
+
+        public string Nick                        // Public property
+        {
+            get { return m_nick; }
+            set { m_nick = value; }
+        }
+        
+        private bool m_enabled = false;            // connector enablement
+        public bool Enabled
+        {
+            get { return m_enabled; }
+        }
+
+        private bool m_connected = false;        // connection status
+        public bool Connected
+        {
+            get { return m_connected; }
+        }
+
+        private string m_ircChannel;            // associated channel id
+        public string IrcChannel
+        {
+            get { return m_ircChannel; }
+            set { m_ircChannel = value; }
+        }
+        
+        private uint m_port = 6667;                // session port
+        public uint Port 
+        {
+            get { return m_port; }
+            set { m_port = value; }
+        }
+
+        private string m_server = null;            // IRC server name
+        public string Server
+        {
+            get { return m_server; }
+            set { m_server = value; }
+        }
+
+        private string m_user = "USER OpenSimBot 8 * :I'm an OpenSim to IRC bot";
+        public string User
+        {
+            get { return m_user; }
+        }
+
+        // Network interface
+
+        private TcpClient     m_tcp;
+        private NetworkStream m_stream = null;
+        private StreamReader  m_reader;
+        private StreamWriter  m_writer;
+
+        // Channel characteristic info (if available)
+
+        internal string usermod = String.Empty;
+        internal string chanmod = String.Empty;
+        internal string version = String.Empty;
+        internal bool motd = false;
+
+        #endregion
+
+        #region connector instance management
+
+        internal IRCConnector(ChannelState cs)
+        {
+
+            // Prepare network interface
+
+            m_tcp    = null;
+            m_writer = null;
+            m_reader = null;
+
+            // Setup IRC session parameters
+
+            m_server        = cs.Server;
+            m_baseNick      = cs.BaseNickname;
+            m_randomizeNick = cs.RandomizeNickname;
+            m_ircChannel    = cs.IrcChannel;
+            m_port          = (uint) cs.Port;
+            m_user          = cs.User;
+
+            if (m_watchdog == null)
+            {
+                // Non-differentiating
+
+                ICCD_PERIOD     = cs.ConnectDelay;
+                PING_PERIOD     = cs.PingDelay;
+
+                // Smaller values are not reasonable
+
+                if (ICCD_PERIOD < 5)
+                    ICCD_PERIOD = 5;
+
+                if (PING_PERIOD < 5)
+                    PING_PERIOD = 5;
+
+                _icc_ = ICCD_PERIOD;    // get started right away!
+
+            }
+
+            // The last line of defense
+
+            if (m_server == null || m_baseNick == null || m_ircChannel == null || m_user == null)
+                throw new Exception("Invalid connector configuration");
+
+            // Generate an initial nickname if randomizing is enabled
+
+            if (m_randomizeNick)
+            {
+                m_nick = m_baseNick + Util.RandomClass.Next(1, 99);
+            }
+
+            // Add the newly created connector to the known connectors list
+
+            m_connectors.Add(this);
+
+            m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn);
+
+        }
+
+        ~IRCConnector()
+        {
+            m_watchdog.Stop();
+            Close();
+        }
+
+        // Mark the connector as connectable. Harmless if already enabled.
+
+        public void Open()
+        {
+            if (!m_enabled)
+            {
+
+                m_connectors.Add(this);
+                m_enabled = true;
+
+                if (!Connected)
+                {
+                    Connect();
+                }
+
+            }
+        }
+
+        // Only close the connector if the dependency count is zero.
+
+        public void Close()
+        {
+
+            m_log.InfoFormat("[IRC-Connector-{0}] Closing", idn);
+
+            lock (msyncConnect)
+            {
+
+                if ((depends == 0) && Enabled)
+                {
+
+                    m_enabled = false;
+
+                    if (Connected)
+                    {
+                        m_log.DebugFormat("[IRC-Connector-{0}] Closing interface", idn);
+
+                        // Cleanup the IRC session
+
+                        try
+                        {
+                            m_writer.WriteLine(String.Format("QUIT :{0} to {1} wormhole to {2} closing",
+                                m_nick, m_ircChannel, m_server));
+                            m_writer.Flush();
+                        }
+                        catch (Exception) {}
+       
+
+                        m_connected = false;
+
+                        try { m_writer.Close(); } catch (Exception) {}
+                        try { m_reader.Close(); } catch (Exception) {}
+                        try { m_stream.Close(); } catch (Exception) {}
+                        try { m_tcp.Close();    } catch (Exception) {}
+
+                    }
+       
+                    m_connectors.Remove(this);
+
+                }
+            }
+
+            m_log.InfoFormat("[IRC-Connector-{0}] Closed", idn);
+
+        }
+
+        #endregion
+
+        #region session management
+
+        // Connect to the IRC server. A connector should always be connected, once enabled
+
+        public void Connect()
+        {
+
+            if (!m_enabled)
+                return;
+
+            // Delay until next WD cycle if this is too close to the last start attempt
+
+            while (_icc_ < ICCD_PERIOD)
+                return;
+
+            m_log.DebugFormat("[IRC-Connector-{0}]: Connection request for {1} on {2}:{3}", idn, m_nick, m_server, m_ircChannel);
+
+            lock (msyncConnect)
+            {
+
+                _icc_ = 0;
+
+                try
+                {
+                    if (m_connected) return;
+
+                    m_connected = true;
+
+                    m_tcp    = new TcpClient(m_server, (int)m_port);
+                    m_stream = m_tcp.GetStream();
+                    m_reader = new StreamReader(m_stream);
+                    m_writer = new StreamWriter(m_stream);
+
+                    m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); 
+
+                    m_listener = new Thread(new ThreadStart(ListenerRun));
+                    m_listener.Name = "IRCConnectorListenerThread";
+                    m_listener.IsBackground = true;
+                    m_listener.Start();
+                    ThreadTracker.Add(m_listener);
+
+                    // This is the message order recommended by RFC 2812
+
+                    m_writer.WriteLine(String.Format("NICK {0}", m_nick));
+                    m_writer.Flush();
+                    m_writer.WriteLine(m_user);
+                    m_writer.Flush();
+                    m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel));
+                    m_writer.Flush();
+
+                    m_log.InfoFormat("[IRC-Connector-{0}]: {1} has joined {2}", idn, m_nick, m_ircChannel);
+                    m_log.InfoFormat("[IRC-Connector-{0}] Connected", idn);
+
+                }
+                catch (Exception e)
+                {
+                    m_log.ErrorFormat("[IRC-Connector-{0}] cannot connect {1} to {2}:{3}: {4}",
+                                      idn, m_nick, m_server, m_port, e.Message);
+                    m_connected = false;
+                }
+
+            }
+
+            return;
+
+        }
+
+        // Reconnect is used to force a re-cycle of the IRC connection. Should generally
+        // be a transparent event
+
+        public void Reconnect()
+        {
+
+            m_log.DebugFormat("[IRC-Connector-{0}]: Reconnect request for {1} on {2}:{3}", idn, m_nick, m_server, m_ircChannel);
+
+            // Don't do this if a Connect is in progress...
+
+            lock (msyncConnect)
+            {
+
+                if (m_connected)
+                {
+                    m_log.InfoFormat("[IRC-Connector-{0}] Resetting connector", idn);
+
+                    // Mark as disconnected. This will allow the listener thread
+                    // to exit if still in-flight.
+
+
+                    // The listener thread is not aborted - it *might* actually be
+                    // the thread that is running the Reconnect! Instead just close
+                    // the socket and it will disappear of its own accord, once this
+                    // processing is completed.
+
+                    try { m_writer.Close(); } catch (Exception) {}
+                    try { m_reader.Close(); } catch (Exception) {}
+                    try { m_tcp.Close();    } catch (Exception) {}
+
+                    m_connected = false;
+
+                }
+
+            }
+
+            Connect();
+
+        }
+
+        #endregion
+
+        #region Outbound (to-IRC) message handlers
+
+        public void PrivMsg(string pattern, string from, string region, string msg)
+        {
+
+            m_log.DebugFormat("[IRC-Connector-{0}] PrivMsg to IRC from {1}: <{2}>", idn, from, 
+                String.Format(pattern, m_ircChannel, from, region, msg));
+
+            // One message to the IRC server
+
+            try
+            {
+                m_writer.WriteLine(pattern, m_ircChannel, from, region, msg);
+                m_writer.Flush();
+                m_log.DebugFormat("[IRC-Connector-{0}]: PrivMsg from {1} in {2}: {3}", idn, from, region, msg);
+            }
+            catch (IOException)
+            {
+                m_log.ErrorFormat("[IRC-Connector-{0}]: PrivMsg I/O Error: disconnected from IRC server", idn);
+                Reconnect();
+            }
+            catch (Exception ex)
+            {
+                m_log.ErrorFormat("[IRC-Connector-{0}]: PrivMsg exception : {1}", idn, ex.Message);
+                m_log.Debug(ex);
+            }
+
+        }
+
+        public void Send(string msg)
+        {
+
+            m_log.DebugFormat("[IRC-Connector-{0}] Send to IRC : <{1}>", idn,  msg);
+
+            try
+            {
+                m_writer.WriteLine(msg);
+                m_writer.Flush();
+                m_log.DebugFormat("[IRC-Connector-{0}] Sent command string: {1}", idn, msg);
+            }
+            catch (IOException)
+            {
+                m_log.ErrorFormat("[IRC-Connector-{0}] Disconnected from IRC server.(Send)", idn);
+                Reconnect();
+            }
+            catch (Exception ex)
+            {
+                m_log.ErrorFormat("[IRC-Connector-{0}] Send exception trap: {0}", idn, ex.Message);
+                m_log.Debug(ex);
+            }
+
+        }
+
+        #endregion
+
+        public void ListenerRun()
+        {
+            string inputLine;
+
+            try
+            {
+                while (m_enabled && m_connected)
+                {
+
+                    if ((inputLine = m_reader.ReadLine()) == null)
+                        throw new Exception("Listener input socket closed");
+
+                    // m_log.Info("[IRCConnector]: " + inputLine);
+
+                    if (inputLine.Contains("PRIVMSG"))
+                    {
+
+                        Dictionary<string, string> data = ExtractMsg(inputLine);
+
+                        // Any chat ???
+                        if (data != null)
+                        {
+
+                            OSChatMessage c = new OSChatMessage();
+                            c.Message = data["msg"];
+                            c.Type = ChatTypeEnum.Region;
+                            c.Position = CenterOfRegion;
+                            c.From = data["nick"];
+                            c.Sender = null;
+                            c.SenderUUID = UUID.Zero;
+
+                            // Is message "\001ACTION foo bar\001"? 
+                            // Then change to: "/me foo bar"
+
+                            if ((1 == c.Message[0]) && c.Message.Substring(1).StartsWith("ACTION"))
+                                c.Message = String.Format("/me {0}", c.Message.Substring(8, c.Message.Length - 9));
+
+                            ChannelState.OSChat(this, c, false);
+
+                        }
+
+                    }
+                    else
+                    {
+                        ProcessIRCCommand(inputLine);
+                    }
+                }
+            }
+            catch (Exception /*e*/)
+            {
+                // m_log.ErrorFormat("[IRC-Connector-{0}]: ListenerRun exception trap: {1}", idn, e.Message);
+                // m_log.Debug(e);
+            }
+
+            if (m_enabled) Reconnect();
+
+        }
+
+        private Regex RE = new Regex(@":(?<nick>[\w-]*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)", 
+                                     RegexOptions.Multiline);
+
+        private Dictionary<string, string> ExtractMsg(string input)
+        {
+            //examines IRC commands and extracts any private messages
+            // which will then be reboadcast in the Sim
+
+            // m_log.InfoFormat("[IRC-Connector-{0}]: ExtractMsg: {1}", idn, input);
+
+            Dictionary<string, string> result = null;
+            MatchCollection matches = RE.Matches(input);
+
+            // Get some direct matches $1 $4 is a
+            if ((matches.Count == 0) || (matches.Count != 1) || (matches[0].Groups.Count != 5))
+            {
+                // m_log.Info("[IRCConnector]: Number of matches: " + matches.Count);
+                // if (matches.Count > 0)
+                // {
+                //     m_log.Info("[IRCConnector]: Number of groups: " + matches[0].Groups.Count);
+                // }
+                return null;
+            }
+
+            result = new Dictionary<string, string>();
+            result.Add("nick", matches[0].Groups[1].Value);
+            result.Add("user", matches[0].Groups[2].Value);
+            result.Add("channel", matches[0].Groups[3].Value);
+            result.Add("msg", matches[0].Groups[4].Value);
+
+            return result;
+        }
+
+        public void BroadcastSim(string sender, string format, params string[] args)
+        {
+            try
+            {
+                OSChatMessage c = new OSChatMessage();
+                c.From = sender;
+                c.Message = String.Format(format, args);
+                c.Type = ChatTypeEnum.Region; // ChatTypeEnum.Say;
+                c.Position = CenterOfRegion;
+                c.Sender = null;
+                c.SenderUUID = UUID.Zero;
+
+                ChannelState.OSChat(this, c, true);
+
+            }
+            catch (Exception ex) // IRC gate should not crash Sim
+            {
+                m_log.ErrorFormat("[IRC-Connector-{0}]: BroadcastSim Exception Trap: {1}\n{2}", idn, ex.Message, ex.StackTrace);
+            }
+        }
+
+        #region IRC Command Handlers
+
+        public void ProcessIRCCommand(string command)
+        {
+
+            string[] commArgs;
+            string c_server = m_server;
+
+            string pfx   = String.Empty;
+            string cmd   = String.Empty;
+            string parms = String.Empty;
+
+            // ":" indicates that a prefix is present
+            // There are NEVER more than 17 real 
+            // fields. A parameter that starts with 
+            // ":" indicates that the remainder of the
+            // line is a single parameter value.
+
+            commArgs = command.Split(CS_SPACE,2);
+
+            if (commArgs[0].StartsWith(":"))
+            {
+                pfx = commArgs[0].Substring(1);
+                commArgs = commArgs[1].Split(CS_SPACE,2);
+            }
+
+            cmd   = commArgs[0];
+            parms = commArgs[1];
+
+            // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd);
+
+            switch (cmd)
+            {
+
+                // Messages 001-004 are always sent
+                // following signon.
+
+                case "001" : // Welcome ...
+                case "002" : // Server information
+                case "003" : // Welcome ...
+                    break;
+                case "004" : // Server information
+                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
+                    commArgs = parms.Split(CS_SPACE);
+                    c_server = commArgs[1];
+                    m_server = c_server;
+                    version  = commArgs[2];
+                    usermod  = commArgs[3];
+                    chanmod  = commArgs[4];
+                    break;
+                case "005" : // Server information
+                    break;
+                case "042" :
+                case "250" :
+                case "251" :
+                case "252" :
+                case "254" :
+                case "255" :
+                case "265" :
+                case "266" :
+                case "332" : // Subject
+                case "333" : // Subject owner (?)
+                case "353" : // Name list
+                case "366" : // End-of-Name list marker
+                case "372" : // MOTD body
+                case "375" : // MOTD start
+                    m_log.InfoFormat("[IRC-Connector-{0}] {1}", idn, parms.Split(CS_SPACE,2)[1]);
+                    break;
+                case "376" : // MOTD end
+                    m_log.InfoFormat("[IRC-Connector-{0}] {1}", idn, parms.Split(CS_SPACE,2)[1]);
+                    motd = true;
+                    break;
+                case "451" : // Not registered
+                    break;
+                case "433" : // Nickname in use
+                    // Gen a new name
+                    m_nick = m_baseNick + Util.RandomClass.Next(1, 99);
+                    m_log.ErrorFormat("[IRC-Connector-{0}]: IRC SERVER reports NicknameInUse, trying {1}", idn, m_nick);
+                    // Retry
+                    m_writer.WriteLine(String.Format("NICK {0}", m_nick));
+                    m_writer.Flush();
+                    m_writer.WriteLine(m_user);
+                    m_writer.Flush();
+                    m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel));
+                    m_writer.Flush();
+                    break;
+                case "NOTICE" :
+                    m_log.WarnFormat("[IRC-Connector-{0}] {1}", idn, parms.Split(CS_SPACE,2)[1]);
+                    break;
+                case "ERROR"  :
+                    m_log.ErrorFormat("[IRC-Connector-{0}] {1}", idn, parms.Split(CS_SPACE,2)[1]);
+                    if (parms.Contains("reconnect too fast"))
+                        ICCD_PERIOD++;
+                    break;
+                case "PING"   :
+                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
+                    m_writer.WriteLine(String.Format("PONG {0}", parms));
+                    m_writer.Flush();
+                    break;
+                case "PONG"   :
+                    break;
+                case "JOIN":
+                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
+                    eventIrcJoin(pfx, cmd, parms);
+                    break;
+                case "PART":
+                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
+                    eventIrcPart(pfx, cmd, parms);
+                    break;
+                case "MODE":
+                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
+                    eventIrcMode(pfx, cmd, parms);
+                    break;
+                case "NICK":
+                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
+                    eventIrcNickChange(pfx, cmd, parms);
+                    break;
+                case "KICK":
+                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
+                    eventIrcKick(pfx, cmd, parms);
+                    break;
+                case "QUIT":
+                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
+                    eventIrcQuit(pfx, cmd, parms);
+                    break;
+                default    :
+                    m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms);
+                    break;
+            }
+
+            // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd);
+  
+        }
+
+        public void eventIrcJoin(string prefix, string command, string parms)
+        {
+            string[]     args = parms.Split(CS_SPACE,2);
+            string IrcUser    = prefix.Split('!')[0];
+            string IrcChannel = args[0];
+
+            if (IrcChannel.StartsWith(":"))
+                IrcChannel = IrcChannel.Substring(1);
+
+            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCJoin {1}:{2}", idn, m_server, m_ircChannel);
+            BroadcastSim(IrcUser, "/me joins {0}", IrcChannel);
+        }
+
+        public void eventIrcPart(string prefix, string command, string parms)
+        {
+            string[]     args = parms.Split(CS_SPACE,2);
+            string    IrcUser = prefix.Split('!')[0];
+            string IrcChannel = args[0];
+
+            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel);
+            BroadcastSim(IrcUser, "/me parts {0}", IrcChannel);
+        }
+
+        public void eventIrcMode(string prefix, string command, string parms)
+        {
+            string[]   args = parms.Split(CS_SPACE,2);
+            string UserMode = args[1];
+
+            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel);
+            if (UserMode.Substring(0, 1) == ":")
+            {
+                UserMode = UserMode.Remove(0, 1);
+            }
+        }
+
+        public void eventIrcNickChange(string prefix, string command, string parms)
+        {
+            string[]      args = parms.Split(CS_SPACE,2);
+            string UserOldNick = prefix.Split('!')[0];
+            string UserNewNick = args[0].Remove(0, 1);
+
+            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCNickChange {1}:{2}", idn, m_server, m_ircChannel);
+            BroadcastSim(UserOldNick, "/me is now known as {0}", UserNewNick);
+        }
+
+        public void eventIrcKick(string prefix, string command, string parms)
+        {
+            string[]      args = parms.Split(CS_SPACE,3);
+            string UserKicker  = prefix.Split('!')[0];
+            string IrcChannel  = args[0];
+            string UserKicked  = args[1];
+            string KickMessage = args[2]; 
+
+            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCKick {1}:{2}", idn, m_server, m_ircChannel);
+            BroadcastSim(UserKicker, "/me kicks kicks {0} off {1} saying \"{2}\"", UserKicked, IrcChannel, KickMessage);
+
+            if (UserKicked == m_nick)
+            {
+                BroadcastSim(m_nick, "Hey, that was me!!!");
+            }
+
+        }
+
+        public void eventIrcQuit(string prefix, string command, string parms)
+        {
+            string     IrcUser = prefix.Split('!')[0];
+            string QuitMessage = parms;
+
+            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel);
+            BroadcastSim(IrcUser, "/me quits saying \"{0}\"", QuitMessage);
+        }
+
+        #endregion
+
+        #region Connector Watch Dog
+
+        // A single watch dog monitors extant connectors and makes sure that they
+        // are re-connected as necessary. If a connector IS connected, then it is
+        // pinged, but only if a PING period has elapsed.
+
+        protected static void WatchdogHandler(Object source, ElapsedEventArgs args)
+        {
+
+            // m_log.InfoFormat("[IRC-Watchdog] Status scan");
+
+            _pdk_ = (_pdk_+1)%PING_PERIOD;    // cycle the ping trigger
+            _icc_++;    // increment the inter-consecutive-connect-delay counter
+
+            foreach (IRCConnector connector in m_connectors)
+            {
+                if (connector.Enabled)
+                {
+                    if (!connector.Connected)
+                    {
+                        try
+                        {
+                            // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel);
+                            connector.Connect();
+                        }
+                        catch (Exception e)
+                        {
+                            m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message);
+                        }
+                    }
+                    else
+                    {
+                        if (_pdk_ == 0)
+                        {
+                            try
+                            {
+                                connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server));
+                                connector.m_writer.Flush();
+                            }
+                            catch (Exception /*e*/)
+                            {
+                                // m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message);
+                                // m_log.Debug(e);
+                                connector.Reconnect();
+                            }
+                        }
+                    }
+                }
+            }
+
+            // m_log.InfoFormat("[IRC-Watchdog] Status scan completed");
+
+        }
+
+        #endregion
+
+    }
+}
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs
deleted file mode 100644
index 9bd7946..0000000
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCBridgeModule.cs
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * 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;
-using System.Collections.Generic;
-using System.Reflection;
-using log4net;
-using Nini.Config;
-using Nwc.XmlRpc;
-using OpenSim.Framework;
-using OpenSim.Region.Environment.Interfaces;
-using OpenSim.Region.Environment.Scenes;
-
-namespace OpenSim.Region.Environment.Modules.Avatar.Chat
-{
-
-    public class XIRCBridgeModule : IRegionModule
-    {
-
-        private static readonly ILog m_log =
-            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
-        internal static bool   configured = false;
-        internal static bool   enabled    = false;
-        internal static IConfig m_config  = null;
-
-        internal static List<RegionState>  m_regions  = new List<RegionState>();
-        internal static List<ChannelState> m_channels = new List<ChannelState>();
-
-        internal static string password = String.Empty;
-
-        #region IRegionModule Members
-
-        public string Name
-        {
-            get { return "XIRCBridgeModule"; }
-        }
-
-        public bool IsSharedModule
-        {
-            get { return true; }
-        }
-
-        public void Initialise(Scene scene, IConfigSource config)
-        {
-
-            // Do a once-only scan of the configuration file to make
-            // sure it's basically intact.
-
-            if (!configured)
-            {
-
-                configured = true;
-
-                try
-                {
-                    if ((m_config = config.Configs["IRC"]) == null)
-                    {
-                        m_log.InfoFormat("[XIRC-Bridge] module not configured");
-                        return;
-                    }
-
-                    if (!m_config.GetBoolean("enabled", false))
-                    {
-                        m_log.InfoFormat("[XIRC-Bridge] module disabled in configuration");
-                        return;
-                    }
-                }
-                catch (Exception e)
-                {
-                    m_log.ErrorFormat("[XIRC-Bridge] configuration failed : {0}", e.Message);
-                    return;
-                }
-
-                enabled = true;
-
-                if (config.Configs["RemoteAdmin"] != null)
-                {
-                    password = config.Configs["RemoteAdmin"].GetString("access_password", password);
-                    scene.CommsManager.HttpServer.AddXmlRPCHandler("xirc_admin", XmlRpcAdminMethod, false);
-                }
-
-            }
-
-            // Iff the IRC bridge is enabled, then each new region may be 
-            // connected to IRC. But it should NOT be obligatory (and it 
-            // is not).
-             
-            if (enabled)
-            {
-                try
-                {
-                    m_log.InfoFormat("[XIRC-Bridge] Connecting region {0}", scene.RegionInfo.RegionName);
-                    m_regions.Add(new RegionState(scene, m_config));
-                }
-                catch (Exception e)
-                {
-                    m_log.WarnFormat("[XIRC-Bridge] Region {0} not connected to IRC : {1}", scene.RegionInfo.RegionName, e.Message);
-                    m_log.Debug(e);
-                }
-            }
-            else
-            {
-                m_log.WarnFormat("[XIRC-Bridge] Not enabled. Connect for region {0} ignored", scene.RegionInfo.RegionName);
-            }
-
-        }
-
-        // Called after all region modules have been loaded.
-        // Iff the IRC bridge is enabled, then start all of the
-        // configured channels. The set of channels is a side
-        // effect of RegionState creation.
-
-        public void PostInitialise()
-        {
-
-            if (!enabled)
-                return;
-
-            foreach (RegionState region in m_regions)
-            {
-                m_log.InfoFormat("[XIRC-Bridge] Opening connection for {0}:{1} on IRC server {2}:{3}",
-                            region.Region, region.cs.BaseNickname, region.cs.Server, region.cs.IrcChannel);
-                try
-                {
-                    region.Open();
-                }
-                catch (Exception e)
-                {
-                    m_log.ErrorFormat("[XIRC-Bridge] Open failed for {0}:{1} on IRC server {2}:{3} : {4}",
-                            region.Region, region.cs.BaseNickname, region.cs.Server, region.cs.IrcChannel,
-                            e.Message);
-                }
-            }
-
-        }
-
-        // Called immediately before the region module is unloaded. Close all
-        // associated channels.
-
-        public void Close()
-        {
-
-            if (!enabled)
-                return;
-
-            // Stop each of the region sessions
-
-            foreach (RegionState region in m_regions)
-            {
-                m_log.InfoFormat("[XIRC-Bridge] Closing connection for {0}:{1} on IRC server {2}:{3}",
-                            region.Region, region.cs.BaseNickname, region.cs.Server, region.cs.IrcChannel);
-                try
-                {
-                    region.Close();
-                }
-                catch (Exception e)
-                {
-                    m_log.ErrorFormat("[XIRC-Bridge] Close failed for {0}:{1} on IRC server {2}:{3} : {4}",
-                            region.Region, region.cs.BaseNickname, region.cs.Server, region.cs.IrcChannel,
-                            e.Message);
-                }
-            }
-
-            // Perform final cleanup of the channels (they now have no active clients)
-
-            foreach (ChannelState channel in m_channels)
-            {
-                m_log.InfoFormat("[XIRC-Bridge] Closing connection for {0} on IRC server {1}:{2}",
-                            channel.BaseNickname, channel.Server, channel.IrcChannel);
-                try
-                {
-                    channel.Close();
-                }
-                catch (Exception e)
-                {
-                    m_log.ErrorFormat("[XIRC-Bridge] Close failed for {0} on IRC server {1}:{2} : {3}",
-                            channel.BaseNickname, channel.Server, channel.IrcChannel,
-                            e.Message);
-                }
-            }
-
-        }
-
-        #endregion
-
-        public XmlRpcResponse XmlRpcAdminMethod(XmlRpcRequest request)
-        {
-
-            m_log.Info("[XIRC-Bridge]: XML RPC Admin Entry");
-
-            XmlRpcResponse response = new XmlRpcResponse();
-            Hashtable  responseData = new Hashtable();
-
-            try
-            {
-
-                Hashtable requestData = (Hashtable)request.Params[0];
-                bool    found = false;
-                string region = String.Empty;
-
-                if (password != String.Empty)
-                {
-                    if (!requestData.ContainsKey("password"))
-                        throw new Exception("Invalid request");
-                    if ((string)requestData["password"] != password)
-                        throw new Exception("Invalid request");
-                }
-
-                if (!requestData.ContainsKey("region"))
-                    throw new Exception("No region name specified");
-                
-                foreach (RegionState rs in m_regions)
-                {
-                    if (rs.Region == region)
-                    {
-                        responseData["server"]    = rs.cs.Server;
-                        responseData["port"]      = rs.cs.Port;
-                        responseData["user"]      = rs.cs.User;
-                        responseData["channel"]   = rs.cs.IrcChannel;
-                        responseData["enabled"]   = rs.cs.irc.Enabled;
-                        responseData["connected"] = rs.cs.irc.Connected;
-                        responseData["nickname"]  = rs.cs.irc.Nick;
-                        found = true;
-                        break;
-                    }
-                }
-
-                if (!found) throw new Exception(String.Format("Region <{0}> not found", region));
-
-                responseData["success"] = true;
-
-            }
-            catch (Exception e)
-            {
-                m_log.InfoFormat("[XIRC-Bridge] XML RPC Admin request failed : {0}", e.Message);
-
-                responseData["success"] = "false";
-                responseData["error"]   = e.Message;
-
-            }
-            finally
-            {
-                response.Value = responseData;
-            }
-
-            m_log.Debug("[XIRC-Bridge]: XML RPC Admin Exit");
-
-            return response;
-
-        }
-
-    }
-
-}
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs
deleted file mode 100644
index f6a07b8..0000000
--- a/OpenSim/Region/Environment/Modules/Avatar/Chat/XIRCConnector.cs
+++ /dev/null
@@ -1,843 +0,0 @@
-/*
- * 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.Timers;
-using System.Collections.Generic;
-using System.IO;
-using System.Net.Sockets;
-using System.Reflection;
-using System.Text.RegularExpressions;
-using System.Threading;
-using OpenMetaverse;
-using log4net;
-using Nini.Config;
-using OpenSim.Framework;
-using OpenSim.Region.Environment.Interfaces;
-using OpenSim.Region.Environment.Scenes;
-
-namespace OpenSim.Region.Environment.Modules.Avatar.Chat
-{
-    public class XIRCConnector
-    {
-
-        #region Global (static) state
-
-        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
-        // Local constants
- 
-        private static readonly Vector3 CenterOfRegion = new Vector3(128, 128, 20);
-        private static readonly char[]  CS_SPACE = { ' ' };
-
-        private const  int  WD_INTERVAL = 1000;     // base watchdog interval
-        private static int  PING_PERIOD = 15;       // WD intervals per PING
-        private static int  ICCD_PERIOD = 10;       // WD intervals between Connects
-
-        private static int _idk_        = 0;        // core connector identifier
-        private static int _pdk_        = 0;        // ping interval counter
-        private static int _icc_        = 0;        // IRC connect counter
-
-        // List of configured connectors
-
-        private static List<XIRCConnector> m_connectors = new List<XIRCConnector>();
-
-        // Watchdog state
-
-        private static System.Timers.Timer m_watchdog = null;
-
-        static XIRCConnector()
-        {
-            m_log.DebugFormat("[IRC-Connector]: Static initialization started");
-            m_watchdog = new System.Timers.Timer(WD_INTERVAL);
-            m_watchdog.Elapsed += new ElapsedEventHandler(WatchdogHandler);
-            m_watchdog.AutoReset = true;
-            m_watchdog.Start();
-            m_log.DebugFormat("[IRC-Connector]: Static initialization complete");
-        }
-
-        #endregion
-
-        #region Instance state
-
-        // Connector identity
-
-        internal int idn = _idk_++;
-
-        // How many regions depend upon this connection
-        // This count is updated by the ChannelState object and reflects the sum
-        // of the region clients associated with the set of associated channel 
-        // state instances. That's why it cannot be managed here.
-
-        internal int depends = 0;
-
-        // Working threads
-
-        private Thread m_listener = null;
-
-        private Object msyncConnect = new Object();
-
-        internal bool   m_randomizeNick = true; // add random suffix
-        internal string m_baseNick = null;      // base name for randomizing
-        internal string m_nick = null;          // effective nickname
-
-        public string Nick                        // Public property
-        {
-            get { return m_nick; }
-            set { m_nick = value; }
-        }
-        
-        private bool m_enabled = false;            // connector enablement
-        public bool Enabled
-        {
-            get { return m_enabled; }
-        }
-
-        private bool m_connected = false;        // connection status
-        public bool Connected
-        {
-            get { return m_connected; }
-        }
-
-        private string m_ircChannel;            // associated channel id
-        public string IrcChannel
-        {
-            get { return m_ircChannel; }
-            set { m_ircChannel = value; }
-        }
-        
-        private uint m_port = 6667;                // session port
-        public uint Port 
-        {
-            get { return m_port; }
-            set { m_port = value; }
-        }
-
-        private string m_server = null;            // IRC server name
-        public string Server
-        {
-            get { return m_server; }
-            set { m_server = value; }
-        }
-
-        private string m_user = "USER OpenSimBot 8 * :I'm an OpenSim to IRC bot";
-        public string User
-        {
-            get { return m_user; }
-        }
-
-        // Network interface
-
-        private TcpClient     m_tcp;
-        private NetworkStream m_stream = null;
-        private StreamReader  m_reader;
-        private StreamWriter  m_writer;
-
-        // Channel characteristic info (if available)
-
-        internal string usermod = String.Empty;
-        internal string chanmod = String.Empty;
-        internal string version = String.Empty;
-        internal bool motd = false;
-
-        #endregion
-
-        #region connector instance management
-
-        internal XIRCConnector(ChannelState cs)
-        {
-
-            // Prepare network interface
-
-            m_tcp    = null;
-            m_writer = null;
-            m_reader = null;
-
-            // Setup IRC session parameters
-
-            m_server        = cs.Server;
-            m_baseNick      = cs.BaseNickname;
-            m_randomizeNick = cs.RandomizeNickname;
-            m_ircChannel    = cs.IrcChannel;
-            m_port          = (uint) cs.Port;
-            m_user          = cs.User;
-
-            if (m_watchdog == null)
-            {
-                // Non-differentiating
-
-                ICCD_PERIOD     = cs.ConnectDelay;
-                PING_PERIOD     = cs.PingDelay;
-
-                // Smaller values are not reasonable
-
-                if (ICCD_PERIOD < 5)
-                    ICCD_PERIOD = 5;
-
-                if (PING_PERIOD < 5)
-                    PING_PERIOD = 5;
-
-                _icc_ = ICCD_PERIOD;    // get started right away!
-
-            }
-
-            // The last line of defense
-
-            if (m_server == null || m_baseNick == null || m_ircChannel == null || m_user == null)
-                throw new Exception("Invalid connector configuration");
-
-            // Generate an initial nickname if randomizing is enabled
-
-            if (m_randomizeNick)
-            {
-                m_nick = m_baseNick + Util.RandomClass.Next(1, 99);
-            }
-
-            // Add the newly created connector to the known connectors list
-
-            m_connectors.Add(this);
-
-            m_log.InfoFormat("[IRC-Connector-{0}]: Initialization complete", idn);
-
-        }
-
-        ~XIRCConnector()
-        {
-            m_watchdog.Stop();
-            Close();
-        }
-
-        // Mark the connector as connectable. Harmless if already enabled.
-
-        public void Open()
-        {
-            if (!m_enabled)
-            {
-
-                m_connectors.Add(this);
-                m_enabled = true;
-
-                if (!Connected)
-                {
-                    Connect();
-                }
-
-            }
-        }
-
-        // Only close the connector if the dependency count is zero.
-
-        public void Close()
-        {
-
-            m_log.InfoFormat("[IRC-Connector-{0}] Closing", idn);
-
-            lock (msyncConnect)
-            {
-
-                if ((depends == 0) && Enabled)
-                {
-
-                    m_enabled = false;
-
-                    if (Connected)
-                    {
-                        m_log.DebugFormat("[IRC-Connector-{0}] Closing interface", idn);
-
-                        // Cleanup the IRC session
-
-                        try
-                        {
-                            m_writer.WriteLine(String.Format("QUIT :{0} to {1} wormhole to {2} closing",
-                                m_nick, m_ircChannel, m_server));
-                            m_writer.Flush();
-                        }
-                        catch (Exception) {}
-       
-
-                        m_connected = false;
-
-                        try { m_writer.Close(); } catch (Exception) {}
-                        try { m_reader.Close(); } catch (Exception) {}
-                        try { m_stream.Close(); } catch (Exception) {}
-                        try { m_tcp.Close();    } catch (Exception) {}
-
-                    }
-       
-                    m_connectors.Remove(this);
-
-                }
-            }
-
-            m_log.InfoFormat("[IRC-Connector-{0}] Closed", idn);
-
-        }
-
-        #endregion
-
-        #region session management
-
-        // Connect to the IRC server. A connector should always be connected, once enabled
-
-        public void Connect()
-        {
-
-            if (!m_enabled)
-                return;
-
-            // Delay until next WD cycle if this is too close to the last start attempt
-
-            while (_icc_ < ICCD_PERIOD)
-                return;
-
-            m_log.DebugFormat("[IRC-Connector-{0}]: Connection request for {1} on {2}:{3}", idn, m_nick, m_server, m_ircChannel);
-
-            lock (msyncConnect)
-            {
-
-                _icc_ = 0;
-
-                try
-                {
-                    if (m_connected) return;
-
-                    m_connected = true;
-
-                    m_tcp    = new TcpClient(m_server, (int)m_port);
-                    m_stream = m_tcp.GetStream();
-                    m_reader = new StreamReader(m_stream);
-                    m_writer = new StreamWriter(m_stream);
-
-                    m_log.InfoFormat("[IRC-Connector-{0}]: Connected to {1}:{2}", idn, m_server, m_port); 
-
-                    m_listener = new Thread(new ThreadStart(ListenerRun));
-                    m_listener.Name = "IRCConnectorListenerThread";
-                    m_listener.IsBackground = true;
-                    m_listener.Start();
-                    ThreadTracker.Add(m_listener);
-
-                    // This is the message order recommended by RFC 2812
-
-                    m_writer.WriteLine(String.Format("NICK {0}", m_nick));
-                    m_writer.Flush();
-                    m_writer.WriteLine(m_user);
-                    m_writer.Flush();
-                    m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel));
-                    m_writer.Flush();
-
-                    m_log.InfoFormat("[IRC-Connector-{0}]: {1} has joined {2}", idn, m_nick, m_ircChannel);
-                    m_log.InfoFormat("[IRC-Connector-{0}] Connected", idn);
-
-                }
-                catch (Exception e)
-                {
-                    m_log.ErrorFormat("[IRC-Connector-{0}] cannot connect {1} to {2}:{3}: {4}",
-                                      idn, m_nick, m_server, m_port, e.Message);
-                    m_connected = false;
-                }
-
-            }
-
-            return;
-
-        }
-
-        // Reconnect is used to force a re-cycle of the IRC connection. Should generally
-        // be a transparent event
-
-        public void Reconnect()
-        {
-
-            m_log.DebugFormat("[IRC-Connector-{0}]: Reconnect request for {1} on {2}:{3}", idn, m_nick, m_server, m_ircChannel);
-
-            // Don't do this if a Connect is in progress...
-
-            lock (msyncConnect)
-            {
-
-                if (m_connected)
-                {
-                    m_log.InfoFormat("[IRC-Connector-{0}] Resetting connector", idn);
-
-                    // Mark as disconnected. This will allow the listener thread
-                    // to exit if still in-flight.
-
-
-                    // The listener thread is not aborted - it *might* actually be
-                    // the thread that is running the Reconnect! Instead just close
-                    // the socket and it will disappear of its own accord, once this
-                    // processing is completed.
-
-                    try { m_writer.Close(); } catch (Exception) {}
-                    try { m_reader.Close(); } catch (Exception) {}
-                    try { m_tcp.Close();    } catch (Exception) {}
-
-                    m_connected = false;
-
-                }
-
-            }
-
-            Connect();
-
-        }
-
-        #endregion
-
-        #region Outbound (to-IRC) message handlers
-
-        public void PrivMsg(string pattern, string from, string region, string msg)
-        {
-
-            m_log.DebugFormat("[IRC-Connector-{0}] PrivMsg to IRC from {1}: <{2}>", idn, from, 
-                String.Format(pattern, m_ircChannel, from, region, msg));
-
-            // One message to the IRC server
-
-            try
-            {
-                m_writer.WriteLine(pattern, m_ircChannel, from, region, msg);
-                m_writer.Flush();
-                m_log.DebugFormat("[IRC-Connector-{0}]: PrivMsg from {1} in {2}: {3}", idn, from, region, msg);
-            }
-            catch (IOException)
-            {
-                m_log.ErrorFormat("[IRC-Connector-{0}]: PrivMsg I/O Error: disconnected from IRC server", idn);
-                Reconnect();
-            }
-            catch (Exception ex)
-            {
-                m_log.ErrorFormat("[IRC-Connector-{0}]: PrivMsg exception : {1}", idn, ex.Message);
-                m_log.Debug(ex);
-            }
-
-        }
-
-        public void Send(string msg)
-        {
-
-            m_log.DebugFormat("[IRC-Connector-{0}] Send to IRC : <{1}>", idn,  msg);
-
-            try
-            {
-                m_writer.WriteLine(msg);
-                m_writer.Flush();
-                m_log.DebugFormat("[IRC-Connector-{0}] Sent command string: {1}", idn, msg);
-            }
-            catch (IOException)
-            {
-                m_log.ErrorFormat("[IRC-Connector-{0}] Disconnected from IRC server.(Send)", idn);
-                Reconnect();
-            }
-            catch (Exception ex)
-            {
-                m_log.ErrorFormat("[IRC-Connector-{0}] Send exception trap: {0}", idn, ex.Message);
-                m_log.Debug(ex);
-            }
-
-        }
-
-        #endregion
-
-        public void ListenerRun()
-        {
-            string inputLine;
-
-            try
-            {
-                while (m_enabled && m_connected)
-                {
-
-                    if ((inputLine = m_reader.ReadLine()) == null)
-                        throw new Exception("Listener input socket closed");
-
-                    // m_log.Info("[IRCConnector]: " + inputLine);
-
-                    if (inputLine.Contains("PRIVMSG"))
-                    {
-
-                        Dictionary<string, string> data = ExtractMsg(inputLine);
-
-                        // Any chat ???
-                        if (data != null)
-                        {
-
-                            OSChatMessage c = new OSChatMessage();
-                            c.Message = data["msg"];
-                            c.Type = ChatTypeEnum.Region;
-                            c.Position = CenterOfRegion;
-                            c.From = data["nick"];
-                            c.Sender = null;
-                            c.SenderUUID = UUID.Zero;
-
-                            // Is message "\001ACTION foo bar\001"? 
-                            // Then change to: "/me foo bar"
-
-                            if ((1 == c.Message[0]) && c.Message.Substring(1).StartsWith("ACTION"))
-                                c.Message = String.Format("/me {0}", c.Message.Substring(8, c.Message.Length - 9));
-
-                            ChannelState.OSChat(this, c, false);
-
-                        }
-
-                    }
-                    else
-                    {
-                        ProcessIRCCommand(inputLine);
-                    }
-                }
-            }
-            catch (Exception /*e*/)
-            {
-                // m_log.ErrorFormat("[IRC-Connector-{0}]: ListenerRun exception trap: {1}", idn, e.Message);
-                // m_log.Debug(e);
-            }
-
-            if (m_enabled) Reconnect();
-
-        }
-
-        private Regex RE = new Regex(@":(?<nick>[\w-]*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)", 
-                                     RegexOptions.Multiline);
-
-        private Dictionary<string, string> ExtractMsg(string input)
-        {
-            //examines IRC commands and extracts any private messages
-            // which will then be reboadcast in the Sim
-
-            // m_log.InfoFormat("[IRC-Connector-{0}]: ExtractMsg: {1}", idn, input);
-
-            Dictionary<string, string> result = null;
-            MatchCollection matches = RE.Matches(input);
-
-            // Get some direct matches $1 $4 is a
-            if ((matches.Count == 0) || (matches.Count != 1) || (matches[0].Groups.Count != 5))
-            {
-                // m_log.Info("[IRCConnector]: Number of matches: " + matches.Count);
-                // if (matches.Count > 0)
-                // {
-                //     m_log.Info("[IRCConnector]: Number of groups: " + matches[0].Groups.Count);
-                // }
-                return null;
-            }
-
-            result = new Dictionary<string, string>();
-            result.Add("nick", matches[0].Groups[1].Value);
-            result.Add("user", matches[0].Groups[2].Value);
-            result.Add("channel", matches[0].Groups[3].Value);
-            result.Add("msg", matches[0].Groups[4].Value);
-
-            return result;
-        }
-
-        public void BroadcastSim(string sender, string format, params string[] args)
-        {
-            try
-            {
-                OSChatMessage c = new OSChatMessage();
-                c.From = sender;
-                c.Message = String.Format(format, args);
-                c.Type = ChatTypeEnum.Region; // ChatTypeEnum.Say;
-                c.Position = CenterOfRegion;
-                c.Sender = null;
-                c.SenderUUID = UUID.Zero;
-
-                ChannelState.OSChat(this, c, true);
-
-            }
-            catch (Exception ex) // IRC gate should not crash Sim
-            {
-                m_log.ErrorFormat("[IRC-Connector-{0}]: BroadcastSim Exception Trap: {1}\n{2}", idn, ex.Message, ex.StackTrace);
-            }
-        }
-
-        #region IRC Command Handlers
-
-        public void ProcessIRCCommand(string command)
-        {
-
-            string[] commArgs;
-            string c_server = m_server;
-
-            string pfx   = String.Empty;
-            string cmd   = String.Empty;
-            string parms = String.Empty;
-
-            // ":" indicates that a prefix is present
-            // There are NEVER more than 17 real 
-            // fields. A parameter that starts with 
-            // ":" indicates that the remainder of the
-            // line is a single parameter value.
-
-            commArgs = command.Split(CS_SPACE,2);
-
-            if (commArgs[0].StartsWith(":"))
-            {
-                pfx = commArgs[0].Substring(1);
-                commArgs = commArgs[1].Split(CS_SPACE,2);
-            }
-
-            cmd   = commArgs[0];
-            parms = commArgs[1];
-
-            // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}>", idn, pfx, cmd);
-
-            switch (cmd)
-            {
-
-                // Messages 001-004 are always sent
-                // following signon.
-
-                case "001" : // Welcome ...
-                case "002" : // Server information
-                case "003" : // Welcome ...
-                    break;
-                case "004" : // Server information
-                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
-                    commArgs = parms.Split(CS_SPACE);
-                    c_server = commArgs[1];
-                    m_server = c_server;
-                    version  = commArgs[2];
-                    usermod  = commArgs[3];
-                    chanmod  = commArgs[4];
-                    break;
-                case "005" : // Server information
-                    break;
-                case "042" :
-                case "250" :
-                case "251" :
-                case "252" :
-                case "254" :
-                case "255" :
-                case "265" :
-                case "266" :
-                case "332" : // Subject
-                case "333" : // Subject owner (?)
-                case "353" : // Name list
-                case "366" : // End-of-Name list marker
-                case "372" : // MOTD body
-                case "375" : // MOTD start
-                    m_log.InfoFormat("[IRC-Connector-{0}] {1}", idn, parms.Split(CS_SPACE,2)[1]);
-                    break;
-                case "376" : // MOTD end
-                    m_log.InfoFormat("[IRC-Connector-{0}] {1}", idn, parms.Split(CS_SPACE,2)[1]);
-                    motd = true;
-                    break;
-                case "451" : // Not registered
-                    break;
-                case "433" : // Nickname in use
-                    // Gen a new name
-                    m_nick = m_baseNick + Util.RandomClass.Next(1, 99);
-                    m_log.ErrorFormat("[IRC-Connector-{0}]: IRC SERVER reports NicknameInUse, trying {1}", idn, m_nick);
-                    // Retry
-                    m_writer.WriteLine(String.Format("NICK {0}", m_nick));
-                    m_writer.Flush();
-                    m_writer.WriteLine(m_user);
-                    m_writer.Flush();
-                    m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel));
-                    m_writer.Flush();
-                    break;
-                case "NOTICE" :
-                    m_log.WarnFormat("[IRC-Connector-{0}] {1}", idn, parms.Split(CS_SPACE,2)[1]);
-                    break;
-                case "ERROR"  :
-                    m_log.ErrorFormat("[IRC-Connector-{0}] {1}", idn, parms.Split(CS_SPACE,2)[1]);
-                    if (parms.Contains("reconnect too fast"))
-                        ICCD_PERIOD++;
-                    break;
-                case "PING"   :
-                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
-                    m_writer.WriteLine(String.Format("PONG {0}", parms));
-                    m_writer.Flush();
-                    break;
-                case "PONG"   :
-                    break;
-                case "JOIN":
-                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
-                    eventIrcJoin(pfx, cmd, parms);
-                    break;
-                case "PART":
-                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
-                    eventIrcPart(pfx, cmd, parms);
-                    break;
-                case "MODE":
-                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
-                    eventIrcMode(pfx, cmd, parms);
-                    break;
-                case "NICK":
-                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
-                    eventIrcNickChange(pfx, cmd, parms);
-                    break;
-                case "KICK":
-                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
-                    eventIrcKick(pfx, cmd, parms);
-                    break;
-                case "QUIT":
-                    m_log.DebugFormat("[IRC-Connector-{0}] parms = <{1}>", idn, parms);
-                    eventIrcQuit(pfx, cmd, parms);
-                    break;
-                default    :
-                    m_log.DebugFormat("[IRC-Connector-{0}] Command '{1}' ignored, parms = {2}", idn, cmd, parms);
-                    break;
-            }
-
-            // m_log.DebugFormat("[IRC-Connector-{0}] prefix = <{1}> cmd = <{2}> complete", idn, pfx, cmd);
-  
-        }
-
-        public void eventIrcJoin(string prefix, string command, string parms)
-        {
-            string[]     args = parms.Split(CS_SPACE,2);
-            string IrcUser    = prefix.Split('!')[0];
-            string IrcChannel = args[0];
-
-            if (IrcChannel.StartsWith(":"))
-                IrcChannel = IrcChannel.Substring(1);
-
-            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCJoin {1}:{2}", idn, m_server, m_ircChannel);
-            BroadcastSim(IrcUser, "/me joins {0}", IrcChannel);
-        }
-
-        public void eventIrcPart(string prefix, string command, string parms)
-        {
-            string[]     args = parms.Split(CS_SPACE,2);
-            string    IrcUser = prefix.Split('!')[0];
-            string IrcChannel = args[0];
-
-            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCPart {1}:{2}", idn, m_server, m_ircChannel);
-            BroadcastSim(IrcUser, "/me parts {0}", IrcChannel);
-        }
-
-        public void eventIrcMode(string prefix, string command, string parms)
-        {
-            string[]   args = parms.Split(CS_SPACE,2);
-            string UserMode = args[1];
-
-            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCMode {1}:{2}", idn, m_server, m_ircChannel);
-            if (UserMode.Substring(0, 1) == ":")
-            {
-                UserMode = UserMode.Remove(0, 1);
-            }
-        }
-
-        public void eventIrcNickChange(string prefix, string command, string parms)
-        {
-            string[]      args = parms.Split(CS_SPACE,2);
-            string UserOldNick = prefix.Split('!')[0];
-            string UserNewNick = args[0].Remove(0, 1);
-
-            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCNickChange {1}:{2}", idn, m_server, m_ircChannel);
-            BroadcastSim(UserOldNick, "/me is now known as {0}", UserNewNick);
-        }
-
-        public void eventIrcKick(string prefix, string command, string parms)
-        {
-            string[]      args = parms.Split(CS_SPACE,3);
-            string UserKicker  = prefix.Split('!')[0];
-            string IrcChannel  = args[0];
-            string UserKicked  = args[1];
-            string KickMessage = args[2]; 
-
-            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCKick {1}:{2}", idn, m_server, m_ircChannel);
-            BroadcastSim(UserKicker, "/me kicks kicks {0} off {1} saying \"{2}\"", UserKicked, IrcChannel, KickMessage);
-
-            if (UserKicked == m_nick)
-            {
-                BroadcastSim(m_nick, "Hey, that was me!!!");
-            }
-
-        }
-
-        public void eventIrcQuit(string prefix, string command, string parms)
-        {
-            string     IrcUser = prefix.Split('!')[0];
-            string QuitMessage = parms;
-
-            m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCQuit {1}:{2}", idn, m_server, m_ircChannel);
-            BroadcastSim(IrcUser, "/me quits saying \"{0}\"", QuitMessage);
-        }
-
-        #endregion
-
-        #region Connector Watch Dog
-
-        // A single watch dog monitors extant connectors and makes sure that they
-        // are re-connected as necessary. If a connector IS connected, then it is
-        // pinged, but only if a PING period has elapsed.
-
-        protected static void WatchdogHandler(Object source, ElapsedEventArgs args)
-        {
-
-            // m_log.InfoFormat("[IRC-Watchdog] Status scan");
-
-            _pdk_ = (_pdk_+1)%PING_PERIOD;    // cycle the ping trigger
-            _icc_++;    // increment the inter-consecutive-connect-delay counter
-
-            foreach (XIRCConnector connector in m_connectors)
-            {
-                if (connector.Enabled)
-                {
-                    if (!connector.Connected)
-                    {
-                        try
-                        {
-                            // m_log.DebugFormat("[IRC-Watchdog] Connecting {1}:{2}", connector.idn, connector.m_server, connector.m_ircChannel);
-                            connector.Connect();
-                        }
-                        catch (Exception e)
-                        {
-                            m_log.ErrorFormat("[IRC-Watchdog] Exception on connector {0}: {1} ", connector.idn, e.Message);
-                        }
-                    }
-                    else
-                    {
-                        if (_pdk_ == 0)
-                        {
-                            try
-                            {
-                                connector.m_writer.WriteLine(String.Format("PING :{0}", connector.m_server));
-                                connector.m_writer.Flush();
-                            }
-                            catch (Exception /*e*/)
-                            {
-                                // m_log.ErrorFormat("[IRC-PingRun] Exception on connector {0}: {1} ", connector.idn, e.Message);
-                                // m_log.Debug(e);
-                                connector.Reconnect();
-                            }
-                        }
-                    }
-                }
-            }
-
-            // m_log.InfoFormat("[IRC-Watchdog] Status scan completed");
-
-        }
-
-        #endregion
-
-    }
-}
-- 
cgit v1.1