/// <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)); }
/// <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)); } }
// ------------------------ 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); }