using System; using System.Net.Sockets; using System.Text; using System.Threading; public class IRCClient { private TcpClient ircClient; private bool Shutdown = false; private string ServerHost; private int ServerPort; private string Nickname; private string RealName = String.Empty; private Thread LoopThread; private Thread ConnectThread; public delegate void ConnectCallback(); public event ConnectCallback OnConnectFail; public event ConnectCallback OnConnected; public event ConnectCallback OnDisconnected; public delegate void DataCallback(string data); public event DataCallback OnData; public delegate void MessageCallback(string target, string name, string address, string message); public event MessageCallback OnMessage; /// /// Basic class for a threaded, sychronous TCP client with built-in functions and events for IRC connectivity /// /// /// /// /// public IRCClient(string serverHost, int port, string nickname, string realName) { ircClient = new TcpClient(); ServerHost = serverHost; ServerPort = port; Nickname = nickname; RealName = realName; } /// /// Connect to IRC network /// public void Connect() { ConnectThread = new Thread(new ThreadStart(ConnectThreadStart)); ConnectThread.Start(); } /// /// Connect to IRC network with the specified parameters /// /// /// /// /// public void Connect(string serverHost, int port, string nickname, string realName) { ServerHost = serverHost; ServerPort = port; Nickname = nickname; RealName = realName; Connect(); } /// /// Join an IRC channel /// /// public void JoinChannel(string channel) { ircClient.Client.Send(Encoding.ASCII.GetBytes("JOIN " + channel + "\r\n")); } /// /// Send a message to the specified nickname or channel /// /// /// public void SendMessage(string target, string message) { ircClient.Client.Send(Encoding.ASCII.GetBytes("PRIVMSG " + target + " :" + message + "\r\n")); } private void ConnectThreadStart() { ircClient.Connect(ServerHost, ServerPort); if (!ircClient.Connected) { if (OnConnectFail != null) OnConnectFail(); return; } ircClient.Client.Send(Encoding.ASCII.GetBytes("USER " + Nickname + " x x :" + RealName + "\r\n")); ircClient.Client.Send(Encoding.ASCII.GetBytes("NICK " + Nickname + "\r\n")); LoopThread = new Thread(new ThreadStart(LoopThreadStart)); LoopThread.Start(); } private void LoopThreadStart() { while (!Shutdown && ircClient.Connected) { byte[] buffer = new byte[4096]; ircClient.Client.Receive(buffer); if (buffer.Length == 0) break; string[] lines = Encoding.ASCII.GetString(buffer).Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries); for(int i=0; i 0) OnData(lines[i]); if (words.Length < 2) return; if (words[0].ToUpper() == "PING") ircClient.Client.Send(Encoding.ASCII.GetBytes("PONG " + words[1] + "\r\n")); else if (words[1] == "001") { if (OnConnected != null) OnConnected(); } else if (words[1].ToUpper() == "PRIVMSG") { if (OnMessage != null) { int nameIndex = words[0].IndexOf('!'); string name = nameIndex > 0 ? words[0].Substring(1, nameIndex - 1) : words[0]; string address = words[0].Substring(nameIndex + 1); OnMessage(words[2], name, address, lines[i].Substring(lines[i].IndexOf(":", 1) + 1)); } } } } if (!ircClient.Connected) { if (OnDisconnected != null) OnDisconnected(); } else ircClient.Close(); } }