From bbc92fcffcd4683e2f42a8b2e3029d767a4faee7 Mon Sep 17 00:00:00 2001 From: Gamebuster19901 Date: Thu, 9 Mar 2023 22:29:04 -0500 Subject: [PATCH] This is as good of a workaround for #162 as I can get --- .../excite/bot/EventReceiver.java | 132 ++++++++++++++---- .../excite/bot/command/ArchiveCommand.java | 2 +- .../excite/bot/command/BanCommand.java | 2 +- .../excite/bot/command/CRCCommand.java | 6 +- .../excite/bot/command/ChangelogCommand.java | 2 +- .../excite/bot/command/Commands.java | 67 ++++++++- .../excite/bot/command/Debug.java | 2 +- .../excite/bot/command/GameDataCommand.java | 2 +- .../excite/bot/command/HelpCommand.java | 2 +- .../excite/bot/command/IconDumpCommand.java | 2 +- .../excite/bot/command/InsertCommand.java | 2 +- .../excite/bot/command/NotifyCommand.java | 2 +- .../excite/bot/command/OnlineCommand.java | 2 +- .../excite/bot/command/PardonCommand.java | 2 +- .../excite/bot/command/RankCommand.java | 2 +- .../excite/bot/command/RegisterCommand.java | 2 +- .../excite/bot/command/StopCommand.java | 2 +- .../excite/bot/command/WhoIsCommand.java | 2 +- .../GlobalLiteralArgumentBuilder.java | 31 +++- .../bot/command/argument/PrivateNode.java | 5 + .../suggestion/AnyStringSuggestion.java | 22 +++ .../AnyStringSuggestionProvider.java | 44 ++++++ .../suggestion/MatchingStringSuggestion.java | 25 ++++ .../suggestion/MatchingSuggestion.java | 5 + .../builder/ExciteSuggestionsBuilder.java | 43 ++++++ 25 files changed, 360 insertions(+), 50 deletions(-) create mode 100644 src/main/java/com/gamebuster19901/excite/bot/command/argument/PrivateNode.java create mode 100644 src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/AnyStringSuggestion.java create mode 100644 src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/AnyStringSuggestionProvider.java create mode 100644 src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/MatchingStringSuggestion.java create mode 100644 src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/MatchingSuggestion.java create mode 100644 src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/builder/ExciteSuggestionsBuilder.java diff --git a/src/main/java/com/gamebuster19901/excite/bot/EventReceiver.java b/src/main/java/com/gamebuster19901/excite/bot/EventReceiver.java index 78f66d0..8c96166 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/EventReceiver.java +++ b/src/main/java/com/gamebuster19901/excite/bot/EventReceiver.java @@ -1,6 +1,7 @@ package com.gamebuster19901.excite.bot; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutionException; @@ -8,6 +9,7 @@ import com.gamebuster19901.excite.bot.command.CommandContext; import com.gamebuster19901.excite.bot.command.Commands; import com.gamebuster19901.excite.bot.command.argument.GlobalNode; +import com.gamebuster19901.excite.bot.command.argument.suggestion.MatchingSuggestion; import com.gamebuster19901.excite.bot.command.interaction.Interactions; import com.gamebuster19901.excite.bot.user.DiscordUser; import com.gamebuster19901.excite.util.StacktraceUtil; @@ -30,6 +32,8 @@ public class EventReceiver extends ListenerAdapter { + public static final char DATA_ESCAPE = 0x10; + private final Sub sub = new Sub(); @Override @@ -100,52 +104,124 @@ public void onGuildReady(GuildReadyEvent e) { e.getGuild().updateCommands().addCommands(commands).queue(); } + @Override - public void onCommandAutoCompleteInteraction(CommandAutoCompleteInteractionEvent e) { + @SuppressWarnings("unlikely-arg-type") + public void onCommandAutoCompleteInteraction(final CommandAutoCompleteInteractionEvent e) { - String command = e.getName() + " " + e.getFocusedOption().getValue(); - final String arguments = e.getFocusedOption().getValue(); - String fixedArguments = e.getFocusedOption().getValue(); - System.err.println(command + "-----"); + final String command = (e.getName() + " " + e.getFocusedOption().getValue()); + final List arguments = Commands.getArgs(command); + String lastArg = ""; + if(arguments.size() > 0) { + lastArg = arguments.get(arguments.size() - 1); + arguments.remove(arguments.size() - 1); + } - boolean spaceAdded = false; - if(fixedArguments.indexOf(' ') != -1) { - fixedArguments = fixedArguments.substring(0, fixedArguments.lastIndexOf(' ')); - } - else { - fixedArguments = ""; - } - ParseResults parseResults = Commands.DISPATCHER.getDispatcher().parse(command, new CommandContext(e)); - List suggestions; - List returnedSuggestions = new ArrayList(); + System.err.println(command + "-----"); + + + CommandContext context = new CommandContext<>(e); + + ParseResults parseResults = Commands.DISPATCHER.getDispatcher().parse(command, context); + ParseResults spacedParseResults = Commands.DISPATCHER.getDispatcher().parse(command + " ", context); + List suggestions = new ArrayList<>(); try { - suggestions = Commands.DISPATCHER.getDispatcher().getCompletionSuggestions(parseResults, command.length()).get().getList(); - if(suggestions.size() == 0) { - command = command + " "; - spaceAdded = true; - parseResults = Commands.DISPATCHER.getDispatcher().parse(command, new CommandContext(e)); - suggestions = Commands.DISPATCHER.getDispatcher().getCompletionSuggestions(parseResults, command.length()).get().getList(); + List foundSuggestions = new ArrayList<>(); + Suggestion completedSuggestion = null; + for(Suggestion suggestion : Commands.DISPATCHER.getDispatcher().getCompletionSuggestions(parseResults, command.length()).get().getList()) { + if(lastArg.equalsIgnoreCase(suggestion.getText()) || (suggestion instanceof MatchingSuggestion && ((MatchingSuggestion) suggestion).matches(lastArg))) { + completedSuggestion = suggestion; + break; + } + foundSuggestions.add(suggestion); + System.out.println(lastArg + " != " + suggestion.getText()); } - } catch (InterruptedException | ExecutionException ex) { - ex.printStackTrace(); - return; + suggestions.addAll(foundSuggestions); + if(completedSuggestion != null) { + System.out.println("EMEPTYASHDFPIOWHAEPHF AWIEUFHOUIWHQEF"); + for(Suggestion suggestion : Commands.DISPATCHER.getDispatcher().getCompletionSuggestions(spacedParseResults, command.length() + 1).get().getList()) { + suggestions.add(suggestion); + } + if(suggestions.isEmpty() && !foundSuggestions.isEmpty()) { + + } + else { + suggestions.add(completedSuggestion); + } + + //suggestions.add(completedSuggestion); + } + } catch (InterruptedException | ExecutionException e1) { + throw new RuntimeException(e1); } + String completedArgs = getCompletedArgs(arguments); + List returnedSuggestions = new ArrayList(); + + if(suggestions.size() > 25) { suggestions = suggestions.subList(0, 25); } - System.out.println("Arguments:" + arguments); + a: + { + break a; + + } + + /* + for(int s = 0; s < suggestions.size(); s++) { + Suggestion suggestion = suggestions.get(s); + StringBuilder returnedSuggestionsBuilder = new StringBuilder(); + int index = Commands.getMatchingIndex(arguments, suggestion); + if(index > -1) { + for(int i = 0; i < arguments.size() - 1; i++) { + returnedSuggestionsBuilder.append(arguments.get(i)); + returnedSuggestionsBuilder.append(' '); + } + returnedSuggestionsBuilder.append(suggestion.getText()); + } + else { + for(int i = 0; i < arguments.size(); i++) { + returnedSuggestionsBuilder.append(arguments.get(i)); + returnedSuggestionsBuilder.append(' '); + } + returnedSuggestionsBuilder.append(suggestion.getText()); + } + returnedSuggestions.add(returnedSuggestionsBuilder.toString()); + } + e.replyChoiceStrings(returnedSuggestions).queue(); + */ + for(Suggestion suggestion : suggestions) { - if(!spaceAdded) { - returnedSuggestions.add(fixedArguments + " " + suggestion.getText()); + if(suggestion instanceof MatchingSuggestion) { + if(((MatchingSuggestion) suggestion).matches(lastArg)) { + System.out.println(suggestion + " matches " + lastArg); + returnedSuggestions.add(completedArgs + " " + suggestion.getText()); + } + else { + returnedSuggestions.add(completedArgs); + } } else { - returnedSuggestions.add(fixedArguments + arguments + " " + suggestion.getText()); + returnedSuggestions.add(completedArgs + " " + suggestion.getText()); } } + e.replyChoiceStrings(returnedSuggestions).queue(); } } + + private static final String getCompletedArgs(List args) { + StringBuilder ret = new StringBuilder(); + Iterator i = args.iterator(); + while(i.hasNext()) { + ret = ret.append(i.next()); + if(i.hasNext()) { + ret.append(' '); + } + } + return ret.toString(); + } } diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/ArchiveCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/ArchiveCommand.java index 91fd6cd..7d4ed62 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/ArchiveCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/ArchiveCommand.java @@ -37,7 +37,7 @@ public class ArchiveCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("archive").then(Commands.argument("channels", StringArgumentType.greedyString()).executes((context) -> { + dispatcher.register(Commands.global("archive").then(Commands.argument("channels", StringArgumentType.greedyString()).executes((context) -> { return archive(context.getSource(), context.getArgument("channels", String.class)); }))); } diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/BanCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/BanCommand.java index f0a2311..3e2597c 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/BanCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/BanCommand.java @@ -22,7 +22,7 @@ public class BanCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("ban") + dispatcher.register(Commands.userGlobal("ban") .then(Commands.argument("discordUser", new DiscordUserArgumentType()) .executes((context) -> { return banDiscordUser(context.getSource(), context.getArgument("discordUser", User.class), TimeUtils.FOREVER, parseReason(TimeUtils.FOREVER, null)); diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/CRCCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/CRCCommand.java index c876958..0f26b9f 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/CRCCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/CRCCommand.java @@ -14,7 +14,7 @@ public class CRCCommand { public static void register(CommandDispatcher dispatcher) { dispatcher.register( - Commands.literal("crc") + Commands.userGlobal("crc") .then(Commands.literal("test") .then(Commands.argument("data", StringArgumentType.greedyString()) .executes(context -> { @@ -23,8 +23,8 @@ public static void register(CommandDispatcher dispatcher) { ) ) .then(Commands.literal("assert") - .then(Commands.argument("expected", StringArgumentType.string()) - .then(Commands.argument("data", StringArgumentType.greedyString()) + .then(Commands.anyString("expected") + .then(Commands.anyStringGreedy("data") .executes(context -> { String expectedString = context.getArgument("expected", String.class); Integer expected = null; diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/ChangelogCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/ChangelogCommand.java index 3a00905..28f7539 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/ChangelogCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/ChangelogCommand.java @@ -26,7 +26,7 @@ public class ChangelogCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("cl").executes((context) -> { + dispatcher.register(Commands.userGlobal("changelog").executes((context) -> { return message(context.getSource()); })); } diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/Commands.java b/src/main/java/com/gamebuster19901/excite/bot/command/Commands.java index 5d6e3c7..6ec8fba 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/Commands.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/Commands.java @@ -1,15 +1,23 @@ package com.gamebuster19901.excite.bot.command; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; + import com.gamebuster19901.excite.Main; import com.gamebuster19901.excite.bot.audit.CommandAudit; +import com.gamebuster19901.excite.bot.command.argument.GlobalLiteralArgumentBuilder; +import com.gamebuster19901.excite.bot.command.argument.suggestion.AnyStringSuggestionProvider; import com.gamebuster19901.excite.util.StacktraceUtil; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.Suggestion; @SuppressWarnings("rawtypes") public class Commands { @@ -56,10 +64,27 @@ public void handleCommand(String command) { } } + @Deprecated public static LiteralArgumentBuilder literal(String name) { return LiteralArgumentBuilder.literal(name); } + public static GlobalLiteralArgumentBuilder global(String name) { + return GlobalLiteralArgumentBuilder.literal(name); + } + + public static RequiredArgumentBuilder anyString(String name) { + return argument(name, StringArgumentType.string()).suggests(new AnyStringSuggestionProvider<>(name)); + } + + public static RequiredArgumentBuilder anyStringGreedy(String name) { + return argument(name, StringArgumentType.greedyString()).suggests(new AnyStringSuggestionProvider<>(name)); + } + + public static GlobalLiteralArgumentBuilder userGlobal(String name) { + return GlobalLiteralArgumentBuilder.literal(name, true); + } + public static RequiredArgumentBuilder argument(String name, ArgumentType type) { return RequiredArgumentBuilder.argument(name, type); } @@ -114,10 +139,48 @@ public static String readQuotedString(StringReader reader) throws CommandSyntaxE } public static String lastArgOf(String command) { - if(command.indexOf(' ') > 0) { - return command.substring(command.lastIndexOf(' ') + 1); + List args = getArgs(command); + if(args.size() > 0) { + return args.get(args.size() - 1); } return ""; } + public static ArrayList getArgs(String command) { + ArrayList args = new ArrayList<>(); + if(command.indexOf(' ') > 0) { + String[] split = command.split(Pattern.quote(" ")); + for(int i = 1; i < split.length; i++) { + String arg = split[i]; + if(!arg.isBlank()) { + args.add(split[i]); + } + } + } + return args; + } + + public static int getMatchingIndex(List arguments, Suggestion suggested) { + return getMatchingIndex(arguments, suggested.getText()); + } + + public static int getMatchingIndex(List arguments, String suggested) { + if(arguments.size() > 0) { + String arg = arguments.get(arguments.size() - 1); + String suggestion = suggested; + if(!(arg.isBlank() || suggestion.isBlank())) { + if(arg.charAt(0) == suggestion.charAt(0)) { + int i = 1; + for(; i < arg.length() && i < suggestion.length(); i++) { + if(arg.charAt(i) != suggestion.charAt(i)) { + break; + } + } + return i; + } + } + } + return -1; + } + } diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/Debug.java b/src/main/java/com/gamebuster19901/excite/bot/command/Debug.java index 1a11322..ae10819 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/Debug.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/Debug.java @@ -20,7 +20,7 @@ public class Debug { public static void register(CommandDispatcher dispatcher) { dispatcher.register( - Commands.literal("debug") + Commands.userGlobal("debug") .then(Commands.literal("out") /*.executes( (context -> diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/GameDataCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/GameDataCommand.java index bfc6dfa..2acb0d3 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/GameDataCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/GameDataCommand.java @@ -13,7 +13,7 @@ public class GameDataCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("gameData").executes((context) -> { + dispatcher.register(Commands.userGlobal("game").then(Commands.literal("data")).executes((context) -> { return getData(context.getSource()); })); } diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/HelpCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/HelpCommand.java index 4921c7f..8349151 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/HelpCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/HelpCommand.java @@ -6,7 +6,7 @@ public class HelpCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("help").executes((context) -> { + dispatcher.register(Commands.userGlobal("help").executes((context) -> { return sendHelpInfo(context.getSource()); })); } diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/IconDumpCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/IconDumpCommand.java index 6103163..9b72c7f 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/IconDumpCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/IconDumpCommand.java @@ -13,7 +13,7 @@ public class IconDumpCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("icondump").executes((context) -> { + dispatcher.register(Commands.userGlobal("icondump").executes((context) -> { context.getSource().sendMessage("Provide a server id"); return 0; }).then(Commands.argument("server", LongArgumentType.longArg()).executes((command) -> { diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/InsertCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/InsertCommand.java index 8553b09..ddc61f8 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/InsertCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/InsertCommand.java @@ -11,7 +11,7 @@ public class InsertCommand { public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("insert").then(Commands.literal("profile") + dispatcher.register(Commands.userGlobal("insert").then(Commands.literal("profile") .then(Commands.argument("pid", IntegerArgumentType.integer(1, 999999999)) .then(Commands.argument("fc", StringArgumentType.string()) .then(Commands.argument("name", StringArgumentType.greedyString()) diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/NotifyCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/NotifyCommand.java index c32b2ff..3e484e1 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/NotifyCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/NotifyCommand.java @@ -13,7 +13,7 @@ public class NotifyCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("notify").then(Commands.literal("threshold").then(Commands.argument("amount", IntegerArgumentType.integer()).executes((context) -> { + dispatcher.register(Commands.userGlobal("notify").then(Commands.literal("threshold").then(Commands.argument("amount", IntegerArgumentType.integer()).executes((context) -> { return setThreshold(context.getSource(), context.getArgument("amount", Integer.class)); }))) .then(Commands.literal("frequency").then(Commands.argument("amount", IntegerArgumentType.integer()).then(Commands.argument("timeUnit", StringArgumentType.word()).executes((context) -> { diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/OnlineCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/OnlineCommand.java index a52de25..3320dc8 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/OnlineCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/OnlineCommand.java @@ -10,7 +10,7 @@ public class OnlineCommand { public static void register(CommandDispatcher dispatcher) { - LiteralArgumentBuilder builder = Commands.literal("online").executes((command) -> { + LiteralArgumentBuilder builder = Commands.userGlobal("online").executes((command) -> { return sendResponse(command.getSource(), command); }); diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/PardonCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/PardonCommand.java index b988294..145420b 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/PardonCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/PardonCommand.java @@ -17,7 +17,7 @@ public class PardonCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("pardon") + dispatcher.register(Commands.userGlobal("pardon") .then(Commands.argument("discord", new DiscordUserArgumentType()) .executes((context) -> { diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/RankCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/RankCommand.java index 46d380e..b79339d 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/RankCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/RankCommand.java @@ -11,7 +11,7 @@ public class RankCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("rank") + dispatcher.register(Commands.userGlobal("rank") .then(Commands.literal("add") .then(Commands.argument("rank", StringArgumentType.word()) .then(Commands.argument("user", new DiscordUserArgumentType()) diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/RegisterCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/RegisterCommand.java index c6963d4..e69cfa5 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/RegisterCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/RegisterCommand.java @@ -23,7 +23,7 @@ public class RegisterCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("register") + dispatcher.register(Commands.userGlobal("register") .then(Commands.literal("profile") .then(Commands.argument("player", PlayerArgumentType.player()) .executes(context -> { diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/StopCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/StopCommand.java index c07a0d4..228dcb6 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/StopCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/StopCommand.java @@ -7,7 +7,7 @@ public class StopCommand { @SuppressWarnings("rawtypes") public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("stop").executes((context) -> { + dispatcher.register(Commands.userGlobal("stop").executes((context) -> { return stop(context.getSource()); })); } diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/WhoIsCommand.java b/src/main/java/com/gamebuster19901/excite/bot/command/WhoIsCommand.java index 4e98d6a..46a6682 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/WhoIsCommand.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/WhoIsCommand.java @@ -18,7 +18,7 @@ public class WhoIsCommand { private static final boolean [] HOURS_ONLY = new boolean[] {false, false, false, false, true, false, false}; public static void register(CommandDispatcher dispatcher) { - LiteralCommandNode builder = dispatcher.register(Commands.literal("whois") + LiteralCommandNode builder = dispatcher.register(Commands.userGlobal("whois") .then(Commands.argument("player", StringArgumentType.greedyString()).executes((command) -> { return sendResponse(command.getSource(), command.getArgument("player", String.class)); } diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/argument/GlobalLiteralArgumentBuilder.java b/src/main/java/com/gamebuster19901/excite/bot/command/argument/GlobalLiteralArgumentBuilder.java index aea047e..8f009c0 100644 --- a/src/main/java/com/gamebuster19901/excite/bot/command/argument/GlobalLiteralArgumentBuilder.java +++ b/src/main/java/com/gamebuster19901/excite/bot/command/argument/GlobalLiteralArgumentBuilder.java @@ -5,18 +5,45 @@ import com.mojang.brigadier.Command; import com.mojang.brigadier.RedirectModifier; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.LiteralCommandNode; public class GlobalLiteralArgumentBuilder extends LiteralArgumentBuilder { - protected GlobalLiteralArgumentBuilder(String literal) { + private final boolean privateNode; + private SuggestionProvider suggestionProvider = null; + + protected GlobalLiteralArgumentBuilder(String literal, boolean privateNode) { super(literal); + this.privateNode = privateNode; + } + + protected GlobalLiteralArgumentBuilder(String literal) { + this(literal, false); } public static GlobalLiteralArgumentBuilder literal(final String name) { return new GlobalLiteralArgumentBuilder<>(name); } + + public static GlobalLiteralArgumentBuilder literal(final String name, final boolean privateNode) { + return new GlobalLiteralArgumentBuilder<>(name); + } + + public GlobalLiteralArgumentBuilder suggests(final SuggestionProvider provider) { + this.suggestionProvider = provider; + return getThis(); + } + + public SuggestionProvider getSuggestionsProvider() { + return suggestionProvider; + } + + @Override + protected GlobalLiteralArgumentBuilder getThis() { + return this; + } @Override public GlobalLiteralCommandNode build() { @@ -29,7 +56,7 @@ public GlobalLiteralCommandNode build() { return result; } - public static final class GlobalLiteralCommandNode extends LiteralCommandNode implements GlobalNode { + public static final class GlobalLiteralCommandNode extends LiteralCommandNode implements GlobalNode, PrivateNode { public GlobalLiteralCommandNode(String literal, Command command, Predicate requirement, CommandNode redirect, RedirectModifier modifier, boolean forks) { super(literal, command, requirement, redirect, modifier, forks); diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/argument/PrivateNode.java b/src/main/java/com/gamebuster19901/excite/bot/command/argument/PrivateNode.java new file mode 100644 index 0000000..3d94204 --- /dev/null +++ b/src/main/java/com/gamebuster19901/excite/bot/command/argument/PrivateNode.java @@ -0,0 +1,5 @@ +package com.gamebuster19901.excite.bot.command.argument; + +public interface PrivateNode { + +} diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/AnyStringSuggestion.java b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/AnyStringSuggestion.java new file mode 100644 index 0000000..13cabb9 --- /dev/null +++ b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/AnyStringSuggestion.java @@ -0,0 +1,22 @@ +package com.gamebuster19901.excite.bot.command.argument.suggestion; + +import com.mojang.brigadier.Message; +import com.mojang.brigadier.context.StringRange; +import com.mojang.brigadier.suggestion.Suggestion; + +public class AnyStringSuggestion extends Suggestion implements MatchingSuggestion { + + public AnyStringSuggestion(StringRange range, String text) { + super(range, text); + } + + public AnyStringSuggestion(StringRange range, String text, Message tooltip) { + super(range, text, tooltip); + } + + @Override + public boolean matches(String s) { + return s != null && !s.isBlank(); + } + +} diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/AnyStringSuggestionProvider.java b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/AnyStringSuggestionProvider.java new file mode 100644 index 0000000..052e153 --- /dev/null +++ b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/AnyStringSuggestionProvider.java @@ -0,0 +1,44 @@ +package com.gamebuster19901.excite.bot.command.argument.suggestion; + +import java.util.concurrent.CompletableFuture; + +import com.gamebuster19901.excite.bot.command.argument.suggestion.builder.ExciteSuggestionsBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.suggestion.SuggestionProvider; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; + +public class AnyStringSuggestionProvider implements SuggestionProvider { + + private final String name; + private final boolean greedy; + + public AnyStringSuggestionProvider(String name) { + this(name, false); + } + + public AnyStringSuggestionProvider(String name, boolean greedy) { + this.name = name; + this.greedy = greedy; + } + + @Override + public CompletableFuture getSuggestions(CommandContext context, SuggestionsBuilder builder) throws CommandSyntaxException { + int i = context.getNodes().size() - 1 ; + ExciteSuggestionsBuilder b = new ExciteSuggestionsBuilder(builder); + String arg = builder.getRemaining(); + if(builder.getRemaining().isBlank()) { + System.out.println("1AnyString: " + builder.getRemaining()); + b.suggestAnyString(name); + } + else { + System.out.println("2AnyString: " + builder.getRemaining()); + b.suggestAsMatchable(b.getRemaining()); + } + + builder.add(b); + return builder.buildFuture(); + } + +} diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/MatchingStringSuggestion.java b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/MatchingStringSuggestion.java new file mode 100644 index 0000000..76a28c6 --- /dev/null +++ b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/MatchingStringSuggestion.java @@ -0,0 +1,25 @@ +package com.gamebuster19901.excite.bot.command.argument.suggestion; + +import com.mojang.brigadier.Message; +import com.mojang.brigadier.context.StringRange; +import com.mojang.brigadier.suggestion.Suggestion; + +public class MatchingStringSuggestion extends Suggestion implements MatchingSuggestion { + + public MatchingStringSuggestion(StringRange range, String text) { + super(range, text); + } + + public MatchingStringSuggestion(StringRange range, String text, Message tooltip) { + super(range, text, tooltip); + } + + @Override + public boolean matches(String s) { + if(s.isBlank()) { + return false; + } + return getText().toLowerCase().endsWith(s.toLowerCase()); + } + +} diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/MatchingSuggestion.java b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/MatchingSuggestion.java new file mode 100644 index 0000000..0a4087d --- /dev/null +++ b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/MatchingSuggestion.java @@ -0,0 +1,5 @@ +package com.gamebuster19901.excite.bot.command.argument.suggestion; + +public interface MatchingSuggestion { + public boolean matches(String s); +} diff --git a/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/builder/ExciteSuggestionsBuilder.java b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/builder/ExciteSuggestionsBuilder.java new file mode 100644 index 0000000..d855541 --- /dev/null +++ b/src/main/java/com/gamebuster19901/excite/bot/command/argument/suggestion/builder/ExciteSuggestionsBuilder.java @@ -0,0 +1,43 @@ +package com.gamebuster19901.excite.bot.command.argument.suggestion.builder; + +import com.gamebuster19901.excite.bot.command.argument.suggestion.AnyStringSuggestion; +import com.gamebuster19901.excite.bot.command.argument.suggestion.MatchingStringSuggestion; +import com.mojang.brigadier.Message; +import com.mojang.brigadier.context.StringRange; +import com.mojang.brigadier.suggestion.Suggestion; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; + +public class ExciteSuggestionsBuilder extends SuggestionsBuilder { + + public ExciteSuggestionsBuilder(SuggestionsBuilder builder) { + this(builder.getInput(), builder.getStart()); + } + + public ExciteSuggestionsBuilder(String input, int start) { + super(input, start); + } + + @Override + public ExciteSuggestionsBuilder suggest(final Suggestion suggestion) { + return (ExciteSuggestionsBuilder) super.suggest(suggestion); //super always returns this + } + + public ExciteSuggestionsBuilder suggestAnyString(String name) { + Thread.dumpStack(); + return suggest(new AnyStringSuggestion(getDefaultRange(), "<" + name + ">")); + } + + public ExciteSuggestionsBuilder suggestAnyString(String name, Message tooltip) { + Thread.dumpStack(); + return suggest(new AnyStringSuggestion(getDefaultRange(), "<" + name + ">", tooltip)); + } + + public ExciteSuggestionsBuilder suggestAsMatchable(String text) { + return suggest(new MatchingStringSuggestion(getDefaultRange(), text)); + } + + protected StringRange getDefaultRange() { + return StringRange.between(getStart(), getInput().length()); + } + +}