diff --git a/src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs b/src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs index 823410cdf..a6b8d2c2b 100644 --- a/src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs +++ b/src/Discord.Net.Interactions/Attributes/Commands/ComponentInteractionAttribute.cs @@ -32,6 +32,9 @@ namespace Discord.Interactions /// /// Gets or sets whether the should be treated as a raw Regex pattern. /// + /// + /// defaults to the pattern used before 3.9.0. + /// public bool TreatAsRegex { get; set; } = false; /// diff --git a/src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs b/src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs index f5df950bd..0e79952f3 100644 --- a/src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs +++ b/src/Discord.Net.Interactions/Attributes/Commands/ModalInteractionAttribute.cs @@ -31,6 +31,9 @@ namespace Discord.Interactions /// /// Gets or sets whether the should be treated as a raw Regex pattern. /// + /// + /// defaults to the pattern used before 3.9.0. + /// public bool TreatAsRegex { get; set; } = false; /// diff --git a/src/Discord.Net.Interactions/Utilities/RegexUtils.cs b/src/Discord.Net.Interactions/Utilities/RegexUtils.cs index b3316106c..8f07be66a 100644 --- a/src/Discord.Net.Interactions/Utilities/RegexUtils.cs +++ b/src/Discord.Net.Interactions/Utilities/RegexUtils.cs @@ -1,5 +1,6 @@ using Discord.Interactions; using System; +using System.Collections.Generic; using System.Linq; namespace System.Text.RegularExpressions @@ -90,7 +91,7 @@ namespace System.Text.RegularExpressions return match.Count; } - internal static bool TryBuildRegexPattern(T commandInfo, string wildCardStr, out string pattern) where T: class, ICommandInfo + internal static bool TryBuildRegexPattern(T commandInfo, string wildCardStr, out string pattern) where T : class, ICommandInfo { if (commandInfo.TreatNameAsRegex) { @@ -105,14 +106,72 @@ namespace System.Text.RegularExpressions } var escapedWildCard = Regex.Escape(wildCardStr); - var unquantified = Regex.Replace(commandInfo.Name, $@"(?[^{escapedWildCard}]?)", - @"([^\n\t${delimiter}]+)${delimiter}"); + var unquantifiedPattern = $@"(?[^{escapedWildCard}]?)"; + var quantifiedPattern = $@"(?[0-9]+)(?,[0-9]*)?(?[^{escapedWildCard}]?)"; - var quantified = Regex.Replace(unquantified, $@"(?[0-9]+)(?,[0-9]*)?(?[^{escapedWildCard}]?)", - @"([^\n\t${delimiter}]{${start}${end}})${delimiter}"); + string name = commandInfo.Name; + + var matchPairs = new SortedDictionary(); + + foreach (Match match in Regex.Matches(name, unquantifiedPattern)) + matchPairs.Add(match.Index, new(MatchType.Unquantified, match)); + + foreach (Match match in Regex.Matches(name, quantifiedPattern)) + matchPairs.Add(match.Index, new(MatchType.Quantified, match)); + + var sb = new StringBuilder(); + + var previousMatch = 0; + + foreach (var matchPair in matchPairs) + { + sb.Append(Regex.Escape(name.Substring(previousMatch, matchPair.Key - previousMatch))); + Match match = matchPair.Value.Match; + MatchType type = matchPair.Value.Type; + + previousMatch = matchPair.Key + match.Length; + + var delimiter = match.Groups["delimiter"].Value; + + switch (type) + { + case MatchType.Unquantified: + { + sb.Append(@$"([^\n\t{Regex.Escape(delimiter)}]+){Regex.Escape(delimiter)}"); + } + break; + case MatchType.Quantified: + { + var start = match.Groups["start"].Value; + var end = match.Groups["end"].Value; + + sb.Append($@"([^\n\t{Regex.Escape(delimiter)}]{{{start}{end}}}){Regex.Escape(delimiter)}"); + } + break; + } + } + + pattern = "\\A" + sb.ToString() + "\\Z"; - pattern = "\\A" + quantified + "\\Z"; return true; } + + private enum MatchType + { + Quantified, + Unquantified + } + + private record MatchPair + { + public MatchType Type { get; } + public Match Match { get; } + + public MatchPair(MatchType type, Match match) + { + Type = type; + Match = match; + } + } } }