private void ParseReply(string[] tokens) { ReplyCode code = (ReplyCode)int.Parse(tokens[1], CultureInfo.InvariantCulture); tokens[3] = RemoveLeadingColon(tokens[3]); switch (code) { //Messages sent upon successful registration case ReplyCode.RPL_WELCOME: case ReplyCode.RPL_YOURESERVICE: if (OnRegistered != null) { OnRegistered(this, new EventArgs()); } break; case ReplyCode.RPL_MOTDSTART: case ReplyCode.RPL_MOTD: if (OnMotd != null) { OnMotd(CondenseStrings(tokens, 3), false); } break; case ReplyCode.RPL_ENDOFMOTD: if (OnMotd != null) { OnMotd(CondenseStrings(tokens, 3), true); } break; case ReplyCode.RPL_ISON: if (OnIson != null) { OnIson(tokens[3]); } break; case ReplyCode.RPL_NAMREPLY: if (OnNames != null) { if (tokens[2].EndsWith("=")) //hack: Gamesurge sometimes does this { var newtokens = new List <string>(tokens); newtokens.RemoveAt(2); newtokens.Insert(2, tokens[2].Remove(tokens[2].Length - 1)); newtokens.Insert(3, "="); tokens = newtokens.ToArray(); } tokens[5] = RemoveLeadingColon(tokens[5]); int numberOfUsers = tokens.Length - 5; string[] users = new string[numberOfUsers]; Array.Copy(tokens, 5, users, 0, numberOfUsers); OnNames(this, new NamesEventArgs(tokens[4], users, false)); //Trace.WriteLine("Names", "IRC"); } break; case ReplyCode.RPL_ENDOFNAMES: if (OnNames != null) { OnNames(this, new NamesEventArgs(tokens[3], new string[0], true)); //Trace.WriteLine("Names end", "IRC"); } break; case ReplyCode.RPL_LIST: if (OnList != null) { tokens[5] = RemoveLeadingColon(tokens[5]); OnList( tokens[3], int.Parse(tokens[4], CultureInfo.InvariantCulture), CondenseStrings(tokens, 5), false); } break; case ReplyCode.RPL_LISTEND: if (OnList != null) { OnList("", 0, "", true); } break; case ReplyCode.ERR_NICKNAMEINUSE: case ReplyCode.ERR_NICKCOLLISION: if (OnNickError != null) { tokens[4] = RemoveLeadingColon(tokens[4]); OnNickError(this, new NickErrorEventArgs(tokens[3], CondenseStrings(tokens, 4))); //Trace.WriteLine("Nick collision", "IRC"); } break; case ReplyCode.RPL_NOTOPIC: if (OnError != null) { OnError(this, new ErrorMessageEventArgs(code, CondenseStrings(tokens, 3))); } break; case ReplyCode.RPL_TOPIC: if (OnRecieveTopic != null) { tokens[4] = RemoveLeadingColon(tokens[4]); OnRecieveTopic(tokens[3], CondenseStrings(tokens, 4)); } break; case ReplyCode.RPL_INVITING: if (OnInviteSent != null) { OnInviteSent(this, new InviteSentEventArgs(tokens[3], tokens[4])); } break; case ReplyCode.RPL_AWAY: if (OnAway != null) { OnAway(this, new AwayEventArgs(tokens[3], RemoveLeadingColon(CondenseStrings(tokens, 4)))); } break; case ReplyCode.RPL_WHOREPLY: if (OnWho != null) { User user = new User(tokens[7], tokens[4], tokens[5]); OnWho( user, tokens[3], tokens[6], tokens[8], int.Parse(RemoveLeadingColon(tokens[9]), CultureInfo.InvariantCulture), tokens[10], false); } break; case ReplyCode.RPL_ENDOFWHO: if (OnWho != null) { OnWho(User.Empty, "", "", "", 0, "", true); } break; case ReplyCode.RPL_WHOISUSER: User whoUser = new User(tokens[3], tokens[4], tokens[5]); WhoisInfo whoisInfo = LookupInfo(whoUser.Nick); whoisInfo.user = whoUser; tokens[7] = RemoveLeadingColon(tokens[7]); whoisInfo.realName = CondenseStrings(tokens, 7); break; case ReplyCode.RPL_WHOISCHANNELS: WhoisInfo whoisChannelInfo = LookupInfo(tokens[3]); tokens[4] = RemoveLeadingColon(tokens[4]); int numberOfChannels = tokens.Length - 4; string[] channels = new String[numberOfChannels]; Array.Copy(tokens, 4, channels, 0, numberOfChannels); whoisChannelInfo.SetChannels(channels); break; case ReplyCode.RPL_WHOISSERVER: WhoisInfo whoisServerInfo = LookupInfo(tokens[3]); whoisServerInfo.ircServer = tokens[4]; tokens[5] = RemoveLeadingColon(tokens[5]); whoisServerInfo.serverDescription = CondenseStrings(tokens, 5); break; case ReplyCode.RPL_WHOISOPERATOR: WhoisInfo whoisOpInfo = LookupInfo(tokens[3]); whoisOpInfo.isOperator = true; break; case ReplyCode.RPL_WHOISIDLE: WhoisInfo whoisIdleInfo = LookupInfo(tokens[3]); whoisIdleInfo.idleTime = long.Parse(tokens[5], CultureInfo.InvariantCulture); break; case ReplyCode.RPL_ENDOFWHOIS: string nick = tokens[3]; WhoisInfo whoisEndInfo = LookupInfo(nick); if (OnWhois != null) { OnWhois(whoisEndInfo); } whoisInfos.Remove(nick); break; case ReplyCode.RPL_WHOWASUSER: if (OnWhowas != null) { User whoWasUser = new User(tokens[3], tokens[4], tokens[5]); tokens[7] = RemoveLeadingColon(tokens[7]); OnWhowas(whoWasUser, CondenseStrings(tokens, 7), false); } break; case ReplyCode.RPL_ENDOFWHOWAS: if (OnWhowas != null) { OnWhowas(User.Empty, "", true); } break; case ReplyCode.RPL_UMODEIS: if (OnUserModeRequest != null) { //First drop the '+' string chars = tokens[3].Substring(1); UserMode[] modes = Rfc2812Util.UserModesToArray(chars); OnUserModeRequest(modes); } break; case ReplyCode.RPL_CHANNELMODEIS: if (OnChannelModeRequest != null) { try { ChannelModeInfo[] modes = ChannelModeInfo.ParseModes(tokens, 4); OnChannelModeRequest(tokens[3], modes); } catch (Exception) { if (OnError != null) { OnError(this, new ErrorMessageEventArgs(ReplyCode.UnparseableMessage, CondenseStrings(tokens, 0))); } Debug.WriteLineIf(Rfc2812Util.IrcTrace.TraceWarning, "[" + Thread.CurrentThread.Name + "] Listener::ParseReply() Bad IRC MODE string=" + tokens[0]); } } break; case ReplyCode.RPL_BANLIST: if (OnChannelList != null) { OnChannelList(tokens[3], ChannelMode.Ban, tokens[4], Rfc2812Util.UserFromString(tokens[5]), Convert.ToInt64(tokens[6], CultureInfo.InvariantCulture), false); } break; case ReplyCode.RPL_ENDOFBANLIST: if (OnChannelList != null) { OnChannelList(tokens[3], ChannelMode.Ban, "", User.Empty, 0, true); } break; case ReplyCode.RPL_INVITELIST: if (OnChannelList != null) { OnChannelList(tokens[3], ChannelMode.Invitation, tokens[4], Rfc2812Util.UserFromString(tokens[5]), Convert.ToInt64(tokens[6]), false); } break; case ReplyCode.RPL_ENDOFINVITELIST: if (OnChannelList != null) { OnChannelList(tokens[3], ChannelMode.Invitation, "", User.Empty, 0, true); } break; case ReplyCode.RPL_EXCEPTLIST: if (OnChannelList != null) { OnChannelList(tokens[3], ChannelMode.Exception, tokens[4], Rfc2812Util.UserFromString(tokens[5]), Convert.ToInt64(tokens[6]), false); } break; case ReplyCode.RPL_ENDOFEXCEPTLIST: if (OnChannelList != null) { OnChannelList(tokens[3], ChannelMode.Exception, "", User.Empty, 0, true); } break; case ReplyCode.RPL_UNIQOPIS: if (OnChannelList != null) { OnChannelList(tokens[3], ChannelMode.ChannelCreator, tokens[4], User.Empty, 0, true); } break; case ReplyCode.RPL_VERSION: if (OnVersion != null) { OnVersion(CondenseStrings(tokens, 3)); } break; case ReplyCode.RPL_TIME: if (OnTime != null) { OnTime(CondenseStrings(tokens, 3)); } break; case ReplyCode.RPL_INFO: if (OnInfo != null) { OnInfo(CondenseStrings(tokens, 3), false); } break; case ReplyCode.RPL_ENDOFINFO: if (OnInfo != null) { OnInfo(CondenseStrings(tokens, 3), true); } break; case ReplyCode.RPL_ADMINME: case ReplyCode.RPL_ADMINLOC1: case ReplyCode.RPL_ADMINLOC2: case ReplyCode.RPL_ADMINEMAIL: if (OnAdmin != null) { OnAdmin(RemoveLeadingColon(CondenseStrings(tokens, 3))); } break; case ReplyCode.RPL_LUSERCLIENT: case ReplyCode.RPL_LUSEROP: case ReplyCode.RPL_LUSERUNKNOWN: case ReplyCode.RPL_LUSERCHANNELS: case ReplyCode.RPL_LUSERME: if (OnLusers != null) { OnLusers(RemoveLeadingColon(CondenseStrings(tokens, 3))); } break; case ReplyCode.RPL_LINKS: if (OnLinks != null) { OnLinks(tokens[3], //mask tokens[4], //hostname int.Parse(RemoveLeadingColon(tokens[5]), CultureInfo.InvariantCulture), //hopcount CondenseStrings(tokens, 6), false); } break; case ReplyCode.RPL_ENDOFLINKS: if (OnLinks != null) { OnLinks(String.Empty, String.Empty, -1, String.Empty, true); } break; case ReplyCode.RPL_STATSLINKINFO: case ReplyCode.RPL_STATSCOMMANDS: case ReplyCode.RPL_STATSUPTIME: case ReplyCode.RPL_STATSOLINE: if (OnStats != null) { OnStats(GetQueryType(code), RemoveLeadingColon(CondenseStrings(tokens, 3)), false); } break; case ReplyCode.RPL_ENDOFSTATS: if (OnStats != null) { OnStats(Rfc2812Util.CharToStatsQuery(tokens[3][0]), RemoveLeadingColon(CondenseStrings(tokens, 4)), true); } break; default: HandleDefaultReply(code, tokens); break; } }
public void ProcessJoinCommand(IrcMessage ircMessage) { OnJoin?.Invoke(Rfc2812Util.UserFromString(ircMessage.From), ircMessage.Target); }
/// <summary> /// Parse the message and call the callback methods /// on the listeners. /// /// </summary> /// <param name="tokens">The text received from the IRC server</param> private void ParseCommand(string[] tokens) { //Remove colon user info string tokens[0] = RemoveLeadingColon(tokens[0]); switch (tokens[1]) { case PONG: break; case NOTICE: tokens[3] = RemoveLeadingColon(tokens[3]); if (Rfc2812Util.IsValidChannelName(tokens[2])) { if (OnPublicNotice != null) { OnPublicNotice(this, new UserChannelMessageEventArgs( Rfc2812Util.UserFromString(tokens[0]), tokens[2], CondenseStrings(tokens, 3))); //Trace.WriteLine("Public notice", "IRC"); } } else { if (OnPrivateNotice != null) { OnPrivateNotice(this, new UserMessageEventArgs( Rfc2812Util.UserFromString(tokens[0]), CondenseStrings(tokens, 3))); //Trace.WriteLine("Private notice", "IRC"); } } break; case JOIN: if (OnJoin != null) { OnJoin(Rfc2812Util.UserFromString(tokens[0]), RemoveLeadingColon(tokens[2])); //Trace.WriteLine("Join", "IRC"); } break; case PRIVMSG: tokens[3] = RemoveLeadingColon(tokens[3]); if (tokens[3] == ACTION) { if (Rfc2812Util.IsValidChannelName(tokens[2])) { if (OnAction != null) { int last = tokens.Length - 1; tokens[last] = RemoveTrailingQuote(tokens[last]); OnAction(this, new UserChannelMessageEventArgs(Rfc2812Util.UserFromString(tokens[0]), tokens[2], CondenseStrings(tokens, 4))); //Trace.WriteLine("Channel action", "IRC"); } } else { if (OnPrivateAction != null) { int last = tokens.Length - 1; tokens[last] = RemoveTrailingQuote(tokens[last]); OnPrivateAction(this, new UserMessageEventArgs(Rfc2812Util.UserFromString(tokens[0]), CondenseStrings(tokens, 4))); //Trace.WriteLine("Private action", "IRC"); } } } else if (channelPattern.IsMatch(tokens[2])) { if (OnPublic != null) { OnPublic(this, new UserChannelMessageEventArgs(Rfc2812Util.UserFromString(tokens[0]), tokens[2], CondenseStrings(tokens, 3))); Trace.WriteLine("Public msg", "IRC"); } } else { if (OnPrivate != null) { OnPrivate(this, new UserMessageEventArgs(Rfc2812Util.UserFromString(tokens[0]), CondenseStrings(tokens, 3))); //Trace.WriteLine("Private msg", "IRC"); } } break; case NICK: if (OnNick != null) { OnNick(this, new NickChangeEventArgs(Rfc2812Util.UserFromString(tokens[0]), RemoveLeadingColon(tokens[2]))); //Trace.WriteLine("Nick", "IRC"); } break; case TOPIC: if (OnTopicChanged != null) { tokens[3] = RemoveLeadingColon(tokens[3]); OnTopicChanged(this, new UserChannelMessageEventArgs( Rfc2812Util.UserFromString(tokens[0]), tokens[2], CondenseStrings(tokens, 3))); //Trace.WriteLine("Topic changed", "IRC"); } break; case PART: if (OnPart != null) { OnPart( Rfc2812Util.UserFromString(tokens[0]), RemoveLeadingColon(tokens[2]), tokens.Length >= 4 ? RemoveLeadingColon(CondenseStrings(tokens, 3)) : ""); //Trace.WriteLine("Part", "IRC"); } break; case QUIT: if (OnQuit != null) { tokens[2] = RemoveLeadingColon(tokens[2]); OnQuit(Rfc2812Util.UserFromString(tokens[0]), CondenseStrings(tokens, 2)); //Trace.WriteLine("Quit", "IRC"); } break; case INVITE: if (OnInvite != null) { OnInvite( Rfc2812Util.UserFromString(tokens[0]), RemoveLeadingColon(tokens[3])); //Trace.WriteLine("Invite", "IRC"); } break; case KICK: if (OnKick != null) { tokens[4] = RemoveLeadingColon(tokens[4]); OnKick(Rfc2812Util.UserFromString(tokens[0]), tokens[2], tokens[3], CondenseStrings(tokens, 4)); //Trace.WriteLine("Kick", "IRC"); } break; case MODE: if (channelPattern.IsMatch(tokens[2])) { if (OnChannelModeChange != null) { User who = Rfc2812Util.UserFromString(tokens[0]); try { ChannelModeInfo[] modes = ChannelModeInfo.ParseModes(tokens, 3); string raw = CondenseStrings(tokens, 3); OnChannelModeChange(who, tokens[2], modes, raw); Trace.WriteLine("Channel mode change", "IRC"); } catch (Exception) { if (OnError != null) { OnError(this, new ErrorMessageEventArgs(ReplyCode.UnparseableMessage, CondenseStrings(tokens, 0))); } Debug.WriteLineIf(Rfc2812Util.IrcTrace.TraceWarning, "[" + Thread.CurrentThread.Name + "] Listener::ParseCommand() Bad IRC MODE string=" + tokens[0]); } } } else { if (OnUserModeChange != null) { tokens[3] = RemoveLeadingColon(tokens[3]); OnUserModeChange(this, new UserModeChangeEventArgs(Rfc2812Util.CharToModeAction(tokens[3][0]), Rfc2812Util.CharToUserMode(tokens[3][1]))); //Trace.WriteLine("User mode change", "IRC"); } } break; case KILL: if (OnKill != null) { string reason = ""; if (tokens.Length >= 4) { tokens[3] = RemoveLeadingColon(tokens[3]); reason = CondenseStrings(tokens, 3); } OnKill(Rfc2812Util.UserFromString(tokens[0]), tokens[2], reason); } break; default: if (OnError != null) { OnError(this, new ErrorMessageEventArgs(ReplyCode.UnparseableMessage, CondenseStrings(tokens, 0))); } Debug.WriteLineIf(Rfc2812Util.IrcTrace.TraceWarning, "[" + Thread.CurrentThread.Name + "] Listener::ParseCommand() Unknown IRC command=" + tokens[1]); //Trace.WriteLine("Unknown command", "IRC"); break; } }
public void ProcessNickCommand(IrcMessage message) { OnNick.Fire(this, new NickChangeEventArgs(Rfc2812Util.UserFromString(message.From), message.Message)); }
private void ProcessJoinCommand(string[] tokens) { OnJoin?.Invoke(Rfc2812Util.UserFromString(tokens[0]), RemoveLeadingColon(tokens[2])); //Trace.WriteLine("Join", "IRC"); }
private void ProcessQuitCommand(string[] tokens) { tokens[2] = RemoveLeadingColon(tokens[2]); OnQuit?.Invoke(Rfc2812Util.UserFromString(tokens[0]), CondenseStrings(tokens, 2)); //Trace.WriteLine("Quit", "IRC"); }
private void ProcessNickCommand(string[] tokens) { OnNick.Fire(this, new NickChangeEventArgs(Rfc2812Util.UserFromString(tokens[0]), RemoveLeadingColon(tokens[2]))); //Trace.WriteLine("Nick", "IRC"); }
public void ProcessKickCommand(IrcMessage ircMessage) { OnKick?.Invoke(Rfc2812Util.UserFromString(ircMessage.From), ircMessage.Tokens[2], ircMessage.Tokens[3], ircMessage.Message); }
private void ProcessKickCommand(string[] tokens) { tokens[4] = RemoveLeadingColon(tokens[4]); OnKick?.Invoke(Rfc2812Util.UserFromString(tokens[0]), tokens[2], tokens[3], CondenseStrings(tokens, 4)); //Trace.WriteLine("Kick", "IRC"); }
public void ProcessInviteCommand(IrcMessage ircMessage) { var fromUser = Rfc2812Util.UserFromString(ircMessage.From); OnInvite.Fire(this, new InviteEventArgs(fromUser.Nick, ircMessage.Message)); }
internal static ChannelModeInfo[] ParseModes(string[] tokens, int start) { //This nice piece of code was contributed by Klemen Šavs. //25 October 2003 ArrayList modeInfoArray = new ArrayList(); int i = start; while (i < tokens.Length) { ChannelModeInfo modeInfo = new ChannelModeInfo(); int parmIndex = i + 1; for (int j = 0; j < tokens[i].Length; j++) { while (j < tokens[i].Length && tokens[i][j] == '+') { modeInfo.Action = ModeAction.Add; j++; } while (j < tokens[i].Length && tokens[i][j] == '-') { modeInfo.Action = ModeAction.Remove; j++; } if (j == 0) { break; } else if (j < tokens[i].Length) { switch (tokens[i][j]) { case 'o': case 'h': case 'v': case 'b': case 'e': case 'I': case 'k': case 'O': modeInfo.Mode = Rfc2812Util.CharToChannelMode(tokens[i][j]); modeInfo.Parameter = tokens[parmIndex++]; break; case 'l': modeInfo.Mode = Rfc2812Util.CharToChannelMode(tokens[i][j]); if (modeInfo.Action == ModeAction.Add) { modeInfo.Parameter = tokens[parmIndex++]; } else { modeInfo.Parameter = ""; } break; default: modeInfo.Mode = Rfc2812Util.CharToChannelMode(tokens[i][j]); modeInfo.Parameter = ""; break; } } modeInfoArray.Add(modeInfo.MemberwiseClone()); } i = parmIndex; } ChannelModeInfo[] modes = new ChannelModeInfo[modeInfoArray.Count]; for (int k = 0; k < modeInfoArray.Count; k++) { modes[k] = (ChannelModeInfo)modeInfoArray[k]; } return(modes); }
internal void Parse(Connection connection, string message) { Debug.WriteLineIf(DccUtil.DccTrace.TraceInfo, "[" + Thread.CurrentThread.Name + "] DccListener::Parse()"); Match match = parser.Match(message); string requestor = match.Groups[1].ToString(); string[] tokens = tokenizer.Split(match.Groups[2].ToString().Trim()); switch (tokens[Action]) { case CHAT: if (OnDccChatRequest != null) { //Test for sufficient number of arguments if (tokens.Length < 4) { connection.Listener.Error(ReplyCode.UnparseableMessage, "Incorrect CHAT arguments: " + message); return; } //Send event DccUser dccUser = null; try { dccUser = new DccUser( connection, Rfc2812Util.ParseUserLine(requestor), new IPEndPoint(DccUtil.LongToIPAddress(tokens[Address]), int.Parse(tokens[Port], CultureInfo.InvariantCulture))); } catch (ArgumentException) { connection.Listener.Error(ReplyCode.BadDccEndpoint, "Invalid TCP/IP connection information sent."); return; } try { OnDccChatRequest(dccUser); } catch (ArgumentException ae) { connection.Listener.Error(ReplyCode.UnknownEncryptionProtocol, ae.ToString()); } } break; case SEND: //Test for sufficient number of arguments if (tokens.Length < 5) { connection.Listener.Error(ReplyCode.UnparseableMessage, "Incorrect SEND arguments: " + message); return; } if (OnDccSendRequest != null) { DccUser dccUser = null; try { dccUser = new DccUser( connection, Rfc2812Util.ParseUserLine(requestor), new IPEndPoint(DccUtil.LongToIPAddress(tokens[Address]), int.Parse(tokens[Port], CultureInfo.InvariantCulture))); } catch (ArgumentException ae) { connection.Listener.Error(ReplyCode.BadDccEndpoint, ae.ToString()); return; } try { OnDccSendRequest( dccUser, tokens[FileName], int.Parse(tokens[FileSize], CultureInfo.InvariantCulture), IsTurbo(5, tokens)); } catch (ArgumentException ae) { connection.Listener.Error(ReplyCode.UnknownEncryptionProtocol, ae.ToString()); } } break; case GET: //Test for sufficient number of arguments if (tokens.Length < 2) { connection.Listener.Error(ReplyCode.UnparseableMessage, "Incorrect GET arguments: " + message); return; } if (OnDccGetRequest != null) { try { OnDccGetRequest( new DccUser( connection, Rfc2812Util.ParseUserLine(requestor)), tokens[FileName], IsTurbo(2, tokens)); } catch (ArgumentException ae) { connection.Listener.Error(ReplyCode.UnknownEncryptionProtocol, ae.ToString()); } } break; case ACCEPT: //Test for sufficient number of arguments if (tokens.Length < 4) { connection.Listener.Error(ReplyCode.UnparseableMessage, "Incorrect DCC ACCEPT arguments: " + message); return; } //DccListener will try to handle Receive at correct file position try { DccFileSession session = DccFileSessionManager.DefaultInstance.LookupSession("C" + tokens[2]); session.OnDccAcceptReceived(long.Parse(tokens[3], CultureInfo.InvariantCulture)); } catch (ArgumentException e) { connection.Listener.Error(ReplyCode.UnableToResume, e.ToString()); } break; case RESUME: //Test for sufficient number of arguments if (tokens.Length < 4) { connection.Listener.Error(ReplyCode.UnparseableMessage, "Incorrect DCC RESUME arguments: " + message); return; } //DccListener will automatically handle Resume/Accept interaction try { DccFileSession session = DccFileSessionManager.DefaultInstance.LookupSession("S" + tokens[2]); session.OnDccResumeRequest(long.Parse(tokens[3], CultureInfo.InvariantCulture)); } catch (ArgumentException e) { connection.Listener.Error(ReplyCode.UnableToResume, e.ToString()); } break; default: connection.Listener.Error(ReplyCode.UnparseableMessage, message); Debug.WriteLineIf(DccUtil.DccTrace.TraceError, "[" + Thread.CurrentThread.Name + "] DccListener::Parse() Unknown DCC command"); break; } }