mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
feat(bot): add regex message editing (#587)
This commit is contained in:
parent
95b027d432
commit
c8f2a137a0
2 changed files with 93 additions and 5 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
|
@ -101,6 +102,9 @@ public class ProxiedMessage
|
||||||
if (originalMsg == null)
|
if (originalMsg == null)
|
||||||
throw new PKError("Could not edit message.");
|
throw new PKError("Could not edit message.");
|
||||||
|
|
||||||
|
// Regex flag
|
||||||
|
var useRegex = ctx.MatchFlag("regex", "x");
|
||||||
|
|
||||||
// Check if we should append or prepend
|
// Check if we should append or prepend
|
||||||
var mutateSpace = ctx.MatchFlag("nospace", "ns") ? "" : " ";
|
var mutateSpace = ctx.MatchFlag("nospace", "ns") ? "" : " ";
|
||||||
var append = ctx.MatchFlag("append", "a");
|
var append = ctx.MatchFlag("append", "a");
|
||||||
|
|
@ -118,12 +122,93 @@ public class ProxiedMessage
|
||||||
if (newContent == null)
|
if (newContent == null)
|
||||||
throw new PKSyntaxError("You need to include the message to edit in.");
|
throw new PKSyntaxError("You need to include the message to edit in.");
|
||||||
|
|
||||||
|
// Can't append or prepend a Regex
|
||||||
|
if (useRegex && (append || prepend))
|
||||||
|
throw new PKError("You can't use the append or prepend options with a Regex.");
|
||||||
|
|
||||||
|
// Use the Regex to substitute the message content
|
||||||
|
if (useRegex)
|
||||||
|
{
|
||||||
|
const string regexErrorStr = "Could not parse Regex. The expected formats are s|X|Y or s|X|Y|F, where | is any character, X is a valid Regex to search for matches of, Y is a substitution string, and F is a set of Regex flags.";
|
||||||
|
|
||||||
|
// Smallest valid Regex string is "s||"; 3 chars long
|
||||||
|
if (newContent.Length < 3 || !newContent.StartsWith('s'))
|
||||||
|
throw new PKError(regexErrorStr);
|
||||||
|
|
||||||
|
var separator = newContent[1];
|
||||||
|
|
||||||
|
// s|X|Y => ["s", "X", "Y"]
|
||||||
|
// s|X|Y|F => ["s", "X", "Y", "F"] ("F" may be empty)
|
||||||
|
var splitString = newContent.Split(separator);
|
||||||
|
|
||||||
|
if (splitString.Length != 3 && splitString.Length != 4)
|
||||||
|
throw new PKError(regexErrorStr);
|
||||||
|
|
||||||
|
var flags = splitString.Length == 4 ? splitString[3] : "";
|
||||||
|
|
||||||
|
var regexOptions = RegexOptions.None;
|
||||||
|
var globalMatch = false;
|
||||||
|
|
||||||
|
// Parse flags
|
||||||
|
foreach (char c in flags)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'g':
|
||||||
|
globalMatch = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
regexOptions |= RegexOptions.IgnoreCase;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
regexOptions |= RegexOptions.Multiline;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
regexOptions |= RegexOptions.ExplicitCapture;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
regexOptions |= RegexOptions.Singleline;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
regexOptions |= RegexOptions.IgnorePatternWhitespace;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new PKError($"Invalid Regex flag '{c}'. Valid flags include 'g', 'i', 'm', 'n', 's', and 'x'.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// I would use RegexOptions.NonBacktracking but that's only .NET 7 :(
|
||||||
|
var regex = new Regex(splitString[1], regexOptions, TimeSpan.FromSeconds(0.5));
|
||||||
|
var numMatches = globalMatch ? -1 : 1; // Negative means all matches
|
||||||
|
newContent = regex.Replace(originalContent!, splitString[2], numMatches);
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
throw new PKError(regexErrorStr);
|
||||||
|
}
|
||||||
|
catch (RegexMatchTimeoutException)
|
||||||
|
{
|
||||||
|
throw new PKError("Regex took too long to run.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Append or prepend the new content to the original message content if needed.
|
// Append or prepend the new content to the original message content if needed.
|
||||||
// If no flag is supplied, the new contents will completly overwrite the old contents
|
// If no flag is supplied, the new contents will completly overwrite the old contents
|
||||||
// If both flags are specified. the message will be prepended AND appended
|
// If both flags are specified. the message will be prepended AND appended
|
||||||
if (append && prepend) newContent = $"{newContent}{mutateSpace}{originalContent}{mutateSpace}{newContent}";
|
if (append && prepend)
|
||||||
else if (append) newContent = $"{originalContent}{mutateSpace}{newContent}";
|
newContent = $"{newContent}{mutateSpace}{originalContent}{mutateSpace}{newContent}";
|
||||||
else if (prepend) newContent = $"{newContent}{mutateSpace}{originalContent}";
|
else if (append)
|
||||||
|
newContent = $"{originalContent}{mutateSpace}{newContent}";
|
||||||
|
else if (prepend)
|
||||||
|
newContent = $"{newContent}{mutateSpace}{originalContent}";
|
||||||
|
|
||||||
if (newContent.Length > 2000)
|
if (newContent.Length > 2000)
|
||||||
throw new PKError("PluralKit cannot proxy messages over 2000 characters in length.");
|
throw new PKError("PluralKit cannot proxy messages over 2000 characters in length.");
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,11 @@ You cannot look up private members or groups of another system.
|
||||||
|pk;system frontpercent|-flat||Show "flat" frontpercent - percentages add up to 100%|
|
|pk;system frontpercent|-flat||Show "flat" frontpercent - percentages add up to 100%|
|
||||||
|pk;group \<group> frontpercent|-fronters-only|-fo|Show a group's frontpercent without the "no fronter" entry|
|
|pk;group \<group> frontpercent|-fronters-only|-fo|Show a group's frontpercent without the "no fronter" entry|
|
||||||
|pk;group \<group> frontpercent|-flat||Show "flat" frontpercent - percentages add up to 100%|
|
|pk;group \<group> frontpercent|-flat||Show "flat" frontpercent - percentages add up to 100%|
|
||||||
|pk;edit|-append||Append the new content to the old message instead of overwriting it|
|
|pk;edit|-append|-a|Append the new content to the old message instead of overwriting it|
|
||||||
|pk;edit|-prepend||Prepend the new content to the old message instead of overwriting it|
|
|pk;edit|-prepend|-p|Prepend the new content to the old message instead of overwriting it|
|
||||||
|
|pk;edit|-nospace|-ns|Append/prepend without adding a space|
|
||||||
|
|pk;edit|-clear-embed|-ce|Remove embeds from a message|
|
||||||
|
|pk;edit|-regex|-x|Edit using a C# Regex formatted like s|X|Y or s|X|Y|F, where | is any character, X is a Regex, Y is a substitution string, and F is a set of Regex flags|
|
||||||
|Most commands|-all|-a|Show hidden/private information|
|
|Most commands|-all|-a|Show hidden/private information|
|
||||||
|Most commands|-raw|-r|Show text with formatting, for easier copy-pasting|
|
|Most commands|-raw|-r|Show text with formatting, for easier copy-pasting|
|
||||||
|All commands|-private|-priv|Show private information|
|
|All commands|-private|-priv|Show private information|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue