Example #1
0
        /// <summary>
        /// Convert bytes into IrcPackets
        /// </summary>
        public IrcPacket[] ExtractPackets(ByteBuffer partialResponse)
        {
            var str      = partialResponse.GetString(encoding);
            var response = lastResponsePart + str;
            var ss       = new StringStream(response);
            var packets  = new List <IrcPacket>(3);

            while (ss.HasNext)
            {
                var content = ss.NextWord(PacketTerminator);
                if (!ss.HasNext && !response.EndsWith(PacketTerminator))
                {
                    lastResponsePart = content;
                }
                else
                {
                    try
                    {
                        var packet = CreatePacket(content);
                        packets.Add(packet);
                        if (!ss.HasNext)
                        {
                            lastResponsePart = "";
                        }
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Unable to parse packet: " + content, e);
                    }
                }
            }
            return(packets.ToArray());
        }
Example #2
0
 internal void ActionNotify(IrcUser user, IrcChannel channel, StringStream text)
 {
     if (channel != null)
     {
         channel.ActionNotify(user, text);
     }
     OnAction(user, channel, text);
 }
Example #3
0
 public virtual bool TriggersCommand(IrcUser user, IrcChannel chan, StringStream input)
 {
     return(CommandHandler.RemoteCommandPrefixes.Iterate(prefix => { if (input.String.StartsWith(prefix, StringComparison.CurrentCultureIgnoreCase))
                                                                     {
                                                                         input.Skip(prefix.Length); return true;
                                                                     }
                                                                     return false; }));
 }
Example #4
0
        internal void ChatMessageReceivedNotify(DccChatClient client, StringStream text)
        {
            if (ChatMessageReceived != null)
            {
                ChatMessageReceived(client, text);
            }

            if (m_irc.TriggersCommand(client.User, null, text))
            {
                m_irc.CommandHandler.Execute(new DccChatCmdTrigger(text, client.User));
            }
        }
Example #5
0
 internal void NoticeNotify(IrcUser user, IrcChannel chan, StringStream text)
 {
     if (chan != null)
     {
         chan.NoticeReceivedNotify(user, text);
     }
     OnNotice(user, chan, text);
     if (TriggersCommand(user, chan, text))
     {
         m_CommandHandler.Execute(new NoticeCmdTrigger(text, user, chan));
     }
 }
Example #6
0
        internal void TextNotify(IrcUser user, IrcChannel chan, StringStream text)
        {
            if (chan != null)
            {
                chan.TextNotify(user, text);
            }
            OnText(user, chan, text);

            if (TriggersCommand(user, chan, text))
            {
                m_CommandHandler.Execute(new MsgCmdTrigger(text, user, chan));
            }
        }
Example #7
0
        /// <summary>
        /// Build a packet from a new line of content from the server.
        /// Do as much parsing as possible here before the packet-handler
        /// will then work with the gathered information.
        /// </summary>
        public IrcPacket CreatePacket(string content)
        {
            var line = new StringStream(content.Trim());

            string prefix;

            if (content[0] == ':')
            {
                prefix = line.NextWord().Substring(1);
            }
            else
            {
                prefix = line.NextWord();
            }

            var action = line.NextWord();
            var packet = new IrcPacket(irc, prefix, action, new StringStream(line.Remainder.Trim()), line.String)
            {
                protHandler = this
            };

            return(packet);
        }
Example #8
0
 internal void QueryMsgNotify(IrcUser user, StringStream text)
 {
     OnQueryMsg(user, text);
 }
Example #9
0
        internal void TextNotify(IrcUser user, IrcChannel chan, StringStream text)
        {
            if (chan != null)
                chan.TextNotify(user, text);
            OnText(user, chan, text);

            if (TriggersCommand(user, chan, text))
            {
                m_CommandHandler.Execute(new MsgCmdTrigger(text, user, chan));
            }
        }
Example #10
0
 /// <summary>
 /// Fires when the Client receives a PRIVMSG which was directed to a Channel.
 /// </summary>
 protected virtual void OnChannelMsg(IrcUser user, IrcChannel chan, StringStream text)
 {
 }
Example #11
0
        /// <summary>
        /// Fires when the Client recieves any CTCP ACTION aka /me.
        /// </summary>
        /// <param name="user">The User who sent the text</param>
        /// <param name="channel">The Channel where it was sent (can be null if sent to a User)</param>
        /// <param name="text">The text which was sent</param>

        protected virtual void OnAction(IrcUser user, IrcChannel channel, StringStream text)
        {
        }
Example #12
0
 public MsgCmdTrigger(StringStream args, IrcUser user, IrcChannel chan = null)
     : base(args, user, chan)
 {
 }
 public DccChatCmdTrigger(StringStream args, IrcUser user)
     : base(args, user, null)
 {
 }
Example #14
0
 internal void ChannelMsgNotify(IrcUser user, IrcChannel chan, StringStream text)
 {
     chan.MsgReceivedNotify(user, text);
     OnChannelMsg(user, chan, text);
 }
Example #15
0
 public ExecuteCmdTrigger(StringStream args, IrcUser user, IrcChannel chan)
     : base(args, user, chan)
 {
 }
Example #16
0
 /// <summary>
 /// Fires when the Client recieves any CTCP ACTION aka /me.
 /// </summary>
 /// <param name="user">The User who sent the text</param>
 /// <param name="channel">The Channel where it was sent (can be null if sent to a User)</param>
 /// <param name="text">The text which was sent</param>
 protected virtual void OnAction(IrcUser user, IrcChannel channel, StringStream text)
 {
 }
Example #17
0
 /// <summary>
 /// Fires when the Client receives a PRIVMSG, directed to this Client itself.
 /// </summary>
 protected virtual void OnQueryMsg(IrcUser user, StringStream text)
 {
 }
Example #18
0
 internal void QueryMsgNotify(IrcUser user, StringStream text)
 {
     OnQueryMsg(user, text);
 }
Example #19
0
 /// <summary>
 /// Fires when the Client receives a PRIVMSG which was directed to a Channel.
 /// </summary>
 protected virtual void OnChannelMsg(IrcUser user, IrcChannel chan, StringStream text)
 {
 }
Example #20
0
 public bool NextBool(string separator)
 {
     return(StringStream.GetBool(this.NextWord(separator)));
 }
Example #21
0
 public DccChatCmdTrigger(StringStream args, IrcUser user)
     : base(args, user, null)
 {
 }
Example #22
0
 /// <summary>
 /// Fires when the Client receives a PRIVMSG, directed to this Client itself.
 /// </summary>
 protected virtual void OnQueryMsg(IrcUser user, StringStream text)
 {
 }
Example #23
0
        internal void ChatMessageReceivedNotify(DccChatClient client, StringStream text)
        {
            if (ChatMessageReceived != null)
                ChatMessageReceived(client, text);

            if (m_irc.TriggersCommand(client.User, null, text))
            {
                m_irc.CommandHandler.Execute(new DccChatCmdTrigger(text, client.User));
            }
        }
Example #24
0
 public virtual bool TriggersCommand(IrcUser user, IrcChannel chan, StringStream input)
 {
     return CommandHandler.RemoteCommandPrefixes.Iterate(prefix => { if (input.String.StartsWith(prefix, StringComparison.CurrentCultureIgnoreCase)) { input.Skip(prefix.Length); return true; } return false; });
 }
Example #25
0
        /// <summary>
        ///
        /// </summary>
        private void SetupHandlers()
        {
            // If its not recognized:
            defaultPacketHandler = packet =>
            {
                // PING is special
                if (packet.Prefix == "PING")
                {
                    packet.IrcClient.Send("PONG " + packet.Key);
                }
                else if (packet.Key.StartsWith("4") || packet.Key.StartsWith("5"))
                {
                    // Error Replies
                    packet.IrcClient.ErrorNotify(packet);
                }
                else
                {
                    // Normal replies
                    packet.IrcClient.UnspecifiedInfoNotify(packet);
                }
            };

            // Connection Handling
            AddPacketHandler("001", packet =>
            {
                // :Serv 001 Me :<Welcomemessage>
                packet.IrcClient.Me.ChangeNick(packet.Content.NextWord());
                defaultPacketHandler(packet);
                packet.IrcClient.Send("USERHOST " + packet.IrcClient.Me);
            });

            AddPacketHandler("005", packet => { packet.IrcClient.ConnectionInfoNotify(packet); });

            // Finished login
            AddPacketHandler("302", packet => { packet.IrcClient.PerformNotify(); });

            // Messaging
            AddPacketHandler("PRIVMSG", packet =>
            {
                var strStream  = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());

                var args = packet.Args;

                if (args.StartsWith("") && args.EndsWith(""))
                {
                    // CTCP
                    args = packet.Args.Split('')[1];

                    var argsStream = new StringStream(args);
                    packet.IrcClient.CtcpRequestNotify(packet.User, packet.channel, argsStream.NextWord(),
                                                       argsStream.Remainder);
                }
                else
                {
                    // Text message
                    packet.IrcClient.TextNotify(packet.User, packet.channel, new StringStream(args));
                    var argsStream = new StringStream(args);

                    if (packet.channel == null)
                    {
                        packet.IrcClient.QueryMsgNotify(packet.User, argsStream);
                    }
                    else
                    {
                        packet.IrcClient.ChannelMsgNotify(packet.User, packet.channel, argsStream);
                    }
                }
            });

            AddPacketHandler("NOTICE", packet =>
            {
                var strStream  = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());

                var args = packet.Args;

                if (packet.Args.StartsWith("") && packet.Args.EndsWith(""))
                {
                    args = packet.Args.Split('')[1];

                    var argsStream = new StringStream(args);
                    packet.IrcClient.CtcpReplyNotify(packet.User, packet.channel, argsStream.NextWord(),
                                                     argsStream.Remainder);
                }
                else
                {
                    packet.IrcClient.TextNotify(packet.User, packet.channel, new StringStream(args));
                    packet.IrcClient.NoticeNotify(packet.User, packet.channel, new StringStream(packet.Args));
                }
            });

            // Nick / Quit
            AddPacketHandler("NICK", packet => { packet.IrcClient.NickNotify(packet.User, packet.Args); });
            AddPacketHandler("QUIT", packet => { packet.IrcClient.QuitNotify(packet.User, packet.Args); });
            AddPacketHandler("431", packet => { packet.IrcClient.InvalidNickNotify("431", "", packet.Args); }); // :Serv 431 Me :No nickname given
            AddPacketHandler("433", packet =>                                                                   // :Serv 433 Me <Nick> :Nickname is already in use.
            {
                var strStream = new StringStream(packet.Content);
                strStream.SkipWord();
                packet.IrcClient.InvalidNickNotify(packet.Key, strStream.NextWord(), packet.Args);
            });

            AddPacketHandler("432", packetHandlers["433"][0]);             // :Serv 432 Me <Nick> :Invalid nickname: ...

            // Channel related Stuff
            AddPacketHandler("INVITE", packet =>
            {
                var strStream = new StringStream(packet.Content);
                strStream.NextWord("#");
                packet.IrcClient.InviteNotify(packet.User, "#" + strStream.NextWord());
            });
            AddPacketHandler("JOIN", packet => { packet.IrcClient.JoinNotify(packet.User, packet.ArgsOrFirstWord); });
            AddPacketHandler("485", packet =>                                                                                           // cannot join channel
            {
                packet.channel = packet.IrcClient.GetChannel(packet.Content.NextWord());
                packet.IrcClient.CannotJoinNotify(packet.channel, packet.Args);
            });
            AddPacketHandler("471", delegate { });
            AddPacketHandler("473", delegate { });
            AddPacketHandler("474", delegate { });
            AddPacketHandler("475", delegate { });
            AddPacketHandler("477", delegate { });

            AddPacketHandler("TOPIC", packet =>
            {
                // User TOPIC Channel :Topic
                var content = packet.Content;

                packet.channel              = packet.IrcClient.GetOrCreateChannel(content.NextWord());
                packet.channel.TopicSetter  = packet.User;
                packet.channel.TopicSetTime = DateTime.Now;
                packet.IrcClient.TopicNotify(packet.User, packet.channel, packet.Args, false);
                packet.channel.SetTopic(packet.Args);
            });
            AddPacketHandler("332", packet =>
            {
                // :Sender 332 Me Channel :Topic
                var content = packet.Content;
                //packet.User = packet.IrcClient.GetOrCreateUser(content.NextWord());
                content.SkipWord();
                packet.channel = packet.IrcClient.GetOrCreateChannel(content.NextWord());
                packet.IrcClient.TopicNotify(packet.User, packet.channel, packet.Args, true);
                packet.channel.SetTopic(packet.Args);
            });

            AddPacketHandler("333", packet =>
            {
                // :Sender 333 Me Channel TopicSetter TopicTimestamp
                StringStream content = packet.Content;
                content.SkipWord();
                packet.channel              = packet.IrcClient.GetOrCreateChannel(content.NextWord());
                packet.User                 = packet.IrcClient.GetOrCreateUser(content.NextWord());
                packet.channel.TopicSetter  = packet.User;
                packet.channel.TopicSetTime = new DateTime(1970, 1, 1) +
                                              TimeSpan.FromSeconds(content.NextInt());
            });

            AddPacketHandler("353", packet =>             // :Serv 353 Me = Channel :Namelist
            {
                var strStream = new StringStream(packet.Content);
                strStream.SkipWords(2);
                packet.channel  = packet.IrcClient.GetChannel(strStream.NextWord());
                IrcUser[] users = packet.channel.AddNames(packet.Args);
                packet.IrcClient.UsersAddedNotify(packet.channel, users);
            });
            AddPacketHandler("MODE", packet =>             // :Serv MODE Channel Modes [ModeArgs]
            {
                var strStream  = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());
                strStream.Consume(':', 1);
                string modes = strStream.NextWord();
                strStream.Consume(':', 1);
                string[] prms = strStream.RemainingWords();
                packet.ProtHandler.ParseModes(packet.User, packet.channel, modes, prms);
            });
            AddPacketHandler("PART", packet =>
            {
                var strStream  = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());
                packet.IrcClient.PartNotify(packet.User, packet.channel, packet.Args);
            });
            AddPacketHandler("KICK", packet =>
            {
                var strStream  = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());
                IrcUser user   = packet.IrcClient.GetOrCreateUser(strStream.NextWord());
                packet.IrcClient.KickNotify(packet.User, packet.channel, user, packet.Args);
            });
            AddPacketHandler("324", packet =>             // :Serv 324 Me Channel Modes [ModeArgs]
            {
                var strStream = new StringStream(packet.Content);
                strStream.SkipWord();                                                                 // skip "Me"
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());

                strStream.Consume(':', 1);
                string modes = strStream.NextWord();
                strStream.Consume(':', 1);
                string[] prms = strStream.RemainingWords();
                packet.ProtHandler.ParseModes(packet.User, packet.channel, modes, prms);
            });
            AddPacketHandler("329", packet =>             // :Serv 329 [Me] #Channel CreationTime
            {
                var strStream   = new StringStream(packet.Content);
                String chanName = strStream.NextWord();
                if (!chanName.StartsWith("#"))
                {
                    chanName = strStream.NextWord();
                }
                packet.channel = packet.IrcClient.GetChannel(chanName);
                DateTime time  = new DateTime(1970, 1, 1) +
                                 TimeSpan.FromSeconds(Convert.ToInt32(strStream.NextWord()));
                if (packet.channel != null)
                {
                    packet.channel.SetCreationTime(time);
                }
                packet.IrcClient.ChanCreationTimeNotify(packet.channel, time);
            });

            // RPL_WHOREPLY
            AddPacketHandler("352", packet =>
            {
                var content = packet.Content;
                // the first word is our own nick
                content.SkipWord();
                packet.channel = packet.IrcClient.GetChannel(content.NextWord());
                var username   = content.NextWord();
                var host       = content.NextWord();
                var server     = content.NextWord();
                var nick       = content.NextWord();
                var flags      = content.NextWord();
                // the distance is the number *after* the character ":"
                var hops = content.NextWord().Substring(1);
                var info = packet.Args.Substring(packet.Args.IndexOf(" ") + 1);
                packet.IrcClient.GetOrCreateUser(nick).SetInfo(username, host, info);
                packet.IrcClient.WhoReplyNotify(packet.channel.Name, username, host, server, nick, flags, hops, info);
            });
            // Reply to extended WHO
            AddPacketHandler("354", packet =>
            {
                packet.Content.SkipWord();                              // first word is own nick

                var nick     = packet.Content.NextWord();
                var authName = packet.Content.NextWord();
                if (authName != "0")
                {
                    var user      = packet.User = packet.IrcClient.GetOrCreateUser(nick);
                    user.AuthName = authName;
                    var authMgr   = packet.IrcClient.AuthMgr;
                    if (authMgr != null)
                    {
                        authMgr.OnAuthResolved(user);
                    }
                }
            });
            AddPacketHandler("367", packet =>             // :Serv 367 Me Channel banMask bannerName banTime
            {
                var content = packet.Content;
                content.SkipWord();
                packet.channel = packet.IrcClient.GetChannel(content.NextWord());

                var banmask = content.NextWord();
                var banner  = content.NextWord();
                var bantime = content.NextWord();
                var entry   = new BanEntry(banmask, banner, new DateTime(1970, 1, 1) +
                                           TimeSpan.FromSeconds(Convert.ToInt32(bantime)));
                if (packet.channel != null && !packet.channel.BanMasks.ContainsKey(banmask))
                {
                    packet.channel.BanMasks.Add(banmask, entry);
                }
                packet.IrcClient.BanListEntryNotify(packet.channel, entry);
            });

            // Ban List completed
            AddPacketHandler("368", packet =>
            {
                packet.channel = packet.IrcClient.GetChannel(packet.Content.NextWord());
                packet.IrcClient.BanListCompleteNotify(packet.channel);
            });
        }
Example #26
0
 internal void ActionNotify(IrcUser user, IrcChannel channel, StringStream text)
 {
     if (channel != null)
         channel.ActionNotify(user, text);
     OnAction(user, channel, text);
 }
Example #27
0
 internal void ChannelMsgNotify(IrcUser user, IrcChannel chan, StringStream text)
 {
     chan.MsgReceivedNotify(user, text);
     OnChannelMsg(user, chan, text);
 }
Example #28
0
 internal void NoticeNotify(IrcUser user, IrcChannel chan, StringStream text)
 {
     if (chan != null)
         chan.NoticeReceivedNotify(user, text);
     OnNotice(user, chan, text);
     if (TriggersCommand(user, chan, text))
     {
         m_CommandHandler.Execute(new NoticeCmdTrigger(text, user, chan));
     }
 }
Example #29
0
        /// <summary>
        /// 
        /// </summary>
        private void SetupHandlers()
        {
            // If its not recognized:
            defaultPacketHandler = packet =>
            {
                // PING is special
                if (packet.Prefix == "PING")
                {
                    packet.IrcClient.Send("PONG " + packet.Key);
                }
                else if (packet.Key.StartsWith("4") || packet.Key.StartsWith("5"))
                {
                    // Error Replies
                    packet.IrcClient.ErrorNotify(packet);
                }
                else
                {
                    // Normal replies
                    packet.IrcClient.UnspecifiedInfoNotify(packet);
                }
            };

            // Connection Handling
            AddPacketHandler("001", packet =>
            {
                // :Serv 001 Me :<Welcomemessage>
                packet.IrcClient.Me.ChangeNick(packet.Content.NextWord());
                defaultPacketHandler(packet);
                packet.IrcClient.Send("USERHOST " + packet.IrcClient.Me);
            });

            AddPacketHandler("005", packet => { packet.IrcClient.ConnectionInfoNotify(packet); });

            // Finished login
            AddPacketHandler("302", packet => { packet.IrcClient.PerformNotify(); });

            // Messaging
            AddPacketHandler("PRIVMSG", packet =>
            {
                var strStream = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());

                var args = packet.Args;

                if (args.StartsWith("") && args.EndsWith(""))
                {
                    // CTCP
                    args = packet.Args.Split('')[1];

                    var argsStream = new StringStream(args);
                    packet.IrcClient.CtcpRequestNotify(packet.User, packet.channel, argsStream.NextWord(),
                                                       argsStream.Remainder);
                }
                else
                {
                    // Text message
                    packet.IrcClient.TextNotify(packet.User, packet.channel, new StringStream(args));
                    var argsStream = new StringStream(args);

                    if (packet.channel == null)
                    {
                        packet.IrcClient.QueryMsgNotify(packet.User, argsStream);
                    }
                    else
                    {
                        packet.IrcClient.ChannelMsgNotify(packet.User, packet.channel, argsStream);
                    }
                }
            });

            AddPacketHandler("NOTICE", packet =>
            {
                var strStream = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());

                var args = packet.Args;

                if (packet.Args.StartsWith("") && packet.Args.EndsWith(""))
                {
                    args = packet.Args.Split('')[1];

                    var argsStream = new StringStream(args);
                    packet.IrcClient.CtcpReplyNotify(packet.User, packet.channel, argsStream.NextWord(),
                                                     argsStream.Remainder);
                }
                else
                {
                    packet.IrcClient.TextNotify(packet.User, packet.channel, new StringStream(args));
                    packet.IrcClient.NoticeNotify(packet.User, packet.channel, new StringStream(packet.Args));
                }
            });

            // Nick / Quit
            AddPacketHandler("NICK", packet => { packet.IrcClient.NickNotify(packet.User, packet.Args); });
            AddPacketHandler("QUIT", packet => { packet.IrcClient.QuitNotify(packet.User, packet.Args); });
            AddPacketHandler("431", packet => { packet.IrcClient.InvalidNickNotify("431", "", packet.Args); }); // :Serv 431 Me :No nickname given
            AddPacketHandler("433", packet => // :Serv 433 Me <Nick> :Nickname is already in use.
                                    {
                                        var strStream = new StringStream(packet.Content);
                                        strStream.SkipWord();
                                        packet.IrcClient.InvalidNickNotify(packet.Key, strStream.NextWord(), packet.Args);
                                    });

            AddPacketHandler("432", packetHandlers["433"][0]); // :Serv 432 Me <Nick> :Invalid nickname: ...

            // Channel related Stuff
            AddPacketHandler("INVITE", packet =>
                                        {
                                            var strStream = new StringStream(packet.Content);
                                            strStream.NextWord("#");
                                            packet.IrcClient.InviteNotify(packet.User, "#"+strStream.NextWord());
                                        });

            AddPacketHandler("JOIN", packet =>
                                         {
                                             string chanName = packet.Content.NextWord();
                                             packet.IrcClient.JoinNotify(packet.User, chanName.Trim(':'));
                                         });
            AddPacketHandler("485", packet =>										// cannot join channel
            {
                packet.channel = packet.IrcClient.GetChannel(packet.Content.NextWord());
                packet.IrcClient.CannotJoinNotify(packet.channel, packet.Args);
            });
            AddPacketHandler("471", delegate { });
            AddPacketHandler("473", delegate { });
            AddPacketHandler("474", delegate { });
            AddPacketHandler("475", delegate { });
            AddPacketHandler("477", delegate { });

            AddPacketHandler("TOPIC", packet =>
            {
                // User TOPIC Channel :Topic
                var content = packet.Content;

                packet.channel = packet.IrcClient.GetOrCreateChannel(content.NextWord());
                packet.channel.TopicSetter = packet.User;
                packet.channel.TopicSetTime = DateTime.Now;
                packet.IrcClient.TopicNotify(packet.User, packet.channel, packet.Args, false);
                packet.channel.SetTopic(packet.Args);
            });
            AddPacketHandler("332", packet =>
            {
                // :Sender 332 Me Channel :Topic
                var content = packet.Content;
                //packet.User = packet.IrcClient.GetOrCreateUser(content.NextWord());
                content.SkipWord();
                packet.channel = packet.IrcClient.GetOrCreateChannel(content.NextWord());
                packet.IrcClient.TopicNotify(packet.User, packet.channel, packet.Args, true);
                packet.channel.SetTopic(packet.Args);
            });

            AddPacketHandler("333", packet =>
            {
                // :Sender 333 Me Channel TopicSetter TopicTimestamp
                StringStream content = packet.Content;
                content.SkipWord();
                packet.channel = packet.IrcClient.GetOrCreateChannel(content.NextWord());
                packet.User = packet.IrcClient.GetOrCreateUser(content.NextWord());
                packet.channel.TopicSetter = packet.User;
                packet.channel.TopicSetTime = new DateTime(1970, 1, 1) +
                                              TimeSpan.FromSeconds(content.NextInt());
            });

            AddPacketHandler("353", packet => // :Serv 353 Me = Channel :Namelist
                                    {
                                        var strStream = new StringStream(packet.Content);
                                        strStream.SkipWords(2);
                                        packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());
                                        if (packet.channel == null)
                                            return;
                                        IrcUser[] users = packet.channel.AddNames(packet.Args);
                                        packet.IrcClient.UsersAddedNotify(packet.channel, users);
                                    });
            AddPacketHandler("MODE", packet => // :Serv MODE Channel Modes [ModeArgs]
                                     {
                                         var strStream = new StringStream(packet.Content);
                                         packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());
                                         strStream.Consume(':', 1);
                                         string modes = strStream.NextWord();
                                         strStream.Consume(':', 1);
                                         string[] prms = strStream.RemainingWords();
                                         packet.ProtHandler.ParseModes(packet.User, packet.channel, modes, prms);
                                     });
            AddPacketHandler("PART", packet =>
            {
                var strStream = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());
                packet.IrcClient.PartNotify(packet.User, packet.channel, packet.Args);
            });
            AddPacketHandler("KICK", packet =>
            {
                var strStream = new StringStream(packet.Content);
                packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());
                IrcUser user = packet.IrcClient.GetOrCreateUser(strStream.NextWord());
                packet.IrcClient.KickNotify(packet.User, packet.channel, user, packet.Args);
            });
            AddPacketHandler("324", packet => // :Serv 324 Me Channel Modes [ModeArgs]
                                    {
                                        var strStream = new StringStream(packet.Content);
                                        strStream.SkipWord(); // skip "Me"
                                        packet.channel = packet.IrcClient.GetChannel(strStream.NextWord());

                                        strStream.Consume(':', 1);
                                        string modes = strStream.NextWord();
                                        strStream.Consume(':', 1);
                                        string[] prms = strStream.RemainingWords();
                                        packet.ProtHandler.ParseModes(packet.User, packet.channel, modes, prms);
                                    });
            AddPacketHandler("329", packet => // :Serv 329 [Me] #Channel CreationTime
                                    {
                                        var strStream = new StringStream(packet.Content);
                                        String chanName = strStream.NextWord();
                                        if (!chanName.StartsWith("#"))
                                        {
                                            chanName = strStream.NextWord();
                                        }
                                        packet.channel = packet.IrcClient.GetChannel(chanName);
                                        DateTime time = new DateTime(1970, 1, 1) +
                                                        TimeSpan.FromSeconds(Convert.ToInt32(strStream.NextWord()));
                                        if (packet.channel != null)
                                            packet.channel.SetCreationTime(time);
                                        packet.IrcClient.ChanCreationTimeNotify(packet.channel, time);
                                    });

            // RPL_WHOREPLY
            AddPacketHandler("352", packet =>
            {
                var content = packet.Content;
                // the first word is our own nick
                content.SkipWord();
                packet.channel = packet.IrcClient.GetChannel(content.NextWord());
                var username = content.NextWord();
                var host = content.NextWord();
                var server = content.NextWord();
                var nick = content.NextWord();
                var flags = content.NextWord();
                // the distance is the number *after* the character ":"
                var hops = content.NextWord().Substring(1);
                var info = packet.Args.Substring(packet.Args.IndexOf(" ") + 1);
                packet.IrcClient.GetOrCreateUser(nick).SetInfo(username, host, info);
                packet.IrcClient.WhoReplyNotify(packet.channel.Name, username, host, server, nick, flags, hops, info);
            });
            // Reply to extended WHO
            AddPacketHandler("354", packet =>
            {
                packet.Content.SkipWord();		// first word is own nick

                var nick = packet.Content.NextWord();
                var authName = packet.Content.NextWord();
                if (authName != "0")
                {
                    var user = packet.User = packet.IrcClient.GetOrCreateUser(nick);
                    user.AuthName = authName;
                    var authMgr = packet.IrcClient.AuthMgr;
                    if (authMgr != null)
                    {
                        authMgr.OnAuthResolved(user);
                    }
                }
            });
            AddPacketHandler("367", packet => // :Serv 367 Me Channel banMask bannerName banTime
                                    {
                                        var content = packet.Content;
                                        content.SkipWord();
                                        packet.channel = packet.IrcClient.GetChannel(content.NextWord());

                                        var banmask = content.NextWord();
                                        var banner = content.NextWord();
                                        var bantime = content.NextWord();
                                        var entry = new BanEntry(banmask, banner, new DateTime(1970, 1, 1) +
                                                                                  TimeSpan.FromSeconds(Convert.ToInt32(bantime)));
                                        if (packet.channel != null && !packet.channel.BanMasks.ContainsKey(banmask))
                                        {
                                            packet.channel.BanMasks.Add(banmask, entry);
                                        }
                                        packet.IrcClient.BanListEntryNotify(packet.channel, entry);
                                    });

            // Ban List completed
            AddPacketHandler("368", packet =>
            {
                packet.channel = packet.IrcClient.GetChannel(packet.Content.NextWord());
                packet.IrcClient.BanListCompleteNotify(packet.channel);
            });

            // Reply to extended WHO
            AddPacketHandler("354", packet =>
            {
                packet.Content.SkipWord();		// first word is own nick

                var nick = packet.Content.NextWord();
                var authName = packet.Content.NextWord();
                if (authName != "0")
                {
                    var user = packet.User = packet.IrcClient.GetOrCreateUser(nick);
                    user.AuthName = authName;
                    var authMgr = packet.IrcClient.AuthMgr;
                    if (authMgr != null)
                    {
                        authMgr.OnAuthResolved(user);
                    }
                }
            });
        }
 public MsgCmdTrigger(StringStream args, IrcUser user, IrcChannel chan = null)
     : base(args, user, chan)
 {
 }