From 1dd3e32aa2890acd9b0096ff36cab9e0e2bf35d4 Mon Sep 17 00:00:00 2001 From: Revxrsal Date: Thu, 3 Oct 2024 12:02:05 +0300 Subject: [PATCH] migrate to Java 8 --- .../revxrsal/commands/brigadier/BNode.java | 22 +-- .../commands/brigadier/BrigadierAdapter.java | 56 ++++++-- .../commands/brigadier/BrigadierParser.java | 3 +- .../brigadier/types/ArgumentTypes.java | 8 +- .../brigadier/types/BTypeFactory.java | 12 +- build.gradle.kts | 4 +- bukkit/build.gradle.kts | 8 +- .../commands/bukkit/BukkitVisitors.java | 2 +- .../bukkit/actor/BasicBukkitActor.java | 66 +++++++-- .../bukkit/brigadier/ByPaperEvents.java | 3 +- .../exception/BukkitExceptionHandler.java | 14 +- .../parameters/PlayerParameterType.java | 3 +- .../sender/BukkitCommandPermission.java | 32 ++++- .../commands/bukkit/util/BukkitVersion.java | 2 + bungee/build.gradle.kts | 2 - .../bungee/actor/BasicBungeeActor.java | 32 ++++- .../exception/BungeeExceptionHandler.java | 14 +- .../commands/cli/actor/CommandLineActor.java | 66 ++++++++- common/build.gradle.kts | 4 - .../src/main/java/revxrsal/commands/Lamp.java | 21 +-- .../annotation/dynamic/Annotations.java | 50 +++++-- .../list/AnnotationListFromMap.java | 7 +- .../annotation/list/EmptyAnnotationList.java | 2 +- .../autocomplete/AsyncSuggestionProvider.java | 22 +-- .../ClassSuggestionProviderFactory.java | 43 +++++- .../autocomplete/EmptySuggestionProvider.java | 3 +- .../autocomplete/StandardAutoCompleter.java | 47 +++--- .../SuggestWithProviderFactory.java | 9 +- .../autocomplete/SuggestionProvider.java | 5 +- .../autocomplete/SuggestionProviders.java | 3 +- .../exception/DefaultExceptionHandler.java | 12 +- .../exception/RuntimeExceptionAdapter.java | 10 +- .../exception/context/ErrorContext.java | 6 +- .../context/ExecutingFunctionContext.java | 37 ++++- .../context/ParsingLiteralContext.java | 44 +++++- .../context/ParsingParameterContext.java | 52 ++++++- .../context/UnknownCommandContext.java | 30 +++- .../context/UnknownParameterContext.java | 36 ++++- .../java/revxrsal/commands/help/Help.java | 24 +--- .../java/revxrsal/commands/hook/Hooks.java | 15 +- .../node/parser/BaseCommandRegistry.java | 32 ++++- .../commands/node/parser/Execution.java | 23 +-- .../node/parser/FunctionParameter.java | 64 +++++++-- .../commands/node/parser/TreeParser.java | 9 +- .../commands/orphan/OrphanRegistry.java | 40 +++++- .../revxrsal/commands/orphan/Orphans.java | 34 ++++- .../commands/parameter/ParameterTypes.java | 5 +- .../commands/parameter/PrioritySpec.java | 33 ++++- .../ClassContextParameterFactory.java | 33 ++++- .../builtins/ClassParameterTypeFactory.java | 44 +++++- .../CollectionParameterTypeFactory.java | 3 +- .../builtins/EnumParameterTypeFactory.java | 46 ++++-- .../ParseWithParameterTypeFactory.java | 6 +- .../builtins/SenderContextParameter.java | 33 ++++- .../commands/reflect/ktx/CallableMethod.java | 45 +++++- .../reflect/ktx/KotlinFunctionImpl.java | 15 +- .../response/ClassResponseHandlerFactory.java | 41 +++++- .../stream/MutableStringStreamImpl.java | 16 ++- .../commands/stream/token/LiteralToken.java | 29 +++- .../commands/stream/token/ParameterToken.java | 29 +++- .../util/BuiltInNamingStrategies.java | 2 +- .../java/revxrsal/commands/util/Classes.java | 3 +- .../revxrsal/commands/util/Collections.java | 17 +++ .../revxrsal/commands/util/CommandPaths.java | 2 +- .../commands/util/InstanceCreator.java | 13 +- .../commands/util/StackTraceSanitizer.java | 3 +- .../java/revxrsal/commands/util/Strings.java | 36 ++++- .../java/com/example/plugin/TestPlugin.java | 4 +- examples/cli-app/build.gradle.kts | 4 - .../src/main/java/com/example/cli/CLIApp.java | 12 +- .../main/java/com/example/bot/SimpleBot.java | 4 +- .../fabric/actor/BasicActorFactory.java | 46 +++++- .../fabric/actor/BasicFabricActor.java | 56 +++++++- .../exception/FabricExceptionHandler.java | 14 +- .../parameters/PlayerParameterType.java | 4 +- .../fabric/parameters/WorldParameterType.java | 4 +- internal-paper-stubs/README.md | 10 +- internal-paper-stubs/build.gradle.kts | 3 +- .../brigadier/CommandRegisteredEvent.java | 135 ++++++++++++++++++ .../paper/command/brigadier/BasicCommand.java | 9 +- .../paper/command/brigadier/Commands.java | 16 ++- .../plugin/configuration/PluginMeta.java | 2 +- .../lifecycle/event/LifecycleEvent.java | 1 + .../LifecycleEventHandlerConfiguration.java | 1 - ...torLifecycleEventHandlerConfiguration.java | 1 - ...zedLifecycleEventHandlerConfiguration.java | 1 - .../event/types/LifecycleEventType.java | 1 - .../event/types/LifecycleEvents.java | 8 +- .../event/command/UnknownCommandEvent.java | 93 ++++++++++++ .../java/revxrsal/commands/jda/JDAUtils.java | 37 +++-- .../commands/jda/slash/JDAParser.java | 3 +- .../commands/jda/slash/JDASlashListener.java | 12 +- .../minestom/actor/BasicActorFactory.java | 46 +++++- .../minestom/actor/BasicMinestomActor.java | 54 ++++++- .../minestom/argument/ArgumentTypes.java | 7 +- .../exception/MinestomExceptionHandler.java | 14 +- .../commands/minestom/hooks/ArgumentColl.java | 6 +- .../minestom/hooks/MinestomCommandHooks.java | 9 +- .../sponge/actor/BasicActorFactory.java | 46 +++++- .../sponge/actor/BasicSpongeActor.java | 56 +++++++- .../sponge/actor/SpongeCommandActor.java | 3 +- .../exception/SpongeExceptionHandler.java | 14 +- .../velocity/actor/BasicActorFactory.java | 46 +++++- .../velocity/actor/BasicVelocityActor.java | 56 +++++++- .../exception/VelocityExceptionHandler.java | 14 +- .../velocity/hooks/VelocityCommandHooks.java | 1 - .../parameters/PlayerParameterType.java | 31 +++- 107 files changed, 1943 insertions(+), 428 deletions(-) create mode 100644 internal-paper-stubs/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java create mode 100644 internal-paper-stubs/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java diff --git a/brigadier/src/main/java/revxrsal/commands/brigadier/BNode.java b/brigadier/src/main/java/revxrsal/commands/brigadier/BNode.java index 39c9ec97..bd4c3606 100644 --- a/brigadier/src/main/java/revxrsal/commands/brigadier/BNode.java +++ b/brigadier/src/main/java/revxrsal/commands/brigadier/BNode.java @@ -43,6 +43,15 @@ private BNode(CommandNode node) { this.node = node; } + public static @NotNull BNode of(@NotNull CommandNode node) { + notNull(node, "node"); + return new BNode<>(node); + } + + public static @NotNull BNode literal(@NotNull String name) { + return of(LiteralArgumentBuilder.literal(name).build()); + } + public @NotNull BNode executes(Command command) { Nodes.setCommand(node, command); return this; @@ -54,8 +63,10 @@ private BNode(CommandNode node) { } public @NotNull BNode suggests(SuggestionProvider suggestionProvider) { - if (node instanceof ArgumentCommandNode argument) + if (node instanceof ArgumentCommandNode) { + ArgumentCommandNode argument = (ArgumentCommandNode) node; Nodes.setSuggestionProvider(argument, suggestionProvider); + } return this; } @@ -74,15 +85,6 @@ private BNode(CommandNode node) { return node; } - public static @NotNull BNode of(@NotNull CommandNode node) { - notNull(node, "node"); - return new BNode<>(node); - } - - public static @NotNull BNode literal(@NotNull String name) { - return of(LiteralArgumentBuilder.literal(name).build()); - } - @NotNull BNode nextChild() { return of(node.getChildren().iterator().next()); } diff --git a/brigadier/src/main/java/revxrsal/commands/brigadier/BrigadierAdapter.java b/brigadier/src/main/java/revxrsal/commands/brigadier/BrigadierAdapter.java index 8a2aac50..2c41a868 100644 --- a/brigadier/src/main/java/revxrsal/commands/brigadier/BrigadierAdapter.java +++ b/brigadier/src/main/java/revxrsal/commands/brigadier/BrigadierAdapter.java @@ -46,7 +46,10 @@ import revxrsal.commands.stream.StringStream; import java.util.Collection; +import java.util.List; +import java.util.Objects; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; import static revxrsal.commands.autocomplete.SuggestionProvider.empty; import static revxrsal.commands.util.Strings.stripNamespace; @@ -78,9 +81,10 @@ public final class BrigadierAdapter { ParameterNode parameter, BrigadierConverter converter ) { - var suggestions = parameter.suggestions(); + revxrsal.commands.autocomplete.SuggestionProvider suggestions = parameter.suggestions(); if (suggestions.equals(empty())) { - if (parameter.parameterType() instanceof BrigadierParameterType brigadierParameterType) { + if (parameter.parameterType() instanceof BrigadierParameterType) { + BrigadierParameterType brigadierParameterType = (BrigadierParameterType) parameter.parameterType(); return brigadierParameterType.argumentType::listSuggestions; } return null; @@ -102,12 +106,12 @@ public final class BrigadierAdapter { return provideAsyncCompletions((AsyncSuggestionProvider) suggestions, builder, test.context(), tooltip); } - var values = suggestions.getSuggestions(test.context()) + List<@NotNull Suggestion> values = suggestions.getSuggestions(test.context()) .stream() .sorted(String.CASE_INSENSITIVE_ORDER) .distinct() .map(s -> toSuggestion(s, builder, tooltip)) - .toList(); + .collect(Collectors.toList()); return CompletableFuture.completedFuture(Suggestions.create(builder.getInput(), values)); }; } @@ -126,7 +130,7 @@ public final class BrigadierAdapter { .sorted(String.CASE_INSENSITIVE_ORDER) .distinct() .map(v -> toSuggestion(v, builder, tooltip)) - .toList()); + .collect(Collectors.toList())); }); } @@ -163,17 +167,20 @@ public final class BrigadierAdapter { /** * A {@link ParameterType} that wraps a Brigadier {@link ArgumentType} - * - * @param argumentType The argument to wrap - * @param The actor type - * @param The parameter type */ - private record BrigadierParameterType( - ArgumentType argumentType - ) implements ParameterType { + private static final class BrigadierParameterType implements ParameterType { + private final ArgumentType argumentType; + + /** + * @param argumentType The argument to wrap + */ + private BrigadierParameterType( + ArgumentType argumentType + ) {this.argumentType = argumentType;} @Override public boolean isGreedy() { - if (argumentType instanceof StringArgumentType sat) { + if (argumentType instanceof StringArgumentType) { + StringArgumentType sat = (StringArgumentType) argumentType; return sat.getType() == StringArgumentType.StringType.GREEDY_PHRASE; } return false; @@ -187,5 +194,28 @@ private record BrigadierParameterType( input.setPosition(reader.getCursor()); return result; } + + public ArgumentType argumentType() {return argumentType;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + //noinspection unchecked + BrigadierParameterType that = (BrigadierParameterType) obj; + return Objects.equals(this.argumentType, that.argumentType); + } + + @Override + public int hashCode() { + return Objects.hash(argumentType); + } + + @Override + public String toString() { + return "BrigadierParameterType[" + + "argumentType=" + argumentType + ']'; + } + } } diff --git a/brigadier/src/main/java/revxrsal/commands/brigadier/BrigadierParser.java b/brigadier/src/main/java/revxrsal/commands/brigadier/BrigadierParser.java index f9f4b091..6db5d228 100644 --- a/brigadier/src/main/java/revxrsal/commands/brigadier/BrigadierParser.java +++ b/brigadier/src/main/java/revxrsal/commands/brigadier/BrigadierParser.java @@ -73,7 +73,8 @@ public BrigadierParser(@NotNull BrigadierConverter converter) { BNode elementNode; if (node.isLiteral()) { elementNode = BNode.literal(node.name()); - } else if (node instanceof ParameterNode parameter) { + } else if (node instanceof ParameterNode) { + ParameterNode parameter = (ParameterNode) node; if (parameter.isSwitch() || parameter.isFlag()) break; elementNode = BNode.of(ofParameter(parameter)); diff --git a/brigadier/src/main/java/revxrsal/commands/brigadier/types/ArgumentTypes.java b/brigadier/src/main/java/revxrsal/commands/brigadier/types/ArgumentTypes.java index cf9a6bfe..a2173b77 100644 --- a/brigadier/src/main/java/revxrsal/commands/brigadier/types/ArgumentTypes.java +++ b/brigadier/src/main/java/revxrsal/commands/brigadier/types/ArgumentTypes.java @@ -31,9 +31,7 @@ import revxrsal.commands.command.CommandActor; import revxrsal.commands.node.ParameterNode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; import static revxrsal.commands.util.Preconditions.notNull; @@ -50,7 +48,7 @@ public final class ArgumentTypes { *

* These also will not be included in {@link #toBuilder()}. */ - private static final List> HIGHEST_PRIORITY = List.of( + private static final List> HIGHEST_PRIORITY = Collections.singletonList( BTypeFactory.INSTANCE ); @@ -60,7 +58,7 @@ public final class ArgumentTypes { *

* These also will not be included in {@link #toBuilder()}. */ - private static final List> DEFAULT_FACTORIES = List.of( + private static final List> DEFAULT_FACTORIES = Arrays.asList( DefaultTypeFactories.LONG, DefaultTypeFactories.INTEGER, DefaultTypeFactories.SHORT, diff --git a/brigadier/src/main/java/revxrsal/commands/brigadier/types/BTypeFactory.java b/brigadier/src/main/java/revxrsal/commands/brigadier/types/BTypeFactory.java index 0296bdc5..4829e781 100644 --- a/brigadier/src/main/java/revxrsal/commands/brigadier/types/BTypeFactory.java +++ b/brigadier/src/main/java/revxrsal/commands/brigadier/types/BTypeFactory.java @@ -39,17 +39,19 @@ enum BTypeFactory implements ArgumentTypeFactory { INSTANCE; @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public @Nullable ArgumentType getArgumentType(@NotNull ParameterNode parameter) { BType b = parameter.annotations().get(BType.class); if (b == null) return null; Object v = InstanceCreator.create(b.value()); - if (v instanceof ArgumentTypeFactory factory) - //noinspection rawtypes + if (v instanceof ArgumentTypeFactory) { + ArgumentTypeFactory factory = (ArgumentTypeFactory) v; return factory.getArgumentType(((ParameterNode) parameter)); - if (v instanceof ArgumentType type) - return type; + } + if (v instanceof ArgumentType) { + return (ArgumentType) v; + } throw new IllegalArgumentException("Don't know how to create an ArgumentType from @BType(" + b.value().getName() + ".class)"); } } diff --git a/build.gradle.kts b/build.gradle.kts index e89fd714..50a8294d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,7 +20,7 @@ version = "4.0.0-beta.16" java { toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) + languageVersion.set(JavaLanguageVersion.of(8)) } } @@ -39,7 +39,7 @@ subprojects { java { toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) + languageVersion.set(JavaLanguageVersion.of(8)) } } diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts index b9642d7b..183c3612 100644 --- a/bukkit/build.gradle.kts +++ b/bukkit/build.gradle.kts @@ -16,12 +16,12 @@ dependencies { exclude(module = "spigot-api") exclude(module = "brigadier") } + compileOnly("com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT") { + exclude(module = "spigot-api") + exclude(module = "adventure") + } compileOnly("org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT") compileOnly("com.mojang:brigadier:1.0.18") - compileOnly("io.papermc.paper:paper-mojangapi:1.19.1-R0.1-SNAPSHOT") - compileOnly("io.papermc.paper:paper-api:1.19.1-R0.1-SNAPSHOT") compileOnly("net.kyori:adventure-platform-bukkit:4.3.4") } - -java.toolchain.languageVersion.set(JavaLanguageVersion.of(17)) \ No newline at end of file diff --git a/bukkit/src/main/java/revxrsal/commands/bukkit/BukkitVisitors.java b/bukkit/src/main/java/revxrsal/commands/bukkit/BukkitVisitors.java index f48dbf1f..d5b5719b 100644 --- a/bukkit/src/main/java/revxrsal/commands/bukkit/BukkitVisitors.java +++ b/bukkit/src/main/java/revxrsal/commands/bukkit/BukkitVisitors.java @@ -281,7 +281,7 @@ public final class BukkitVisitors { @NotNull ActorFactory actorFactory ) { if (BukkitVersion.supportsAsyncCompletion()) { - return new LampBuilderVisitor<>() { + return new LampBuilderVisitor() { private boolean registered = false; @Override public void visit(Lamp.@NotNull Builder builder) { diff --git a/bukkit/src/main/java/revxrsal/commands/bukkit/actor/BasicBukkitActor.java b/bukkit/src/main/java/revxrsal/commands/bukkit/actor/BasicBukkitActor.java index 9a763383..bcc7972d 100644 --- a/bukkit/src/main/java/revxrsal/commands/bukkit/actor/BasicBukkitActor.java +++ b/bukkit/src/main/java/revxrsal/commands/bukkit/actor/BasicBukkitActor.java @@ -11,18 +11,32 @@ import revxrsal.commands.process.MessageSender; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.Optional; import java.util.UUID; -record BasicBukkitActor( - CommandSender sender, - Plugin plugin, - Optional audiences, - MessageSender messageSender, - Lamp lamp -) implements BukkitCommandActor { +final class BasicBukkitActor implements BukkitCommandActor { private static final UUID CONSOLE_UUID = new UUID(0, 0); + private final CommandSender sender; + private final Plugin plugin; + private final Optional audiences; + private final MessageSender messageSender; + private final Lamp lamp; + + BasicBukkitActor( + CommandSender sender, + Plugin plugin, + Optional audiences, + MessageSender messageSender, + Lamp lamp + ) { + this.sender = sender; + this.plugin = plugin; + this.audiences = audiences; + this.messageSender = messageSender; + this.lamp = lamp; + } @Override public @NotNull CommandSender sender() { return sender; @@ -38,8 +52,8 @@ record BasicBukkitActor( @Override public @NotNull Optional audience() { //noinspection DataFlowIssue if (sender instanceof Audience) - return Optional.of(sender); - if (audiences.isEmpty()) + return Optional.of((Audience) sender); + if (!audiences.isPresent()) return Optional.empty(); BukkitAudiences bukkitAudiences = audiences.get(); return Optional.of(bukkitAudiences.sender(sender())); @@ -57,4 +71,38 @@ else if (isConsole()) @Override public Lamp lamp() { return lamp; } + + public Plugin plugin() {return plugin;} + + public Optional audiences() {return audiences;} + + public MessageSender messageSender() {return messageSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + BasicBukkitActor that = (BasicBukkitActor) obj; + return Objects.equals(this.sender, that.sender) && + Objects.equals(this.plugin, that.plugin) && + Objects.equals(this.audiences, that.audiences) && + Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.lamp, that.lamp); + } + + @Override + public int hashCode() { + return Objects.hash(sender, plugin, audiences, messageSender, lamp); + } + + @Override + public String toString() { + return "BasicBukkitActor[" + + "sender=" + sender + ", " + + "plugin=" + plugin + ", " + + "audiences=" + audiences + ", " + + "messageSender=" + messageSender + ", " + + "lamp=" + lamp + ']'; + } + } \ No newline at end of file diff --git a/bukkit/src/main/java/revxrsal/commands/bukkit/brigadier/ByPaperEvents.java b/bukkit/src/main/java/revxrsal/commands/bukkit/brigadier/ByPaperEvents.java index eb7ae107..12623d45 100644 --- a/bukkit/src/main/java/revxrsal/commands/bukkit/brigadier/ByPaperEvents.java +++ b/bukkit/src/main/java/revxrsal/commands/bukkit/brigadier/ByPaperEvents.java @@ -143,9 +143,10 @@ public final class CommandRegisterListener implements Listener { @EventHandler @SuppressWarnings("deprecation") public void onCommandRegistered(CommandRegisteredEvent event) { - if (!(event.getCommand() instanceof PluginCommand pCommand)) { + if (!(event.getCommand() instanceof PluginCommand)) { return; } + PluginCommand pCommand = (PluginCommand) event.getCommand(); if (!(pCommand.getExecutor() instanceof LampCommandExecutor)) { return; } diff --git a/bukkit/src/main/java/revxrsal/commands/bukkit/exception/BukkitExceptionHandler.java b/bukkit/src/main/java/revxrsal/commands/bukkit/exception/BukkitExceptionHandler.java index f4f61ec4..686034a8 100644 --- a/bukkit/src/main/java/revxrsal/commands/bukkit/exception/BukkitExceptionHandler.java +++ b/bukkit/src/main/java/revxrsal/commands/bukkit/exception/BukkitExceptionHandler.java @@ -59,11 +59,15 @@ public void onEmptyEntitySelector(EmptyEntitySelectorException e, BukkitCommandA @Override public void onInputParse(@NotNull InputParseException e, @NotNull BukkitCommandActor actor) { switch (e.cause()) { - case INVALID_ESCAPE_CHARACTER -> - actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); - case UNCLOSED_QUOTE -> actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); - case EXPECTED_WHITESPACE -> - actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + case INVALID_ESCAPE_CHARACTER: + actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); + break; + case UNCLOSED_QUOTE: + actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); + break; + case EXPECTED_WHITESPACE: + actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + break; } } diff --git a/bukkit/src/main/java/revxrsal/commands/bukkit/parameters/PlayerParameterType.java b/bukkit/src/main/java/revxrsal/commands/bukkit/parameters/PlayerParameterType.java index ad18ddc7..4615bbdf 100644 --- a/bukkit/src/main/java/revxrsal/commands/bukkit/parameters/PlayerParameterType.java +++ b/bukkit/src/main/java/revxrsal/commands/bukkit/parameters/PlayerParameterType.java @@ -63,8 +63,9 @@ public PlayerParameterType(boolean brigadierEnabled) { if (entityList.size() != 1) throw new MoreThanOneEntityException(selector); Entity entity = entityList.get(0); - if (!(entity instanceof Player player)) + if (!(entity instanceof Player)) throw new NonPlayerEntitiesException(selector); + Player player = (Player) entity; return player; } catch (IllegalArgumentException e) { throw new MalformedEntitySelectorException(selector, e.getCause().getMessage()); diff --git a/bukkit/src/main/java/revxrsal/commands/bukkit/sender/BukkitCommandPermission.java b/bukkit/src/main/java/revxrsal/commands/bukkit/sender/BukkitCommandPermission.java index dfe2b556..cb6686bb 100644 --- a/bukkit/src/main/java/revxrsal/commands/bukkit/sender/BukkitCommandPermission.java +++ b/bukkit/src/main/java/revxrsal/commands/bukkit/sender/BukkitCommandPermission.java @@ -5,12 +5,42 @@ import revxrsal.commands.bukkit.actor.BukkitCommandActor; import revxrsal.commands.command.CommandPermission; +import java.util.Objects; + /** * A Bukkit-adapted wrapper for {@link CommandPermission} */ -public record BukkitCommandPermission(@NotNull Permission permission) implements CommandPermission { +public final class BukkitCommandPermission implements CommandPermission { + private final @NotNull Permission permission; + + /** + * + */ + public BukkitCommandPermission(@NotNull Permission permission) {this.permission = permission;} @Override public boolean isExecutableBy(@NotNull BukkitCommandActor actor) { return actor.sender().hasPermission(permission); } + + public @NotNull Permission permission() {return permission;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + BukkitCommandPermission that = (BukkitCommandPermission) obj; + return Objects.equals(this.permission, that.permission); + } + + @Override + public int hashCode() { + return Objects.hash(permission); + } + + @Override + public String toString() { + return "BukkitCommandPermission[" + + "permission=" + permission + ']'; + } + } diff --git a/bukkit/src/main/java/revxrsal/commands/bukkit/util/BukkitVersion.java b/bukkit/src/main/java/revxrsal/commands/bukkit/util/BukkitVersion.java index f3f9d619..d57623b4 100644 --- a/bukkit/src/main/java/revxrsal/commands/bukkit/util/BukkitVersion.java +++ b/bukkit/src/main/java/revxrsal/commands/bukkit/util/BukkitVersion.java @@ -25,10 +25,12 @@ public final class BukkitVersion { * The current version string, for example 1_17_R1 */ private static final String VERSION = fetchVersion(); + /** * The version where NMS no longer uses versions in the package names */ private static final int UNVERSION_NMS = 17; + /** * The CraftBukkit package */ diff --git a/bungee/build.gradle.kts b/bungee/build.gradle.kts index d92d0888..84a53796 100644 --- a/bungee/build.gradle.kts +++ b/bungee/build.gradle.kts @@ -11,5 +11,3 @@ dependencies { implementation(project(":common")) compileOnly("net.md-5:bungeecord-api:1.16-R0.4") } - -java.toolchain.languageVersion.set(JavaLanguageVersion.of(17)) \ No newline at end of file diff --git a/bungee/src/main/java/revxrsal/commands/bungee/actor/BasicBungeeActor.java b/bungee/src/main/java/revxrsal/commands/bungee/actor/BasicBungeeActor.java index 122d4a56..516e6b87 100644 --- a/bungee/src/main/java/revxrsal/commands/bungee/actor/BasicBungeeActor.java +++ b/bungee/src/main/java/revxrsal/commands/bungee/actor/BasicBungeeActor.java @@ -6,9 +6,17 @@ import revxrsal.commands.Lamp; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.UUID; -record BasicBungeeActor(CommandSender sender, Lamp lamp) implements BungeeCommandActor { +final class BasicBungeeActor implements BungeeCommandActor { + private final CommandSender sender; + private final Lamp lamp; + + BasicBungeeActor(CommandSender sender, Lamp lamp) { + this.sender = sender; + this.lamp = lamp; + } @Override public @NotNull CommandSender sender() { return sender; @@ -24,4 +32,26 @@ record BasicBungeeActor(CommandSender sender, Lamp lamp) imp @Override public Lamp lamp() { return lamp; } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + BasicBungeeActor that = (BasicBungeeActor) obj; + return Objects.equals(this.sender, that.sender) && + Objects.equals(this.lamp, that.lamp); + } + + @Override + public int hashCode() { + return Objects.hash(sender, lamp); + } + + @Override + public String toString() { + return "BasicBungeeActor[" + + "sender=" + sender + ", " + + "lamp=" + lamp + ']'; + } + } \ No newline at end of file diff --git a/bungee/src/main/java/revxrsal/commands/bungee/exception/BungeeExceptionHandler.java b/bungee/src/main/java/revxrsal/commands/bungee/exception/BungeeExceptionHandler.java index aa20d52c..8f862952 100644 --- a/bungee/src/main/java/revxrsal/commands/bungee/exception/BungeeExceptionHandler.java +++ b/bungee/src/main/java/revxrsal/commands/bungee/exception/BungeeExceptionHandler.java @@ -29,11 +29,15 @@ public void onSenderNotPlayer(SenderNotPlayerException e, BungeeCommandActor act @Override public void onInputParse(@NotNull InputParseException e, @NotNull BungeeCommandActor actor) { switch (e.cause()) { - case INVALID_ESCAPE_CHARACTER -> - actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); - case UNCLOSED_QUOTE -> actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); - case EXPECTED_WHITESPACE -> - actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + case INVALID_ESCAPE_CHARACTER: + actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); + break; + case UNCLOSED_QUOTE: + actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); + break; + case EXPECTED_WHITESPACE: + actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + break; } } diff --git a/cli/src/main/java/revxrsal/commands/cli/actor/CommandLineActor.java b/cli/src/main/java/revxrsal/commands/cli/actor/CommandLineActor.java index e19a8717..6161ae1c 100644 --- a/cli/src/main/java/revxrsal/commands/cli/actor/CommandLineActor.java +++ b/cli/src/main/java/revxrsal/commands/cli/actor/CommandLineActor.java @@ -6,18 +6,32 @@ import java.io.InputStream; import java.io.PrintStream; +import java.util.Objects; import java.util.Scanner; import java.util.UUID; -record CommandLineActor( - Lamp lamp, - InputStream inputStream, - PrintStream outputStream, - PrintStream errorStream, - Scanner scanner -) implements ConsoleActor { +final class CommandLineActor implements ConsoleActor { private static final UUID CLI_UUID = new UUID(0, 0); + private final Lamp lamp; + private final InputStream inputStream; + private final PrintStream outputStream; + private final PrintStream errorStream; + private final Scanner scanner; + + CommandLineActor( + Lamp lamp, + InputStream inputStream, + PrintStream outputStream, + PrintStream errorStream, + Scanner scanner + ) { + this.lamp = lamp; + this.inputStream = inputStream; + this.outputStream = outputStream; + this.errorStream = errorStream; + this.scanner = scanner; + } @Override public @NotNull String name() { return "Command Line"; @@ -34,4 +48,42 @@ record CommandLineActor( @Override public void sendRawError(@NotNull String message) { errorStream.println(message); } + + @Override public Lamp lamp() {return lamp;} + + @Override public InputStream inputStream() {return inputStream;} + + @Override public PrintStream outputStream() {return outputStream;} + + @Override public PrintStream errorStream() {return errorStream;} + + @Override public Scanner scanner() {return scanner;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + CommandLineActor that = (CommandLineActor) obj; + return Objects.equals(this.lamp, that.lamp) && + Objects.equals(this.inputStream, that.inputStream) && + Objects.equals(this.outputStream, that.outputStream) && + Objects.equals(this.errorStream, that.errorStream) && + Objects.equals(this.scanner, that.scanner); + } + + @Override + public int hashCode() { + return Objects.hash(lamp, inputStream, outputStream, errorStream, scanner); + } + + @Override + public String toString() { + return "CommandLineActor[" + + "lamp=" + lamp + ", " + + "inputStream=" + inputStream + ", " + + "outputStream=" + outputStream + ", " + + "errorStream=" + errorStream + ", " + + "scanner=" + scanner + ']'; + } + } diff --git a/common/build.gradle.kts b/common/build.gradle.kts index ef1d28af..a495d09e 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -12,8 +12,4 @@ tasks { test { useJUnitPlatform() } -} - -kotlin { - jvmToolchain(17) } \ No newline at end of file diff --git a/common/src/main/java/revxrsal/commands/Lamp.java b/common/src/main/java/revxrsal/commands/Lamp.java index fc7e072b..da8500b4 100644 --- a/common/src/main/java/revxrsal/commands/Lamp.java +++ b/common/src/main/java/revxrsal/commands/Lamp.java @@ -65,6 +65,8 @@ import static revxrsal.commands.util.Classes.checkRetention; import static revxrsal.commands.util.Classes.wrap; +import static revxrsal.commands.util.Collections.copyList; +import static revxrsal.commands.util.Collections.copyMap; import static revxrsal.commands.util.Preconditions.notNull; /** @@ -95,14 +97,16 @@ public final class Lamp { private final BaseCommandRegistry tree; private final AutoCompleter autoCompleter; + @SuppressWarnings("unchecked") public Lamp(Builder builder) { - this.annotationReplacers = Map.copyOf(builder.annotationReplacers); - this.senderResolvers = List.copyOf(builder.senderResolvers); - this.validators = List.copyOf(builder.validators); - this.responseHandlers = List.copyOf(builder.responseHandlers); - this.commandConditions = List.copyOf(builder.conditions); - this.permissionFactories = List.copyOf(builder.permissionFactories); - this.dependencies = Map.copyOf(builder.dependencies); + this.annotationReplacers = copyMap(builder.annotationReplacers); + this.senderResolvers = copyList(builder.senderResolvers); + this.validators = copyList(builder.validators); + this.responseHandlers = copyList(builder.responseHandlers); + this.commandConditions = copyList(builder.conditions); + //noinspection rawtypes + this.permissionFactories = (List) copyList(builder.permissionFactories); + this.dependencies = copyMap(builder.dependencies); this.messageSender = builder.messageSender; this.errorSender = builder.errorSender; this.parameterNamingStrategy = builder.namingStrategy; @@ -294,7 +298,8 @@ public SuggestionProvider findNextSuggestionProvider(Type type, AnnotationLis if (instance instanceof Orphans) { throw new IllegalArgumentException("You forgot to call .handler(OrphanCommand) in your Orphans.path(...)!"); } - if (instance instanceof OrphanRegistry registry) { + if (instance instanceof OrphanRegistry) { + OrphanRegistry registry = (OrphanRegistry) instance; commandClass = registry.handler().getClass(); instance = registry.handler(); return tree.register(commandClass, instance, registry.paths()); diff --git a/common/src/main/java/revxrsal/commands/annotation/dynamic/Annotations.java b/common/src/main/java/revxrsal/commands/annotation/dynamic/Annotations.java index 3a56e037..01306043 100644 --- a/common/src/main/java/revxrsal/commands/annotation/dynamic/Annotations.java +++ b/common/src/main/java/revxrsal/commands/annotation/dynamic/Annotations.java @@ -42,14 +42,6 @@ */ public final class Annotations { - /** - * An annotation that implies that the annotated type cannot be dynamically - * created using {@link Annotations#create(Class)} - */ - @Target(ElementType.ANNOTATION_TYPE) - @Retention(RetentionPolicy.RUNTIME) - public @interface CannotBeCreated {} - /** * Creates a new annotation with no values. Any default values will * automatically be used. @@ -177,10 +169,18 @@ private static String deepToString(Object arg) { return s.substring(1, s.length() - 1); // cut off the [] } - private record DynamicAnnotationHandler( - Class annotationType, - Map annotationMembers - ) implements InvocationHandler { + /** + * An annotation that implies that the annotated type cannot be dynamically + * created using {@link Annotations#create(Class)} + */ + @Target(ElementType.ANNOTATION_TYPE) + @Retention(RetentionPolicy.RUNTIME) + public @interface CannotBeCreated {} + + private static final class DynamicAnnotationHandler implements InvocationHandler { + private final Class annotationType; + private final Map annotationMembers; + private DynamicAnnotationHandler(Class annotationType, Map annotationMembers) { if (annotationType.isAnnotationPresent(CannotBeCreated.class)) @@ -225,6 +225,32 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl } } } + + public Class annotationType() {return annotationType;} + + public Map annotationMembers() {return annotationMembers;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + DynamicAnnotationHandler that = (DynamicAnnotationHandler) obj; + return Objects.equals(this.annotationType, that.annotationType) && + Objects.equals(this.annotationMembers, that.annotationMembers); + } + + @Override + public int hashCode() { + return Objects.hash(annotationType, annotationMembers); + } + + @Override + public String toString() { + return "DynamicAnnotationHandler[" + + "annotationType=" + annotationType + ", " + + "annotationMembers=" + annotationMembers + ']'; + } + } } diff --git a/common/src/main/java/revxrsal/commands/annotation/list/AnnotationListFromMap.java b/common/src/main/java/revxrsal/commands/annotation/list/AnnotationListFromMap.java index 125cf0cc..a7e487fb 100644 --- a/common/src/main/java/revxrsal/commands/annotation/list/AnnotationListFromMap.java +++ b/common/src/main/java/revxrsal/commands/annotation/list/AnnotationListFromMap.java @@ -85,7 +85,7 @@ private static void distributeAnnotations( ) { Class top = element.getDeclaringClass(); while (top != null) { - var classAnnotations = AnnotationList.create(top) + AnnotationList classAnnotations = AnnotationList.create(top) .replaceAnnotations(top, replacers); for (Annotation annotation : classAnnotations) { if (annotation.annotationType().isAnnotationPresent(DistributeOnMethods.class)) @@ -154,7 +154,8 @@ public boolean contains(@NotNull Class type) { annotations.putAll(toMap(newAnnotations)); } } - if (element instanceof Method method) { + if (element instanceof Method) { + Method method = (Method) element; distributeAnnotations(annotations, method, replacers); } return new AnnotationListFromMap(annotations); @@ -186,7 +187,7 @@ public boolean any(@NotNull Predicate predicate) { @Override public @NotNull AnnotationList withAnnotations(boolean overrideExisting, @NotNull Annotation... annotations) { - var map = new HashMap<>(this.annotations); + HashMap, Annotation> map = new HashMap<>(this.annotations); for (@NotNull Annotation annotation : annotations) { if (overrideExisting) map.put(annotation.annotationType(), annotation); diff --git a/common/src/main/java/revxrsal/commands/annotation/list/EmptyAnnotationList.java b/common/src/main/java/revxrsal/commands/annotation/list/EmptyAnnotationList.java index b55a251d..0c23b23d 100644 --- a/common/src/main/java/revxrsal/commands/annotation/list/EmptyAnnotationList.java +++ b/common/src/main/java/revxrsal/commands/annotation/list/EmptyAnnotationList.java @@ -100,7 +100,7 @@ public boolean isEmpty() { @Override public @NotNull AnnotationList withAnnotations(boolean overrideExisting, @NotNull Annotation... annotations) { - var map = AnnotationListFromMap.toMap(annotations); + Map, Annotation> map = AnnotationListFromMap.toMap(annotations); return new AnnotationListFromMap(map); } diff --git a/common/src/main/java/revxrsal/commands/autocomplete/AsyncSuggestionProvider.java b/common/src/main/java/revxrsal/commands/autocomplete/AsyncSuggestionProvider.java index e1440069..32d1dd83 100644 --- a/common/src/main/java/revxrsal/commands/autocomplete/AsyncSuggestionProvider.java +++ b/common/src/main/java/revxrsal/commands/autocomplete/AsyncSuggestionProvider.java @@ -42,6 +42,17 @@ @FunctionalInterface public interface AsyncSuggestionProvider extends BaseSuggestionProvider { + /** + * Creates a {@link AsyncSuggestionProvider} from the given {@link SuggestionProvider} + * + * @param provider Provider to wrap + * @param The actor type + * @return The {@link AsyncSuggestionProvider} + */ + static @NotNull AsyncSuggestionProvider from(@NotNull SuggestionProvider provider) { + return context -> CompletableFuture.supplyAsync(() -> provider.getSuggestions(context)); + } + /** * Returns the suggestions * @@ -52,15 +63,4 @@ public interface AsyncSuggestionProvider extends BaseSug */ @NotNull CompletableFuture> getSuggestionsAsync(@NotNull ExecutionContext context); - - /** - * Creates a {@link AsyncSuggestionProvider} from the given {@link SuggestionProvider} - * - * @param provider Provider to wrap - * @param The actor type - * @return The {@link AsyncSuggestionProvider} - */ - static @NotNull AsyncSuggestionProvider from(@NotNull SuggestionProvider provider) { - return context -> CompletableFuture.supplyAsync(() -> provider.getSuggestions(context)); - } } diff --git a/common/src/main/java/revxrsal/commands/autocomplete/ClassSuggestionProviderFactory.java b/common/src/main/java/revxrsal/commands/autocomplete/ClassSuggestionProviderFactory.java index 53fe434b..8cc4e8e3 100644 --- a/common/src/main/java/revxrsal/commands/autocomplete/ClassSuggestionProviderFactory.java +++ b/common/src/main/java/revxrsal/commands/autocomplete/ClassSuggestionProviderFactory.java @@ -30,6 +30,7 @@ import revxrsal.commands.command.CommandActor; import java.lang.reflect.Type; +import java.util.Objects; import static revxrsal.commands.util.Classes.getRawType; import static revxrsal.commands.util.Classes.wrap; @@ -40,14 +41,12 @@ *

* Create using {@link SuggestionProvider.Factory#forType(Class, SuggestionProvider)} * and {@link SuggestionProvider.Factory#forTypeAndSubclasses(Class, SuggestionProvider)} - * - * @param The actor type */ -record ClassSuggestionProviderFactory( - Class type, - SuggestionProvider provider, - boolean allowSubclasses -) implements SuggestionProvider.Factory { +final class ClassSuggestionProviderFactory implements SuggestionProvider.Factory { + private final Class type; + private final SuggestionProvider provider; + private final boolean allowSubclasses; + ClassSuggestionProviderFactory(Class type, SuggestionProvider provider, boolean allowSubclasses) { this.type = wrap(type); @@ -65,4 +64,34 @@ record ClassSuggestionProviderFactory( return provider; return null; } + + public Class type() {return type;} + + public SuggestionProvider provider() {return provider;} + + public boolean allowSubclasses() {return allowSubclasses;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + ClassSuggestionProviderFactory that = (ClassSuggestionProviderFactory) obj; + return Objects.equals(this.type, that.type) && + Objects.equals(this.provider, that.provider) && + this.allowSubclasses == that.allowSubclasses; + } + + @Override + public int hashCode() { + return Objects.hash(type, provider, allowSubclasses); + } + + @Override + public String toString() { + return "ClassSuggestionProviderFactory[" + + "type=" + type + ", " + + "provider=" + provider + ", " + + "allowSubclasses=" + allowSubclasses + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/autocomplete/EmptySuggestionProvider.java b/common/src/main/java/revxrsal/commands/autocomplete/EmptySuggestionProvider.java index 9fa3e47d..6b70756f 100644 --- a/common/src/main/java/revxrsal/commands/autocomplete/EmptySuggestionProvider.java +++ b/common/src/main/java/revxrsal/commands/autocomplete/EmptySuggestionProvider.java @@ -27,6 +27,7 @@ import revxrsal.commands.command.CommandActor; import revxrsal.commands.node.ExecutionContext; +import java.util.Collections; import java.util.List; /** @@ -41,7 +42,7 @@ private EmptySuggestionProvider() { @Override public @NotNull List getSuggestions(@NotNull ExecutionContext context) { - return List.of(); + return Collections.emptyList(); } @Override diff --git a/common/src/main/java/revxrsal/commands/autocomplete/StandardAutoCompleter.java b/common/src/main/java/revxrsal/commands/autocomplete/StandardAutoCompleter.java index 025ec4b8..1cd5c076 100644 --- a/common/src/main/java/revxrsal/commands/autocomplete/StandardAutoCompleter.java +++ b/common/src/main/java/revxrsal/commands/autocomplete/StandardAutoCompleter.java @@ -33,11 +33,11 @@ import revxrsal.commands.stream.StringStream; import java.util.*; +import java.util.stream.Collectors; import static revxrsal.commands.node.DispatcherSettings.LONG_FORMAT_PREFIX; import static revxrsal.commands.node.DispatcherSettings.SHORT_FORMAT_PREFIX; -import static revxrsal.commands.util.Collections.filter; -import static revxrsal.commands.util.Collections.map; +import static revxrsal.commands.util.Collections.*; /** * A basic implementation of {@link AutoCompleter} that respects secret @@ -60,7 +60,7 @@ public StandardAutoCompleter(Lamp lamp) { .stream() .filter(suggestion -> startsWithIgnoreCase(suggestion, consumed)) .map(s -> getRemainingContent(s, consumed)) - .toList(); + .collect(Collectors.toList()); } private static boolean startsWithIgnoreCase(String a, String b) { @@ -106,7 +106,8 @@ public static String getRemainingContent(String suggestion, String consumed) { private List complete(ExecutableCommand possible, MutableStringStream input, A actor) { MutableExecutionContext context = ExecutionContext.createMutable(possible, actor, input.toImmutableCopy()); for (CommandNode child : possible.nodes()) { - if (child instanceof ParameterNode parameter) { + if (child instanceof ParameterNode) { + ParameterNode parameter = (ParameterNode) child; if (parameter.isFlag() || parameter.isSwitch()) break; } @@ -115,20 +116,21 @@ private List complete(ExecutableCommand possible, MutableStringStream return promptWith(child, actor, context, input); } - if (child instanceof LiteralNode l) { + if (child instanceof LiteralNode) { + LiteralNode l = (LiteralNode) child; String nextWord = input.readUnquotedString(); if (input.hasFinished()) { if (l.name().startsWith(nextWord)) { // complete it for the user :) - return List.of(l.name()); + return Arrays.asList(l.name()); } else { // the user inputted a command that isn't ours. dismiss the operation - return List.of(); + return Arrays.asList(); } } else { if (!l.name().equalsIgnoreCase(nextWord)) { // the user inputted a command that isn't ours. dismiss the operation - return List.of(); + return Arrays.asList(); } if (input.canRead(1) && input.peek() == ' ') { // our literal is just fine. move to the next node @@ -136,10 +138,11 @@ private List complete(ExecutableCommand possible, MutableStringStream continue; } } - } else if (child instanceof ParameterNode parameter) { + } else if (child instanceof ParameterNode) { + ParameterNode parameter = (ParameterNode) child; int posBeforeParsing = input.position(); if (!parameter.permission().isExecutableBy(actor)) - return List.of(); + return Arrays.asList(); try { Object value = parameter.parse(input, context); context.addResolvedArgument(parameter.name(), value); @@ -187,17 +190,17 @@ private List complete(ExecutableCommand possible, MutableStringStream @Nullable ParameterNode parameter = removeParameterNamed(flags, flagName); input.readUnquotedString(); if (input.hasFinished()) - return List.of(); + return Arrays.asList(); if (input.hasRemaining() && input.peek() == ' ') { input.skipWhitespace(); } if (input.hasFinished() && parameter != null) { - return List.copyOf(parameter.suggestions().getSuggestions(context)); + return copyList(parameter.suggestions().getSuggestions(context)); } else { if (parameter != null) { tryParseFlag(parameter, input, context); if (input.hasFinished() || input.peek() != ' ') { - return List.of(); + return Arrays.asList(); } } continue; @@ -213,7 +216,7 @@ private List complete(ExecutableCommand possible, MutableStringStream tryParseFlag(parameter, input, context); if (input.hasRemaining() && input.peek() == ' ') { input.skipWhitespace(); - return List.copyOf(parameter.suggestions().getSuggestions(context)); + return copyList(parameter.suggestions().getSuggestions(context)); } else if (input.hasFinished()) { return flags.stream().map(f -> { if (f.shorthand() != null) { @@ -222,7 +225,7 @@ private List complete(ExecutableCommand possible, MutableStringStream } return null; }).filter(Objects::nonNull) - .toList(); + .collect(Collectors.toList()); } } } else { @@ -252,12 +255,14 @@ private void tryParseFlag(@NotNull ParameterNode parameter, MutableSt private @NotNull List promptWith(CommandNode child, A actor, ExecutionContext context, StringStream input) { - if (child instanceof LiteralNode l) - return List.of(l.name()); - else if (child instanceof ParameterNode p) - return List.copyOf(p.complete(actor, input, context)); - else - return List.of(); + if (child instanceof LiteralNode) { + LiteralNode l = (LiteralNode) child; + return Arrays.asList(l.name()); + } else if (child instanceof ParameterNode) { + ParameterNode p = (ParameterNode) child; + return copyList(p.complete(actor, input, context)); + } else + return Arrays.asList(); } private @Nullable ParameterNode removeParameterWithShorthand(List> parametersLeft, char c) { diff --git a/common/src/main/java/revxrsal/commands/autocomplete/SuggestWithProviderFactory.java b/common/src/main/java/revxrsal/commands/autocomplete/SuggestWithProviderFactory.java index 69e24e4d..6bd8e104 100644 --- a/common/src/main/java/revxrsal/commands/autocomplete/SuggestWithProviderFactory.java +++ b/common/src/main/java/revxrsal/commands/autocomplete/SuggestWithProviderFactory.java @@ -47,11 +47,14 @@ enum SuggestWithProviderFactory implements SuggestionProvider.Factory pType) { + if (type instanceof SuggestionProvider) { + SuggestionProvider pType = (SuggestionProvider) type; return (SuggestionProvider) pType; - } else if (type instanceof SuggestionProvider.Factory factory) { + } else if (type instanceof SuggestionProvider.Factory) { + SuggestionProvider.Factory factory = (SuggestionProvider.Factory) type; return factory.create(parameterType, annotations, (Lamp) lamp); - } else if (type instanceof AsyncSuggestionProvider async) { + } else if (type instanceof AsyncSuggestionProvider) { + AsyncSuggestionProvider async = (AsyncSuggestionProvider) type; return (SuggestionProvider) SuggestionProvider.fromAsync(async); } else { throw new IllegalArgumentException("Don't know how to create a SuggestionProvider from " + type); diff --git a/common/src/main/java/revxrsal/commands/autocomplete/SuggestionProvider.java b/common/src/main/java/revxrsal/commands/autocomplete/SuggestionProvider.java index 36db1ea3..e858beb2 100644 --- a/common/src/main/java/revxrsal/commands/autocomplete/SuggestionProvider.java +++ b/common/src/main/java/revxrsal/commands/autocomplete/SuggestionProvider.java @@ -33,6 +33,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.function.Function; @@ -65,7 +66,7 @@ public interface SuggestionProvider extends BaseSuggesti * block. * * @param provider The asynchronous provider - * @param The actor type + * @param The actor type * @return The {@link SuggestionProvider} */ @Contract("_ -> new") @@ -83,7 +84,7 @@ public interface SuggestionProvider extends BaseSuggesti static @NotNull SuggestionProvider of(@NotNull String... suggestions) { if (suggestions == null || suggestions.length == 0) return empty(); - List list = List.of(suggestions); + List list = Arrays.asList(suggestions); return (context) -> list; } diff --git a/common/src/main/java/revxrsal/commands/autocomplete/SuggestionProviders.java b/common/src/main/java/revxrsal/commands/autocomplete/SuggestionProviders.java index a004379f..a4893bea 100644 --- a/common/src/main/java/revxrsal/commands/autocomplete/SuggestionProviders.java +++ b/common/src/main/java/revxrsal/commands/autocomplete/SuggestionProviders.java @@ -34,6 +34,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.function.Function; @@ -56,7 +57,7 @@ public final class SuggestionProviders { *

* These also will not be included in {@link #toBuilder()}. */ - private static final List> DEFAULT_FACTORIES = List.of( + private static final List> DEFAULT_FACTORIES = Arrays.asList( SuggestAnnotationProviderFactory.INSTANCE, SuggestWithProviderFactory.INSTANCE ); diff --git a/common/src/main/java/revxrsal/commands/exception/DefaultExceptionHandler.java b/common/src/main/java/revxrsal/commands/exception/DefaultExceptionHandler.java index a4bbe6ea..12cc3b73 100644 --- a/common/src/main/java/revxrsal/commands/exception/DefaultExceptionHandler.java +++ b/common/src/main/java/revxrsal/commands/exception/DefaultExceptionHandler.java @@ -42,9 +42,15 @@ public void onExpectedLiteral(@NotNull ExpectedLiteralException e, @NotNull A ac @HandleException public void onInputParse(@NotNull InputParseException e, @NotNull A actor) { switch (e.cause()) { - case INVALID_ESCAPE_CHARACTER -> actor.error("Invalid input. Use \\\\ to include a backslash."); - case UNCLOSED_QUOTE -> actor.error("Unclosed quote. Make sure to close all quotes."); - case EXPECTED_WHITESPACE -> actor.error("Expected whitespace to end one argument, but found trailing data"); + case INVALID_ESCAPE_CHARACTER: + actor.error("Invalid input. Use \\\\ to include a backslash."); + break; + case UNCLOSED_QUOTE: + actor.error("Unclosed quote. Make sure to close all quotes."); + break; + case EXPECTED_WHITESPACE: + actor.error("Expected whitespace to end one argument, but found trailing data."); + break; } } diff --git a/common/src/main/java/revxrsal/commands/exception/RuntimeExceptionAdapter.java b/common/src/main/java/revxrsal/commands/exception/RuntimeExceptionAdapter.java index 925c6f1e..bd49814a 100644 --- a/common/src/main/java/revxrsal/commands/exception/RuntimeExceptionAdapter.java +++ b/common/src/main/java/revxrsal/commands/exception/RuntimeExceptionAdapter.java @@ -108,7 +108,7 @@ public RuntimeExceptionAdapter() { for (Method method : Reflections.getAllMethods(getClass())) { if (!isHandler(method)) continue; - var handler = createHandler(method); + CommandExceptionHandler handler = createHandler(method); handlers.add(handler); } } @@ -164,15 +164,15 @@ private static boolean isHandler(Method method) { suppliers[i] = (throwable, errorContext) -> errorContext.context().command().function(); } else if (CommandParameter.class.isAssignableFrom(type)) { /* handle a CommandParameter parameter */ - conditions.add((throwable, errorContext) -> errorContext instanceof ParsingParameter); + conditions.add((throwable, errorContext) -> errorContext instanceof ParsingParameter); suppliers[i] = (throwable, errorContext) -> ((ParsingParameter) errorContext).parameter().parameter(); } else if (ParameterNode.class.isAssignableFrom(type)) { /* handle a ParameterNode parameter */ - conditions.add((throwable, errorContext) -> errorContext instanceof ParsingParameter); + conditions.add((throwable, errorContext) -> errorContext instanceof ParsingParameter); suppliers[i] = (throwable, errorContext) -> ((ParsingParameter) errorContext).parameter(); } else if (LiteralNode.class.isAssignableFrom(type)) { /* handle a LiteralNode parameter */ - conditions.add((throwable, errorContext) -> errorContext instanceof ParsingLiteral); + conditions.add((throwable, errorContext) -> errorContext instanceof ParsingLiteral); suppliers[i] = (throwable, errorContext) -> ((ParsingLiteral) errorContext).literal(); } else { throw new IllegalArgumentException("Don't know how to handle parameter of type " + type + " for a @HandleException function (" + method + ")"); @@ -200,7 +200,7 @@ private static boolean isHandler(Method method) { @Override public final void handleException(@NotNull Throwable throwable, @NotNull ErrorContext errorContext) { - for (var handler : handlers) { + for (CommandExceptionHandler handler : handlers) { handler.handleException(throwable, errorContext); } } diff --git a/common/src/main/java/revxrsal/commands/exception/context/ErrorContext.java b/common/src/main/java/revxrsal/commands/exception/context/ErrorContext.java index 0ccc78e4..bfbf2816 100644 --- a/common/src/main/java/revxrsal/commands/exception/context/ErrorContext.java +++ b/common/src/main/java/revxrsal/commands/exception/context/ErrorContext.java @@ -144,7 +144,7 @@ default boolean hasExecutionContext() { * @return whether the error occurred during parsing a literal */ default boolean isParsingLiteral() { - return this instanceof ParsingLiteral; + return this instanceof ParsingLiteral; } /** @@ -153,7 +153,7 @@ default boolean isParsingLiteral() { * @return whether the error occurred during parsing a parameter */ default boolean isParsingParameter() { - return this instanceof ParsingParameter; + return this instanceof ParsingParameter; } /** @@ -162,7 +162,7 @@ default boolean isParsingParameter() { * @return whether the error occurred during executing a function */ default boolean isExecutingFunction() { - return this instanceof ExecutingFunctionContext; + return this instanceof ExecutingFunctionContext; } /** diff --git a/common/src/main/java/revxrsal/commands/exception/context/ExecutingFunctionContext.java b/common/src/main/java/revxrsal/commands/exception/context/ExecutingFunctionContext.java index 89d32b47..13935896 100644 --- a/common/src/main/java/revxrsal/commands/exception/context/ExecutingFunctionContext.java +++ b/common/src/main/java/revxrsal/commands/exception/context/ExecutingFunctionContext.java @@ -28,13 +28,22 @@ import revxrsal.commands.command.CommandActor; import revxrsal.commands.node.ExecutionContext; +import java.util.Objects; + /** * Right now this context stores no information. We can just use * a singleton for it */ -record ExecutingFunctionContext( - ExecutionContext context -) implements ErrorContext.ExecutingFunction { +final class ExecutingFunctionContext implements ErrorContext.ExecutingFunction { + private final ExecutionContext context; + + /** + * + */ + ExecutingFunctionContext( + ExecutionContext context + ) {this.context = context;} + @Override public @NotNull A actor() { return context.actor(); @@ -44,4 +53,26 @@ record ExecutingFunctionContext( public @NotNull Lamp lamp() { return context.lamp(); } + + @Override public ExecutionContext context() {return context;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + ExecutingFunctionContext that = (ExecutingFunctionContext) obj; + return Objects.equals(this.context, that.context); + } + + @Override + public int hashCode() { + return Objects.hash(context); + } + + @Override + public String toString() { + return "ExecutingFunctionContext[" + + "context=" + context + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/exception/context/ParsingLiteralContext.java b/common/src/main/java/revxrsal/commands/exception/context/ParsingLiteralContext.java index 9a3ab145..1333d23b 100644 --- a/common/src/main/java/revxrsal/commands/exception/context/ParsingLiteralContext.java +++ b/common/src/main/java/revxrsal/commands/exception/context/ParsingLiteralContext.java @@ -29,10 +29,20 @@ import revxrsal.commands.node.ExecutionContext; import revxrsal.commands.node.LiteralNode; -record ParsingLiteralContext( - @NotNull ExecutionContext context, - @NotNull LiteralNode literal -) implements ErrorContext.ParsingLiteral { +import java.util.Objects; + +final class ParsingLiteralContext implements ErrorContext.ParsingLiteral { + private final @NotNull ExecutionContext context; + private final @NotNull LiteralNode literal; + + ParsingLiteralContext( + @NotNull ExecutionContext context, + @NotNull LiteralNode literal + ) { + this.context = context; + this.literal = literal; + } + @Override public @NotNull A actor() { return context().actor(); @@ -42,4 +52,30 @@ record ParsingLiteralContext( public @NotNull Lamp lamp() { return context.lamp(); } + + @Override public @NotNull ExecutionContext context() {return context;} + + @Override public @NotNull LiteralNode literal() {return literal;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + ParsingLiteralContext that = (ParsingLiteralContext) obj; + return Objects.equals(this.context, that.context) && + Objects.equals(this.literal, that.literal); + } + + @Override + public int hashCode() { + return Objects.hash(context, literal); + } + + @Override + public String toString() { + return "ParsingLiteralContext[" + + "context=" + context + ", " + + "literal=" + literal + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/exception/context/ParsingParameterContext.java b/common/src/main/java/revxrsal/commands/exception/context/ParsingParameterContext.java index 6fd21dd8..3b571f0a 100644 --- a/common/src/main/java/revxrsal/commands/exception/context/ParsingParameterContext.java +++ b/common/src/main/java/revxrsal/commands/exception/context/ParsingParameterContext.java @@ -30,11 +30,23 @@ import revxrsal.commands.node.ParameterNode; import revxrsal.commands.stream.StringStream; -record ParsingParameterContext( - @NotNull ExecutionContext context, - @NotNull ParameterNode parameter, - @NotNull StringStream input -) implements ErrorContext.ParsingParameter { +import java.util.Objects; + +final class ParsingParameterContext implements ErrorContext.ParsingParameter { + private final @NotNull ExecutionContext context; + private final @NotNull ParameterNode parameter; + private final @NotNull StringStream input; + + ParsingParameterContext( + @NotNull ExecutionContext context, + @NotNull ParameterNode parameter, + @NotNull StringStream input + ) { + this.context = context; + this.parameter = parameter; + this.input = input; + } + @Override public @NotNull A actor() { return context.actor(); @@ -44,4 +56,34 @@ record ParsingParameterContext( public @NotNull Lamp lamp() { return context.lamp(); } + + @Override public @NotNull ExecutionContext context() {return context;} + + @Override public @NotNull ParameterNode parameter() {return parameter;} + + public @NotNull StringStream input() {return input;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + ParsingParameterContext that = (ParsingParameterContext) obj; + return Objects.equals(this.context, that.context) && + Objects.equals(this.parameter, that.parameter) && + Objects.equals(this.input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(context, parameter, input); + } + + @Override + public String toString() { + return "ParsingParameterContext[" + + "context=" + context + ", " + + "parameter=" + parameter + ", " + + "input=" + input + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/exception/context/UnknownCommandContext.java b/common/src/main/java/revxrsal/commands/exception/context/UnknownCommandContext.java index d28732cb..c4f1d74d 100644 --- a/common/src/main/java/revxrsal/commands/exception/context/UnknownCommandContext.java +++ b/common/src/main/java/revxrsal/commands/exception/context/UnknownCommandContext.java @@ -28,11 +28,19 @@ import revxrsal.commands.command.CommandActor; import revxrsal.commands.node.ExecutionContext; +import java.util.Objects; + /** * Right now this context stores no information. We can just use * a singleton for it */ -record UnknownCommandContext(@NotNull A actor) implements ErrorContext.UnknownCommand { +final class UnknownCommandContext implements ErrorContext.UnknownCommand { + private final @NotNull A actor; + + /** + * + */ + UnknownCommandContext(@NotNull A actor) {this.actor = actor;} @Override public boolean hasExecutionContext() { @@ -53,4 +61,24 @@ public ExecutionContext context() { public @NotNull Lamp lamp() { return (Lamp) actor.lamp(); } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + UnknownCommandContext that = (UnknownCommandContext) obj; + return Objects.equals(this.actor, that.actor); + } + + @Override + public int hashCode() { + return Objects.hash(actor); + } + + @Override + public String toString() { + return "UnknownCommandContext[" + + "actor=" + actor + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/exception/context/UnknownParameterContext.java b/common/src/main/java/revxrsal/commands/exception/context/UnknownParameterContext.java index b4bc2447..2dc75da1 100644 --- a/common/src/main/java/revxrsal/commands/exception/context/UnknownParameterContext.java +++ b/common/src/main/java/revxrsal/commands/exception/context/UnknownParameterContext.java @@ -28,14 +28,22 @@ import revxrsal.commands.command.CommandActor; import revxrsal.commands.node.ExecutionContext; +import java.util.Objects; + /** * Right now this context stores no information. We can just use * a singleton for it */ -record UnknownParameterContext( - @NotNull ExecutionContext context +final class UnknownParameterContext implements ErrorContext.UnknownParameter { + private final @NotNull ExecutionContext context; + + /** + * + */ + UnknownParameterContext( + @NotNull ExecutionContext context -) implements ErrorContext.UnknownParameter { + ) {this.context = context;} @Override public boolean hasExecutionContext() { @@ -51,4 +59,26 @@ public boolean hasExecutionContext() { public @NotNull Lamp lamp() { return context.lamp(); } + + @Override public @NotNull ExecutionContext context() {return context;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + UnknownParameterContext that = (UnknownParameterContext) obj; + return Objects.equals(this.context, that.context); + } + + @Override + public int hashCode() { + return Objects.hash(context); + } + + @Override + public String toString() { + return "UnknownParameterContext[" + + "context=" + context + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/help/Help.java b/common/src/main/java/revxrsal/commands/help/Help.java index ebf95d8f..df32c9c1 100644 --- a/common/src/main/java/revxrsal/commands/help/Help.java +++ b/common/src/main/java/revxrsal/commands/help/Help.java @@ -58,7 +58,7 @@ public interface Help { @Range(from = 1, to = Integer.MAX_VALUE) int elementsPerPage ) throws InvalidHelpPageException { if (commands.isEmpty()) - return List.of(); + return Collections.emptyList(); int size = numberOfPages(commands.size(), elementsPerPage); if (page <= 0) throw new InvalidHelpPageException(commands, page, elementsPerPage, size); @@ -125,28 +125,6 @@ interface CommandList extends Iterable - * Note that the list returned by this method is immutable. - * - * @param pageNumber The page number - * @param elementsPerPage The elements to include in each page - * @return The pages list. - * @throws InvalidHelpPageException if {@code pageNumber} is greater than - * {@link #numberOfPages(int)} or less than 1 - * @deprecated Use {@link #paginate(int, int)} instead. - */ - @Unmodifiable - @Deprecated(forRemoval = true) - default List> asPage( - @Range(from = 1, to = Integer.MAX_VALUE) int pageNumber, - @Range(from = 1, to = Integer.MAX_VALUE) int elementsPerPage - ) throws InvalidHelpPageException { - return paginate(pageNumber, elementsPerPage); - } - /** * Returns the list of commands that belong to a specific page after paginating * this list. diff --git a/common/src/main/java/revxrsal/commands/hook/Hooks.java b/common/src/main/java/revxrsal/commands/hook/Hooks.java index 0f118bd5..4d4b42af 100644 --- a/common/src/main/java/revxrsal/commands/hook/Hooks.java +++ b/common/src/main/java/revxrsal/commands/hook/Hooks.java @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.List; +import static revxrsal.commands.util.Collections.copyList; import static revxrsal.commands.util.Preconditions.notNull; /** @@ -55,7 +56,7 @@ public final class Hooks { private final @Unmodifiable List hooks; private Hooks(Builder builder) { - this.hooks = List.copyOf(builder.hooks); + this.hooks = copyList(builder.hooks); } /** @@ -89,8 +90,10 @@ private Hooks(Builder builder) { public boolean onCommandRegistered(@NotNull ExecutableCommand command) { CancelHandle cancelHandle = newCancelHandle(); for (Hook hook : hooks) { - if (hook instanceof CommandRegisteredHook registeredHook) + if (hook instanceof CommandRegisteredHook) { + CommandRegisteredHook registeredHook = (CommandRegisteredHook) hook; registeredHook.onRegistered(command, cancelHandle); + } } return !cancelHandle.wasCancelled(); } @@ -106,8 +109,10 @@ public boolean onCommandRegistered(@NotNull ExecutableCommand command) { public boolean onCommandUnregistered(@NotNull ExecutableCommand command) { CancelHandle cancelHandle = newCancelHandle(); for (Hook hook : hooks) { - if (hook instanceof CommandUnregisteredHook unregisteredHook) + if (hook instanceof CommandUnregisteredHook) { + CommandUnregisteredHook unregisteredHook = (CommandUnregisteredHook) hook; unregisteredHook.onUnregistered(command, cancelHandle); + } } return !cancelHandle.wasCancelled(); } @@ -124,8 +129,10 @@ public boolean onCommandUnregistered(@NotNull ExecutableCommand command) { public boolean onCommandExecuted(@NotNull ExecutableCommand command, @NotNull ExecutionContext context) { CancelHandle cancelHandle = newCancelHandle(); for (Hook hook : hooks) { - if (hook instanceof CommandExecutedHook executedHook) + if (hook instanceof CommandExecutedHook) { + CommandExecutedHook executedHook = (CommandExecutedHook) hook; executedHook.onExecuted(command, context, cancelHandle); + } } return !cancelHandle.wasCancelled(); } diff --git a/common/src/main/java/revxrsal/commands/node/parser/BaseCommandRegistry.java b/common/src/main/java/revxrsal/commands/node/parser/BaseCommandRegistry.java index 0389026a..b27cbde2 100644 --- a/common/src/main/java/revxrsal/commands/node/parser/BaseCommandRegistry.java +++ b/common/src/main/java/revxrsal/commands/node/parser/BaseCommandRegistry.java @@ -50,6 +50,7 @@ import java.util.*; import java.util.function.Predicate; +import static revxrsal.commands.util.Collections.copyList; import static revxrsal.commands.util.Collections.unmodifiableIterator; import static revxrsal.commands.util.Reflections.getAllMethods; @@ -92,7 +93,7 @@ public List> register(@NotNull Class containerClass, Obj if (orphanPaths != null && !annotations.isEmpty()) { if (orphanPaths.isEmpty()) throw new IllegalArgumentException("Cannot have an OrphanCommand with no paths (supplied from .path())"); - String[] values = orphanPaths.toArray(String[]::new); + String[] values = orphanPaths.toArray(new String[0]); annotations = annotations.withAnnotations(false, new DynamicCommand(values)); } @@ -110,7 +111,7 @@ public List> register(@NotNull Class containerClass, Obj } } } - return List.copyOf(registered); + return copyList(registered); } private boolean isCommandMethod(AnnotationList annotations) { @@ -210,11 +211,36 @@ public void execute(@NotNull A actor, @NotNull StringStream input) { return unmodifiableIterator(children.iterator()); } - private record DynamicCommand(String[] value) implements Command { + private static final class DynamicCommand implements Command { + private final String[] value; + + private DynamicCommand(String[] value) {this.value = value;} @Override public Class annotationType() { return Command.class; } + + @Override public String[] value() {return value;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + DynamicCommand that = (DynamicCommand) obj; + return Objects.equals(this.value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash((Object) value); + } + + @Override + public String toString() { + return "DynamicCommand[" + + "value=" + Arrays.toString(value) + ']'; + } + } } diff --git a/common/src/main/java/revxrsal/commands/node/parser/Execution.java b/common/src/main/java/revxrsal/commands/node/parser/Execution.java index 0be18bcf..d87ca5a0 100644 --- a/common/src/main/java/revxrsal/commands/node/parser/Execution.java +++ b/common/src/main/java/revxrsal/commands/node/parser/Execution.java @@ -37,6 +37,7 @@ import revxrsal.commands.exception.context.ErrorContext; import revxrsal.commands.help.Help; import revxrsal.commands.node.*; +import revxrsal.commands.process.CommandCondition; import revxrsal.commands.stream.MutableStringStream; import java.util.*; @@ -58,8 +59,8 @@ final class Execution implements ExecutableCommand { private final String siblingPath; private final String path; private final boolean containsFlags; - private int optionalParameters, requiredInput; private final boolean lowPriority; + private int optionalParameters, requiredInput; public Execution(CommandFunction function, List> nodes) { this.function = function; @@ -81,7 +82,7 @@ public Execution(CommandFunction function, List> nodes) { this.priority = function.annotations() .mapOr(CommandPriority.class, c -> OptionalInt.of(c.value()), OptionalInt.empty()); this.siblingPath = computeSiblingPath(); - this.containsFlags = any(nodes, n -> n instanceof ParameterNode p && (p.isFlag() || p.isSwitch())); + this.containsFlags = any(nodes, n -> n instanceof ParameterNode && (((ParameterNode) n).isFlag() || ((ParameterNode) n).isSwitch())); this.lowPriority = function.annotations().contains(CommandPriority.Low.class); if (lowPriority && priority.isPresent()) { throw new IllegalArgumentException("You cannot have @CommandPriority and @CommandPriority.Low on the same function!"); @@ -96,8 +97,10 @@ private static boolean isOptional(@NotNull CommandNode n private @Unmodifiable Map> computeParameters() { Map> parameters = new LinkedHashMap<>(); for (CommandNode node : nodes) { - if (node instanceof ParameterNode parameter) + if (node instanceof ParameterNode) { + ParameterNode parameter = (ParameterNode) node; parameters.put(parameter.name(), parameter); + } } return unmodifiableMap(parameters); } @@ -190,7 +193,7 @@ public void unregister() { @SuppressWarnings({"rawtypes", "unchecked"}) @Override public void execute(@NotNull ExecutionContext context) { try { - for (var condition : context.lamp().commandConditions()) + for (CommandCondition condition : context.lamp().commandConditions()) condition.test((ExecutionContext) context); action().execute(context); } catch (Throwable t) { @@ -284,9 +287,10 @@ public String toString() { @Override public int compareTo(@NotNull ExecutableCommand o) { - if (!(o instanceof Execution exec)) { + if (!(o instanceof Execution)) { return 0; // Handle the case where o is not an instance of Execution } + Execution exec = (Execution) o; if (lowPriority != exec.lowPriority) { return lowPriority ? 1 : -1; } @@ -340,8 +344,10 @@ private boolean test() { } } for (CommandNode node : execution.nodes) { - if (node instanceof ParameterNode p && (p.isFlag() || p.isSwitch())) + if (node instanceof ParameterNode && (((ParameterNode) node).isFlag() || ((ParameterNode) node).isSwitch())) { + ParameterNode p = (ParameterNode) node; continue; + } if (!tryParse(node, input, context)) { context.clearResolvedArguments(); return false; @@ -369,7 +375,7 @@ private boolean tryParseFlags() { @SuppressWarnings({"rawtypes", "unchecked"}) private boolean testConditions() { try { - for (var condition : context.lamp().commandConditions()) { + for (CommandCondition condition : context.lamp().commandConditions()) { condition.test(((ExecutionContext) context)); } return true; @@ -438,7 +444,8 @@ private boolean tryParse( if (input.hasRemaining() && input.peek() == ' ') input.skipWhitespace(); int pos = input.position(); - if (node instanceof LiteralNodeImpl l) { + if (node instanceof LiteralNodeImpl) { + LiteralNodeImpl l = (LiteralNodeImpl) node; String value = input.readUnquotedString(); if (node.name().equalsIgnoreCase(value)) { checkForSpace(input); diff --git a/common/src/main/java/revxrsal/commands/node/parser/FunctionParameter.java b/common/src/main/java/revxrsal/commands/node/parser/FunctionParameter.java index b2dcd7d9..58eccb22 100644 --- a/common/src/main/java/revxrsal/commands/node/parser/FunctionParameter.java +++ b/common/src/main/java/revxrsal/commands/node/parser/FunctionParameter.java @@ -32,14 +32,28 @@ import java.lang.reflect.Parameter; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Objects; -record FunctionParameter( - @NotNull Parameter parameter, - @NotNull String name, - @NotNull AnnotationList annotations, - int methodIndex -) implements CommandParameter { +final class FunctionParameter implements CommandParameter { + private final @NotNull Parameter parameter; + private final @NotNull String name; + private final @NotNull AnnotationList annotations; + private final int methodIndex; + + FunctionParameter( + @NotNull Parameter parameter, + @NotNull String name, + @NotNull AnnotationList annotations, + int methodIndex + ) { + this.parameter = parameter; + this.name = name; + this.annotations = annotations; + this.methodIndex = methodIndex; + } @Override public boolean isLastInMethod() { @@ -65,8 +79,8 @@ public boolean isLastInMethod() { public @NotNull List generics() { Type type = parameter.getParameterizedType(); if (type instanceof ParameterizedType) - return List.of(((ParameterizedType) type).getActualTypeArguments()); - return List.of(); + return Arrays.asList(((ParameterizedType) type).getActualTypeArguments()); + return Collections.emptyList(); } @Override @@ -83,4 +97,38 @@ public boolean isOptional() { return length.min() == 0; return false; } + + @Override public @NotNull Parameter parameter() {return parameter;} + + @Override public @NotNull String name() {return name;} + + @Override public @NotNull AnnotationList annotations() {return annotations;} + + @Override public int methodIndex() {return methodIndex;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + FunctionParameter that = (FunctionParameter) obj; + return Objects.equals(this.parameter, that.parameter) && + Objects.equals(this.name, that.name) && + Objects.equals(this.annotations, that.annotations) && + this.methodIndex == that.methodIndex; + } + + @Override + public int hashCode() { + return Objects.hash(parameter, name, annotations, methodIndex); + } + + @Override + public String toString() { + return "FunctionParameter[" + + "parameter=" + parameter + ", " + + "name=" + name + ", " + + "annotations=" + annotations + ", " + + "methodIndex=" + methodIndex + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/node/parser/TreeParser.java b/common/src/main/java/revxrsal/commands/node/parser/TreeParser.java index 0df9bb9e..58b15364 100644 --- a/common/src/main/java/revxrsal/commands/node/parser/TreeParser.java +++ b/common/src/main/java/revxrsal/commands/node/parser/TreeParser.java @@ -198,9 +198,10 @@ private void pushNode(MutableCommandNode node) { } private void validateFlagName(MutableCommandNode node) { - if (!(node instanceof MutableParameterNode parameter)) { + if (!(node instanceof MutableParameterNode)) { return; } + MutableParameterNode parameter = (MutableParameterNode) node; Switch switchAnn = parameter.parameter().getAnnotation(Switch.class); Flag flag = parameter.parameter().getAnnotation(Flag.class); if (flag != null) @@ -245,12 +246,12 @@ private boolean isLiteral(@NotNull MutableCommandNode node) { } private boolean isOptional(MutableCommandNode node) { - return node instanceof MutableParameterNode p && p.isOptional(); + return node instanceof MutableParameterNode && ((MutableParameterNode) node).isOptional(); } private boolean isFlagOrSwitch(MutableCommandNode node) { - return node instanceof MutableParameterNode p && ( - p.parameter().hasAnnotation(Switch.class) || p.parameter().hasAnnotation(Flag.class) + return node instanceof MutableParameterNode && ( + ((MutableParameterNode) node).parameter().hasAnnotation(Switch.class) || ((MutableParameterNode) node).parameter().hasAnnotation(Flag.class) ); } diff --git a/common/src/main/java/revxrsal/commands/orphan/OrphanRegistry.java b/common/src/main/java/revxrsal/commands/orphan/OrphanRegistry.java index ac810d5e..b5367eb5 100644 --- a/common/src/main/java/revxrsal/commands/orphan/OrphanRegistry.java +++ b/common/src/main/java/revxrsal/commands/orphan/OrphanRegistry.java @@ -28,6 +28,7 @@ import revxrsal.commands.Lamp; import java.util.List; +import java.util.Objects; /** * Represents an orphan command that has finally found its parent path. @@ -37,5 +38,42 @@ *

* This should be constructed using {@link Orphans}'s methods. */ -public record OrphanRegistry(@NotNull @Unmodifiable List paths, @NotNull OrphanCommand handler) { +public final class OrphanRegistry { + private final @NotNull + @Unmodifiable List paths; + private final @NotNull OrphanCommand handler; + + /** + * + */ + public OrphanRegistry(@NotNull @Unmodifiable List paths, @NotNull OrphanCommand handler) { + this.paths = paths; + this.handler = handler; + } + + public @NotNull @Unmodifiable List paths() {return paths;} + + public @NotNull OrphanCommand handler() {return handler;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + OrphanRegistry that = (OrphanRegistry) obj; + return Objects.equals(this.paths, that.paths) && + Objects.equals(this.handler, that.handler); + } + + @Override + public int hashCode() { + return Objects.hash(paths, handler); + } + + @Override + public String toString() { + return "OrphanRegistry[" + + "paths=" + paths + ", " + + "handler=" + handler + ']'; + } + } \ No newline at end of file diff --git a/common/src/main/java/revxrsal/commands/orphan/Orphans.java b/common/src/main/java/revxrsal/commands/orphan/Orphans.java index 50f88f1e..155c4603 100644 --- a/common/src/main/java/revxrsal/commands/orphan/Orphans.java +++ b/common/src/main/java/revxrsal/commands/orphan/Orphans.java @@ -27,7 +27,9 @@ import revxrsal.commands.Lamp; import revxrsal.commands.annotation.Command; +import java.util.Arrays; import java.util.List; +import java.util.Objects; import static revxrsal.commands.util.Preconditions.notNull; @@ -54,7 +56,13 @@ * * @see OrphanCommand */ -public record Orphans(List paths) { +public final class Orphans { + private final List paths; + + /** + * + */ + public Orphans(List paths) {this.paths = paths;} /** * Starts the registration of an orphan command. The input for @@ -70,7 +78,7 @@ public record Orphans(List paths) { */ public static Orphans path(@NotNull String... paths) { notNull(paths, "paths"); - return new Orphans(List.of(paths)); + return new Orphans(Arrays.asList(paths)); } /** @@ -85,4 +93,26 @@ public OrphanRegistry handler(OrphanCommand handler) { notNull(handler, "orphan command"); return new OrphanRegistry(paths, handler); } + + public List paths() {return paths;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + Orphans that = (Orphans) obj; + return Objects.equals(this.paths, that.paths); + } + + @Override + public int hashCode() { + return Objects.hash(paths); + } + + @Override + public String toString() { + return "Orphans[" + + "paths=" + paths + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/parameter/ParameterTypes.java b/common/src/main/java/revxrsal/commands/parameter/ParameterTypes.java index c9130b02..b845fd26 100644 --- a/common/src/main/java/revxrsal/commands/parameter/ParameterTypes.java +++ b/common/src/main/java/revxrsal/commands/parameter/ParameterTypes.java @@ -40,6 +40,7 @@ import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.UUID; @@ -60,7 +61,7 @@ public final class ParameterTypes { * Highest priority factories. These come even before the user's * parameter types, but work in very specific conditions only. */ - private static final List HIGHEST_PRIORITY_FACTORIES = List.of( + private static final List HIGHEST_PRIORITY_FACTORIES = Arrays.asList( ParseWithParameterTypeFactory.INSTANCE ); @@ -70,7 +71,7 @@ public final class ParameterTypes { *

* These also will not be included in {@link #toBuilder()}. */ - private static final List DEFAULT_FACTORIES = List.of( + private static final List DEFAULT_FACTORIES = Arrays.asList( ArrayParameterTypeFactory.INSTANCE, ListParameterTypeFactory.INSTANCE, SetParameterTypeFactory.INSTANCE, diff --git a/common/src/main/java/revxrsal/commands/parameter/PrioritySpec.java b/common/src/main/java/revxrsal/commands/parameter/PrioritySpec.java index 82792bee..2309feac 100644 --- a/common/src/main/java/revxrsal/commands/parameter/PrioritySpec.java +++ b/common/src/main/java/revxrsal/commands/parameter/PrioritySpec.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Comparator; +import java.util.Objects; /** * Represents a priority specification for a certain {@link ParameterType}. @@ -51,10 +52,8 @@ * will suffice. *

* {@link PrioritySpec} can be created using {@link #toBuilder()}. - * - * @param comparator The underlying comparator of this priority specification. */ -public record PrioritySpec(Comparator> comparator) { +public final class PrioritySpec { /** * @see #defaultPriority() @@ -78,6 +77,12 @@ public record PrioritySpec(Comparator> comparator) { return 0; return -1; }); + private final Comparator> comparator; + + /** + * @param comparator The underlying comparator of this priority specification. + */ + public PrioritySpec(Comparator> comparator) {this.comparator = comparator;} /** * Creates a new {@link Builder} @@ -137,6 +142,28 @@ public record PrioritySpec(Comparator> comparator) { return new Builder(comparator); } + public Comparator> comparator() {return comparator;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + PrioritySpec that = (PrioritySpec) obj; + return Objects.equals(this.comparator, that.comparator); + } + + @Override + public int hashCode() { + return Objects.hash(comparator); + } + + @Override + public String toString() { + return "PrioritySpec[" + + "comparator=" + comparator + ']'; + } + + /** * A builder for creating a {@link PrioritySpec}. */ diff --git a/common/src/main/java/revxrsal/commands/parameter/builtins/ClassContextParameterFactory.java b/common/src/main/java/revxrsal/commands/parameter/builtins/ClassContextParameterFactory.java index b2790807..08f479a8 100644 --- a/common/src/main/java/revxrsal/commands/parameter/builtins/ClassContextParameterFactory.java +++ b/common/src/main/java/revxrsal/commands/parameter/builtins/ClassContextParameterFactory.java @@ -31,16 +31,17 @@ import revxrsal.commands.parameter.ContextParameter; import java.lang.reflect.Type; +import java.util.Objects; import static revxrsal.commands.util.Classes.getRawType; import static revxrsal.commands.util.Classes.wrap; @ApiStatus.Internal -public record ClassContextParameterFactory( - Class type, - ContextParameter parameterType, - boolean allowSubclasses -) implements ContextParameter.Factory { +public final class ClassContextParameterFactory implements ContextParameter.Factory { + private final Class type; + private final ContextParameter parameterType; + private final boolean allowSubclasses; + public ClassContextParameterFactory( Class type, @@ -72,4 +73,26 @@ public String toString() { "allowSubclasses=" + allowSubclasses + ']'; } + public Class type() {return type;} + + public ContextParameter parameterType() {return parameterType;} + + public boolean allowSubclasses() {return allowSubclasses;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + ClassContextParameterFactory that = (ClassContextParameterFactory) obj; + return Objects.equals(this.type, that.type) && + Objects.equals(this.parameterType, that.parameterType) && + this.allowSubclasses == that.allowSubclasses; + } + + @Override + public int hashCode() { + return Objects.hash(type, parameterType, allowSubclasses); + } + + } diff --git a/common/src/main/java/revxrsal/commands/parameter/builtins/ClassParameterTypeFactory.java b/common/src/main/java/revxrsal/commands/parameter/builtins/ClassParameterTypeFactory.java index 817e85a5..9d0623cf 100644 --- a/common/src/main/java/revxrsal/commands/parameter/builtins/ClassParameterTypeFactory.java +++ b/common/src/main/java/revxrsal/commands/parameter/builtins/ClassParameterTypeFactory.java @@ -29,19 +29,19 @@ import revxrsal.commands.annotation.list.AnnotationList; import revxrsal.commands.command.CommandActor; import revxrsal.commands.parameter.ParameterType; -import revxrsal.commands.util.Classes; import java.lang.reflect.Type; +import java.util.Objects; import static revxrsal.commands.util.Classes.getRawType; import static revxrsal.commands.util.Classes.wrap; @ApiStatus.Internal -public record ClassParameterTypeFactory( - Class type, - ParameterType parameterType, - boolean allowSubclasses -) implements ParameterType.Factory { +public final class ClassParameterTypeFactory implements ParameterType.Factory { + private final Class type; + private final ParameterType parameterType; + private final boolean allowSubclasses; + public ClassParameterTypeFactory(Class type, ParameterType parameterType, boolean allowSubclasses) { this.type = wrap(type); @@ -52,7 +52,7 @@ public ClassParameterTypeFactory(Class type, ParameterType parameterTyp @Override @SuppressWarnings("unchecked") public ParameterType create(@NotNull Type parameterType, @NotNull AnnotationList annotations, @NotNull Lamp lamp) { - Class pType = Classes.wrap(getRawType(parameterType)); + Class pType = wrap(getRawType(parameterType)); if (allowSubclasses && type.isAssignableFrom(pType)) { return (ParameterType) this.parameterType; } @@ -60,4 +60,34 @@ public ParameterType create(@NotNull Type parameterType, @NotNull Anno return (ParameterType) this.parameterType; return null; } + + public Class type() {return type;} + + public ParameterType parameterType() {return parameterType;} + + public boolean allowSubclasses() {return allowSubclasses;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + ClassParameterTypeFactory that = (ClassParameterTypeFactory) obj; + return Objects.equals(this.type, that.type) && + Objects.equals(this.parameterType, that.parameterType) && + this.allowSubclasses == that.allowSubclasses; + } + + @Override + public int hashCode() { + return Objects.hash(type, parameterType, allowSubclasses); + } + + @Override + public String toString() { + return "ClassParameterTypeFactory[" + + "type=" + type + ", " + + "parameterType=" + parameterType + ", " + + "allowSubclasses=" + allowSubclasses + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/parameter/builtins/CollectionParameterTypeFactory.java b/common/src/main/java/revxrsal/commands/parameter/builtins/CollectionParameterTypeFactory.java index b889ca68..f09b8021 100644 --- a/common/src/main/java/revxrsal/commands/parameter/builtins/CollectionParameterTypeFactory.java +++ b/common/src/main/java/revxrsal/commands/parameter/builtins/CollectionParameterTypeFactory.java @@ -42,6 +42,7 @@ import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static revxrsal.commands.autocomplete.SuggestionProvider.empty; @@ -137,7 +138,7 @@ public Object parse(@NotNull MutableStringStream input, @NotNull ExecutionContex if (paramSuggestions.equals(empty())) return empty(); return (context) -> { - List inputted = List.of(context.input().peekRemaining().split(Character.toString(delimiter))); + List inputted = Arrays.asList(context.input().peekRemaining().split(Character.toString(delimiter))); if (preventsDuplicates()) { return filter( paramSuggestions.getSuggestions(context), diff --git a/common/src/main/java/revxrsal/commands/parameter/builtins/EnumParameterTypeFactory.java b/common/src/main/java/revxrsal/commands/parameter/builtins/EnumParameterTypeFactory.java index e16f7b11..3ec29e7f 100644 --- a/common/src/main/java/revxrsal/commands/parameter/builtins/EnumParameterTypeFactory.java +++ b/common/src/main/java/revxrsal/commands/parameter/builtins/EnumParameterTypeFactory.java @@ -36,10 +36,7 @@ import revxrsal.commands.stream.MutableStringStream; import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import static revxrsal.commands.util.Classes.getRawType; @@ -64,10 +61,17 @@ public ParameterType create(@NotNull Type parameterType, @N return new EnumParameterType(byKeys, suggestions); } - private record EnumParameterType>( - Map byKeys, - List suggestions - ) implements ParameterType { + private static final class EnumParameterType> implements ParameterType { + private final Map byKeys; + private final List suggestions; + + private EnumParameterType( + Map byKeys, + List suggestions + ) { + this.byKeys = byKeys; + this.suggestions = suggestions; + } @Override public E parse(@NotNull MutableStringStream input, @NotNull ExecutionContext context) { @@ -86,5 +90,31 @@ public E parse(@NotNull MutableStringStream input, @NotNull ExecutionContext byKeys() {return byKeys;} + + public List suggestions() {return suggestions;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + EnumParameterType that = (EnumParameterType) obj; + return Objects.equals(this.byKeys, that.byKeys) && + Objects.equals(this.suggestions, that.suggestions); + } + + @Override + public int hashCode() { + return Objects.hash(byKeys, suggestions); + } + + @Override + public String toString() { + return "EnumParameterType[" + + "byKeys=" + byKeys + ", " + + "suggestions=" + suggestions + ']'; + } + } } diff --git a/common/src/main/java/revxrsal/commands/parameter/builtins/ParseWithParameterTypeFactory.java b/common/src/main/java/revxrsal/commands/parameter/builtins/ParseWithParameterTypeFactory.java index bdbd5b16..6ee3ebbf 100644 --- a/common/src/main/java/revxrsal/commands/parameter/builtins/ParseWithParameterTypeFactory.java +++ b/common/src/main/java/revxrsal/commands/parameter/builtins/ParseWithParameterTypeFactory.java @@ -45,9 +45,11 @@ public enum ParseWithParameterTypeFactory implements ParameterType.Factory pType) { + if (type instanceof ParameterType) { + ParameterType pType = (ParameterType) type; return (ParameterType) pType; - } else if (type instanceof ParameterType.Factory factory) { + } else if (type instanceof ParameterType.Factory) { + ParameterType.Factory factory = (ParameterType.Factory) type; return factory.create(parameterType, annotations, (Lamp) lamp); } else { throw new IllegalArgumentException("Don't know how to create a ParameterType from " + type); diff --git a/common/src/main/java/revxrsal/commands/parameter/builtins/SenderContextParameter.java b/common/src/main/java/revxrsal/commands/parameter/builtins/SenderContextParameter.java index 715895d0..d65064ef 100644 --- a/common/src/main/java/revxrsal/commands/parameter/builtins/SenderContextParameter.java +++ b/common/src/main/java/revxrsal/commands/parameter/builtins/SenderContextParameter.java @@ -30,11 +30,16 @@ import revxrsal.commands.parameter.ContextParameter; import revxrsal.commands.process.SenderResolver; +import java.util.Objects; + import static revxrsal.commands.util.Preconditions.notNull; -public record SenderContextParameter( - SenderResolver resolver -) implements ContextParameter { +public final class SenderContextParameter implements ContextParameter { + private final SenderResolver resolver; + + public SenderContextParameter( + SenderResolver resolver + ) {this.resolver = resolver;} @Override public T resolve(@NotNull CommandParameter parameter, @NotNull ExecutionContext context) { @@ -44,4 +49,26 @@ public T resolve(@NotNull CommandParameter parameter, @NotNull ExecutionContext< //noinspection unchecked return (T) sender; } + + public SenderResolver resolver() {return resolver;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + SenderContextParameter that = (SenderContextParameter) obj; + return Objects.equals(this.resolver, that.resolver); + } + + @Override + public int hashCode() { + return Objects.hash(resolver); + } + + @Override + public String toString() { + return "SenderContextParameter[" + + "resolver=" + resolver + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/reflect/ktx/CallableMethod.java b/common/src/main/java/revxrsal/commands/reflect/ktx/CallableMethod.java index a51b8428..1bd7602e 100644 --- a/common/src/main/java/revxrsal/commands/reflect/ktx/CallableMethod.java +++ b/common/src/main/java/revxrsal/commands/reflect/ktx/CallableMethod.java @@ -27,6 +27,7 @@ import revxrsal.commands.reflect.MethodCaller; import java.lang.reflect.Method; +import java.util.Objects; /** * A utility class that combines a {@link Method} with a {@link MethodCaller}. @@ -34,8 +35,44 @@ * This class is immutable, therefore is safe to share across multiple * threads. */ -public record CallableMethod( - @NotNull Method method, - @NotNull MethodCaller caller -) { +public final class CallableMethod { + private final @NotNull Method method; + private final @NotNull MethodCaller caller; + + /** + * + */ + public CallableMethod( + @NotNull Method method, + @NotNull MethodCaller caller + ) { + this.method = method; + this.caller = caller; + } + + public @NotNull Method method() {return method;} + + public @NotNull MethodCaller caller() {return caller;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + CallableMethod that = (CallableMethod) obj; + return Objects.equals(this.method, that.method) && + Objects.equals(this.caller, that.caller); + } + + @Override + public int hashCode() { + return Objects.hash(method, caller); + } + + @Override + public String toString() { + return "CallableMethod[" + + "method=" + method + ", " + + "caller=" + caller + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/reflect/ktx/KotlinFunctionImpl.java b/common/src/main/java/revxrsal/commands/reflect/ktx/KotlinFunctionImpl.java index c16b9b72..9dbec57a 100644 --- a/common/src/main/java/revxrsal/commands/reflect/ktx/KotlinFunctionImpl.java +++ b/common/src/main/java/revxrsal/commands/reflect/ktx/KotlinFunctionImpl.java @@ -40,7 +40,8 @@ import static revxrsal.commands.reflect.ktx.KotlinConstants.continuation; import static revxrsal.commands.reflect.ktx.KotlinConstants.defaultPrimitiveValue; import static revxrsal.commands.reflect.ktx.KotlinSingletons.getCallerForNonDefault; -import static revxrsal.commands.util.Collections.*; +import static revxrsal.commands.util.Collections.getOrNull; +import static revxrsal.commands.util.Collections.mapKeys; import static revxrsal.commands.util.Lazy.of; final class KotlinFunctionImpl implements KotlinFunction { @@ -170,13 +171,11 @@ else if (isOptional.apply(parameter)) { if (mainMethod.method().getParameterCount() == args.size()) //noinspection unchecked return (T) mainMethod.caller().call(instance, args.toArray()); - throw new IllegalArgumentException(""" - Unable to invoke function with default parameters.\s - This may happen because you have an @Optional non-null primitive type (e.g. Int) \ - with no default value using @Default or a Kotlin-default value. - It may also occur if you have @Switch with no default value. (@Switch param: Boolean = ...) - Either mark it as nullable, add a default value (@Optional param: Type = ...), or use @Default""" - ); + throw new IllegalArgumentException("Unable to invoke function with default parameters. " + + "This may happen because you have an @Optional non-null primitive type (e.g. Int) " + + "with no default value using @Default or a Kotlin-default value. " + + "It may also occur if you have @Switch with no default value. (@Switch param: Boolean = ...). " + + "Either mark it as nullable, add a default value (@Optional param: Type = ...), or use @Default"); } masks.add(mask); diff --git a/common/src/main/java/revxrsal/commands/response/ClassResponseHandlerFactory.java b/common/src/main/java/revxrsal/commands/response/ClassResponseHandlerFactory.java index 50da65fc..2055c604 100644 --- a/common/src/main/java/revxrsal/commands/response/ClassResponseHandlerFactory.java +++ b/common/src/main/java/revxrsal/commands/response/ClassResponseHandlerFactory.java @@ -30,16 +30,17 @@ import revxrsal.commands.command.CommandActor; import java.lang.reflect.Type; +import java.util.Objects; import static revxrsal.commands.util.Classes.getRawType; import static revxrsal.commands.util.Classes.wrap; @ApiStatus.Internal -public record ClassResponseHandlerFactory( - Class type, - ResponseHandler responseHandler, - boolean allowSubclasses -) implements ResponseHandler.Factory { +public final class ClassResponseHandlerFactory implements ResponseHandler.Factory { + private final Class type; + private final ResponseHandler responseHandler; + private final boolean allowSubclasses; + public ClassResponseHandlerFactory(Class type, ResponseHandler responseHandler, boolean allowSubclasses) { this.type = wrap(type); @@ -58,4 +59,34 @@ public ResponseHandler create(@NotNull Type parameterType, @NotNull An return (ResponseHandler) this.responseHandler; return null; } + + public Class type() {return type;} + + public ResponseHandler responseHandler() {return responseHandler;} + + public boolean allowSubclasses() {return allowSubclasses;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + ClassResponseHandlerFactory that = (ClassResponseHandlerFactory) obj; + return Objects.equals(this.type, that.type) && + Objects.equals(this.responseHandler, that.responseHandler) && + this.allowSubclasses == that.allowSubclasses; + } + + @Override + public int hashCode() { + return Objects.hash(type, responseHandler, allowSubclasses); + } + + @Override + public String toString() { + return "ClassResponseHandlerFactory[" + + "type=" + type + ", " + + "responseHandler=" + responseHandler + ", " + + "allowSubclasses=" + allowSubclasses + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/stream/MutableStringStreamImpl.java b/common/src/main/java/revxrsal/commands/stream/MutableStringStreamImpl.java index 5b3cf94a..051d6295 100644 --- a/common/src/main/java/revxrsal/commands/stream/MutableStringStreamImpl.java +++ b/common/src/main/java/revxrsal/commands/stream/MutableStringStreamImpl.java @@ -186,13 +186,17 @@ public byte readByte() { public boolean readBoolean() { String value = readString(); - return switch (value.toLowerCase(Locale.ENGLISH)) { - case "true", "yes" -> true; - case "false", "no", "nope" -> false; - default -> { + switch (value.toLowerCase(Locale.ENGLISH)) { + case "true": + case "yes": + return true; + case "false": + case "no": + case "nope": + return false; + default: throw new InvalidBooleanException(value); - } - }; + } } public void setPosition(int pos) { diff --git a/common/src/main/java/revxrsal/commands/stream/token/LiteralToken.java b/common/src/main/java/revxrsal/commands/stream/token/LiteralToken.java index 82854696..b989af20 100644 --- a/common/src/main/java/revxrsal/commands/stream/token/LiteralToken.java +++ b/common/src/main/java/revxrsal/commands/stream/token/LiteralToken.java @@ -23,5 +23,32 @@ */ package revxrsal.commands.stream.token; -public record LiteralToken(String value) implements Token { +import java.util.Objects; + +public final class LiteralToken implements Token { + private final String value; + + public LiteralToken(String value) {this.value = value;} + + public String value() {return value;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + LiteralToken that = (LiteralToken) obj; + return Objects.equals(this.value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return "LiteralToken[" + + "value=" + value + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/stream/token/ParameterToken.java b/common/src/main/java/revxrsal/commands/stream/token/ParameterToken.java index 2f6e02ec..5d9538ab 100644 --- a/common/src/main/java/revxrsal/commands/stream/token/ParameterToken.java +++ b/common/src/main/java/revxrsal/commands/stream/token/ParameterToken.java @@ -23,5 +23,32 @@ */ package revxrsal.commands.stream.token; -public record ParameterToken(String name) implements Token { +import java.util.Objects; + +public final class ParameterToken implements Token { + private final String name; + + public ParameterToken(String name) {this.name = name;} + + public String name() {return name;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + ParameterToken that = (ParameterToken) obj; + return Objects.equals(this.name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @Override + public String toString() { + return "ParameterToken[" + + "name=" + name + ']'; + } + } diff --git a/common/src/main/java/revxrsal/commands/util/BuiltInNamingStrategies.java b/common/src/main/java/revxrsal/commands/util/BuiltInNamingStrategies.java index 0ce7081c..d5f727eb 100644 --- a/common/src/main/java/revxrsal/commands/util/BuiltInNamingStrategies.java +++ b/common/src/main/java/revxrsal/commands/util/BuiltInNamingStrategies.java @@ -36,7 +36,7 @@ public static String separateCamelCase(String name, String separator) { StringBuilder translation = new StringBuilder(); for (int i = 0; i < name.length(); i++) { char character = name.charAt(i); - if (Character.isUpperCase(character) && !translation.isEmpty()) { + if (Character.isUpperCase(character) && translation.length() != 0) { translation.append(separator); } translation.append(character); diff --git a/common/src/main/java/revxrsal/commands/util/Classes.java b/common/src/main/java/revxrsal/commands/util/Classes.java index b1720e9a..f72b3145 100644 --- a/common/src/main/java/revxrsal/commands/util/Classes.java +++ b/common/src/main/java/revxrsal/commands/util/Classes.java @@ -153,7 +153,8 @@ public static Class getRawType(Type type) { // type is a normal class. return (Class) type; - } else if (type instanceof ParameterizedType parameterizedType) { + } else if (type instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) type; // I'm not exactly sure why getRawType() returns Type instead of Class. // Neal isn't either but suspects some pathological case related diff --git a/common/src/main/java/revxrsal/commands/util/Collections.java b/common/src/main/java/revxrsal/commands/util/Collections.java index a32ca1bf..d4b3fdc4 100644 --- a/common/src/main/java/revxrsal/commands/util/Collections.java +++ b/common/src/main/java/revxrsal/commands/util/Collections.java @@ -169,6 +169,23 @@ public static boolean any(@NotNull Iterable iterator, Predicate predic return new UnmodifiableIterator<>(iterator); } + @Contract("_ -> new") + @CheckReturnValue + @Unmodifiable + public static @NotNull Map copyMap(@NotNull Map map) { + if (map instanceof LinkedHashMap) { + return java.util.Collections.unmodifiableMap(new LinkedHashMap<>(map)); + } + return java.util.Collections.unmodifiableMap(new HashMap<>(map)); + } + + @Contract("_ -> new") + @CheckReturnValue + @Unmodifiable + public static @NotNull List copyList(@NotNull Collection list) { + return java.util.Collections.unmodifiableList(new ArrayList<>(list)); + } + /** * UnmodifiableIterator, A wrapper around an iterator instance that * disables the remove method. diff --git a/common/src/main/java/revxrsal/commands/util/CommandPaths.java b/common/src/main/java/revxrsal/commands/util/CommandPaths.java index 03154dd5..0a0b1f6f 100644 --- a/common/src/main/java/revxrsal/commands/util/CommandPaths.java +++ b/common/src/main/java/revxrsal/commands/util/CommandPaths.java @@ -58,7 +58,7 @@ private CommandPaths() { List parentSubcommandAliases = new ArrayList<>(); for (Class topClass : getTopClasses(container)) { - var annotations = AnnotationList.create(topClass) + AnnotationList annotations = AnnotationList.create(topClass) .replaceAnnotations(topClass, function.lamp().annotationReplacers()); Subcommand ps = annotations.get(Subcommand.class); if (ps != null) { diff --git a/common/src/main/java/revxrsal/commands/util/InstanceCreator.java b/common/src/main/java/revxrsal/commands/util/InstanceCreator.java index e3cce2f1..d0957be7 100644 --- a/common/src/main/java/revxrsal/commands/util/InstanceCreator.java +++ b/common/src/main/java/revxrsal/commands/util/InstanceCreator.java @@ -45,8 +45,8 @@ private InstanceCreator() { public static @NotNull T create(@NotNull Class type) { if (type.isAnnotation()) throw new IllegalArgumentException("Cannot construct annotation types"); - if (type.isRecord()) - throw new IllegalArgumentException("Cannot construct record types"); +// if (type.isRecord()) +// throw new IllegalArgumentException("Cannot construct record types"); if (type.isArray()) return (T) Array.newInstance(type, 0); if (type.isEnum()) @@ -73,7 +73,7 @@ private InstanceCreator() { private static @Nullable T fromNoArgConstructor(Class type) { try { Constructor constructor = type.getDeclaredConstructor(); - constructor.trySetAccessible(); + constructor.setAccessible(true); return constructor.newInstance(); } catch (ReflectiveOperationException e) { return null; @@ -89,7 +89,7 @@ private static T fromGetter(Class type) { continue; if (method.getParameterCount() != 0) continue; - method.trySetAccessible(); + method.setAccessible(true); try { return (T) method.invoke(null); } catch (IllegalAccessException | InvocationTargetException e) { @@ -99,7 +99,8 @@ private static T fromGetter(Class type) { return null; } - private static @NotNull > T firstEnum(Class type) { + @SuppressWarnings("rawtypes") + private static @NotNull T firstEnum(Class type) { T[] values = type.getEnumConstants(); if (values.length == 0) throw new IllegalArgumentException("Attempted to construct an enum that has no fields"); @@ -113,7 +114,7 @@ private static T fromGetter(Class type) { continue; if (!isStatic(field.getModifiers())) continue; - field.trySetAccessible(); + field.setAccessible(true); try { return (T) field.get(null); } catch (IllegalAccessException e) { diff --git a/common/src/main/java/revxrsal/commands/util/StackTraceSanitizer.java b/common/src/main/java/revxrsal/commands/util/StackTraceSanitizer.java index cf23871d..6dfdacb7 100644 --- a/common/src/main/java/revxrsal/commands/util/StackTraceSanitizer.java +++ b/common/src/main/java/revxrsal/commands/util/StackTraceSanitizer.java @@ -36,6 +36,7 @@ import java.util.function.Predicate; import static java.util.Collections.emptyList; +import static revxrsal.commands.util.Collections.copyList; /** * A utility for stripping stacktrace from local paths to classes. This helps @@ -187,7 +188,7 @@ public Builder ignoreNativeMethods() { * @return The newly created sanitizer */ public StackTraceSanitizer build() { - return new StackTraceSanitizer(List.copyOf(filters)); + return new StackTraceSanitizer(copyList(filters)); } } diff --git a/common/src/main/java/revxrsal/commands/util/Strings.java b/common/src/main/java/revxrsal/commands/util/Strings.java index 30a01a6e..8615d6cb 100644 --- a/common/src/main/java/revxrsal/commands/util/Strings.java +++ b/common/src/main/java/revxrsal/commands/util/Strings.java @@ -30,6 +30,7 @@ import java.util.Comparator; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -108,6 +109,39 @@ public static Optional getOverriddenName(@NotNull AnnotationList paramet return builder.toString(); } - public record StringRange(int start, int end) {} + public static final class StringRange { + private final int start; + private final int end; + + public StringRange(int start, int end) { + this.start = start; + this.end = end; + } + + public int start() {return start;} + + public int end() {return end;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + StringRange that = (StringRange) obj; + return this.start == that.start && + this.end == that.end; + } + + @Override + public int hashCode() { + return Objects.hash(start, end); + } + + @Override + public String toString() { + return "StringRange[" + + "start=" + start + ", " + + "end=" + end + ']'; + } + } } diff --git a/examples/bukkit-plugin/src/main/java/com/example/plugin/TestPlugin.java b/examples/bukkit-plugin/src/main/java/com/example/plugin/TestPlugin.java index f5a939b9..ab6ce6e1 100644 --- a/examples/bukkit-plugin/src/main/java/com/example/plugin/TestPlugin.java +++ b/examples/bukkit-plugin/src/main/java/com/example/plugin/TestPlugin.java @@ -1,13 +1,15 @@ package com.example.plugin; import org.bukkit.plugin.java.JavaPlugin; +import revxrsal.commands.Lamp; import revxrsal.commands.bukkit.BukkitLamp; +import revxrsal.commands.bukkit.actor.BukkitCommandActor; public final class TestPlugin extends JavaPlugin { @Override public void onEnable() { - var lamp = BukkitLamp.builder(this).build(); + Lamp lamp = BukkitLamp.builder(this).build(); lamp.register(new GreetCommands()); } } \ No newline at end of file diff --git a/examples/cli-app/build.gradle.kts b/examples/cli-app/build.gradle.kts index 4a478b69..7a6f884a 100644 --- a/examples/cli-app/build.gradle.kts +++ b/examples/cli-app/build.gradle.kts @@ -19,7 +19,3 @@ tasks.withType { // Preserve parameter names in the bytecode options.compilerArgs.add("-parameters") } - -kotlin { - jvmToolchain(17) -} \ No newline at end of file diff --git a/examples/cli-app/src/main/java/com/example/cli/CLIApp.java b/examples/cli-app/src/main/java/com/example/cli/CLIApp.java index 59ea00cc..4cba4528 100644 --- a/examples/cli-app/src/main/java/com/example/cli/CLIApp.java +++ b/examples/cli-app/src/main/java/com/example/cli/CLIApp.java @@ -23,7 +23,10 @@ */ package com.example.cli; +import revxrsal.commands.Lamp; import revxrsal.commands.annotation.Command; +import revxrsal.commands.annotation.CommandPriority; +import revxrsal.commands.annotation.Subcommand; import revxrsal.commands.cli.CLILamp; import revxrsal.commands.cli.ConsoleActor; @@ -32,9 +35,10 @@ public final class CLIApp { public static void main(String[] args) { - var lamp = CLILamp.builder() + Lamp lamp = CLILamp.builder() .build(); lamp.register(new PingCommand()); + System.out.println(lamp.registry().commands()); /* register all other commands here */ // Call this to continuously read input from the console @@ -47,8 +51,14 @@ public static void main(String[] args) { static class PingCommand { @Command("ping") + @CommandPriority.Low public void ping(ConsoleActor actor) { actor.reply("Pong"); } + + @Command("ping help") + public void pingHelp(ConsoleActor actor) { + ping(actor); + } } } diff --git a/examples/jda-bot/src/main/java/com/example/bot/SimpleBot.java b/examples/jda-bot/src/main/java/com/example/bot/SimpleBot.java index a1e03b42..0106b1a0 100644 --- a/examples/jda-bot/src/main/java/com/example/bot/SimpleBot.java +++ b/examples/jda-bot/src/main/java/com/example/bot/SimpleBot.java @@ -25,7 +25,9 @@ import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; +import revxrsal.commands.Lamp; import revxrsal.commands.jda.JDALamp; +import revxrsal.commands.jda.actor.SlashCommandActor; import static revxrsal.commands.jda.JDAVisitors.slashCommands; @@ -33,7 +35,7 @@ public class SimpleBot { public static void main(String[] args) { JDA jda = JDABuilder.createDefault(args[0]).build(); - var lamp = JDALamp.builder().build(); + Lamp lamp = JDALamp.builder().build(); // register all our commands here lamp.register(new PunishmentCommands()); diff --git a/fabric/src/main/java/revxrsal/commands/fabric/actor/BasicActorFactory.java b/fabric/src/main/java/revxrsal/commands/fabric/actor/BasicActorFactory.java index c1729d4a..bb133035 100644 --- a/fabric/src/main/java/revxrsal/commands/fabric/actor/BasicActorFactory.java +++ b/fabric/src/main/java/revxrsal/commands/fabric/actor/BasicActorFactory.java @@ -29,21 +29,59 @@ import revxrsal.commands.Lamp; import revxrsal.commands.process.MessageSender; +import java.util.Objects; + /** * Default implementation of {@link ActorFactory} */ -record BasicActorFactory( - MessageSender messageSender, - MessageSender errorSender -) implements ActorFactory { +final class BasicActorFactory implements ActorFactory { public static final ActorFactory INSTANCE = new BasicActorFactory( FabricCommandActor::sendRawMessage, FabricCommandActor::sendRawError ); + private final MessageSender messageSender; + private final MessageSender errorSender; + + /** + * + */ + BasicActorFactory( + MessageSender messageSender, + MessageSender errorSender + ) { + this.messageSender = messageSender; + this.errorSender = errorSender; + } @Override public @NotNull FabricCommandActor create(@NotNull ServerCommandSource sender, @NotNull Lamp lamp) { return new BasicFabricActor(sender, lamp, messageSender, errorSender); } + + public MessageSender messageSender() {return messageSender;} + + public MessageSender errorSender() {return errorSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (BasicActorFactory) obj; + return Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.errorSender, that.errorSender); + } + + @Override + public int hashCode() { + return Objects.hash(messageSender, errorSender); + } + + @Override + public String toString() { + return "BasicActorFactory[" + + "messageSender=" + messageSender + ", " + + "errorSender=" + errorSender + ']'; + } + } diff --git a/fabric/src/main/java/revxrsal/commands/fabric/actor/BasicFabricActor.java b/fabric/src/main/java/revxrsal/commands/fabric/actor/BasicFabricActor.java index 83c8193d..ada652a6 100644 --- a/fabric/src/main/java/revxrsal/commands/fabric/actor/BasicFabricActor.java +++ b/fabric/src/main/java/revxrsal/commands/fabric/actor/BasicFabricActor.java @@ -7,16 +7,28 @@ import revxrsal.commands.process.MessageSender; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.UUID; -record BasicFabricActor( - ServerCommandSource sender, - Lamp lamp, - MessageSender messageSender, - MessageSender errorSender -) implements FabricCommandActor { +final class BasicFabricActor implements FabricCommandActor { private static final UUID CONSOLE_UUID = new UUID(0, 0); + private final ServerCommandSource sender; + private final Lamp lamp; + private final MessageSender messageSender; + private final MessageSender errorSender; + + BasicFabricActor( + ServerCommandSource sender, + Lamp lamp, + MessageSender messageSender, + MessageSender errorSender + ) { + this.sender = sender; + this.lamp = lamp; + this.messageSender = messageSender; + this.errorSender = errorSender; + } @Override public @NotNull ServerCommandSource source() { return sender; @@ -42,4 +54,36 @@ else if (isConsole()) @Override public Lamp lamp() { return lamp; } + + public ServerCommandSource sender() {return sender;} + + public MessageSender messageSender() {return messageSender;} + + public MessageSender errorSender() {return errorSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (BasicFabricActor) obj; + return Objects.equals(this.sender, that.sender) && + Objects.equals(this.lamp, that.lamp) && + Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.errorSender, that.errorSender); + } + + @Override + public int hashCode() { + return Objects.hash(sender, lamp, messageSender, errorSender); + } + + @Override + public String toString() { + return "BasicFabricActor[" + + "sender=" + sender + ", " + + "lamp=" + lamp + ", " + + "messageSender=" + messageSender + ", " + + "errorSender=" + errorSender + ']'; + } + } \ No newline at end of file diff --git a/fabric/src/main/java/revxrsal/commands/fabric/exception/FabricExceptionHandler.java b/fabric/src/main/java/revxrsal/commands/fabric/exception/FabricExceptionHandler.java index 449c65da..43150d87 100644 --- a/fabric/src/main/java/revxrsal/commands/fabric/exception/FabricExceptionHandler.java +++ b/fabric/src/main/java/revxrsal/commands/fabric/exception/FabricExceptionHandler.java @@ -39,11 +39,15 @@ public void onSenderNotConsole(SenderNotConsoleException e, FabricCommandActor a @Override public void onInputParse(@NotNull InputParseException e, @NotNull FabricCommandActor actor) { switch (e.cause()) { - case INVALID_ESCAPE_CHARACTER -> - actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); - case UNCLOSED_QUOTE -> actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); - case EXPECTED_WHITESPACE -> - actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + case INVALID_ESCAPE_CHARACTER: + actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); + break; + case UNCLOSED_QUOTE: + actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); + break; + case EXPECTED_WHITESPACE: + actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + break; } } diff --git a/fabric/src/main/java/revxrsal/commands/fabric/parameters/PlayerParameterType.java b/fabric/src/main/java/revxrsal/commands/fabric/parameters/PlayerParameterType.java index 7f98e225..c0be5f82 100644 --- a/fabric/src/main/java/revxrsal/commands/fabric/parameters/PlayerParameterType.java +++ b/fabric/src/main/java/revxrsal/commands/fabric/parameters/PlayerParameterType.java @@ -33,7 +33,7 @@ import revxrsal.commands.parameter.ParameterType; import revxrsal.commands.stream.MutableStringStream; -import java.util.List; +import java.util.Arrays; /** * A parameter type for {@link ServerPlayerEntity} types. @@ -58,7 +58,7 @@ public ServerPlayerEntity parse(@NotNull MutableStringStream input, @NotNull Exe @Override public @NotNull SuggestionProvider defaultSuggestions() { return (context) -> { MinecraftServer server = context.actor().source().getServer(); - return List.of(server.getPlayerManager().getPlayerNames()); + return Arrays.asList(server.getPlayerManager().getPlayerNames()); }; } } diff --git a/fabric/src/main/java/revxrsal/commands/fabric/parameters/WorldParameterType.java b/fabric/src/main/java/revxrsal/commands/fabric/parameters/WorldParameterType.java index 9795cbec..c4952209 100644 --- a/fabric/src/main/java/revxrsal/commands/fabric/parameters/WorldParameterType.java +++ b/fabric/src/main/java/revxrsal/commands/fabric/parameters/WorldParameterType.java @@ -36,7 +36,7 @@ import revxrsal.commands.parameter.ParameterType; import revxrsal.commands.stream.MutableStringStream; -import java.util.List; +import java.util.Arrays; /** * A parameter type for {@link ServerPlayerEntity} types. @@ -70,7 +70,7 @@ public World parse(@NotNull MutableStringStream input, @NotNull ExecutionContext @Override public @NotNull SuggestionProvider defaultSuggestions() { return (context) -> { MinecraftServer server = context.actor().source().getServer(); - return List.of(server.getPlayerManager().getPlayerNames()); + return Arrays.asList(server.getPlayerManager().getPlayerNames()); }; } } diff --git a/internal-paper-stubs/README.md b/internal-paper-stubs/README.md index 167e1e2c..083d7f56 100644 --- a/internal-paper-stubs/README.md +++ b/internal-paper-stubs/README.md @@ -1,10 +1,14 @@ # Paper stubs ## What is this? -This simply contains definitions for classes and methods in the Paper API. _Only definitions_. We don't include any implementations here, and any non-abstract functions throw exceptions. -This is simply to provide resolvable classes at compile-time, without having to depend on Paper's dependency directly, because it requires Java 21. +This simply contains definitions for classes and methods in the Paper API. _Only definitions_. We don't include any +implementations here, and any non-abstract functions throw exceptions. -Even then, these stubs are not 100% equal to Paper's. They have been modified a little to avoid compiler errors and Javadoc problems. +This is simply to provide resolvable classes at compile-time, without having to depend on Paper's dependency directly, +because it requires Java 21. + +Even then, these stubs are not 100% equal to Paper's. They have been modified a little to avoid compiler errors and +Javadoc problems. This is internal and is not intended for public use. It may change or get removed without notice. \ No newline at end of file diff --git a/internal-paper-stubs/build.gradle.kts b/internal-paper-stubs/build.gradle.kts index eccf3263..bab846d9 100644 --- a/internal-paper-stubs/build.gradle.kts +++ b/internal-paper-stubs/build.gradle.kts @@ -12,6 +12,5 @@ repositories { dependencies { compileOnly("org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT") compileOnly("com.mojang:brigadier:1.0.18") + compileOnly("net.kyori:adventure-api:4.14.0") } - -java.toolchain.languageVersion.set(JavaLanguageVersion.of(17)) \ No newline at end of file diff --git a/internal-paper-stubs/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java b/internal-paper-stubs/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java new file mode 100644 index 00000000..b1353b5b --- /dev/null +++ b/internal-paper-stubs/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java @@ -0,0 +1,135 @@ +package com.destroystokyo.paper.event.brigadier; + +import com.mojang.brigadier.tree.ArgumentCommandNode; +import com.mojang.brigadier.tree.LiteralCommandNode; +import com.mojang.brigadier.tree.RootCommandNode; +import org.bukkit.command.Command; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.server.ServerEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * Fired anytime the server synchronizes Bukkit commands to Brigadier. + * + *

Allows a plugin to control the command node structure for its commands. + * This is done at Plugin Enable time after commands have been registered, but may also + * run at a later point in the server lifetime due to plugins, a server reload, etc.

+ * + *

This is a draft/experimental API and is subject to change.

+ */ +@ApiStatus.Experimental +public class CommandRegisteredEvent extends ServerEvent implements Cancellable { + + @NotNull + public static HandlerList getHandlerList() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets the command label of the {@link Command} being registered. + * + * @return the command label + */ + public String getCommandLabel() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets the {@link Command} being registered. + * + * @return the {@link Command} + */ + public Command getCommand() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets the {@link RootCommandNode} which is being registered to. + * + * @return the {@link RootCommandNode} + */ + public RootCommandNode getRoot() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets the Bukkit APIs default arguments node (greedy string), for if + * you wish to reuse it. + * + * @return default arguments node + */ + public ArgumentCommandNode getDefaultArgs() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets the {@link LiteralCommandNode} to be registered for the {@link Command}. + * + * @return the {@link LiteralCommandNode} + */ + public LiteralCommandNode getLiteral() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Sets the {@link LiteralCommandNode} used to register this command. The default literal is mutable, so + * this is primarily if you want to completely replace the object. + * + * @param literal new node + */ + public void setLiteral(LiteralCommandNode literal) { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets whether this command should is treated as "raw". + * + * @return whether this command is treated as "raw" + * @see #setRawCommand(boolean) + */ + public boolean isRawCommand() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Sets whether this command should be treated as "raw". + * + *

A "raw" command will only use the node provided by this event for + * sending the command tree to the client. For execution purposes, the default + * greedy string execution of a standard Bukkit {@link Command} is used.

+ * + *

On older versions of Paper, this was the default and only behavior of this + * event.

+ * + * @param rawCommand whether this command should be treated as "raw" + */ + public void setRawCommand(final boolean rawCommand) { + throw new UnsupportedOperationException("Stub"); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isCancelled() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Cancels registering this command to Brigadier, but will remain in Bukkit Command Map. Can be used to hide a + * command from all players. + *

+ * {@inheritDoc} + */ + @Override + public void setCancelled(boolean cancel) { + throw new UnsupportedOperationException("Stub"); + } + + @NotNull + public HandlerList getHandlers() { + throw new UnsupportedOperationException("Stub"); + } +} \ No newline at end of file diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/command/brigadier/BasicCommand.java b/internal-paper-stubs/src/main/java/io/papermc/paper/command/brigadier/BasicCommand.java index 99a9a5ec..da085844 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/command/brigadier/BasicCommand.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/command/brigadier/BasicCommand.java @@ -1,12 +1,13 @@ package io.papermc.paper.command.brigadier; -import java.util.Collection; -import java.util.Collections; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; +import java.util.Collections; + /** * Implementing this interface allows for easily creating "Bukkit-style" {@code String[] args} commands. * The implementation handles converting the command to a representation compatible with Brigadier on registration, usually in the form of {@literal /commandlabel }. @@ -19,7 +20,7 @@ public interface BasicCommand { * Executes the command with the given {@link CommandSourceStack} and arguments. * * @param commandSourceStack the commandSourceStack of the command - * @param args the arguments of the command ignoring repeated spaces + * @param args the arguments of the command ignoring repeated spaces */ @ApiStatus.OverrideOnly void execute(@NotNull CommandSourceStack commandSourceStack, @NotNull String[] args); @@ -28,7 +29,7 @@ public interface BasicCommand { * Suggests possible completions for the given command {@link CommandSourceStack} and arguments. * * @param commandSourceStack the commandSourceStack of the command - * @param args the arguments of the command including repeated spaces + * @param args the arguments of the command including repeated spaces * @return a collection of suggestions */ @ApiStatus.OverrideOnly diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/command/brigadier/Commands.java b/internal-paper-stubs/src/main/java/io/papermc/paper/command/brigadier/Commands.java index 3188a253..3a7eef41 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/command/brigadier/Commands.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/command/brigadier/Commands.java @@ -39,7 +39,7 @@ * }) * .build(), * "some bukkit help description string", - * List.of("an-alias") + * Arrays.asList("an-alias") * ); * }); * } @@ -149,7 +149,7 @@ public interface Commands extends Registrar { *

  • The main command/namespaced label will override already existing commands
  • * * - * @param node the built literal command node + * @param node the built literal command node * @param aliases a collection of aliases to register the literal node's command to * @return successfully registered root command labels (including aliases and namespaced variants) */ @@ -171,7 +171,8 @@ public interface Commands extends Registrar { * @param aliases a collection of aliases to register the literal node's command to * @return successfully registered root command labels (including aliases and namespaced variants) */ - @Unmodifiable @NotNull Set register(@NotNull LiteralCommandNode node, @Nullable String description, @NotNull Collection aliases); + @Unmodifiable + @NotNull Set register(@NotNull LiteralCommandNode node, @Nullable String description, @NotNull Collection aliases); /** * Registers a command for a plugin. @@ -188,7 +189,8 @@ public interface Commands extends Registrar { * @param aliases a collection of aliases to register the literal node's command to * @return successfully registered root command labels (including aliases and namespaced variants) */ - @Unmodifiable @NotNull Set register(@NotNull PluginMeta pluginMeta, @NotNull LiteralCommandNode node, @Nullable String description, @NotNull Collection aliases); + @Unmodifiable + @NotNull Set register(@NotNull PluginMeta pluginMeta, @NotNull LiteralCommandNode node, @Nullable String description, @NotNull Collection aliases); /** * Registers a command under the same logic as {@link Commands#register(LiteralCommandNode, String, Collection)}. @@ -234,7 +236,8 @@ public interface Commands extends Registrar { * @param basicCommand the basic command instance to register * @return successfully registered root command labels (including aliases and namespaced variants) */ - @Unmodifiable @NotNull Set register(@NotNull String label, @Nullable String description, @NotNull Collection aliases, @NotNull BasicCommand basicCommand); + @Unmodifiable + @NotNull Set register(@NotNull String label, @Nullable String description, @NotNull Collection aliases, @NotNull BasicCommand basicCommand); /** * Registers a command under the same logic as {@link Commands#register(PluginMeta, LiteralCommandNode, String, Collection)}. @@ -246,5 +249,6 @@ public interface Commands extends Registrar { * @param basicCommand the basic command instance to register * @return successfully registered root command labels (including aliases and namespaced variants) */ - @Unmodifiable @NotNull Set register(@NotNull PluginMeta pluginMeta, @NotNull String label, @Nullable String description, @NotNull Collection aliases, @NotNull BasicCommand basicCommand); + @Unmodifiable + @NotNull Set register(@NotNull PluginMeta pluginMeta, @NotNull String label, @Nullable String description, @NotNull Collection aliases, @NotNull BasicCommand basicCommand); } diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/configuration/PluginMeta.java b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/configuration/PluginMeta.java index 859aaa19..cb5b28aa 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/configuration/PluginMeta.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/configuration/PluginMeta.java @@ -81,7 +81,7 @@ default String getDisplayName() { * plugin. * * @return the specific overwrite of the logger prefix as defined by the plugin. If the plugin did not define a - * custom logger prefix, this method will return null + * custom logger prefix, this method will return null */ @Nullable String getLoggerPrefix(); diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java index 0b8eafd3..1f67e559 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java @@ -9,6 +9,7 @@ * Lifecycle events are generally fired when the older * event system is not available, like during early * server initialization. + * * @see LifecycleEvents */ @ApiStatus.Experimental diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java index cac60870..0a6a2db7 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java @@ -1,6 +1,5 @@ package io.papermc.paper.plugin.lifecycle.event.handler.configuration; -import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; import org.jetbrains.annotations.ApiStatus; diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java index 5d85e4e6..b7dd4617 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java @@ -1,6 +1,5 @@ package io.papermc.paper.plugin.lifecycle.event.handler.configuration; -import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java index 70f3263c..d738a05f 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java @@ -1,6 +1,5 @@ package io.papermc.paper.plugin.lifecycle.event.handler.configuration; -import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java index f74cb28f..76d037b7 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java @@ -2,7 +2,6 @@ import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; -import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfiguration; diff --git a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java index 029d4b52..e0b3d755 100644 --- a/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java +++ b/internal-paper-stubs/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java @@ -24,12 +24,12 @@ public final class LifecycleEvents { */ public static final LifecycleEventType.Prioritizable> COMMANDS = prioritized("commands", LifecycleEventOwner.class); - @ApiStatus.Internal - private static LifecycleEventType.Prioritizable prioritized(final String name, final Class ownerType) { - throw new UnsupportedOperationException("Stub"); + private LifecycleEvents() { } // - private LifecycleEvents() { + @ApiStatus.Internal + private static LifecycleEventType.Prioritizable prioritized(final String name, final Class ownerType) { + throw new UnsupportedOperationException("Stub"); } } diff --git a/internal-paper-stubs/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java b/internal-paper-stubs/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java new file mode 100644 index 00000000..aca6adc2 --- /dev/null +++ b/internal-paper-stubs/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java @@ -0,0 +1,93 @@ +package org.bukkit.event.command; + +import net.kyori.adventure.text.Component; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class UnknownCommandEvent extends Event { + + @NotNull + public static HandlerList getHandlerList() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets the CommandSender or ConsoleCommandSender + *

    + * + * @return Sender of the command + */ + @NotNull + public CommandSender getSender() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets the command that was send + *

    + * + * @return Command sent + */ + @NotNull + public String getCommandLine() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets message that will be returned + *

    + * + * @return Unknown command message + * @deprecated use {@link #message()} + */ + @Nullable + @Deprecated + public String getMessage() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Sets message that will be returned + *

    + * Set to null to avoid any message being sent + * + * @param message the message to be returned, or null + * @deprecated use {@link #message(Component)} + */ + @Deprecated + public void setMessage(@Nullable String message) { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Gets message that will be returned + *

    + * + * @return Unknown command message + */ + @Nullable + @Contract(pure = true) + public Component message() { + throw new UnsupportedOperationException("Stub"); + } + + /** + * Sets message that will be returned + *

    * These also will not be included in {@link #toBuilder()}. */ - private static final List> DEFAULT_FACTORIES = List.of( + private static final List> DEFAULT_FACTORIES = Arrays.asList( DefaultTypeFactories.LONG, DefaultTypeFactories.INTEGER, DefaultTypeFactories.SHORT, diff --git a/minestom/src/main/java/revxrsal/commands/minestom/exception/MinestomExceptionHandler.java b/minestom/src/main/java/revxrsal/commands/minestom/exception/MinestomExceptionHandler.java index 1597ff2a..e0c58692 100644 --- a/minestom/src/main/java/revxrsal/commands/minestom/exception/MinestomExceptionHandler.java +++ b/minestom/src/main/java/revxrsal/commands/minestom/exception/MinestomExceptionHandler.java @@ -45,11 +45,15 @@ public void onSenderNotConsole(SenderNotConsoleException e, MinestomCommandActor @Override public void onInputParse(@NotNull InputParseException e, @NotNull MinestomCommandActor actor) { switch (e.cause()) { - case INVALID_ESCAPE_CHARACTER -> - actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); - case UNCLOSED_QUOTE -> actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); - case EXPECTED_WHITESPACE -> - actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + case INVALID_ESCAPE_CHARACTER: + actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); + break; + case UNCLOSED_QUOTE: + actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); + break; + case EXPECTED_WHITESPACE: + actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + break; } } diff --git a/minestom/src/main/java/revxrsal/commands/minestom/hooks/ArgumentColl.java b/minestom/src/main/java/revxrsal/commands/minestom/hooks/ArgumentColl.java index 167aac2f..57148b8f 100644 --- a/minestom/src/main/java/revxrsal/commands/minestom/hooks/ArgumentColl.java +++ b/minestom/src/main/java/revxrsal/commands/minestom/hooks/ArgumentColl.java @@ -27,6 +27,8 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; final class ArgumentColl { @@ -34,11 +36,11 @@ final class ArgumentColl { private final List> arguments; public ArgumentColl(Argument first, Argument second) { - this.arguments = List.of(first, second); + this.arguments = Arrays.asList(first, second); } public ArgumentColl(Argument argument) { - this.arguments = List.of(argument); + this.arguments = Collections.singletonList(argument); } public List> arguments() { diff --git a/minestom/src/main/java/revxrsal/commands/minestom/hooks/MinestomCommandHooks.java b/minestom/src/main/java/revxrsal/commands/minestom/hooks/MinestomCommandHooks.java index ed8a3b59..b182c28b 100644 --- a/minestom/src/main/java/revxrsal/commands/minestom/hooks/MinestomCommandHooks.java +++ b/minestom/src/main/java/revxrsal/commands/minestom/hooks/MinestomCommandHooks.java @@ -107,7 +107,8 @@ private void addCommand(@NotNull ExecutableCommand command, @NotNull Command if (node.isLiteral()) arguments.add(toArgument(node)); - else if (node instanceof ParameterNode parameter) { + else if (node instanceof ParameterNode) { + ParameterNode parameter = (ParameterNode) node; if (parameter.isSwitch()) { // add the required minestomCommand.addSyntax(generateAction(command), arguments.toArray(Argument[]::new)); @@ -220,9 +221,11 @@ private ArgumentColl ofFlag(ParameterNode parameter) { A actor = actorFactory.create(sender, node.lamp()); StringStream input = StringStream.create(exception.getInput()); ExecutionContext context = ExecutionContext.create(node.command(), actor, input); - if (node instanceof LiteralNode literal) { + if (node instanceof LiteralNode) { + LiteralNode literal = (LiteralNode) node; node.lamp().handleException(exception, ErrorContext.parsingLiteral(context, literal)); - } else if (node instanceof ParameterNode parameter) { + } else if (node instanceof ParameterNode) { + ParameterNode parameter = (ParameterNode) node; node.lamp().handleException(exception, ErrorContext.parsingParameter(context, parameter, input)); } }; diff --git a/sponge/src/main/java/revxrsal/commands/sponge/actor/BasicActorFactory.java b/sponge/src/main/java/revxrsal/commands/sponge/actor/BasicActorFactory.java index 403556d0..97944728 100644 --- a/sponge/src/main/java/revxrsal/commands/sponge/actor/BasicActorFactory.java +++ b/sponge/src/main/java/revxrsal/commands/sponge/actor/BasicActorFactory.java @@ -29,22 +29,60 @@ import revxrsal.commands.Lamp; import revxrsal.commands.process.MessageSender; +import java.util.Objects; + /** * Default implementation of {@link ActorFactory} */ -record BasicActorFactory( - MessageSender messageSender, - MessageSender errorSender -) implements ActorFactory { +final class BasicActorFactory implements ActorFactory { public static final ActorFactory INSTANCE = new BasicActorFactory( SpongeCommandActor::sendRawMessage, SpongeCommandActor::sendRawError ); + private final MessageSender messageSender; + private final MessageSender errorSender; + + /** + * + */ + BasicActorFactory( + MessageSender messageSender, + MessageSender errorSender + ) { + this.messageSender = messageSender; + this.errorSender = errorSender; + } @Override public @NotNull SpongeCommandActor create(@NotNull CommandCause sender, @NotNull Lamp lamp) { return new BasicSpongeActor(sender, lamp, messageSender, errorSender); } + + public MessageSender messageSender() {return messageSender;} + + public MessageSender errorSender() {return errorSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + BasicActorFactory that = (BasicActorFactory) obj; + return Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.errorSender, that.errorSender); + } + + @Override + public int hashCode() { + return Objects.hash(messageSender, errorSender); + } + + @Override + public String toString() { + return "BasicActorFactory[" + + "messageSender=" + messageSender + ", " + + "errorSender=" + errorSender + ']'; + } + } diff --git a/sponge/src/main/java/revxrsal/commands/sponge/actor/BasicSpongeActor.java b/sponge/src/main/java/revxrsal/commands/sponge/actor/BasicSpongeActor.java index da3bd660..f6209da3 100644 --- a/sponge/src/main/java/revxrsal/commands/sponge/actor/BasicSpongeActor.java +++ b/sponge/src/main/java/revxrsal/commands/sponge/actor/BasicSpongeActor.java @@ -8,16 +8,28 @@ import revxrsal.commands.process.MessageSender; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.UUID; -record BasicSpongeActor( - CommandCause sender, - Lamp lamp, - MessageSender messageSender, - MessageSender errorSender -) implements SpongeCommandActor { +final class BasicSpongeActor implements SpongeCommandActor { private static final UUID CONSOLE_UUID = new UUID(0, 0); + private final CommandCause sender; + private final Lamp lamp; + private final MessageSender messageSender; + private final MessageSender errorSender; + + BasicSpongeActor( + CommandCause sender, + Lamp lamp, + MessageSender messageSender, + MessageSender errorSender + ) { + this.sender = sender; + this.lamp = lamp; + this.messageSender = messageSender; + this.errorSender = errorSender; + } @Override public @NotNull CommandCause cause() { return sender; @@ -43,4 +55,36 @@ else if (isConsole()) @Override public Lamp lamp() { return lamp; } + + public CommandCause sender() {return sender;} + + public MessageSender messageSender() {return messageSender;} + + public MessageSender errorSender() {return errorSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + BasicSpongeActor that = (BasicSpongeActor) obj; + return Objects.equals(this.sender, that.sender) && + Objects.equals(this.lamp, that.lamp) && + Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.errorSender, that.errorSender); + } + + @Override + public int hashCode() { + return Objects.hash(sender, lamp, messageSender, errorSender); + } + + @Override + public String toString() { + return "BasicSpongeActor[" + + "sender=" + sender + ", " + + "lamp=" + lamp + ", " + + "messageSender=" + messageSender + ", " + + "errorSender=" + errorSender + ']'; + } + } \ No newline at end of file diff --git a/sponge/src/main/java/revxrsal/commands/sponge/actor/SpongeCommandActor.java b/sponge/src/main/java/revxrsal/commands/sponge/actor/SpongeCommandActor.java index ebdca659..a5a346ac 100644 --- a/sponge/src/main/java/revxrsal/commands/sponge/actor/SpongeCommandActor.java +++ b/sponge/src/main/java/revxrsal/commands/sponge/actor/SpongeCommandActor.java @@ -207,7 +207,8 @@ default void sendRawError(@NotNull ComponentLike message) { */ @Override @NotNull default String name() { - if (subject() instanceof Nameable n) { + if (subject() instanceof Nameable) { + Nameable n = (Nameable) subject(); return n.name(); } else if (isConsole()) { return "Console"; diff --git a/sponge/src/main/java/revxrsal/commands/sponge/exception/SpongeExceptionHandler.java b/sponge/src/main/java/revxrsal/commands/sponge/exception/SpongeExceptionHandler.java index be089dda..939d02ec 100644 --- a/sponge/src/main/java/revxrsal/commands/sponge/exception/SpongeExceptionHandler.java +++ b/sponge/src/main/java/revxrsal/commands/sponge/exception/SpongeExceptionHandler.java @@ -39,11 +39,15 @@ public void onSenderNotPlayer(SenderNotPlayerException e, SpongeCommandActor act @Override public void onInputParse(@NotNull InputParseException e, @NotNull SpongeCommandActor actor) { switch (e.cause()) { - case INVALID_ESCAPE_CHARACTER -> - actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); - case UNCLOSED_QUOTE -> actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); - case EXPECTED_WHITESPACE -> - actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + case INVALID_ESCAPE_CHARACTER: + actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); + break; + case UNCLOSED_QUOTE: + actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); + break; + case EXPECTED_WHITESPACE: + actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + break; } } diff --git a/velocity/src/main/java/revxrsal/commands/velocity/actor/BasicActorFactory.java b/velocity/src/main/java/revxrsal/commands/velocity/actor/BasicActorFactory.java index 1c598951..34cf73aa 100644 --- a/velocity/src/main/java/revxrsal/commands/velocity/actor/BasicActorFactory.java +++ b/velocity/src/main/java/revxrsal/commands/velocity/actor/BasicActorFactory.java @@ -29,21 +29,59 @@ import revxrsal.commands.Lamp; import revxrsal.commands.process.MessageSender; +import java.util.Objects; + /** * Default implementation of {@link ActorFactory} */ -record BasicActorFactory( - MessageSender messageSender, - MessageSender errorSender -) implements ActorFactory { +final class BasicActorFactory implements ActorFactory { public static final ActorFactory INSTANCE = new BasicActorFactory( VelocityCommandActor::sendRawMessage, VelocityCommandActor::sendRawError ); + private final MessageSender messageSender; + private final MessageSender errorSender; + + /** + * + */ + BasicActorFactory( + MessageSender messageSender, + MessageSender errorSender + ) { + this.messageSender = messageSender; + this.errorSender = errorSender; + } @Override public @NotNull VelocityCommandActor create(@NotNull CommandSource sender, @NotNull Lamp lamp) { return new BasicVelocityActor(sender, lamp, messageSender, errorSender); } + + public MessageSender messageSender() {return messageSender;} + + public MessageSender errorSender() {return errorSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + BasicActorFactory that = (BasicActorFactory) obj; + return Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.errorSender, that.errorSender); + } + + @Override + public int hashCode() { + return Objects.hash(messageSender, errorSender); + } + + @Override + public String toString() { + return "BasicActorFactory[" + + "messageSender=" + messageSender + ", " + + "errorSender=" + errorSender + ']'; + } + } diff --git a/velocity/src/main/java/revxrsal/commands/velocity/actor/BasicVelocityActor.java b/velocity/src/main/java/revxrsal/commands/velocity/actor/BasicVelocityActor.java index 8989a3a0..628eee7d 100644 --- a/velocity/src/main/java/revxrsal/commands/velocity/actor/BasicVelocityActor.java +++ b/velocity/src/main/java/revxrsal/commands/velocity/actor/BasicVelocityActor.java @@ -8,16 +8,28 @@ import revxrsal.commands.process.MessageSender; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.UUID; -record BasicVelocityActor( - CommandSource sender, - Lamp lamp, - MessageSender messageSender, - MessageSender errorSender -) implements VelocityCommandActor { +final class BasicVelocityActor implements VelocityCommandActor { private static final UUID CONSOLE_UUID = new UUID(0, 0); + private final CommandSource sender; + private final Lamp lamp; + private final MessageSender messageSender; + private final MessageSender errorSender; + + BasicVelocityActor( + CommandSource sender, + Lamp lamp, + MessageSender messageSender, + MessageSender errorSender + ) { + this.sender = sender; + this.lamp = lamp; + this.messageSender = messageSender; + this.errorSender = errorSender; + } @Override public @NotNull CommandSource source() { return sender; @@ -43,4 +55,36 @@ else if (isConsole()) @Override public Lamp lamp() { return lamp; } + + public CommandSource sender() {return sender;} + + public MessageSender messageSender() {return messageSender;} + + public MessageSender errorSender() {return errorSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + BasicVelocityActor that = (BasicVelocityActor) obj; + return Objects.equals(this.sender, that.sender) && + Objects.equals(this.lamp, that.lamp) && + Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.errorSender, that.errorSender); + } + + @Override + public int hashCode() { + return Objects.hash(sender, lamp, messageSender, errorSender); + } + + @Override + public String toString() { + return "BasicVelocityActor[" + + "sender=" + sender + ", " + + "lamp=" + lamp + ", " + + "messageSender=" + messageSender + ", " + + "errorSender=" + errorSender + ']'; + } + } \ No newline at end of file diff --git a/velocity/src/main/java/revxrsal/commands/velocity/exception/VelocityExceptionHandler.java b/velocity/src/main/java/revxrsal/commands/velocity/exception/VelocityExceptionHandler.java index 763b608d..8f006af0 100644 --- a/velocity/src/main/java/revxrsal/commands/velocity/exception/VelocityExceptionHandler.java +++ b/velocity/src/main/java/revxrsal/commands/velocity/exception/VelocityExceptionHandler.java @@ -34,11 +34,15 @@ public void onSenderNotConsole(SenderNotConsoleException e, VelocityCommandActor @Override public void onInputParse(@NotNull InputParseException e, @NotNull VelocityCommandActor actor) { switch (e.cause()) { - case INVALID_ESCAPE_CHARACTER -> - actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); - case UNCLOSED_QUOTE -> actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); - case EXPECTED_WHITESPACE -> - actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + case INVALID_ESCAPE_CHARACTER: + actor.error(legacyColorize("&cInvalid input. Use &e\\\\ &cto include a backslash.")); + break; + case UNCLOSED_QUOTE: + actor.error(legacyColorize("&cUnclosed quote. Make sure to close all quotes.")); + break; + case EXPECTED_WHITESPACE: + actor.error(legacyColorize("&cExpected whitespace to end one argument, but found trailing data.")); + break; } } diff --git a/velocity/src/main/java/revxrsal/commands/velocity/hooks/VelocityCommandHooks.java b/velocity/src/main/java/revxrsal/commands/velocity/hooks/VelocityCommandHooks.java index 261f83ff..d82099c0 100644 --- a/velocity/src/main/java/revxrsal/commands/velocity/hooks/VelocityCommandHooks.java +++ b/velocity/src/main/java/revxrsal/commands/velocity/hooks/VelocityCommandHooks.java @@ -29,7 +29,6 @@ import com.velocitypowered.api.command.CommandSource; import org.jetbrains.annotations.NotNull; import revxrsal.commands.Lamp; -import revxrsal.commands.brigadier.BrigadierAdapter; import revxrsal.commands.brigadier.BrigadierConverter; import revxrsal.commands.brigadier.BrigadierParser; import revxrsal.commands.command.ExecutableCommand; diff --git a/velocity/src/main/java/revxrsal/commands/velocity/parameters/PlayerParameterType.java b/velocity/src/main/java/revxrsal/commands/velocity/parameters/PlayerParameterType.java index d1fb1ce6..c38cec95 100644 --- a/velocity/src/main/java/revxrsal/commands/velocity/parameters/PlayerParameterType.java +++ b/velocity/src/main/java/revxrsal/commands/velocity/parameters/PlayerParameterType.java @@ -34,6 +34,7 @@ import revxrsal.commands.velocity.actor.VelocityCommandActor; import revxrsal.commands.velocity.exception.InvalidPlayerException; +import java.util.Objects; import java.util.Optional; import static revxrsal.commands.util.Collections.map; @@ -44,7 +45,13 @@ * If the player inputs {@code me} or {@code self} or {@code @s}, the parser will * return the executing player (or give an error if the sender is not a player) */ -public record PlayerParameterType(@NotNull ProxyServer server) implements ParameterType { +public final class PlayerParameterType implements ParameterType { + private final @NotNull ProxyServer server; + + /** + * + */ + public PlayerParameterType(@NotNull ProxyServer server) {this.server = server;} @Override public Player parse(@NotNull MutableStringStream input, @NotNull ExecutionContext context) { @@ -60,4 +67,26 @@ public Player parse(@NotNull MutableStringStream input, @NotNull ExecutionContex @Override public @NotNull SuggestionProvider defaultSuggestions() { return (context) -> map(server.getAllPlayers(), Player::getUsername); } + + public @NotNull ProxyServer server() {return server;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + PlayerParameterType that = (PlayerParameterType) obj; + return Objects.equals(this.server, that.server); + } + + @Override + public int hashCode() { + return Objects.hash(server); + } + + @Override + public String toString() { + return "PlayerParameterType[" + + "server=" + server + ']'; + } + }

    + * Set to null to avoid any message being sent + * + * @param message the message to be returned, or null + */ + public void message(@Nullable Component message) { + throw new UnsupportedOperationException("Stub"); + } + + @NotNull + public HandlerList getHandlers() { + throw new UnsupportedOperationException("Stub"); + } +} diff --git a/jda/src/main/java/revxrsal/commands/jda/JDAUtils.java b/jda/src/main/java/revxrsal/commands/jda/JDAUtils.java index b9324d0b..0a3334dc 100644 --- a/jda/src/main/java/revxrsal/commands/jda/JDAUtils.java +++ b/jda/src/main/java/revxrsal/commands/jda/JDAUtils.java @@ -130,45 +130,40 @@ private JDAUtils() { @NotNull ParameterNode parameter ) { switch (option.getType()) { - case STRING -> { + case STRING: return option.getAsString(); - } - case INTEGER -> { + case INTEGER: return safeIntegerCast(option.getAsInt(), parameter.type()); - } - case NUMBER -> { + case NUMBER: return safeDoubleCast(option.getAsInt(), parameter.type()); - } - case BOOLEAN -> { + case BOOLEAN: return option.getAsBoolean(); - } - case USER -> { + case USER: if (parameter.type() == Member.class) { Member asMember = option.getAsMember(); - if (asMember == null) + if (asMember == null) { throw new MemberNotInGuildException(option.getAsUser()); + } return asMember; } return option.getAsUser(); - } - case CHANNEL -> { - if (option.getChannelType().getInterface().isAssignableFrom(parameter.type())) + case CHANNEL: + if (option.getChannelType().getInterface().isAssignableFrom(parameter.type())) { return option.getAsChannel(); + } throw new WrongChannelTypeException(option.getAsChannel(), parameter.type()); - } - case ROLE -> { + case ROLE: return option.getAsRole(); - } - case MENTIONABLE -> { + case MENTIONABLE: return option.getAsMentionable(); - } - case ATTACHMENT -> { + case ATTACHMENT: return option.getAsAttachment(); - } + default: + throw new IllegalArgumentException("Don't know how to fetch a value from Option: " + option + " for parameter " + parameter.name() + " of type " + parameter.type()); } - throw new IllegalArgumentException("Don't know how to fetch a value from Option: " + option + " for parameter " + parameter.name() + " of type " + parameter.type()); } + private static @NotNull Object safeIntegerCast(int value, Class type) { if (type == int.class) return value; diff --git a/jda/src/main/java/revxrsal/commands/jda/slash/JDAParser.java b/jda/src/main/java/revxrsal/commands/jda/slash/JDAParser.java index d0734c57..3b8a920c 100644 --- a/jda/src/main/java/revxrsal/commands/jda/slash/JDAParser.java +++ b/jda/src/main/java/revxrsal/commands/jda/slash/JDAParser.java @@ -111,7 +111,8 @@ private void checkCommand(@NotNull ExecutableCommand executable) { if (!canUseLiterals) throw new IllegalArgumentException("You can only have 3 consecutive literals in slash commands!"); } - if (node instanceof ParameterNode parameter) { + if (node instanceof ParameterNode) { + ParameterNode parameter = (ParameterNode) node; if (parameter.isSwitch()) throw new IllegalArgumentException("Switches are not supported in JDA slash commands."); if (parameter.isFlag()) diff --git a/jda/src/main/java/revxrsal/commands/jda/slash/JDASlashListener.java b/jda/src/main/java/revxrsal/commands/jda/slash/JDASlashListener.java index 7b45388e..3ad21a71 100644 --- a/jda/src/main/java/revxrsal/commands/jda/slash/JDASlashListener.java +++ b/jda/src/main/java/revxrsal/commands/jda/slash/JDASlashListener.java @@ -42,6 +42,7 @@ import revxrsal.commands.stream.MutableStringStream; import revxrsal.commands.stream.StringStream; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -63,7 +64,8 @@ public JDASlashListener(Lamp lamp, SlashActorFactory actorFactory) { private void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { A actor = actorFactory.create(event, lamp); String fullPath = event.getFullCommandName(); - ExecutableCommand command = findCommand(lamp, fullPath, event.getOptions()).orElseThrow(); + ExecutableCommand command = findCommand(lamp, fullPath, event.getOptions()) + .orElseThrow(() -> new IllegalArgumentException("No such command")); ExecutionContext context = readArgumentsIntoContext( actor, command, @@ -90,7 +92,7 @@ private void onCommandAutoCompleteInteraction(@NotNull CommandAutoCompleteIntera true ); ParameterNode node = command.parameter(event.getFocusedOption().getName()); - var suggestions = node.suggestions().getSuggestions(context); + Collection suggestions = node.suggestions().getSuggestions(context); List choices = toChoices(suggestions, event.getFocusedOption().getType()); event.replyChoices(choices).queue(); @@ -144,9 +146,11 @@ private void onCommandAutoCompleteInteraction(@NotNull CommandAutoCompleteIntera } @Override public void onEvent(@NotNull GenericEvent event) { - if (event instanceof SlashCommandInteractionEvent slash) { + if (event instanceof SlashCommandInteractionEvent) { + SlashCommandInteractionEvent slash = (SlashCommandInteractionEvent) event; onSlashCommandInteraction(slash); - } else if (event instanceof CommandAutoCompleteInteractionEvent complete) { + } else if (event instanceof CommandAutoCompleteInteractionEvent) { + CommandAutoCompleteInteractionEvent complete = (CommandAutoCompleteInteractionEvent) event; onCommandAutoCompleteInteraction(complete); } } diff --git a/minestom/src/main/java/revxrsal/commands/minestom/actor/BasicActorFactory.java b/minestom/src/main/java/revxrsal/commands/minestom/actor/BasicActorFactory.java index efcd0f80..50cc8e70 100644 --- a/minestom/src/main/java/revxrsal/commands/minestom/actor/BasicActorFactory.java +++ b/minestom/src/main/java/revxrsal/commands/minestom/actor/BasicActorFactory.java @@ -29,21 +29,59 @@ import revxrsal.commands.Lamp; import revxrsal.commands.process.MessageSender; +import java.util.Objects; + /** * Default implementation of {@link ActorFactory} */ -record BasicActorFactory( - MessageSender messageSender, - MessageSender errorSender -) implements ActorFactory { +final class BasicActorFactory implements ActorFactory { public static final ActorFactory INSTANCE = new BasicActorFactory( MinestomCommandActor::sendRawMessage, MinestomCommandActor::sendRawError ); + private final MessageSender messageSender; + private final MessageSender errorSender; + + /** + * + */ + BasicActorFactory( + MessageSender messageSender, + MessageSender errorSender + ) { + this.messageSender = messageSender; + this.errorSender = errorSender; + } @Override public @NotNull MinestomCommandActor create(@NotNull CommandSender sender, @NotNull Lamp lamp) { return new BasicMinestomActor(sender, lamp, messageSender, errorSender); } + + public MessageSender messageSender() {return messageSender;} + + public MessageSender errorSender() {return errorSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (BasicActorFactory) obj; + return Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.errorSender, that.errorSender); + } + + @Override + public int hashCode() { + return Objects.hash(messageSender, errorSender); + } + + @Override + public String toString() { + return "BasicActorFactory[" + + "messageSender=" + messageSender + ", " + + "errorSender=" + errorSender + ']'; + } + } diff --git a/minestom/src/main/java/revxrsal/commands/minestom/actor/BasicMinestomActor.java b/minestom/src/main/java/revxrsal/commands/minestom/actor/BasicMinestomActor.java index bc73e5fd..c82c2572 100644 --- a/minestom/src/main/java/revxrsal/commands/minestom/actor/BasicMinestomActor.java +++ b/minestom/src/main/java/revxrsal/commands/minestom/actor/BasicMinestomActor.java @@ -8,14 +8,26 @@ import revxrsal.commands.process.MessageSender; import java.nio.charset.StandardCharsets; +import java.util.Objects; import java.util.UUID; -record BasicMinestomActor( - CommandSender sender, - Lamp lamp, - MessageSender messageSender, - MessageSender errorSender -) implements MinestomCommandActor { +final class BasicMinestomActor implements MinestomCommandActor { + private final CommandSender sender; + private final Lamp lamp; + private final MessageSender messageSender; + private final MessageSender errorSender; + + BasicMinestomActor( + CommandSender sender, + Lamp lamp, + MessageSender messageSender, + MessageSender errorSender + ) { + this.sender = sender; + this.lamp = lamp; + this.messageSender = messageSender; + this.errorSender = errorSender; + } @Override public @NotNull CommandSender sender() { return sender; @@ -39,4 +51,34 @@ record BasicMinestomActor( @Override public Lamp lamp() { return lamp; } + + public MessageSender messageSender() {return messageSender;} + + public MessageSender errorSender() {return errorSender;} + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (BasicMinestomActor) obj; + return Objects.equals(this.sender, that.sender) && + Objects.equals(this.lamp, that.lamp) && + Objects.equals(this.messageSender, that.messageSender) && + Objects.equals(this.errorSender, that.errorSender); + } + + @Override + public int hashCode() { + return Objects.hash(sender, lamp, messageSender, errorSender); + } + + @Override + public String toString() { + return "BasicMinestomActor[" + + "sender=" + sender + ", " + + "lamp=" + lamp + ", " + + "messageSender=" + messageSender + ", " + + "errorSender=" + errorSender + ']'; + } + } \ No newline at end of file diff --git a/minestom/src/main/java/revxrsal/commands/minestom/argument/ArgumentTypes.java b/minestom/src/main/java/revxrsal/commands/minestom/argument/ArgumentTypes.java index 22d4b193..7deec809 100644 --- a/minestom/src/main/java/revxrsal/commands/minestom/argument/ArgumentTypes.java +++ b/minestom/src/main/java/revxrsal/commands/minestom/argument/ArgumentTypes.java @@ -31,10 +31,7 @@ import revxrsal.commands.command.CommandActor; import revxrsal.commands.node.ParameterNode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.function.Function; import static revxrsal.commands.util.Preconditions.notNull; @@ -52,7 +49,7 @@ public final class ArgumentTypes { *