public MainWindow() { InitializeComponent(); m_Servers = new List<TreeViewItem>(); this.messageField.KeyDown += textBoxEnter; //Instantiate an IRC client session irc = new IRCSocket( System.Net.Dns.Resolve(System.Configuration.ConfigurationManager.AppSettings["Server"]).AddressList[0].ToString(), int.Parse(System.Configuration.ConfigurationManager.AppSettings["Port"]), System.Configuration.ConfigurationManager.AppSettings["Username"], System.Configuration.ConfigurationManager.AppSettings["Auth"]); NerdySocket.main(); //IrcRegistrationInfo info = new IrcUserRegistrationInfo() //{ // NickName = Environment.UserName, // "NerdChat", // UserName = Environment.UserName + "NerdChat", // RealName = "NerdChat" //}; //Open IRC client connection //irc.doWork(); //irc.RawMessageReceived += IrcClient_Receive; // Add server to treeview m_Servers.Add( new TreeViewItem()); m_Servers[0].Header = System.Configuration.ConfigurationManager.AppSettings["Server"]; channelTree.Items.Add(m_Servers[0]); // Populate channel list with some test channels m_Channels.Add("#amagital-spam"); m_Channels.Add("#nerdchat-testing"); // Join and add channels to the tree foreach (String channel in m_Channels) { IRCMessage outB = new IRCMessage("JOIN"); outB.payload = channel; irc.m_Outbound.Enqueue(new IRCMessage("JOIN",channel)); TreeViewItem channelTreeItem = new TreeViewItem(); channelTreeItem.Header = channel; m_Servers[0].Items.Add(channelTreeItem); } listenThread = new Thread(() => { while (true) { if (irc.m_Inbound.Count == 0) continue; HandlePrivMsg(irc.m_Inbound.Dequeue()); } }); listenThread.Start(); }
public IRCSocket(String server, int port, String username, String pass = "") { m_userName = username; m_Password = pass; m_ServerAddress = server; m_Port = port; m_Con = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); m_Inbound = new Queue<IRCMessage>(); m_Outbound = new Queue<IRCMessage>(); sendThread = new Thread(() => { while (true) { if (m_Outbound.Count == 0) continue; IRCMessage sendData = m_Outbound.Dequeue(); m_Con.Send(Encoding.ASCII.GetBytes(sendData.command + " " + sendData.payload + "\r\n")); } }); listenThread = new Thread(() => { byte[] inData = new byte[IN_BUFFER]; StringBuilder inbound = new StringBuilder(); //using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"bouncer.txt", true)) while (true) { Array.Clear(inData, 0, IN_BUFFER); int inSize = m_Con.Receive(inData, IN_BUFFER, SocketFlags.None); if (inSize < 1) break; inbound.Append(Encoding.ASCII.GetString(inData).Substring(0, inSize)); if ((inSize == IN_BUFFER) || (!Encoding.ASCII.GetString(inData).Substring(inSize - 2, 2).Equals("\r\n"))) continue; foreach (String line in inbound.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) { //Check for a prefix indicator. If this isnt present the message cannot be processed. We should probably throw an exception. if (!line.Contains(':')) continue; if (line.Substring(0, 4).Equals("PING")) {//This command is parsed in a special way. SendString("PONG " + line.Split(':')[1]); continue; } string logText = ""; IRCMessage inM = new IRCMessage(); try { inM.host = line.Substring(line.IndexOf(':')).Split(' ')[0]; //Check if source is blacklisted //if (m_BlackListHosts.Contains(inM.host)) //{ // //TODO log this? // return; //} //Check if prefix is well formed if (inM.host.Length == 0) throw new FormatException("unable to parse prefix"); inM.command = line.Substring(inM.host.Length).Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries)[0].Trim(); if (inM.command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Count() > 1) { inM.dest = inM.command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]; inM.command = inM.command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0]; if (inM.command == "JOIN") continue; //inM.payload = line.Substring(inM.command.Length + inM.host.Length + inM.command.Length); inM.payload = line.Split(new String[] { inM.dest } ,StringSplitOptions.RemoveEmptyEntries)[1]; if (inM.payload.Length > 0) inM.payload = inM.payload.Substring(1); //Remove the ':' cos who needs it? } } catch (Exception ex) { throw new Exception("pasring error", ex); } //Examine the command if ((inM.command.Length == 3) && (!inM.command.Equals("WHO")))//duurrrrr? { logText = " number "; } else switch (inM.command.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[0]) { case "NOTICE": case "PRIVMSG": if (inM.dest.Equals("AUTH")) { SendString("PASS " + m_userName + ":" + m_Password);// System.Configuration.ConfigurationManager.AppSettings["Auth"]); SendString("NICK " + m_userName); } logText = inM.dest + "||" + inM.host + "> " + inM.payload; break; default: logText = "Unknown Command " + inM.command; break; } //Console.WriteLine(logText); m_Inbound.Enqueue(inM); OnMessageArrived(new NerdyChatEventArgs(inM)); } inbound.Clear(); }//Read socket again m_Con.Close(); }); }
/// <summary> /// Place functionality here that will respond to private messages. This should exist outside of the main thread and so we can take our time here. /// </summary> /// <param name="fromNick">nickname of the user that sent this private message. RFC specifies this can be a list of names or channels separated with commas</param> /// <param name="message">content of this message. RFC 1459 sets a hard limit here around ~512 characters</param> public void HandlePrivMsg(IRCMessage message) { //TODO write a privmsg handler if ((message.dest.Length > 0) && (!m_Channels.Contains(message.dest))) m_Channels.Add(message.dest); //TODO Pass privmsg to handler chatBox.Dispatcher.Invoke(delegate { chatBox.AppendText(message.dest + "\t||" + message.host + "> " + message.payload + "\n"); chatBox.ScrollToEnd(); }); }
public NerdyChatEventArgs(IRCMessage m) { payload = m; }