diff --git a/build-number.txt b/build-number.txt index ca12c174..1d0ae911 100644 --- a/build-number.txt +++ b/build-number.txt @@ -1 +1 @@ -1404 \ No newline at end of file +1417 \ No newline at end of file diff --git a/src/main/java/me/chayapak1/chomens_bot/command/CommandContext.java b/src/main/java/me/chayapak1/chomens_bot/command/CommandContext.java index 64b48ce9..3e05898a 100644 --- a/src/main/java/me/chayapak1/chomens_bot/command/CommandContext.java +++ b/src/main/java/me/chayapak1/chomens_bot/command/CommandContext.java @@ -2,8 +2,11 @@ package me.chayapak1.chomens_bot.command; import me.chayapak1.chomens_bot.Bot; import me.chayapak1.chomens_bot.data.PlayerEntry; +import me.chayapak1.chomens_bot.util.ColorUtilities; +import me.chayapak1.chomens_bot.util.StringUtilities; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; @@ -78,13 +81,91 @@ public class CommandContext { } } - final String string = greedy ? - String.join(" ", Arrays.copyOfRange(args, argsPosition, args.length)) : - args[argsPosition]; + final String greedyString = String.join(" ", Arrays.copyOfRange(args, argsPosition, args.length)); + + final StringBuilder string = new StringBuilder(); + + if (greedy) { + string.append(greedyString); + } else if ( + greedyString.length() > 1 && + (greedyString.startsWith("'") || greedyString.startsWith("\"")) + ) { + // parses arguments with quotes + + final char quote = greedyString.charAt(0); + + int pointer = 1; // skips quote + + while (true) { + if (pointer >= greedyString.length()) { + if (greedyString.charAt(pointer - 1) != quote) { + throw new CommandException( + Component + .translatable("Unterminated quote at %s <-- %s") + .arguments( + Component + .text(greedyString) + .color(ColorUtilities.getColorByString(bot.config.colorPalette.string)), + Component + .text(quote) + .color(NamedTextColor.YELLOW) + ) + ); + } + + break; + } + + final char character = greedyString.charAt(pointer); + + pointer++; + + if (character == ' ') { + argsPosition++; + } + + if (character == '\\') { + if (pointer >= greedyString.length()) { + throw new CommandException( + Component + .translatable("Unterminated escape at %s <--") + .arguments( + Component + .text(greedyString) + .color(ColorUtilities.getColorByString(bot.config.colorPalette.string)) + ) + ); + } + + final char nextCharacter = greedyString.charAt(pointer); // pointer is already incremented above + + final char toAdd = switch (nextCharacter) { + case 'n' -> '\n'; + case 't' -> '\t'; + case 'r' -> '\r'; + default -> nextCharacter; + }; + + string.append(toAdd); + + pointer++; + } else if (character == quote) { + break; + } else { + string.append(character); + } + } + } else { + // else just get the current argument + string.append(args[argsPosition]); + } argsPosition++; - return returnLowerCase ? string.toLowerCase() : string; + final String result = string.toString(); + + return returnLowerCase ? result.toLowerCase() : result; } public String getAction () throws CommandException { @@ -150,7 +231,13 @@ public class CommandContext { } public void checkOverloadArgs (int maximumArgs) throws CommandException { - if (args.length > maximumArgs) throw new CommandException( + final String joined = String.join(" ", args); + + final String quotesReplaced = joined.replaceAll("([\"'])(?:\\.|(?!\1).)*\1", "i"); + + final int count = StringUtilities.countCharacters(quotesReplaced, ' '); + + if (count > maximumArgs) throw new CommandException( Component.translatable( "Too many arguments, expected %s max", Component.text(maximumArgs) diff --git a/src/main/java/me/chayapak1/chomens_bot/util/StringUtilities.java b/src/main/java/me/chayapak1/chomens_bot/util/StringUtilities.java index 478b038a..51430e53 100644 --- a/src/main/java/me/chayapak1/chomens_bot/util/StringUtilities.java +++ b/src/main/java/me/chayapak1/chomens_bot/util/StringUtilities.java @@ -8,8 +8,13 @@ import java.nio.charset.CodingErrorAction; import java.nio.charset.StandardCharsets; public class StringUtilities { + // https://stackoverflow.com/a/8910767/18518424 + public static int countCharacters (String string, char character) { + return string.length() - string.replace(String.valueOf(character), "").length(); + } + // https://stackoverflow.com/a/35148974/18518424 - public static String truncateToFitUtf8ByteLength(String s, int maxBytes) { + public static String truncateToFitUtf8ByteLength (String s, int maxBytes) { if (s == null) { return null; }