From 69ae33db1ad6a5111211d6ccc6c3b2ac2467f4d0 Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Mon, 3 Nov 2008 17:11:28 +0000 Subject: [PATCH] dropping old IRCBridgeModule. --- .../Modules/Avatar/Chat/IRCBridgeModule.cs | 393 ---------- .../Modules/Avatar/Chat/IRCConnector.cs | 702 ------------------ 2 files changed, 1095 deletions(-) delete mode 100644 OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs delete mode 100644 OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs deleted file mode 100644 index 482f469e1f..0000000000 --- a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCBridgeModule.cs +++ /dev/null @@ -1,393 +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.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 IRCBridgeModule : IRegionModule - { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private const int DEBUG_CHANNEL = 2147483647; - - - private IRCConnector m_irc = null; - - private string m_last_leaving_user = null; - private string m_last_new_user = null; - private List m_scenes = new List(); - private List m_validInWorldChannels = new List(); - - internal object m_syncInit = new object(); - internal object m_syncLogout = new object(); - - private IConfig m_config; - private string m_defaultzone = null; - private bool m_commandsEnabled = false; - private int m_commandChannel = -1; - private bool m_relayPrivateChannels = false; - private int m_relayChannelOut = -1; - private bool m_clientReporting = true; - private bool m_relayChat = true; - private Regex m_accessPasswordRe = null; - - #region IRegionModule Members - - public void Initialise(Scene scene, IConfigSource config) - { - try - { - if ((m_config = config.Configs["OIRC"]) == null) - { - m_log.InfoFormat("[IRC] module not configured"); - return; - } - - if (!m_config.GetBoolean("enabled", false)) - { - m_log.InfoFormat("[IRC] module disabled in configuration"); - return; - } - } - catch (Exception) - { - m_log.Info("[IRC] module not configured"); - return; - } - - m_commandsEnabled = m_config.GetBoolean("commands_enabled", m_commandsEnabled); - m_commandChannel = m_config.GetInt("commandchannel", m_commandChannel); // compat - m_commandChannel = m_config.GetInt("command_channel", m_commandChannel); - - m_relayPrivateChannels = m_config.GetBoolean("relay_private_channels", m_relayPrivateChannels); - m_relayChannelOut = m_config.GetInt("relay_private_channel_out", m_relayChannelOut); - m_relayChat = m_config.GetBoolean("relay_chat", m_relayChat); - - m_clientReporting = m_config.GetBoolean("report_clients", m_clientReporting); - - if (m_accessPasswordRe == null) - { - string pass = config.Configs["IRC"].GetString("access_password", String.Empty); - m_accessPasswordRe = new Regex(String.Format(@"^{0},(?[^,]+),(?.+)$", pass), - RegexOptions.Compiled); - } - - if (m_relayChat) - { - m_validInWorldChannels.Add(0); - m_validInWorldChannels.Add(DEBUG_CHANNEL); - } - - if (m_relayPrivateChannels) - m_validInWorldChannels.Add(m_relayChannelOut); - - - lock (m_syncInit) - { - - if (!m_scenes.Contains(scene)) - { - m_scenes.Add(scene); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnChatFromWorld += OnSimChat; - scene.EventManager.OnChatFromClient += OnSimChat; - scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; - scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; - } - - try - { - m_defaultzone = config.Configs["IRC"].GetString("fallback_region", "Sim"); - } - catch (Exception) - { - } - - // setup IRC Relay - if (m_irc == null) - { - m_irc = new IRCConnector(config); - } - m_irc.AddScene(scene); - - m_log.InfoFormat("[IRC] initialized for {0}, nick: {1}, commands {2}, private channels {3}", - scene.RegionInfo.RegionName, m_defaultzone, - m_commandsEnabled ? "enabled" : "not enabled", - m_relayPrivateChannels ? "relayed" : "not relayed"); - } - } - - public void PostInitialise() - { - if (null == m_irc || !m_irc.Enabled) return; - m_irc.Start(); - } - - public void Close() - { - if (null != m_irc) - { - m_irc.Close(); - m_log.Info("[IRC] closed connection to IRC server"); - } - } - - public string Name - { - get { return "IRCBridgeModule"; } - } - - public bool IsSharedModule - { - get { return true; } - } - - #endregion - - #region ISimChat Members - - public void OnSimChat(Object sender, OSChatMessage c) - { - // early return if nothing to forward - if (c.Message.Length == 0) return; - - // early return if this comes from the IRC forwarder - if (m_irc.Equals(sender)) return; - - m_log.DebugFormat("[IRC] heard on channel {0}: {1}", c.Channel, c.Message); - - // check for commands coming from avatars or in-world - // object (if commands are enabled) - if (m_commandsEnabled && c.Channel == m_commandChannel) - { - string[] messages = c.Message.Split(' '); - string command = messages[0].ToLower(); - - try - { - switch (command) - { - case "channel": - m_irc.IrcChannel = messages[1]; - break; - case "close": - m_irc.Close(); - break; - case "connect": - m_irc.Connect(); - break; - case "nick": - m_irc.Nick = messages[1]; - break; - case "port": - m_irc.Port = Convert.ToUInt32(messages[1]); - break; - case "reconnect": - m_irc.Reconnect(); - break; - case "server": - m_irc.Server = messages[1]; - break; - case "client-reporting": - m_irc.ClientReporting = Convert.ToBoolean(messages[1]); - - break; - case "in-channel": - m_irc.RelayChannel = Convert.ToInt32(messages[1]); - break; - case "out-channel": - m_relayChannelOut = Convert.ToInt32(messages[1]); - break; - - default: - m_irc.Send(c.Message); - break; - } - } - catch (Exception ex) - { - m_log.DebugFormat("[IRC] error processing in-world command channel input: {0}", ex); - } - } - - // drop messages if their channel is not on the valid - // in-world channel list - if (!m_validInWorldChannels.Contains(c.Channel)) - { - m_log.DebugFormat("[IRC] dropping message {0} on channel {1}", c, c.Channel); - return; - } - - ScenePresence avatar = null; - Scene scene = (Scene)c.Scene; - - if (scene == null) - scene = m_scenes[0]; - - string fromName = c.From; - - if (c.Sender != null) - { - avatar = scene.GetScenePresence(c.Sender.AgentId); - if (avatar != null) fromName = avatar.Name; - } - - if (!m_irc.Connected) - { - m_log.WarnFormat("[IRC] IRCConnector not connected: dropping message from {0}", fromName); - return; - } - - if (null != avatar && m_relayChat) - { - string msg = c.Message; - if (msg.StartsWith("/me ")) - msg = String.Format("{0} {1}", fromName, c.Message.Substring(4)); - - m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, msg); - return; - } - - if (null == avatar && m_relayPrivateChannels) - { - Match m; - if (m_accessPasswordRe != null && - (m = m_accessPasswordRe.Match(c.Message)) != null) - { - m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(), - m.Groups["message"].ToString()); - m_irc.PrivMsg(m.Groups["avatar"].ToString(), scene.RegionInfo.RegionName, - m.Groups["message"].ToString()); - } - return; - } - } - #endregion - - public void OnNewClient(IClientAPI client) - { - try - { - client.OnLogout += OnClientLoggedOut; - client.OnConnectionClosed += OnClientLoggedOut; - - if (client.Name != m_last_new_user) - { - if ((m_irc.Enabled) && (m_irc.Connected) && (m_clientReporting)) - { - m_log.DebugFormat("[IRC] {0} logging on", client.Name); - m_irc.PrivMsg(m_irc.Nick, "Sim", String.Format("notices {0} logging on", client.Name)); - } - m_last_new_user = client.Name; - } - } - catch (Exception ex) - { - m_log.Error("[IRC]: OnNewClient exception trap:" + ex.ToString()); - } - } - - public void OnMakeRootAgent(ScenePresence presence) - { - try - { - if ((m_irc.Enabled) && (m_irc.Connected) && (m_clientReporting)) - { - string regionName = presence.Scene.RegionInfo.RegionName; - string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); - m_log.DebugFormat("[IRC] noticing {0} in {1}", clientName, regionName); - m_irc.PrivMsg(m_irc.Nick, "Sim", String.Format("notices {0} in {1}", clientName, regionName)); - } - } - catch (Exception) - { - } - } - - public void OnMakeChildAgent(ScenePresence presence) - { - try - { - if ((m_irc.Enabled) && (m_irc.Connected) && (m_clientReporting)) - { - string regionName = presence.Scene.RegionInfo.RegionName; - string clientName = String.Format("{0} {1}", presence.Firstname, presence.Lastname); - m_log.DebugFormat("[IRC] noticing {0} in {1}", clientName, regionName); - m_irc.PrivMsg(m_irc.Nick, "Sim", String.Format("notices {0} left {1}", clientName, regionName)); - } - } - catch (Exception) - { - } - } - - - public void OnClientLoggedOut(IClientAPI client) - { - lock (m_syncLogout) - { - try - { - if ((m_irc.Enabled) && (m_irc.Connected) && (m_clientReporting)) - { - // handles simple case. May not work for - // hundred connecting in per second. and - // OnNewClients calle getting interleaved but - // filters out multiple reports - if (client.Name != m_last_leaving_user) - { - m_last_leaving_user = client.Name; - m_irc.PrivMsg(m_irc.Nick, "Sim", String.Format("notices {0} logging out", client.Name)); - m_log.InfoFormat("[IRC]: {0} logging out", client.Name); - } - - if (m_last_new_user == client.Name) - m_last_new_user = null; - } - } - catch (Exception ex) - { - m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString()); - } - } - } - } -} diff --git a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs deleted file mode 100644 index 29ba17d1ec..0000000000 --- a/OpenSim/Region/Environment/Modules/Avatar/Chat/IRCConnector.cs +++ /dev/null @@ -1,702 +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.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 ErrorReplies enum - - public enum ErrorReplies - { - NotRegistered = 451, // ":You have not registered" - NicknameInUse = 433 // " :Nickname is already in use" - } - - #endregion - - #region Replies enum - - public enum Replies - { - MotdStart = 375, // ":- Message of the day - " - Motd = 372, // ":- " - EndOfMotd = 376 // ":End of /MOTD command" - } - - #endregion - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private Thread m_listener = null; - private Thread m_watchdog = null; - private Thread m_pinger = null; - - private bool m_randomizeNick = true; - - public string m_baseNick = null; - private string m_nick = null; - public string Nick - { - get { return m_baseNick; } - set { m_baseNick = value; } - } - - private bool m_enabled = false; - public bool Enabled - { - get { return m_enabled; } - } - - private bool m_connected = false; - public bool Connected - { - get { return m_connected; } - } - - private string m_ircChannel; - public string IrcChannel - { - get { return m_ircChannel; } - - set { m_ircChannel = value; } - } - - private bool m_relayPrivateChannels = false; - public bool RelayPrivateChannels - { - get { return m_relayPrivateChannels; } - set { m_relayPrivateChannels = value; } - } - - private int m_relayChannel = 0; - public int RelayChannel - { - get { return m_relayChannel; } - set { m_relayChannel = value; } - } - - private bool m_clientReporting = true; - public bool ClientReporting - { - get { return m_clientReporting; } - set { m_clientReporting = value; } - } - - private uint m_port = 6667; - public uint Port - { - get { return m_port; } - set { m_port = value; } - } - - private string m_server = null; - public string Server - { - get { return m_server; } - set { m_server = value; } - } - - private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; - private StreamReader m_reader; - private List m_scenes = new List(); - - private NetworkStream m_stream = null; - internal object m_syncConnect = new object(); - private TcpClient m_tcp; - private string m_user = "USER OpenSimBot 8 * :I'm an OpenSim to IRC bot"; - private StreamWriter m_writer; - - - public IRCConnector(IConfigSource config) - { - m_tcp = null; - m_writer = null; - m_reader = null; - - // configuration in OpenSim.ini - // [IRC] - // server = chat.freenode.net - // nick = OSimBot_mysim - // nicknum = true - // ;nicknum set to true appends a 2 digit random number to the nick - // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot - // ; username is the IRC command line sent - // ; USER * : - // channel = #opensim-regions - // port = 6667 - // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message - // ;for : : - // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}" - // ;for : - : - // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}" - // ;for : - from : - // ;msgformat = "PRIVMSG {0} : {3} - from {1}" - // Traps I/O disconnects so it does not crash the sim - // Trys to reconnect if disconnected and someone says something - // Tells IRC server "QUIT" when doing a close (just to be nice) - // Default port back to 6667 - - try - { - m_server = config.Configs["OIRC"].GetString("server"); - m_baseNick = config.Configs["OIRC"].GetString("nick", "OSimBot"); - - m_randomizeNick = config.Configs["OIRC"].GetBoolean("randomize_nick", m_randomizeNick); - m_randomizeNick = config.Configs["OIRC"].GetBoolean("nicknum", m_randomizeNick); // compat - m_ircChannel = config.Configs["OIRC"].GetString("channel"); - m_port = (uint)config.Configs["OIRC"].GetInt("port", (int)m_port); - m_user = config.Configs["OIRC"].GetString("username", m_user); - m_privmsgformat = config.Configs["OIRC"].GetString("msgformat", m_privmsgformat); - - m_clientReporting = config.Configs["OIRC"].GetInt("verbosity", 2) > 0; - m_clientReporting = config.Configs["OIRC"].GetBoolean("report_clients", m_clientReporting); - - m_relayPrivateChannels = config.Configs["OIRC"].GetBoolean("relay_private_channels", m_relayPrivateChannels); - m_relayPrivateChannels = config.Configs["OIRC"].GetBoolean("useworldcomm", m_relayPrivateChannels); //compat - m_relayChannel = config.Configs["OIRC"].GetInt("relay_private_channel_in", m_relayChannel); - m_relayChannel = config.Configs["OIRC"].GetInt("inchannel", m_relayChannel); - - if (m_server != null && m_baseNick != null && m_ircChannel != null) - { - if (m_randomizeNick) - { - m_nick = m_baseNick + Util.RandomClass.Next(1, 99); - } - m_enabled = true; - } - } - catch (Exception ex) - { - m_log.Error("[IRCConnector]: Incomplete IRC configuration, skipping IRC bridge configuration"); - m_log.DebugFormat("[IRCConnector] Incomplete IRC configuration: {0}", ex.ToString()); - } - - if (null == m_watchdog) - { - m_watchdog = new Thread(WatchdogRun); - m_watchdog.Name = "IRCWatchdog"; - m_watchdog.IsBackground = true; - } - } - - public void Start() - { - if (!m_watchdog.IsAlive) - { - m_watchdog.Start(); - ThreadTracker.Add(m_watchdog); - } - } - - public void AddScene(Scene scene) - { - lock (m_syncConnect) m_scenes.Add(scene); - } - - public bool Connect() - { - lock (m_syncConnect) - { - try - { - if (m_connected) return 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.DebugFormat("[IRCConnector]: Connected to {0}:{1}", m_server, m_port); - - m_pinger = new Thread(new ThreadStart(PingRun)); - m_pinger.Name = "PingSenderThread"; - m_pinger.IsBackground = true; - m_pinger.Start(); - ThreadTracker.Add(m_pinger); - - m_listener = new Thread(new ThreadStart(ListenerRun)); - m_listener.Name = "IRCConnectorListenerThread"; - m_listener.IsBackground = true; - m_listener.Start(); - ThreadTracker.Add(m_listener); - - m_writer.WriteLine(m_user); - m_writer.Flush(); - m_writer.WriteLine(String.Format("NICK {0}", m_nick)); - m_writer.Flush(); - m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); - m_writer.Flush(); - m_log.Info("[IRCConnector]: Connection fully established"); - m_connected = true; - } - catch (Exception e) - { - m_log.ErrorFormat("[IRCConnector] cannot connect to {0}:{1}: {2}", - m_server, m_port, e.Message); - } - m_log.Debug("[IRCConnector] Connected"); - return m_connected; - } - } - - public void Reconnect() - { - m_connected = false; - try - { - m_listener.Abort(); - m_pinger.Abort(); - - m_writer.Close(); - m_reader.Close(); - - m_tcp.Close(); - } - catch (Exception) - { - } - - if (m_enabled) - { - Connect(); - } - } - - public void PrivMsg(string from, string region, string msg) - { - m_log.DebugFormat("[IRCConnector] Sending message to IRC from {0}: {1}", from, msg); - - // One message to the IRC server - try - { - m_writer.WriteLine(m_privmsgformat, m_ircChannel, from, region, msg); - m_writer.Flush(); - m_log.InfoFormat("[IRCConnector]: PrivMsg {0} in {1}: {2}", from, region, msg); - } - catch (IOException) - { - m_log.Error("[IRCConnector]: Disconnected from IRC server.(PrivMsg)"); - Reconnect(); - } - catch (Exception ex) - { - m_log.ErrorFormat("[IRCConnector]: PrivMsg exception trap: {0}", ex.ToString()); - } - } - - public void Send(string msg) - { - try - { - m_writer.WriteLine(msg); - m_writer.Flush(); - m_log.Info("IRC: Sent command string: " + msg); - } - catch (IOException) - { - m_log.Error("[IRCConnector]: Disconnected from IRC server.(PrivMsg)"); - Reconnect(); - } - catch (Exception ex) - { - m_log.ErrorFormat("[IRCConnector]: PrivMsg exception trap: {0}", ex.ToString()); - } - - } - - - private Dictionary ExtractMsg(string input) - { - //examines IRC commands and extracts any private messages - // which will then be reboadcast in the Sim - - m_log.Info("[IRCConnector]: ExtractMsg: " + input); - Dictionary result = null; - string regex = @":(?[\w-]*)!(?\S*) PRIVMSG (?\S+) :(?.*)"; - Regex RE = new Regex(regex, RegexOptions.Multiline); - 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(); - 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 PingRun() - { - // IRC keep alive thread - // send PING ever 15 seconds - while (m_enabled) - { - try - { - if (m_connected == true) - { - m_writer.WriteLine(String.Format("PING :{0}", m_server)); - m_writer.Flush(); - Thread.Sleep(15000); - } - } - catch (IOException) - { - if (m_enabled) - { - m_log.Error("[IRCConnector]: Disconnected from IRC server.(PingRun)"); - Reconnect(); - } - } - catch (Exception ex) - { - m_log.ErrorFormat("[IRCConnector]: PingRun exception trap: {0}\n{1}", ex.ToString(), ex.StackTrace); - } - } - } - - static private Vector3 CenterOfRegion = new Vector3(128, 128, 20); - public void ListenerRun() - { - string inputLine; - - while (m_enabled) - { - try - { - while ((m_connected) && ((inputLine = m_reader.ReadLine()) != null)) - { - // m_log.Info("[IRCConnector]: " + inputLine); - - if (inputLine.Contains(m_ircChannel)) - { - Dictionary data = ExtractMsg(inputLine); - // Any chat ??? - if (data != null) - { - OSChatMessage c = new OSChatMessage(); - c.Message = data["msg"]; - c.Type = ChatTypeEnum.Region; - c.Position = CenterOfRegion; - c.Channel = m_relayPrivateChannels ? m_relayChannel : 0; - c.From = data["nick"]; - c.Sender = null; - c.SenderUUID = UUID.Zero; - - // is message "\001ACTION foo - // bar\001"? -> "/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)); - - m_log.DebugFormat("[IRCConnector] ListenerRun from: {0}, {1}", c.From, c.Message); - - foreach (Scene scene in m_scenes) - { - c.Scene = scene; - scene.EventManager.TriggerOnChatBroadcast(this, c); - } - } - - Thread.Sleep(150); - continue; - } - - ProcessIRCCommand(inputLine); - Thread.Sleep(150); - } - } - catch (IOException) - { - if (m_enabled) - { - m_log.Error("[IRCConnector]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)"); - Reconnect(); - } - } - catch (Exception ex) - { - m_log.ErrorFormat("[IRCConnector]: ListenerRun exception trap: {0}\n{1}", ex.ToString(), ex.StackTrace); - } - } - } - - 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.Channel = m_relayPrivateChannels ? m_relayChannel : 0; - c.Position = CenterOfRegion; - c.Sender = null; - c.SenderUUID = UUID.Zero; - - m_log.DebugFormat("[IRCConnector] BroadcastSim from {0}: {1}", c.From, c.Message); - - foreach (Scene scene in m_scenes) - { - c.Scene = scene; - scene.EventManager.TriggerOnChatBroadcast(this, c); - // // m_scene.EventManager.TriggerOnChatFromWorld(this, c); - // IWorldComm wComm = m_scene.RequestModuleInterface(); - // wComm.DeliverMessage(ChatTypeEnum.Region, m_messageInChannel, sender, UUID.Zero, c.Message); - // //IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); - // //wComm.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text); - - } - } - catch (Exception ex) // IRC gate should not crash Sim - { - m_log.ErrorFormat("[IRCConnector]: BroadcastSim Exception Trap: {0}\n{1}", ex.ToString(), ex.StackTrace); - } - } - - public void ProcessIRCCommand(string command) - { - // m_log.Debug("[IRCConnector]: ProcessIRCCommand:" + command); - - string[] commArgs = new string[command.Split(' ').Length]; - string c_server = m_server; - - commArgs = command.Split(' '); - if (commArgs[0].Substring(0, 1) == ":") - { - commArgs[0] = commArgs[0].Remove(0, 1); - } - - if (commArgs[1] == "002") - { - // fetch the correct servername - // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/... - // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch - - c_server = (commArgs[6].Split('['))[0]; - m_server = c_server; - } - - if (commArgs[0] == "ERROR") - { - m_log.ErrorFormat("[IRCConnector]: IRC SERVER ERROR: {0}", command); - } - - if (commArgs[0] == "PING") - { - string p_reply = ""; - - for (int i = 1; i < commArgs.Length; i++) - { - p_reply += commArgs[i] + " "; - } - - m_writer.WriteLine(String.Format("PONG {0}", p_reply)); - m_writer.Flush(); - } - else if (commArgs[0] == c_server) - { - // server message - try - { - Int32 commandCode = Int32.Parse(commArgs[1]); - switch (commandCode) - { - case (int)ErrorReplies.NicknameInUse: - // Gen a new name - m_nick = m_baseNick + Util.RandomClass.Next(1, 99); - m_log.ErrorFormat("[IRCConnector]: IRC SERVER reports NicknameInUse, trying {0}", m_nick); - // Retry - m_writer.WriteLine(String.Format("NICK {0}", m_nick)); - m_writer.Flush(); - m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel)); - m_writer.Flush(); - break; - case (int)ErrorReplies.NotRegistered: - break; - case (int)Replies.EndOfMotd: - break; - } - } - catch (Exception) - { - } - } - else - { - // Normal message - string commAct = commArgs[1]; - switch (commAct) - { - case "JOIN": - eventIrcJoin(commArgs); - break; - case "PART": - eventIrcPart(commArgs); - break; - case "MODE": - eventIrcMode(commArgs); - break; - case "NICK": - eventIrcNickChange(commArgs); - break; - case "KICK": - eventIrcKick(commArgs); - break; - case "QUIT": - eventIrcQuit(commArgs); - break; - case "PONG": - break; // that's nice - } - } - } - - public void eventIrcJoin(string[] commArgs) - { - string IrcChannel = commArgs[2]; - if (IrcChannel.StartsWith(":")) - IrcChannel = IrcChannel.Substring(1); - string IrcUser = commArgs[0].Split('!')[0]; - if (m_clientReporting) - BroadcastSim(IrcUser, "/me joins {0}", IrcChannel); - } - - public void eventIrcPart(string[] commArgs) - { - string IrcChannel = commArgs[2]; - string IrcUser = commArgs[0].Split('!')[0]; - if (m_clientReporting) - BroadcastSim(IrcUser, "/me parts {0}", IrcChannel); - } - - public void eventIrcMode(string[] commArgs) - { - string UserMode = ""; - for (int i = 3; i < commArgs.Length; i++) - { - UserMode += commArgs[i] + " "; - } - - if (UserMode.Substring(0, 1) == ":") - { - UserMode = UserMode.Remove(0, 1); - } - } - - public void eventIrcNickChange(string[] commArgs) - { - string UserOldNick = commArgs[0].Split('!')[0]; - string UserNewNick = commArgs[2].Remove(0, 1); - if (m_clientReporting) - BroadcastSim(UserOldNick, "/me is now known as {0}", UserNewNick); - } - - public void eventIrcKick(string[] commArgs) - { - string UserKicker = commArgs[0].Split('!')[0]; - string UserKicked = commArgs[3]; - string IrcChannel = commArgs[2]; - string KickMessage = ""; - for (int i = 4; i < commArgs.Length; i++) - { - KickMessage += commArgs[i] + " "; - } - if (m_clientReporting) - 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[] commArgs) - { - string IrcUser = commArgs[0].Split('!')[0]; - string QuitMessage = ""; - - for (int i = 2; i < commArgs.Length; i++) - { - QuitMessage += commArgs[i] + " "; - } - if (m_clientReporting) - BroadcastSim(IrcUser, "/me quits saying \"{0}\"", QuitMessage); - } - - public void Close() - { - m_writer.WriteLine(String.Format("QUIT :{0} to {1} wormhole to {2} closing", - m_nick, m_ircChannel, m_server)); - m_writer.Flush(); - - m_connected = false; - m_enabled = false; - - //listener.Abort(); - //pingSender.Abort(); - - m_writer.Close(); - m_reader.Close(); - m_stream.Close(); - m_tcp.Close(); - } - - protected void WatchdogRun() - { - while (m_enabled) - { - if (!m_connected) Connect(); - Thread.Sleep(15000); - } - } - } -}