protected virtual void OnRawNumeric(Int32 numeric, string line)
        {
            // TODO: Trigger a RawNumericReceivedEvent event
            //Console.WriteLine("{0} {1}", numeric.ToString("[000]"), line);
            string[] toks = line.Split(' ');

            Match m;

            switch (numeric)
            {
            case 001:
            {
                ConnectionEstablishedEvent.Raise(this, EventArgs.Empty);
            } break;

            case 005:
            {
                if ((m = Patterns.rUserPrefix.Match(line)).Success)
                {
                    m_AccessModes    = m.Groups[1].Value;
                    m_AccessPrefixes = m.Groups[2].Value;
                    rRawNames        = new Regex(String.Format(@"([{0}]?)(\S+)", m_AccessPrefixes));
#if DEBUG
                    m_Logger.Debug("Regex Pattern: {0}", rRawNames.ToString());
                    m_Logger.Debug("Access Modes: {0} | Access Prefixes: {1}", m_AccessModes, m_AccessPrefixes);
#endif
                }

                if ((m = Patterns.rChannelModes.Match(line)).Success)
                {
                    m_ChannelModes = m.Groups[1].Value;
                }
            } break;

            case 353:
            {
                Channel c = GetChannel(toks[4]);                                                        // Get the channel from the collection of channels

                string   sub   = line.Substring(line.IndexOf(":", 1)).Remove(0, 1);                     // Get the list of nicks out of the line.
                string[] names = sub.Split(' ');                                                        // Split the list into an array.

                foreach (var name in names)
                {
                    if (String.IsNullOrEmpty(name) || String.IsNullOrEmpty(name))
                    {
                        continue;
                    }

                    if ((m = rRawNames.Match(name)).Success)
                    {                                                                                         // Parse the nicks and match them via RegEx
                        var nick   = m.Groups[2].Value;                                                       // capture the nick
                        var prefix = (String.IsNullOrEmpty(m.Groups[1].Value) ? '\0' : m.Groups[1].Value[0]); // and the prefix

                        if (c.Users.ContainsKey(nick))
                        {
                            c.Users[nick].AddPrefix(prefix);                                                     // Update the nick's prefix, or
                        }
                        else
                        {
                            PrefixList l = new PrefixList(this);
                            l.AddPrefix(prefix);
                            c.Users.Add(nick, l);                                                  // add it to the list if they don't exist.
                        }
#if DEBUG
                        Send("PRIVMSG {0} :Name: {1} - Access: {2}", c.Name, nick, prefix);             // Debug output for reference.
#endif
                    }
                }
            } break;

            case 367:                   // +b
            case 348:                   // +e
            case 346:                   // +I
            {
                string   setBy = toks[5];
                DateTime setOn = (Double.Parse(toks[6]).ToDateTime());
                string   mask  = toks[4];
#if DEBUG
                System.Diagnostics.Debug.WriteLine("debug: [ListMode:{0}] Set By: {1} | Mask: {2} | Channel: {3}", numeric, toks[5], toks[4], toks[3]);
                System.Diagnostics.Debug.WriteLine("\t\t Set On: {0}", setOn);
#endif

                OnListMode(numeric, toks[3], toks[5], setOn, toks[4]);
            } break;

            case 332:
            {
                // TODO: channel topic
            } break;
            }
        }
Beispiel #2
0
        protected virtual async void OnRfcNumeric(int numeric, string source, string[] parameters)
        {
            RfcNumericReceivedEvent.Raise(this, new RfcNumericReceivedEventArgs(numeric, string.Join(" ", parameters)));

            if (numeric == RPL_WELCOME)
            { // Welcome packet
                connectingLock.Release();
                ConnectionEstablishedEvent.Raise(this, EventArgs.Empty);
            }
            else if (numeric == 5)
            { // Contribution for handy parsing of 005 courtesy of @aca20031
                Dictionary <string, string> args = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                string[] tokens = parameters.Skip(1).ToArray();
                foreach (string token in tokens)
                {
                    int equalIndex = token.IndexOf('=');
                    if (equalIndex >= 0)
                    {
                        args[token.Substring(0, equalIndex)] = token.Substring(equalIndex + 1);
                    }
                    else
                    {
                        args[token] = "";
                    }
                }

                if (args.ContainsKey("PREFIX"))
                {
                    string value = args["PREFIX"];
                    Match  m;
                    if (value.TryMatch(@"\(([^\)]+)\)(\S+)", out m))
                    {
                        info.PrefixModes = m.Groups[1].Value;
                        info.Prefixes    = m.Groups[2].Value;
                    }
                }

                if (args.ContainsKey("CHANMODES"))
                {
                    string[] chanmodes = args["CHANMODES"].Split(',');

                    info.ListModes                 = chanmodes[0];
                    info.ModesWithParameter        = chanmodes[1];
                    info.ModesWithParameterWhenSet = chanmodes[2];
                    info.ModesWithNoParameter      = chanmodes[3];
                }

                if (args.ContainsKey("MODES"))
                {
                    int modeslen;
                    if (int.TryParse(args["MODES"], out modeslen))
                    {
                        info.MaxModes = modeslen;
                    }
                }

                if (args.ContainsKey("TOPICLEN"))
                {
                    int topiclen;
                    if (int.TryParse(args["TOPICLEN"], out topiclen))
                    {
                        info.TopicLength = topiclen;
                    }
                }

                if (!EnableV3)
                {
                    if (args.ContainsKey("NAMESX"))
                    {   // Request the server send us extended NAMES (353)
                        // This will format a RPL_NAMES using every single prefix the user has on a channel.

                        useExtendedNames = true;
                        await Send("PROTOCTL NAMESX");
                    }

                    if (args.ContainsKey("UHNAMES"))
                    {
                        useUserhostNames = true;
                        await Send("PROTOCTL UHNAMES");
                    }
                }
            }
            else if (numeric == 353)
            {   // note: NAMESX and UHNAMES are not mutually exclusive.
                // NAMESX: (?<prefix>[!~&@%+]*)(?<nick>[^ ]+)
                // UHNAMES: (?<prefix>[!~&@%+]*)(?<nick>[^!]+)!(?<ident>[^@]+)@(?<host>[^ ]+)
                // (?<prefix>[!~&@%+]*)(?<nick>[^!]+)(?:!(?<ident>[^@]+)@(?<host>[^ ]+))?

                if (string.IsNullOrEmpty(accessRegex))
                {
                    accessRegex = string.Format(@"(?<prefix>[{0}]*)(?<nick>[^! ]+)(?:!(?<ident>[^@]+)@(?<host>[^ ]+))?", Prefixes);
                }

                var c     = GetChannel(parameters[2]); // never null.
                var names = string.Join(" ", parameters.Skip(3));

                MatchCollection matches;
                if (names.TryMatches(accessRegex, out matches))
                {
                    foreach (Match item in matches)
                    { // for now, we only care for the nick and the prefix(es).
                        string nick = item.Groups["nick"].Value;

                        if (useExtendedNames)
                        {
                            c.AddOrUpdateUser(nick, item.Groups["prefix"].Value.ToCharArray());
                        }
                        else
                        {
                            char prefix = item.Groups["prefix"].Value.Length > 0 ? item.Groups["prefix"].Value[0] : (char)0;
                            c.AddOrUpdateUser(nick, new[] { prefix });
                        }

                        //Console.WriteLine("Found \"{0}\" on channel {1}: {2}", nick, c, item.Groups["prefix"].Value);
                    }
                }
            }

            /*else
             * {
             *  Console.WriteLine("[{0:000}] Numeric received with {1} parameters: {{{2}}}",
             *      numeric,
             *      parameters.Length,
             *      String.Join(",", parameters));
             * }*/
        }