private void ProcessModeCommand(string[] tokens) { if (channelPattern.IsMatch(tokens[2])) { if (OnChannelModeChange == null) { return; } 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) { OnError.Fire(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 { tokens[3] = RemoveLeadingColon(tokens[3]); OnUserModeChange?.Invoke(this, new UserModeChangeEventArgs(Rfc2812Util.CharToModeAction(tokens[3][0]), Rfc2812Util.CharToUserMode(tokens[3][1]))); //Trace.WriteLine("User mode change", "IRC"); } }
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; } }
/// <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; } }