Skip to content

Instantly share code, notes, and snippets.

@xPaw
Created July 29, 2015 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xPaw/9a7414e5c8e0cef66cdb to your computer and use it in GitHub Desktop.
Save xPaw/9a7414e5c8e0cef66cdb to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using NetIrc2;
using NetIrc2.Events;
namespace WendySharp
{
public class SedBot
{
private readonly Dictionary<string, IrcString> LastMessage;
private readonly Regex MatchSed;
public SedBot(IrcClient client)
{
LastMessage = new Dictionary<string, IrcString>();
// https://www.azabani.com/2014/02/08/writing-irc-sedbot.html
MatchSed = new Regex(
@"
^ # start of the message
(?: # BEGIN first sed expression
s/ # sed replacement expression delimiter
(?<needle> # BEGIN needle component
(?: # BEGIN single needle character
[^\\/] # anything that isn't a slash or backslash...
|\\. # ...or any backslash escape
)* # END single needle character, zero or more
) # END needle component
/ # slash between needle and replacement
(?<replacement> # BEGIN replacement component
(?: # BEGIN single replacement character
[^\\/]|\\. # escape or non-slash-backslash, as above
)* # END single replacement character, zero or more
) # END replacement component
( # BEGIN flags component (we don't actually use them though)
/ # slash between replacement and flags
(?: # BEGIN single flag
g|i|\d+ # g or i
)* # END single flag, zero or more
)? # END flags component
) # END first sed expression
$ # end of the message",
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace
);
client.GotMessage += OnMessage;
}
private void OnMessage(object obj, ChatMessageEventArgs e)
{
if (e.Message[0] == 's')
{
var match = MatchSed.Match(e.Message);
if (match.Success)
{
if (!LastMessage.ContainsKey(e.Recipient))
{
return;
}
var lastMessage = LastMessage[e.Recipient];
try
{
var needle = match.Groups["needle"].Value;
var replacement = match.Groups["replacement"].Value;
if(string.IsNullOrEmpty(replacement.Trim()))
{
Bootstrap.Client.Client.Notice(e.Sender.Nickname, "sed: replacement can't be empty");
return;
}
if (!Regex.IsMatch(lastMessage, needle, RegexOptions.None, TimeSpan.FromSeconds(1)))
{
Bootstrap.Client.Client.Notice(e.Sender.Nickname, "sed: that needle doesn't match anything in last message");
return;
}
var editedMessage = Regex.Replace(lastMessage, needle, replacement, RegexOptions.None, TimeSpan.FromSeconds(1));
if (editedMessage.Length > 150)
{
editedMessage = editedMessage.Substring(0, 150);
}
editedMessage = editedMessage.Replace("\n", "").Trim(); // Just in case
if (string.IsNullOrEmpty(editedMessage))
{
Bootstrap.Client.Client.Notice(e.Sender.Nickname, "sed: final message is empty");
return;
}
Bootstrap.Client.Client.Message(e.Recipient, editedMessage);
LastMessage[e.Recipient] = editedMessage;
}
catch (Exception regexException)
{
Bootstrap.Client.Client.Notice(e.Sender.Nickname, string.Format("sed: {0}", regexException.Message));
Log.WriteWarn("Sed", "Regex exception: {0} (input: {1} - last message: {2})", regexException.Message, e.Message, lastMessage);
}
return;
}
}
LastMessage[e.Recipient] = e.Message;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment