/// <summary> /// Connection /// </summary> /// <returns></returns> public void Connect() { try { if (!config.UsingNetworkIOLayer) { networkStream = new System.Net.Sockets.TcpClient(Server, 6667).GetStream(); } else { core.Log(ParentInstance.Nick + " is using personal bouncer port " + BouncerPort.ToString()); networkStream = new System.Net.Sockets.TcpClient(Bouncer, BouncerPort).GetStream(); Program.Log("System is using external bouncer"); } connected = true; streamReader = new System.IO.StreamReader(networkStream, System.Text.Encoding.UTF8); streamWriter = new System.IO.StreamWriter(networkStream); bool Auth = true; List <string> Backlog = new List <string>(); if (config.UsingNetworkIOLayer) { SendData("CONTROL: STATUS"); Program.Log("CACHE: Waiting for buffer"); bool done = true; while (done) { string response = streamReader.ReadLine(); if (response == "CONTROL: TRUE") { done = false; Auth = false; ChannelsJoined = true; IsWorking = true; } else if (response.StartsWith(":")) { Backlog.Add(response); } else if (response == "CONTROL: FALSE") { done = false; SendData("CONTROL: CREATE"); streamWriter.Flush(); } } } _Queue = new System.Threading.Thread(_SlowQueue.Run); check_thread = new System.Threading.Thread(Ping); check_thread.Start(); if (Auth) { SendData("USER " + UserName + " 8 * :" + Ident); SendData("NICK " + ParentInstance.Nick); } _Queue.Start(); if (Auth) { Authenticate(); } string nick = ""; string host = ""; string channel = ""; const char delimiter = (char)001; while (IsConnected) { try { while ((!streamReader.EndOfStream || Backlog.Count > 0) && core._Status == core.Status.OK) { string text; if (Backlog.Count == 0) { text = streamReader.ReadLine(); } else { text = Backlog[0]; Backlog.RemoveAt(0); } core.TrafficLog(ParentInstance.Nick + "<<<<<<" + text); if (config.UsingNetworkIOLayer) { if (text.StartsWith("CONTROL: ")) { if (text == "CONTROL: DC") { SendData("CONTROL: CREATE"); streamWriter.Flush(); Console.WriteLine("CACHE: Lost connection to remote, reconnecting"); bool Connected = false; while (!Connected) { System.Threading.Thread.Sleep(800); SendData("CONTROL: STATUS"); string response = streamReader.ReadLine(); core.TrafficLog(ParentInstance.Nick + "<<<<<<" + response); if (response == "CONTROL: OK") { Reconnect(); Connected = true; } } } } } if (text.StartsWith(":")) { ProcessorIRC processor = new ProcessorIRC(text); processor.instance = ParentInstance; processor.Result(); string check = text.Substring(text.IndexOf(" ")); if (!check.StartsWith(" 005")) { string command = ""; if (text.Contains(" :")) { command = text.Substring(1); command = command.Substring(0, command.IndexOf(" :")); } if (command.Contains("PRIVMSG")) { string info = text.Substring(1, text.IndexOf(" :", 1) - 1); // we got a message here :) if (text.Contains("!") && text.Contains("@")) { nick = info.Substring(0, info.IndexOf("!")); host = info.Substring(info.IndexOf("@") + 1, info.IndexOf(" ", info.IndexOf("@")) - 1 - info.IndexOf("@")); } string info_host = info.Substring(info.IndexOf("PRIVMSG ")); string message; if (info_host.Contains("#")) { channel = info_host.Substring(info_host.IndexOf("#")); if (channel == config.DebugChan && ParentInstance.Nick != core.irc.NickName) { continue; } message = text.Replace(info, ""); message = message.Substring(message.IndexOf(" :") + 2); if (message.Contains(delimiter.ToString() + "ACTION")) { core.getAction(message.Replace(delimiter.ToString() + "ACTION", ""), channel, host, nick); continue; } core.getMessage(channel, nick, host, message); continue; } message = text.Substring(text.IndexOf("PRIVMSG")); message = message.Substring(message.IndexOf(" :")); // private message if (message.StartsWith(" :" + delimiter.ToString() + "FINGER")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "FINGER" + " I am a bot don't finger me"); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "TIME")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "TIME " + System.DateTime.Now.ToString()); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "PING")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "PING" + message.Substring(message.IndexOf(delimiter.ToString() + "PING") + 5)); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "VERSION")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "VERSION " + config.Version); continue; } // store which instance this message was from so that we can send it using same instance lock (core.TargetBuffer) { if (!core.TargetBuffer.ContainsKey(nick)) { core.TargetBuffer.Add(nick, ParentInstance); } else { core.TargetBuffer[nick] = ParentInstance; } } bool respond = true; string modules = ""; lock (Module.module) { foreach (Module module in Module.module) { if (module.working) { try { if (module.Hook_OnPrivateFromUser(message.Substring(2), new User(nick, host, Ident))) { respond = false; modules += module.Name + " "; } } catch (Exception fail) { core.handleException(fail); } } } } if (respond) { _SlowQueue.DeliverMessage("Hi, I am robot, this command was not understood. Please bear in mind that every message you send to me will be logged for debuging purposes. See documentation at http://meta.wikimedia.org/wiki/WM-Bot for explanation of commands", nick, priority.low); Program.Log("Ignoring private message: (" + nick + ") " + message.Substring(2), false); } else { Program.Log("Private message: (handled by " + modules + " from " + nick + ") " + message.Substring(2), false); } continue; } if (command.Contains("PING ")) { SendData("PONG " + text.Substring(text.IndexOf("PING ") + 5)); Console.WriteLine(command); } if (command.Contains("KICK")) { string temp = command.Substring(command.IndexOf("KICK")); string[] parts = temp.Split(' '); if (parts.Length > 1) { string _channel = parts[1]; if (_channel == config.DebugChan && ParentInstance.Nick != core.irc.NickName) { continue; } string user = parts[2]; if (user == NickName) { config.channel chan = core.getChannel(_channel); if (chan != null) { if (config.channels.Contains(chan)) { config.channels.Remove(chan); Program.Log("I was kicked from " + parts[1]); config.Save(); } } } } } } } System.Threading.Thread.Sleep(50); } Program.Log("Reconnecting, end of data stream"); IsWorking = false; connected = false; Reconnect(); } catch (System.IO.IOException xx) { Program.Log("Reconnecting, connection failed " + xx.Message + xx.StackTrace); IsWorking = false; connected = false; Reconnect(); } catch (Exception xx) { core.handleException(xx, channel); core.Log("IRC: Connection error!! Terminating instance " + ParentInstance.Nick); IsWorking = false; connected = false; return; } } } catch (Exception fail) { core.handleException(fail); core.Log("IRC: Connection error!! Terminating instance " + ParentInstance.Nick); IsWorking = false; connected = false; // there is no point for being up when connection is dead and can't be reconnected return; } }
/// <summary> /// Connection /// </summary> /// <returns></returns> public void Connect() { try { if (!config.serverIO) { networkStream = new System.Net.Sockets.TcpClient(Server, 6667).GetStream(); } else { networkStream = new System.Net.Sockets.TcpClient("127.0.0.1", 6667).GetStream(); Program.Log("System is using external bouncer"); } connected = true; streamReader = new System.IO.StreamReader(networkStream, System.Text.Encoding.UTF8); streamWriter = new System.IO.StreamWriter(networkStream); bool Auth = true; if (config.serverIO) { SendData("CONTROL: STATUS"); streamWriter.Flush(); Console.WriteLine("CACHE: Waiting for buffer"); bool done = true; while (done) { string response = streamReader.ReadLine(); if (response == "CONTROL: TRUE") { done = false; Auth = false; } else if (response == "CONTROL: FALSE") { done = false; SendData("CONTROL: CREATE"); streamWriter.Flush(); } } } _Queue = new System.Threading.Thread(_SlowQueue.Run); check_thread = new System.Threading.Thread(Ping); check_thread.Start(); if (Auth) { SendData("USER " + UserName + " 8 * :" + Ident); SendData("NICK " + NickName); } _Queue.Start(); System.Threading.Thread.Sleep(2000); if (Auth) { Authenticate(); foreach (config.channel ch in config.channels) { if (ch.Name != "") { this.Join(ch); System.Threading.Thread.Sleep(2000); } } } string text = ""; string nick = ""; string host = ""; string message = ""; string channel = ""; char delimiter = (char)001; while (IsConnected) { try { while (!streamReader.EndOfStream && !core.exit) { text = streamReader.ReadLine(); core.TrafficLog("MAIN<<<<<<" + text); if (config.serverIO) { if (text.StartsWith("CONTROL: ")) { if (text == "CONTROL: DC") { SendData("CONTROL: CREATE"); streamWriter.Flush(); Console.WriteLine("CACHE: Lost connection to remote, reconnecting"); bool Connected = false; while (!Connected) { System.Threading.Thread.Sleep(800); SendData("CONTROL: STATUS"); streamWriter.Flush(); string response = streamReader.ReadLine(); core.TrafficLog("MAIN<<<<<<" + response); if (response == "CONTROL: OK") { Reconnect(); Connected = true; } } } } } if (text.StartsWith(":")) { ProcessorIRC processor = new ProcessorIRC(text); processor.Result(); string check = text.Substring(text.IndexOf(" ")); if (check.StartsWith(" 005")) { } else { string command = ""; string[] part; if (text.Contains(" :")) { part = text.Split(':'); command = text.Substring(1); command = command.Substring(0, command.IndexOf(" :")); } if (command.Contains("PRIVMSG")) { string info = text.Substring(1, text.IndexOf(" :", 1) - 1); string info_host; // we got a message here :) if (text.Contains("!") && text.Contains("@")) { nick = info.Substring(0, info.IndexOf("!")); host = info.Substring(info.IndexOf("@") + 1, info.IndexOf(" ", info.IndexOf("@")) - 1 - info.IndexOf("@")); } info_host = info.Substring(info.IndexOf("PRIVMSG ")); if (info_host.Contains("#")) { channel = info_host.Substring(info_host.IndexOf("#")); message = text.Replace(info, ""); message = message.Substring(message.IndexOf(" :") + 2); if (message.Contains(delimiter.ToString() + "ACTION")) { core.getAction(message.Replace(delimiter.ToString() + "ACTION", ""), channel, host, nick); continue; } else { core.getMessage(channel, nick, host, message); continue; } } else { message = text.Substring(text.IndexOf("PRIVMSG")); message = message.Substring(message.IndexOf(" :")); // private message if (message.StartsWith(" :" + delimiter.ToString() + "FINGER")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "FINGER" + " I am a bot don't finger me"); streamWriter.Flush(); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "TIME")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "TIME " + System.DateTime.Now.ToString()); streamWriter.Flush(); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "PING")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "PING" + message.Substring(message.IndexOf(delimiter.ToString() + "PING") + 5)); streamWriter.Flush(); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "VERSION")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "VERSION " + config.version); streamWriter.Flush(); continue; } bool respond = true; string modules = ""; lock (Module.module) { foreach (Module module in Module.module) { if (module.working) { try { if (module.Hook_OnPrivateFromUser(message.Substring(2), new User(nick, host, Ident))) { respond = false; modules += module.Name + " "; } } catch (Exception fail) { core.handleException(fail); } } } } if (respond) { _SlowQueue.DeliverMessage("Hi, I am robot, this command was not understood. Please bear in mind that every message you send to me will be logged for debuging purposes. See documentation at http://meta.wikimedia.org/wiki/WM-Bot for explanation of commands", nick, priority.low); Program.Log("Ignoring private message: (" + nick + ") " + message.Substring(2), false); } else { Program.Log("Private message: (handled by " + modules + " from " + nick + ") " + message.Substring(2), false); } continue; } } if (command.Contains("PING ")) { SendData("PONG " + text.Substring(text.IndexOf("PING ") + 5)); streamWriter.Flush(); Console.WriteLine(command); } if (command.Contains("KICK")) { string user; string _channel; string temp = command.Substring(command.IndexOf("KICK")); string[] parts = temp.Split(' '); if (parts.Length > 1) { _channel = parts[1]; user = parts[2]; if (user == NickName) { config.channel chan = core.getChannel(_channel); if (chan != null) { if (config.channels.Contains(chan)) { config.channels.Remove(chan); Program.Log("I was kicked from " + parts[1]); config.Save(); } } } } } } } System.Threading.Thread.Sleep(50); } Program.Log("Reconnecting, end of data stream"); connected = false; Reconnect(); } catch (System.IO.IOException xx) { Program.Log("Reconnecting, connection failed " + xx.Message + xx.StackTrace); connected = false; Reconnect(); } catch (Exception xx) { core.handleException(xx, channel); connected = false; } } } catch (Exception) { Console.WriteLine("IRC: Connection error"); connected = false; } }
/// <summary> /// Connection /// </summary> /// <returns></returns> public void ParserExec() { string nick = ""; string host = ""; string channel = ""; const char delimiter = (char)001; while ((!streamReader.EndOfStream || Backlog.Count > 0) && Core.IsRunning) { string text; lock (Backlog) { if (Backlog.Count == 0) { text = streamReader.ReadLine(); } else { text = Backlog[0]; Backlog.RemoveAt(0); } } Core.TrafficLog(ParentInstance.Nick + "<<<<<<" + text); if (Configuration.IRC.UsingBouncer) { if (text.StartsWith("CONTROL: ")) { if (text == "CONTROL: DC") { SendData("CONTROL: CREATE " + Server); streamWriter.Flush(); Syslog.Log("CACHE: Lost connection to remote on " + this.ParentInstance.Nick + ", creating new session on remote" ); ChannelsJoined = false; IsWorking = false; int xx = 0; bool Connected_ = false; while (!Connected_) { System.Threading.Thread.Sleep(2000); SendData("CONTROL: STATUS"); string response = streamReader.ReadLine(); Core.TrafficLog(ParentInstance.Nick + "<<<<<<" + response); if (response.StartsWith(":")) { // we received network data here lock(Backlog) { Backlog.Add(response); } continue; } if (response == "CONTROL: TRUE") { Syslog.Log("Bouncer reconnected to network on: " + NickName); NetworkInit(); ParentInstance.Join(); Connected_ = true; } else { xx++; if (xx > 6) { Syslog.WarningLog("Bouncer failed to connect to the network within 10 seconds, disconnecting it: " + NickName); SendData("CONTROL: DISCONNECT"); return; } Syslog.Log("Still waiting for bouncer (trying " + xx.ToString() + "/6) on " + NickName + " " + response); } } } } } if (text.StartsWith(":")) { ProcessorIRC processor = new ProcessorIRC(text); processor.instance = ParentInstance; processor.Result(); string check = text.Substring(text.IndexOf(" ")); if (!check.StartsWith(" 005")) { string command = ""; if (text.Contains(" :")) { command = text.Substring(1); command = command.Substring(0, command.IndexOf(" :")); } if (command.Contains("PRIVMSG")) { string info = text.Substring(1, text.IndexOf(" :", 1) - 1); // we got a message here :) if (text.Contains("!") && text.Contains("@")) { nick = info.Substring(0, info.IndexOf("!")); host = info.Substring(info.IndexOf("@") + 1, info.IndexOf(" ", info.IndexOf("@")) - 1 - info.IndexOf("@")); } string info_host = info.Substring(info.IndexOf("PRIVMSG ")); string message; if (info_host.Contains("#")) { channel = info_host.Substring(info_host.IndexOf("#")); if (channel == Configuration.System.DebugChan && ParentInstance.Nick != Core.irc.NickName) { continue; } message = text.Replace(info, ""); message = message.Substring(message.IndexOf(" :") + 2); if (message.Contains(delimiter.ToString() + "ACTION")) { Core.GetAction(message.Replace(delimiter.ToString() + "ACTION", ""), channel, host, nick); continue; } Core.GetMessage(channel, nick, host, message); continue; } message = text.Substring(text.IndexOf("PRIVMSG")); message = message.Substring(message.IndexOf(" :")); // private message if (message.StartsWith(" :" + delimiter.ToString() + "FINGER")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "FINGER" + " I am a bot don't finger me" ); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "TIME")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "TIME " + System.DateTime.Now.ToString() ); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "PING")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "PING" + message.Substring( message.IndexOf(delimiter.ToString() + "PING") + 5) ); continue; } if (message.StartsWith(" :" + delimiter.ToString() + "VERSION")) { SendData("NOTICE " + nick + " :" + delimiter.ToString() + "VERSION " + Configuration.System.Version ); continue; } // store which instance this message was from so that we can send it using same instance lock(Core.TargetBuffer) { if (!Core.TargetBuffer.ContainsKey(nick)) { Core.TargetBuffer.Add(nick, ParentInstance); } else { Core.TargetBuffer[nick] = ParentInstance; } } bool respond = true; string modules = ""; lock(ExtensionHandler.Extensions) { foreach (Module module in ExtensionHandler.Extensions) { if (module.IsWorking) { try { if (module.Hook_OnPrivateFromUser(message.Substring(2), new User(nick, host, Ident))) { respond = false; modules += module.Name + " "; } } catch (Exception fail) { Core.HandleException(fail); } } } } if (respond) { Queue.DeliverMessage("Hi, I am robot, this command was not understood." + " Please bear in mind that every message you send" + " to me will be logged for debuging purposes. See" + " documentation at http://meta.wikimedia.org/wiki" + "/WM-Bot for explanation of commands", nick, priority.low); Syslog.Log("Ignoring private message: (" + nick + ") " + message.Substring(2), false); } else { Syslog.Log("Private message: (handled by " + modules + " from " + nick + ") " + message.Substring(2), false); } continue; } if (command.Contains("PING ")) { SendData("PONG " + text.Substring(text.IndexOf("PING ") + 5)); Console.WriteLine(command); } if (command.Contains("KICK")) { string temp = command.Substring(command.IndexOf("KICK")); string[] parts = temp.Split(' '); if (parts.Length > 1) { string _channel = parts[1]; if (_channel == Configuration.System.DebugChan && ParentInstance.Nick != Core.irc.NickName) { continue; } string user = parts[2]; if (user == NickName) { Channel chan = Core.GetChannel(_channel); if (chan != null) { lock(Configuration.Channels) { if (Configuration.Channels.Contains(chan)) { Configuration.Channels.Remove(chan); Syslog.Log("I was kicked from " + parts[1]); Configuration.Save(); } } } } } } } } System.Threading.Thread.Sleep(50); } Syslog.Log("Lost connection to IRC on " + NickName); Disconnect(); IsWorking = false; }