// Process the incoming messsage private void msg() { try { WriteDebug(string.Format("Msg - Connected={0}", clientSocket.Connected)); CommunicationMessage Msg = new CommunicationMessage(); Msg.Message = readData; InMsgQueue.Add(Msg); readData = null; } catch (Exception ex) { AddError(702, ex.Message, "GETMESSAGE"); } }
/* * When a message comes in, put it into the inbound message queue * which is why it's continuously looping in a thread * * TODO: Add automation to handle various things and to allow ease of * making a simple bot to bounce flooders and other such common * issues for an IRC channel * */ void readChat(IrcClient irc) { string message = null; inThread = true; if (DebugLevel > 8) { WriteDebug("readChat has started"); } while (chatThreadStop == false) { // Are you connected? try { Connected = irc.Connected(); chatThreadStop = (!Connected); } catch (Exception ex) { AddError(50, ex.Message, GetType().Name + ".READCHAT", "Failure checking connection"); } // Get the next message try { if (DebugLevel > 8) { WriteDebug("ComIRC.readChat - Waiting for message"); } message = irc.readMessage(); } catch (Exception ex) { AddError(50, ex.Message, GetType().Name + ".READCHAT", "readMessage() failure"); } // Is there a message? if (message != null) { try { // Is it a ping? if (message.Contains("PING ")) { if (DebugLevel > 5) { WriteDebug(string.Format("{0}", message)); } irc.sendIrcMessage(message.Replace("PING", "PONG")); pings++; } else { // parse the message CommunicationMessage msg = new CommunicationMessage(); if (message.IndexOf(':') == 0) { // This is a message from someone or something int prv = message.IndexOf(" PRIVMSG "); int xpt = message.IndexOf('!'); int xpt2 = message.IndexOf('!', xpt + 1); int spc = message.IndexOf(' '); int cln2 = message.IndexOf(':', 1); int nk = message.IndexOf(" " + UserNick + " "); int nkmsg = message.IndexOf(" " + UserNick + " :"); if (xpt > 0 && xpt < spc) { // there's a nick/name combo such as // :JWVFPDev1!JWVFPDev1@localhost // or // :JWVFPDev1!~JWVFPDev1@localhost msg.Sender.NickName = message.Substring(1, xpt - 1); msg.Sender.Name = message.Substring(xpt + 1, spc - xpt).Replace("~", "").Trim(); } else { // must be an address like // :nonstop.ix.me.dal.net 372 JWVFPDev4 msg.Sender.Address = message.Substring(1, spc).Trim(); } if (prv > 0) { // Actual PRIVMSG from someone // Example-> :JWVFPDev1!JWVFPDev1@localhost PRIVMSG #Test1234 :hello // ^Nick^^^^ ^Name@host^^^^^^^^^ ^Channel^ ^Msg^ msg.Sender.Address = (message.IndexOf(':', prv) > 0 ? message.Substring(prv + 7, message.IndexOf(':', prv) - prv + 7) : "").Trim(); // Channel message = (message.IndexOf(':', prv) > 0 ? message.Substring(message.IndexOf(':', prv) + 1) : ""); // message if (DebugLevel > 8) { WriteDebug(string.Format("Code 1 msg - '{0}", message)); } try { // Encryption tie-in if (message.Length > 8 && message.Substring(0, 8).Equals("[CRYPTOR")) { if (DebugLevel > 8) { WriteDebug(string.Format("Decryption of '{0}'", message)); } message = cryptText(message); if (DebugLevel > 8) { WriteDebug(string.Format(" returns '{0}'", message)); } } } catch (Exception ex) { AddError(61, ex.Message, GetType().Name + ".READCHAT", string.Format("Failed with message {0}", message)); } msg.Message = message; msg.Code = 1; // TODO: Keep track of users on the channel - is there a way to see when people leave? } else { if (message.Substring(0, UserNick.Length + 1).Equals(":" + UserNick)) { // Expecting a user control message like // :JWVFPDev1 MODE JWVFPDev1 :+iw // :[email protected] JOIN :#Test1234 msg.Subject = message.Substring(message.IndexOf(' ')).Trim(); // expect a : but have a backup plan if (msg.Subject.Contains(":")) { msg.Message = msg.Subject.Substring(msg.Subject.IndexOf(':') + 1).Trim(); } else { msg.Message = msg.Subject.Substring(msg.Subject.IndexOf(' ') + 1).Trim(); } msg.Subject = msg.Subject.Substring(0, msg.Subject.IndexOf(' ')).Trim(); msg.Code = 2; } else if (nkmsg > spc) { // "Nick :" is just like PRIVMSG // :nonstop.ix.me.dal.net 372 JWVFPDev4 :- * We reserve the right to deny access to this server without * // :^Address^^^^^^^^^^^^^ ^Nick^^^^ ^Message^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ msg.Message = (message.IndexOf(':', nkmsg) > 0 ? message.Substring(message.IndexOf(':', nkmsg) + 1) : ""); // message msg.Code = 3; } else { if (nk > spc) { // _Nick_ after first space in raw message // Example-> :lion.tx.us.dal.net 005 JWVFPDev2 CASEMAPPING=ascii WATCH=128 SILENCE=10 ELIST=cmntu EXCEPTS INVEX CHANMODES=beI,k,jl,ciPAmMnOprRsSt msg.Subject = message.Substring(nk).Trim(); // command msg.Code = 4; } else { // TODO Break command and misc out from message // Message from system // Examples-> :[email protected] JOIN :#Test1234 // ^Nick^^^^ ^Name@host^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^CMD ^Channel^ if (cln2 > 0 && cln2 > spc) { msg.Subject = message.Substring(spc + 1, cln2 - spc - 1).Trim(); msg.Message = message.Substring(cln2 + 1).Trim(); msg.Code = 5; } else { // it's a command msg.Message = message.Substring(spc + 1).Trim(); msg.Code = 6; } } } } } else { // Weird message msg.Code = 99; msg.Message = message; } if (DebugLevel > 5) { WriteDebug(string.Format("<-{0}\r\n Nick: {1}\r\n Name: {2}\r\n Address: {3}\r\n Subject: {4}\r\n Code: {5}\r\n Message: {6}\r\n", message, msg.Sender.NickName, msg.Sender.Name, msg.Sender.Address, msg.Subject, msg.Code, msg.Message)); } // Code 4 - User commands from Server if (msg.Code == 2) { // Possible command if (msg.Subject.Equals("JOIN") && UserHost.Length == 0) { if (msg.Sender.Name.Contains("@")) { UserHost = msg.Sender.Name.Substring(msg.Sender.Name.IndexOf("@") + 1); irc.SetHost(UserHost); //if (DebugLevel > 3) WriteDebug("Setting UserHost to " + UserHost); } } } InMsgQueue.Add(msg); } } catch (Exception ex) { AddError(51, ex.Message, GetType().Name + ".READCHAT"); } } } inThread = false; }
/* * * Receiving a message * */ private void MessageCallBack(IAsyncResult aResult) { if (DebugLevel > 8) { WriteDebug("In MessageCallBack"); } try { int size = sck.EndReceiveFrom(aResult, ref epRemote); // check if theres actually information if (size > 0) { // used to help us on getting the data byte[] receivedData = new byte[1464]; // getting the message data receivedData = (byte[])aResult.AsyncState; // converts message data byte array to string ASCIIEncoding eEncoding = new ASCIIEncoding(); string receivedMessage = eEncoding.GetString(receivedData); receivedMessage = receivedMessage.Replace("\0", string.Empty).Trim(); if (DebugLevel > 5) { WriteDebug("<-" + receivedMessage); } // Save the message to the InMsgQueue list CommunicationMessage msg = new CommunicationMessage(); if (receivedMessage.IndexOf("#") > 0) { if (DebugLevel > 8) { WriteDebug("Breaking out name"); } string[] nameInfo = receivedMessage.Substring(0, receivedMessage.IndexOf("#")).Split('|'); msg.Sender.NickName = nameInfo[0]; if (nameInfo.Length > 1) { msg.Sender.Name = nameInfo[1]; } if (nameInfo.Length > 2) { msg.Sender.IP4Address = nameInfo[2]; } if (nameInfo.Length > 3) { msg.Sender.MachineID = nameInfo[3]; // add to contacts list if not already } if (nameInfo.Length > 5) { // private message string recipient = nameInfo[4].Replace("[", "").Replace("]", ""); // datetime it was sent DateTime dtm; if (DateTime.TryParse(nameInfo[5].Replace("{", "").Replace("}", ""), out dtm) == false) { dtm = DateTime.Now; } msg.MessageTime = dtm; if (recipient.Length > 0) { if (recipient.ToUpper().Equals(UserName.ToUpper()) == false) { // Received a server message, so trash it AddError(805, "Received private message", GetType().Name + ".MESSAGECALLBACK", "Received message meant for " + (recipient.Equals("?") ? "Chat Server" : recipient)); msg = null; } } } else { // This goes to a debug file no matter what int dbl = DebugLevel; DebugLevel = 1; WriteDebug(string.Format(">>>> BAD MESSAGE FORMAT <<<<\r\n {0}\r\n\r\n", receivedMessage)); DebugLevel = dbl; } if (msg != null) { string m = receivedMessage.Substring(receivedMessage.IndexOf("#") + 1).Trim(); // handle any received cryptor messages if (m.Substring(0, 8).Equals("[CRYPTOR")) { if (DebugLevel > 5) { WriteDebug(string.Format("Calling Cryptor with {0}", m)); } m = cryptText(m); } msg.Message = m; } } else { msg.Message = receivedMessage; } // was the message tossed (is null) or do we save it to the queue? if (msg != null) { if (DebugLevel > 5) { WriteDebug(string.Format("<-{0}\r\n Nick: {1}\r\n Name: {2}\r\n Address: {3}\r\n Machine: {4}\r\n Message: {5}\r\n", receivedMessage, msg.Sender.NickName, msg.Sender.Name, msg.Sender.Address, msg.Sender.MachineID, msg.Message)); } InMsgQueue.Add(msg); } if (DebugLevel > 5) { WriteDebug("Waiting..."); } // starts listening to the socket again buffer = new byte[1500]; sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer); } catch (Exception ex) { AddError(803, ex.Message, GetType().Name + ".MESSAGECALLBACK"); } }