using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Collections; using System.ComponentModel; using System.Text; using System.Net; using System.Net.Sockets; using System.IO; using System.Text.RegularExpressions; using System.Threading; namespace IRC { public class ReceiveRawMessageEventArgs : EventArgs { public string messageReceived; public ReceiveRawMessageEventArgs(string messageReceived) { this.messageReceived = messageReceived; } } public class ReceivePrivMsgEventArgs : EventArgs { public string rawMessageReceived; public string messageReceived; public string senderNickname; public string senderHostname; public string channelReceivedOn; public ReceivePrivMsgEventArgs(string rawMessageReceived) { this.rawMessageReceived = rawMessageReceived; this.messageReceived = rawMessageReceived.Split(':')[2]; this.senderHostname = rawMessageReceived.Split(' ')[0].Split('@')[1]; this.channelReceivedOn = rawMessageReceived.Split(' ')[2]; this.senderNickname = rawMessageReceived.Split(':')[1].Split('!')[0]; } } public class ReceiveNoticeEventArgs : EventArgs { public string rawMessageReceived; public string messageReceived; public string senderNickname; public string senderHostname; public ReceiveNoticeEventArgs(string rawMessageReceived) { this.rawMessageReceived = rawMessageReceived; this.messageReceived = rawMessageReceived.Split(':')[2]; this.senderHostname = rawMessageReceived.Split(' ')[0].Split('@')[1]; this.senderNickname = rawMessageReceived.Split(':')[1].Split('!')[0]; } } public class UserJoinChannelEventArgs : EventArgs { public string userNickname; public string userHostname; public string channelJoined; public UserJoinChannelEventArgs(string rawMessageReceived) { this.userHostname = rawMessageReceived.Split(' ')[0].Split('@')[1]; this.channelJoined = rawMessageReceived.Split(':')[2]; this.userNickname = rawMessageReceived.Split(':')[1].Split('!')[0]; } } public class UserPartChannelEventArgs : EventArgs { public string userNickname; public string userHostname; public string channelParted; public UserPartChannelEventArgs(string rawMessageReceived) { this.userHostname = rawMessageReceived.Split(' ')[0].Split('@')[1]; this.channelParted = rawMessageReceived.Split(':')[2]; this.userNickname = rawMessageReceived.Split(':')[1].Split('!')[0]; } } public class UserKickedFromChannelEventArgs : EventArgs { public string userKickedNickname; public string userKickingNickname; public string userKickingHostname; public string channelKickedFrom; public UserKickedFromChannelEventArgs(string rawMessageReceived) { this.userKickingNickname = rawMessageReceived.Split(':')[1].Split('!')[0]; this.userKickingHostname = rawMessageReceived.Split(' ')[0].Split('@')[1]; this.channelKickedFrom = rawMessageReceived.Split(' ')[2]; this.userKickedNickname = rawMessageReceived.Split(' ')[3]; } } public class Client { public string clientNickname; public string nicknamePassword; public string serverAddress; public int serverPort; public bool isConnected = false; static Thread SpawnThread(ThreadStart d, Action a) { Thread t = new Thread(d); a(t); t.Start(); return t; } public bool joinOnInvite = true; public Hashtable autoResponses; public bool autoResponseEnabled = false; private bool isBotFlag_; public bool isBotFlag { get { return isBotFlag_; } set { isBotFlag_ = value; SwitchBotFlag(); } } private void SwitchBotFlag() { if (isBotFlag) { SendRawMessage("MODE " + clientNickname + " +B"); } else { SendRawMessage("MODE " + clientNickname + " -B"); } } public StringCollection channels = new StringCollection(); private StreamWriter writer; private StreamReader reader; private NetworkStream stream; private TcpClient client; ////////////////////////////Event Handlers////////////////////////////////////// private event EventHandler ReceiveRawMessage_; public event EventHandler ReceiveRawMessage { add { ReceiveRawMessage_ += value; } remove { ReceiveRawMessage_ -= value; } } private event EventHandler ReceivePrivMsg_; public event EventHandler ReceivePrivMsg { add { ReceivePrivMsg_ += value; } remove { ReceivePrivMsg_ -= value; } } private event EventHandler UserJoinChannel_; public event EventHandler UserJoinChannel { add { UserJoinChannel_ += value; } remove { UserJoinChannel_ -= value; } } private event EventHandler UserPartChannel_; public event EventHandler UserPartChannel { add { UserPartChannel_ += value; } remove { UserPartChannel_ -= value; } } private event EventHandler UserKickedFromChannel_; public event EventHandler UserKickedFromChannel { add { UserKickedFromChannel_ += value; } remove { UserKickedFromChannel_ -= value; } } private event EventHandler ReceiveNotice_; public event EventHandler ReceiveNotice { add { ReceiveNotice_ += value; } remove { ReceiveNotice_ -= value; } } ///////////////////////////////////////////////////////////////////////////////////// public Client(string botUsername, string serverToUse, int portToUse) { clientNickname = botUsername; serverAddress = serverToUse; serverPort = portToUse; autoResponses = new Hashtable(); } public void Connect() { new Thread(delegate() { try { //Connect to the server client = new TcpClient(serverAddress, serverPort); stream = client.GetStream(); reader = new StreamReader(stream); writer = new StreamWriter(stream); Perform(); PingSender(); while (true) { isConnected = true; string serverResponse = ""; while ((serverResponse = reader.ReadLine()) != null) { if (ReceiveRawMessage_ != null) ReceiveRawMessage_(this, new ReceiveRawMessageEventArgs(serverResponse)); CheckServerResponse(serverResponse); } } isConnected = false; } catch (Exception errorInClient) { isConnected = false; } }) { IsBackground = true }.Start(); } public void Disconnect(string quitMessage) { SendRawMessage("QUIT " + quitMessage); } public void JoinChannel(string channelToJoin) { SendRawMessage("JOIN " + channelToJoin); } public void PartChannel(string channelToPart) { SendRawMessage("PART " + channelToPart); } public void SendMessage(string recipient, string messageToSend) { SendRawMessage("PRIVMSG " + recipient + " " + messageToSend); } public void SendRawMessage(string messageToSend) { try { if (client.Connected) { writer.WriteLine(messageToSend); writer.Flush(); } } catch (Exception e) { } } public void SendMessageAllChannels(string messageToSend) { for (int a = 0; a < channels.Count; a++) { string channelToSendTo = channels[a]; SendMessage(channelToSendTo, messageToSend); } } public void ChangeNickname(string nicknameToChangeTo) { SendRawMessage("NICK " + nicknameToChangeTo); } void Perform() { writer.WriteLine("USER " + clientNickname + " * Just Imagine"); writer.Flush(); if (nicknamePassword != null) { ChangeNickname("NICK " + clientNickname + Convert.ToString(new Random().Next(10, 1000))); SendRawMessage("PRIVMSG nickserv release " + clientNickname + " " + nicknamePassword); SendRawMessage("PRIVMSG nickserv ghost " + clientNickname + " " + nicknamePassword); Thread.Sleep(3000); } ChangeNickname(clientNickname); if (nicknamePassword != null) { SendMessage("nickserv", " identify " + clientNickname + " " + nicknamePassword); SendMessage("nickserv", " set autoop on"); } for (int a = 0; a < channels.Count; a++) { JoinChannel(channels[a]); } new Thread(delegate() { Thread.Sleep(15000); autoResponseEnabled = true; }){ IsBackground = true }.Start(); } void PingSender() { Thread pingSenderThread = new Thread (delegate() { while (true) { Thread.Sleep(13000); writer.WriteLine("PING :" + serverAddress); writer.Flush(); } }); pingSenderThread.IsBackground = true; pingSenderThread.Start(); } void CheckServerResponse(string serverResponse) { try { switch (serverResponse.Split(' ')[1]) { case "INVITE": { if (joinOnInvite) { string channel = serverResponse.Split(':')[2]; JoinChannel(channel); } break; } case "PRIVMSG": { if (autoResponseEnabled) { int a = 0; foreach (object key in autoResponses.Keys) { string strKey = key.ToString(); string message = serverResponse.Split(':')[2]; string strKeyFormatted = key.ToString().Replace("%me%", clientNickname); if (Regex.Match(message, strKeyFormatted).Success) { string[] responses = Regex.Split(autoResponses[strKey].ToString(),"¬!¬"); string randomResponse = responses[new Random().Next(0, responses.Length)]; string channelReceivedOn = serverResponse.Split(' ')[2]; string senderNickname = serverResponse.Split(':')[1].Split('!')[0]; string messageToSend = randomResponse.Replace("%nick%", senderNickname).Replace("%me%", clientNickname).Replace("%channel%", channelReceivedOn); SendMessage(channelReceivedOn, messageToSend); } a++; } } if (ReceivePrivMsg_ != null) ReceivePrivMsg_(this, new ReceivePrivMsgEventArgs(serverResponse)); break; } case "JOIN": { string nick = serverResponse.Split(':')[1].Split('!')[0]; string channel = serverResponse.Split(':')[2]; if ((nick.Equals(clientNickname)) && (!channels.Contains(channel))) { channels.Add(channel); } if (UserJoinChannel_ != null) UserJoinChannel_(this, new UserJoinChannelEventArgs(serverResponse)); break; } case "PART": { string nick = serverResponse.Split(':')[1].Split('!')[0]; string channel = serverResponse.Split(':')[2]; if ((nick.Equals(clientNickname)) && (channels.Contains(channel))) { channels.Remove(channel); } if (UserPartChannel_ != null) UserPartChannel_(this, new UserPartChannelEventArgs(serverResponse)); break; } case "KICK": { string userKickingNickname = serverResponse.Split(':')[1].Split('!')[0]; string userKickingHostname = serverResponse.Split(' ')[0].Split('@')[1]; string channelKickedFrom = serverResponse.Split(' ')[2]; string userKickedNickname = serverResponse.Split(' ')[3]; if ((userKickedNickname.Equals(clientNickname)) && (channels.Contains(channelKickedFrom))) { channels.Remove(channelKickedFrom); } if (UserKickedFromChannel_ != null) UserKickedFromChannel_(this, new UserKickedFromChannelEventArgs(serverResponse)); break; } case "NOTICE": { if (ReceiveNotice_ != null) ReceiveNotice_(this, new ReceiveNoticeEventArgs(serverResponse)); break; } default: { if (ReceiveRawMessage_ != null) ReceiveRawMessage_(this, new ReceiveRawMessageEventArgs(serverResponse)); break; } } } catch (Exception error) { } } } }