Пример #1
0
        /// <summary>
        /// Parses the args and determines if a message should go out.
        /// </summary>
        public PrivateMessageResult ShouldSend(HandlerArgs args)
        {
            PrivateMessageParseResult parseResult = this.ParseAndCheckHandlerArgs(args);

            return(this.ShouldSend(args, parseResult));
        }
Пример #2
0
        /// <summary>
        /// Takes in an already parsed message and does more checks to see if it should go out.
        /// This will not go out if:
        /// - <see cref="ResponseOptions.PmsOnly"/> is set, but it wasn't a PM.
        /// - <see cref="ResponseOptions.ChannelOnly"/> is set, but it was a PM.
        /// - The cooldown has not occurred yet.
        /// - The bot would respond to itself, but <see cref="IPrivateMessageConfig.RespondToSelf"/> is set to false.
        /// </summary>
        /// <param name="parseResult">
        /// The parsed result.
        /// This will be returned (and possibly modified) within the returned object.
        /// </param>
        public PrivateMessageResult ShouldSend(HandlerArgs args, PrivateMessageParseResult parseResult)
        {
            if (parseResult.Success == false)
            {
                return(new PrivateMessageResult(false, parseResult));
            }

            Regex lineRegex = new Regex(
                Parsing.LiquefyStringWithIrcConfig(
                    this.config.LineRegex,
                    parseResult.RemoteUser,
                    args.IrcConfig.Nick,
                    parseResult.Channel
                    ),
                this.config.RegexOptions
                );

            Match messageMatch = lineRegex.Match(parseResult.Message);

            if (messageMatch.Success == false)
            {
                return(new PrivateMessageResult(false, parseResult));
            }

            string channelLowered = parseResult.Channel.ToLower();

            // Return right away if the nick name from the remote user is our own.
            if (
                (this.config.RespondToSelf == false) &&
                string.Equals(parseResult.RemoteUser, args.IrcConfig.Nick, StringComparison.InvariantCultureIgnoreCase)
                )
            {
                return(new PrivateMessageResult(false, parseResult));
            }
            // Return right away if we only wish to respond on the channel we are listening on (ignore PMs).
            else if (
                (this.config.ResponseOption == ResponseOptions.ChannelOnly) &&
                (args.IrcConfig.Channels.Any(c => c.ToLower(CultureInfo.InvariantCulture) == channelLowered) == false)
                )
            {
                return(new PrivateMessageResult(false, parseResult));
            }
            // Return right away if we only wish to respond to Private Messages (the channel will be our nick name).
            else if (
                (this.config.ResponseOption == ResponseOptions.PmsOnly) &&
                (string.Equals(parseResult.Channel, args.IrcConfig.Nick, StringComparison.InvariantCultureIgnoreCase) == false)
                )
            {
                return(new PrivateMessageResult(false, parseResult));
            }

            // If we haven't done a cool-down check yet, stick the minimum value in the dictionary
            // to ensure we will fire if its the first time.
            if (lastEvent.ContainsKey(channelLowered) == false)
            {
                lastEvent[channelLowered] = DateTime.MinValue;
            }

            DateTime currentTime = DateTime.UtcNow;
            TimeSpan timeSpan    = currentTime - this.lastEvent[channelLowered];

            // Only fire if our cooldown was long enough. Cooldown of zero means always fire.
            // Need to explictly say Cooldown == 0 since DateTime.UtcNow has a innacurracy of +/- 15ms.  Therefore,
            // if the action happens too quickly, it can incorrectly not be triggered.
            if ((this.config.CoolDown == 0) || (timeSpan.TotalSeconds > this.config.CoolDown))
            {
                // Sucess! Return a successful parse
                this.lastEvent[channelLowered] = currentTime;

                // If our response is a PM (channel name matches our bot's)
                // we need to change our channel to the remote user's
                // channel so it gets sent out correctly when handle event is called.
                if (string.Equals(parseResult.Channel, args.IrcConfig.Nick, StringComparison.InvariantCultureIgnoreCase))
                {
                    parseResult.Channel = parseResult.RemoteUser;
                }

                return(new PrivateMessageResult(true, parseResult)
                {
                    Regex = lineRegex,
                    Match = messageMatch
                });
            }
            else
            {
                // Otherwise, return a failure parse.
                return(new PrivateMessageResult(false, parseResult));
            }
        }
Пример #3
0
        // ------------------------ Function ------------------------

        /// <summary>
        /// Fires the action if the line regex matches.
        /// </summary>
        public void HandleEvent(HandlerArgs args)
        {
            ArgumentChecker.IsNotNull(args, nameof(args));

            PrivateMessageParseResult parseResult = this.pmHelper.ParseAndCheckHandlerArgs(args);

            if (parseResult.Success == false)
            {
                return;
            }

            // Ensure none of the other PRIVMSG types match for their message.  If they do, THAT handler type
            // should fire, not this one.
            foreach (Regex regex in otherPrivmsgRegexes)
            {
                if (regex.IsMatch(parseResult.Message))
                {
                    return;
                }
            }

            // If we are a bridge bot, we need to change
            // the nick and the channel
            foreach (string bridgeBotRegex in args.IrcConfig.BridgeBots.Keys)
            {
                Match nameMatch = Regex.Match(parseResult.RemoteUser, bridgeBotRegex);
                if (nameMatch.Success)
                {
                    Match bridgeBotMatch = Regex.Match(parseResult.Message, args.IrcConfig.BridgeBots[bridgeBotRegex]);

                    // If the regex matches, then we'll update the nick and message
                    // to be whatever came from the bridge.
                    if (bridgeBotMatch.Success)
                    {
                        string newNick    = bridgeBotMatch.Groups["bridgeUser"].Value;
                        string newMessage = bridgeBotMatch.Groups["bridgeMessage"].Value;

                        // Only change the nick anme and the message if the nick and the message aren't empty.
                        if ((string.IsNullOrEmpty(newNick) == false) && (string.IsNullOrEmpty(newMessage) == false))
                        {
                            parseResult.RemoteUser = newNick;
                            parseResult.Message    = newMessage;
                        }

                        break;  // We have our message, break out of the loop.
                    }
                }
            }

            PrivateMessageResult pmResult = this.pmHelper.ShouldSend(args, parseResult);

            if (pmResult.ShouldSend == false)
            {
                return;
            }

            MessageHandlerArgs response = new MessageHandlerArgs(
                args.IrcWriter,
                pmResult.ParseResult.RemoteUser,
                pmResult.ParseResult.Channel,
                pmResult.ParseResult.Message,
                pmResult.Regex,
                pmResult.Match
                );

            this.LineAction(response);
        }