using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Net.Sockets; namespace Otter { /// /// Component for connecting to and interacting with an IRC server. Contains only very basic functionality. Probably not very useable yet! /// public class IRC : Component { #region Private Fields List channels = new List(); TcpClient connection; NetworkStream networkStream; StreamReader streamReader; StreamWriter streamWriter; BackgroundWorker backgroundWorker = new BackgroundWorker(); #endregion #region Public Fields /// /// The server to connect with. /// public string Server; /// /// The nickname to use when connecting. /// public string Nick; /// /// The password to use when connecting. /// public string Password; /// /// The username to use when connecting. /// public string Name = "Otter Bot"; /// /// The port to use when connecting to the server. /// public int Port; /// /// Determines if debug messages will be printed to the console. /// public bool Debug = true; #endregion #region Public Properties /// /// If there is currently a connection with a server. /// public bool Connected { get; private set; } /// /// If the connection is currently running. /// public bool Running { get; private set; } #endregion #region Constructors /// /// Create a new IRC connection. Call Connect() to actually connect to the server. /// /// The server to connect to. /// The port to use when connecting. /// The nickname to use when connecting. /// The password to use when connecting. public IRC(string server, int port = 6667, string nick = "otter_bot", string pass = null) { Server = server; Nick = nick; Port = port; Password = pass; Running = true; } #endregion #region Private Methods void Work(object sender, DoWorkEventArgs e) { if (Connected) { string data; if (Running) { data = streamReader.ReadLine(); if (Debug) Console.WriteLine("IRC> " + data); if (data != null) { if (data.Substring(0, 4) == "PING") { SendData("PONG"); } } else { //Assume null data is disconnect? Close(); } } } } #endregion #region Public Methods /// /// Join a channel. /// /// The channel to join. /// The password to use when joining. public void Join(string channel, string password = null) { if (!Connected) return; if (!channels.Contains(channel)) { channels.Add(channel); SendData("JOIN", channel); } } /// /// Leave a channel. /// /// The channel to leave. public void Part(string channel) { channels.Remove(channel); } /// /// Close the current connection. /// public void Close() { if (Connected) { streamReader.Close(); streamWriter.Close(); networkStream.Close(); connection.Close(); Connected = false; Running = false; } } /// /// Connect to the server. /// public void Connect() { try { connection = new TcpClient(Server, Port); } catch { if (Debug) Console.WriteLine("Connection Error"); } try { networkStream = connection.GetStream(); streamReader = new StreamReader(networkStream); streamWriter = new StreamWriter(networkStream); } catch { if (Debug) Console.WriteLine("Communication Error"); } finally { Connected = true; if (Password != null) { SendData("PASS", Password); } SendData("USER", Nick + " something something " + Name); SendData("NICK", Nick); backgroundWorker.DoWork += Work; } } /// /// Send data to the IRC server. /// /// The command to send. /// The parameter to send along with the command. public void SendData(string command, string param = null) { if (!Connected) return; if (param == null) { streamWriter.WriteLine(command); } else { streamWriter.WriteLine(command + " " + param); } streamWriter.Flush(); if (Debug) Console.WriteLine("Sent: " + command + " " + param); } /// /// Updates the IRC connection. /// public override void Update() { base.Update(); if (!backgroundWorker.IsBusy) { backgroundWorker.RunWorkerAsync(); } } #endregion } }