diff --git a/PluralKit.Bot/CommandSystem/Context/ContextArgumentsExt.cs b/PluralKit.Bot/CommandSystem/Context/ContextArgumentsExt.cs index aca3485e..d5429312 100644 --- a/PluralKit.Bot/CommandSystem/Context/ContextArgumentsExt.cs +++ b/PluralKit.Bot/CommandSystem/Context/ContextArgumentsExt.cs @@ -24,7 +24,7 @@ public static class ContextArgumentsExt ctx.Parameters.FullCommand; /// - /// Checks if the next parameter is equal to one of the given keywords. Case-insensitive. + /// Checks if the next parameter is equal to one of the given keywords and pops it from the stack. Case-insensitive. /// public static bool Match(this Context ctx, ref string used, params string[] potentialMatches) { @@ -48,6 +48,19 @@ public static class ContextArgumentsExt return ctx.Match(ref used, potentialMatches); } + /// + /// Checks if the next parameter (starting from `ptr`) is equal to one of the given keywords, and leaves it on the stack. Case-insensitive. + /// + public static bool PeekMatch(this Context ctx, ref int ptr, string[] potentialMatches) + { + var arg = ctx.Parameters.PeekWithPtr(ref ptr); + foreach (var match in potentialMatches) + if (arg.Equals(match, StringComparison.InvariantCultureIgnoreCase)) + return true; + + return false; + } + /// /// Matches the next *n* parameters against each parameter consecutively. ///
@@ -56,11 +69,12 @@ public static class ContextArgumentsExt ///
public static bool MatchMultiple(this Context ctx, params string[][] potentialParametersMatches) { - foreach (var param in potentialParametersMatches) - if (!ctx.Match(param)) return false; + int ptr = ctx.Parameters._ptr; - for (var i = 0; i < potentialParametersMatches.Length; i++) - ctx.PopArgument(); + foreach (var param in potentialParametersMatches) + if (!ctx.PeekMatch(ref ptr, param)) return false; + + ctx.Parameters._ptr = ptr; return true; } diff --git a/PluralKit.Bot/CommandSystem/Parameters.cs b/PluralKit.Bot/CommandSystem/Parameters.cs index 0010438a..e4251e82 100644 --- a/PluralKit.Bot/CommandSystem/Parameters.cs +++ b/PluralKit.Bot/CommandSystem/Parameters.cs @@ -27,7 +27,7 @@ public class Parameters }; private ISet _flags; // Only parsed when requested first time - private int _ptr; + public int _ptr; public string FullCommand { get; } @@ -100,8 +100,15 @@ public class Parameters public string Peek() { - // Loop to ignore and skip past flags, temp ptr so we don't move the real ptr - var ptr = _ptr; + // temp ptr so we don't move the real ptr + int ptr = _ptr; + + return PeekWithPtr(ref ptr); + } + + public string PeekWithPtr(ref int ptr) + { + // Loop to ignore and skip past flags while (NextWordPosition(ptr) is { } pos) { ptr = pos.endPos + pos.advanceAfterWord;