feat: proper flags parser stolen from HBot

now code looks a lot less messy
This commit is contained in:
ChomeNS
2025-04-17 10:48:12 +07:00
parent 20d89b14d7
commit 56e3aba21a
7 changed files with 58 additions and 60 deletions

View File

@@ -8,10 +8,15 @@ import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextDecoration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CommandContext {
public static final Component UNKNOWN_ARGUMENT_COMPONENT = Component.text("???").style(Style.style(TextDecoration.UNDERLINED));
private static final Pattern FLAGS_PATTERN = Pattern.compile("^\\s*-([^\\s0-9]\\S*)"); // stolen from HBot
public final Bot bot;
@@ -174,6 +179,36 @@ public class CommandContext {
return getString(false, true, true, "action");
}
public List<String> getFlags () throws CommandException { return getFlags(false); }
public List<String> getFlags (final boolean returnLowerCase) throws CommandException {
final List<String> flags = new ArrayList<>();
String flag = getFlag(returnLowerCase);
while (flag != null) {
flags.add(flag);
flag = getFlag(returnLowerCase);
}
return flags;
}
private String getFlag (final boolean returnLowerCase) throws CommandException {
final String string = getString(false, false, returnLowerCase);
if (string.isBlank()) return null;
final Matcher matcher = FLAGS_PATTERN.matcher(string);
if (matcher.find()) {
return matcher.group(1);
} else {
argsPosition--; // getString incremented argsPosition
return null;
}
}
public Integer getInteger (final boolean required) throws CommandException {
final String string = getString(false, required, "integer");

View File

@@ -40,21 +40,12 @@ public class FilterCommand extends Command {
public Component execute (final CommandContext context) throws CommandException {
final Bot bot = context.bot;
boolean ignoreCase = false;
boolean regex = false;
final List<String> flags = context.getFlags(true);
String action = context.getString(false, true, true);
final boolean ignoreCase = flags.contains("ignorecase");
final boolean regex = flags.contains("regex");
// run 2 times. for example `*filter -ignorecase -regex add test` will be both accepted
for (int i = 0; i < 2; i++) {
if (action.equals("-ignorecase")) {
ignoreCase = true;
action = context.getString(false, true);
} else if (action.equals("-regex")) {
regex = true;
action = context.getString(false, true);
}
}
final String action = context.getString(false, true, true);
switch (action) {
case "add" -> {
@@ -89,10 +80,7 @@ public class FilterCommand extends Command {
}
}
final boolean finalRegex = regex;
final boolean finalIgnoreCase = ignoreCase;
DatabasePlugin.EXECUTOR_SERVICE.submit(() -> bot.playerFilter.add(player, reason, finalRegex, finalIgnoreCase));
DatabasePlugin.EXECUTOR_SERVICE.submit(() -> bot.playerFilter.add(player, reason, regex, ignoreCase));
if (reason.isEmpty()) {
return Component.translatable(
@@ -126,7 +114,7 @@ public class FilterCommand extends Command {
case "clear" -> {
context.checkOverloadArgs(1);
DatabasePlugin.EXECUTOR_SERVICE.submit(() -> bot.playerFilter.clear());
DatabasePlugin.EXECUTOR_SERVICE.submit(bot.playerFilter::clear);
return Component.text("Cleared the filter").color(bot.colorPalette.defaultColor);
}
case "list" -> {

View File

@@ -38,23 +38,11 @@ public class FindAltsCommand extends Command {
Main.database.checkOverloaded();
final String flag = context.getString(false, true);
final List<String> flags = context.getFlags(true);
final boolean allServer = flag.equals("-allserver");
final boolean allServer = flags.contains("allserver");
final String player;
if (allServer) {
player = context.getString(true, true);
} else {
final String rest = context.getString(true, false);
player = flag +
(
rest.isEmpty() ?
"" :
" " + rest
);
}
final String player = context.getString(true, true);
final PlayerEntry playerEntry = bot.players.getEntry(player);

View File

@@ -9,6 +9,8 @@ import me.chayapak1.chomens_bot.command.TrustLevel;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import java.util.List;
public class GrepLogCommand extends Command {
private Thread thread;
@@ -16,7 +18,7 @@ public class GrepLogCommand extends Command {
super(
"greplog",
"Queries the bot's logs",
new String[] { "<input>", "...-ignorecase...", "...-regex...", "stop" },
new String[] { "<input>", "-ignorecase ...", "-regex ...", "stop" },
new String[] { "logquery", "findlog" },
TrustLevel.PUBLIC
);
@@ -30,33 +32,19 @@ public class GrepLogCommand extends Command {
throw new CommandException(Component.text("The bot's Discord integration has to be enabled to use this command."));
}
boolean ignoreCase = false;
boolean regex = false;
final List<String> flags = context.getFlags(true);
String firstInput = context.getString(false, true);
final boolean ignoreCase = flags.contains("ignorecase");
final boolean regex = flags.contains("regex");
// run 2 times. for example `*greplog -ignorecase -regex test` will be both accepted
for (int i = 0; i < 2; i++) {
if (firstInput.equals("-ignorecase")) {
ignoreCase = true;
firstInput = context.getString(false, true);
} else if (firstInput.equals("-regex")) {
regex = true;
firstInput = context.getString(false, true);
}
}
final String input = context.getString(true, true);
// interesting code
final String input = (firstInput + " " + context.getString(true, false)).trim();
if (input.equals("stop")) {
if (input.equalsIgnoreCase("stop")) {
if (thread == null) throw new CommandException(Component.text("There is no query process running"));
bot.grepLog.running = false;
bot.grepLog.pattern = null;
thread.interrupt(); // ? should i interrupt it this way?
thread = null;
return Component.text("Stopped querying the logs").color(bot.colorPalette.defaultColor);
@@ -75,12 +63,9 @@ public class GrepLogCommand extends Command {
)
);
final boolean finalIgnoreCase = ignoreCase;
final boolean finalRegex = regex;
thread = new Thread(() -> {
try {
bot.grepLog.search(context, input, finalIgnoreCase, finalRegex);
bot.grepLog.search(context, input, ignoreCase, regex);
} catch (final CommandException e) {
context.sendOutput(e.message.color(NamedTextColor.RED));
}

View File

@@ -21,10 +21,11 @@ public class TestCommand extends Command {
@Override
public Component execute (final CommandContext context) throws CommandException {
return Component.translatable(
"Hello, World! Username: %s, Sender UUID: %s, Prefix: %s, Args: %s",
"Hello, World! Username: %s, Sender UUID: %s, Prefix: %s, Flags: %s, Args: %s",
Component.text(context.sender.profile.getName()),
Component.text(context.sender.profile.getIdAsString()),
Component.text(context.prefix),
Component.text(String.join(" ", context.getFlags())),
Component.text(context.getString(true, false))
).color(NamedTextColor.GREEN);
}

View File

@@ -155,7 +155,8 @@ public class GrepLogPlugin {
if (regex && pattern == null) {
if (ignoreCase)
pattern = Pattern.compile(input, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CHARACTER_CLASS);
else pattern = Pattern.compile(input, Pattern.UNICODE_CHARACTER_CLASS);
else
pattern = Pattern.compile(input, Pattern.UNICODE_CHARACTER_CLASS);
}
final StringBuilder result = new StringBuilder();