diff --git a/README.md b/README.md index 32070c56..efd0e658 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,6 @@ The code is based on a (W.I.P) paper that can be found [here](https://github.com ## modules - **cloud-core**: Core module containing most of the cloud API, and shared implementations - **cloud-annotations**: Annotation processing code that allows you to use annotated methods rather than builders -- **cloud-jline**: W.I.P JLine3 implementation of cloud - **cloud-services**: Services for Cloud - **cloud-minecraft/cloud-brigadier**: Brigadier mappings for cloud - **cloud-minecraft/cloud-bukkit**: Bukkit 1.8.8+ implementation of cloud diff --git a/build.gradle b/build.gradle index 0614e762..1fe94f70 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,8 @@ allprojects { mapping 'java', 'DOUBLESLASH_STYLE' includes(["**/*.java"]) } + + build.dependsOn(checkstyleMain) } subprojects { diff --git a/cloud-jline/README.md b/cloud-jline/README.md deleted file mode 100644 index 6ceed81a..00000000 --- a/cloud-jline/README.md +++ /dev/null @@ -1 +0,0 @@ -Command implementation for [JLine](https://github.com/jline/jline3) diff --git a/cloud-jline/build.gradle b/cloud-jline/build.gradle deleted file mode 100644 index 69e2563c..00000000 --- a/cloud-jline/build.gradle +++ /dev/null @@ -1,4 +0,0 @@ -dependencies { - compileOnly 'org.jline:jline:3.16.0' - api project(':cloud-core') -} diff --git a/cloud-jline/src/main/java/cloud/commandframework/jline/JLineCommandManager.java b/cloud-jline/src/main/java/cloud/commandframework/jline/JLineCommandManager.java deleted file mode 100644 index 43940461..00000000 --- a/cloud-jline/src/main/java/cloud/commandframework/jline/JLineCommandManager.java +++ /dev/null @@ -1,169 +0,0 @@ -// -// MIT License -// -// Copyright (c) 2020 Alexander Söderberg & Contributors -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -package cloud.commandframework.jline; - -import cloud.commandframework.CommandManager; -import cloud.commandframework.CommandTree; -import cloud.commandframework.arguments.StaticArgument; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.exceptions.InvalidSyntaxException; -import cloud.commandframework.exceptions.NoSuchCommandException; -import cloud.commandframework.execution.CommandExecutionCoordinator; -import cloud.commandframework.internal.CommandRegistrationHandler; -import cloud.commandframework.meta.SimpleCommandMeta; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.jline.reader.Candidate; -import org.jline.reader.Completer; -import org.jline.reader.LineReader; -import org.jline.reader.LineReaderBuilder; -import org.jline.reader.ParsedLine; -import org.jline.terminal.Terminal; -import org.jline.terminal.TerminalBuilder; - -import java.util.List; -import java.util.function.Function; - -/** - * Command manager for use with JLine - */ -public class JLineCommandManager extends CommandManager implements Completer { - - /** - * Construct a new JLine command manager - * - * @param executionCoordinatorFunction Function producing a new coordinator - */ - public JLineCommandManager( - final @NonNull Function, - CommandExecutionCoordinator> executionCoordinatorFunction - ) { - super(executionCoordinatorFunction, CommandRegistrationHandler.nullCommandRegistrationHandler()); - } - - /** - * Main method - * - * @param args Arguments - * @throws Exception Any and all exceptions - */ - public static void main(final String[] args) throws Exception { - final JLineCommandManager jLineCommandManager = new JLineCommandManager(CommandExecutionCoordinator.simpleCoordinator()); - final Terminal terminal = TerminalBuilder.builder().build(); - LineReader lineReader = LineReaderBuilder.builder() - .completer(jLineCommandManager) - .option(LineReader.Option.INSERT_TAB, false) - .terminal(terminal) - .appName("Test") - .build(); - boolean[] shouldStop = new boolean[]{false}; - jLineCommandManager.command( - jLineCommandManager.commandBuilder("stop", SimpleCommandMeta.empty()) - .handler(commandContext -> - shouldStop[0] = true) - .build()) - .command(jLineCommandManager.commandBuilder("echo", SimpleCommandMeta.empty()) - .argument(String.class, "string", builder -> - builder.asRequired() - .withParser(((commandContext, inputQueue) -> { - final StringBuilder stringBuilder = - new StringBuilder(); - while (!inputQueue.isEmpty()) { - stringBuilder.append(inputQueue.remove()); - if (!inputQueue.isEmpty()) { - stringBuilder.append(" "); - } - } - return ArgumentParseResult.success( - stringBuilder.toString()); - })).build()) - .handler(commandContext -> commandContext.getOptional("string") - .ifPresent( - System.out::println)) - .build()) - .command(jLineCommandManager.commandBuilder("test", SimpleCommandMeta.empty()) - .argument(StaticArgument.of("one")) - .handler(commandContext -> System.out.println("Test (1)")) - .build()) - .command(jLineCommandManager.commandBuilder("test", SimpleCommandMeta.empty()) - .argument(StaticArgument.of("two")) - .handler(commandContext -> System.out.println("Test (2)")) - .build()); - System.out.println("Ready..."); - while (!shouldStop[0]) { - final String line = lineReader.readLine(); - if (line == null || line.isEmpty() || !line.startsWith("/")) { - System.out.println("Empty line"); - continue; - } - try { - final List suggestions = jLineCommandManager.suggest(new JLineCommandSender(), line.substring(1)); - for (final String suggestion : suggestions) { - System.out.printf("> %s\n", suggestion); - } - // jLineCommandManager.executeCommand(new JLineCommandSender(), line.substring(1)).join(); - // System.out.println("Successfully executed " + line); - } catch (RuntimeException runtimeException) { - if (runtimeException.getCause() instanceof NoSuchCommandException) { - System.out.println("No such command"); - } else if (runtimeException.getCause() instanceof InvalidSyntaxException) { - System.out.println(runtimeException.getCause().getMessage()); - } else { - System.out.printf("Something went wrong: %s\n", runtimeException.getCause().getMessage()); - runtimeException.printStackTrace(); - } - } - if (shouldStop[0]) { - System.out.println("Stopping."); - } - } - } - - @Override - public final void complete( - final @NonNull LineReader lineReader, - final @NonNull ParsedLine parsedLine, - final @NonNull List<@NonNull Candidate> list - ) { - final String line = parsedLine.line(); - if (line == null || line.isEmpty() || !line.startsWith("/")) { - System.out.println("Cannot suggest: empty line"); - return; - } - System.out.printf("Trying to complete '%s'\n", line); - } - - @Override - public final @NonNull SimpleCommandMeta createDefaultCommandMeta() { - return SimpleCommandMeta.empty(); - } - - @Override - public final boolean hasPermission( - final @NonNull JLineCommandSender sender, - final @NonNull String permission - ) { - return true; - } - -} diff --git a/cloud-jline/src/main/java/cloud/commandframework/jline/JLineCommandSender.java b/cloud-jline/src/main/java/cloud/commandframework/jline/JLineCommandSender.java deleted file mode 100644 index 75ae2453..00000000 --- a/cloud-jline/src/main/java/cloud/commandframework/jline/JLineCommandSender.java +++ /dev/null @@ -1,28 +0,0 @@ -// -// MIT License -// -// Copyright (c) 2020 Alexander Söderberg & Contributors -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -package cloud.commandframework.jline; - -public class JLineCommandSender { - -} diff --git a/cloud-jline/src/main/java/cloud/commandframework/jline/package-info.java b/cloud-jline/src/main/java/cloud/commandframework/jline/package-info.java deleted file mode 100644 index d81485ad..00000000 --- a/cloud-jline/src/main/java/cloud/commandframework/jline/package-info.java +++ /dev/null @@ -1,28 +0,0 @@ -// -// MIT License -// -// Copyright (c) 2020 Alexander Söderberg & Contributors -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -/** - * cloud implementation for JLine3 - */ -package cloud.commandframework.jline; diff --git a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitPluginRegistrationHandler.java b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitPluginRegistrationHandler.java index dc46b4b4..4deec507 100644 --- a/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitPluginRegistrationHandler.java +++ b/cloud-minecraft/cloud-bukkit/src/main/java/cloud/commandframework/bukkit/BukkitPluginRegistrationHandler.java @@ -88,7 +88,8 @@ public class BukkitPluginRegistrationHandler implements CommandRegistrationHa label = commandArgument.getName(); } - @SuppressWarnings("unchecked") final List aliases = new ArrayList<>(((StaticArgument) commandArgument).getAlternativeAliases()); + @SuppressWarnings("unchecked") + final List aliases = new ArrayList<>(((StaticArgument) commandArgument).getAlternativeAliases()); if (!label.contains(":")) { aliases.add(prefixedLabel); diff --git a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityExecutor.java b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityExecutor.java new file mode 100644 index 00000000..1b158025 --- /dev/null +++ b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityExecutor.java @@ -0,0 +1,151 @@ +// +// MIT License +// +// Copyright (c) 2020 Alexander Söderberg & Contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +package cloud.commandframework.velocity; + +import cloud.commandframework.exceptions.ArgumentParseException; +import cloud.commandframework.exceptions.InvalidCommandSenderException; +import cloud.commandframework.exceptions.InvalidSyntaxException; +import cloud.commandframework.exceptions.NoPermissionException; +import cloud.commandframework.exceptions.NoSuchCommandException; +import cloud.commandframework.execution.CommandResult; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.context.CommandContext; +import com.velocitypowered.api.command.CommandSource; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.concurrent.CompletionException; +import java.util.function.BiConsumer; + +final class VelocityExecutor implements Command { + + private static final String MESSAGE_NO_PERMS = + "I'm sorry, but you do not have permission to perform this command. " + + "Please contact the server administrators if you believe that this is in error."; + private static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command. Type \"/help\" for help."; + + private final VelocityCommandManager manager; + + VelocityExecutor(final @NonNull VelocityCommandManager commandManager) { + this.manager = commandManager; + } + + @Override + public int run(final @NonNull CommandContext commandContext) { + final CommandSource source = commandContext.getSource(); + final String input = commandContext.getInput(); + final C sender = this.manager.getCommandSenderMapper().apply( + source); + this.manager.executeCommand(sender, input).whenComplete(this.getResultConsumer(source, sender)); + return com.mojang.brigadier.Command.SINGLE_SUCCESS; + } + + private @NonNull BiConsumer<@NonNull CommandResult, ? super Throwable> getResultConsumer( + final @NonNull CommandSource source, + final @NonNull C sender + ) { + return (result, throwable) -> { + if (throwable != null) { + if (throwable instanceof CompletionException) { + throwable = throwable.getCause(); + } + final Throwable finalThrowable = throwable; + if (throwable instanceof InvalidSyntaxException) { + this.manager.handleException( + sender, + InvalidSyntaxException.class, + (InvalidSyntaxException) throwable, + (c, e) -> + source.sendMessage( + Component + .text() + .append( + Component.text( + "Invalid Command Syntax. Correct command syntax is: ", + NamedTextColor.RED + ) + ).append( + Component.text( + e.getCorrectSyntax(), + NamedTextColor.GRAY + ) + ).build()) + ); + } else if (throwable instanceof InvalidCommandSenderException) { + this.manager.handleException( + sender, + InvalidCommandSenderException.class, + (InvalidCommandSenderException) throwable, + (c, e) -> + source.sendMessage( + Component.text( + finalThrowable.getMessage(), + NamedTextColor.RED + ) + ) + ); + } else if (throwable instanceof NoPermissionException) { + this.manager.handleException( + sender, + NoPermissionException.class, + (NoPermissionException) throwable, + (c, e) -> source.sendMessage(Component.text(MESSAGE_NO_PERMS)) + ); + } else if (throwable instanceof NoSuchCommandException) { + this.manager.handleException( + sender, + NoSuchCommandException.class, + (NoSuchCommandException) throwable, + (c, e) -> source.sendMessage(Component.text(MESSAGE_UNKNOWN_COMMAND)) + ); + } else if (throwable instanceof ArgumentParseException) { + this.manager.handleException( + sender, + ArgumentParseException.class, + (ArgumentParseException) throwable, + (c, e) -> + source.sendMessage( + Component.text() + .append(Component.text( + "Invalid Command Argument: ", + NamedTextColor.RED + )) + .append(Component.text( + finalThrowable.getCause().getMessage(), + NamedTextColor.GRAY + )) + ) + ); + } else { + source.sendMessage( + Component.text(throwable.getMessage(), NamedTextColor.RED) + ); + throwable.printStackTrace(); + } + } + }; + } + +} diff --git a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityPluginRegistrationHandler.java b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityPluginRegistrationHandler.java index a883325f..3c567086 100644 --- a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityPluginRegistrationHandler.java +++ b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityPluginRegistrationHandler.java @@ -28,29 +28,16 @@ import cloud.commandframework.arguments.CommandArgument; import cloud.commandframework.arguments.StaticArgument; import cloud.commandframework.brigadier.CloudBrigadierManager; import cloud.commandframework.context.CommandContext; -import cloud.commandframework.exceptions.ArgumentParseException; -import cloud.commandframework.exceptions.InvalidCommandSenderException; -import cloud.commandframework.exceptions.InvalidSyntaxException; -import cloud.commandframework.exceptions.NoPermissionException; -import cloud.commandframework.exceptions.NoSuchCommandException; import cloud.commandframework.internal.CommandRegistrationHandler; import com.velocitypowered.api.command.BrigadierCommand; import com.velocitypowered.api.command.CommandMeta; import com.velocitypowered.api.command.CommandSource; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.format.NamedTextColor; import org.checkerframework.checker.nullness.qual.NonNull; import java.util.List; -import java.util.concurrent.CompletionException; final class VelocityPluginRegistrationHandler implements CommandRegistrationHandler { - private static final String MESSAGE_NO_PERMS = - "I'm sorry, but you do not have permission to perform this command. " - + "Please contact the server administrators if you believe that this is in error."; - private static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command. Type \"/help\" for help."; - private CloudBrigadierManager brigadierManager; private VelocityCommandManager manager; @@ -70,103 +57,15 @@ final class VelocityPluginRegistrationHandler implements CommandRegistrationH final CommandArgument argument = command.getArguments().get(0); final List aliases = ((StaticArgument) argument).getAlternativeAliases(); final BrigadierCommand brigadierCommand = new BrigadierCommand( - this.brigadierManager.createLiteralCommandNode(command.getArguments().get(0).getName(), (Command) command, + this.brigadierManager.createLiteralCommandNode( + command.getArguments().get(0).getName(), + (Command) command, (c, p) -> this.manager.hasPermission( - this.manager.getCommandSenderMapper() - .apply(c), p), true, - commandContext -> { - final CommandSource source = commandContext.getSource(); - final String input = commandContext.getInput(); - final C sender = this.manager.getCommandSenderMapper().apply( - source); - this.manager - .executeCommand(sender, input) - .whenComplete((result, throwable) -> { - if (throwable != null) { - if (throwable instanceof CompletionException) { - throwable = throwable.getCause(); - } - final Throwable finalThrowable = throwable; - if (throwable instanceof InvalidSyntaxException) { - this.manager.handleException( - sender, - InvalidSyntaxException.class, - (InvalidSyntaxException) throwable, - (c, e) -> - source.sendMessage( - TextComponent - .builder( - "Invalid Command Syntax. Correct command syntax is: ", - NamedTextColor.RED - ) - .append( - e.getCorrectSyntax(), - NamedTextColor.GRAY - ) - .build()) - ); - } else if (throwable instanceof InvalidCommandSenderException) { - this.manager.handleException( - sender, - InvalidCommandSenderException.class, - (InvalidCommandSenderException) throwable, - (c, e) -> - source.sendMessage( - TextComponent - .of(finalThrowable - .getMessage()) - .color(NamedTextColor.RED)) - ); - } else if (throwable instanceof NoPermissionException) { - this.manager.handleException( - sender, - NoPermissionException.class, - (NoPermissionException) throwable, - (c, e) -> - source.sendMessage( - TextComponent - .of(MESSAGE_NO_PERMS)) - ); - } else if (throwable instanceof NoSuchCommandException) { - this.manager.handleException( - sender, - NoSuchCommandException.class, - (NoSuchCommandException) throwable, - (c, e) -> - source.sendMessage( - TextComponent - .of(MESSAGE_UNKNOWN_COMMAND)) - ); - } else if (throwable instanceof ArgumentParseException) { - this.manager.handleException( - sender, - ArgumentParseException.class, - (ArgumentParseException) throwable, - (c, e) -> - source.sendMessage( - TextComponent - .builder( - "Invalid Command Argument: ", - NamedTextColor.RED - ) - .append( - finalThrowable - .getCause() - .getMessage(), - NamedTextColor.GRAY - ) - .build()) - ); - } else { - source.sendMessage(TextComponent - .of(throwable.getMessage()) - .color(NamedTextColor.RED)); - throwable.printStackTrace(); - } - } - }); - return com.mojang.brigadier.Command.SINGLE_SUCCESS; - } + this.manager.getCommandSenderMapper().apply(c), + p + ), + true, + new VelocityExecutor<>(manager) ) ); final CommandMeta commandMeta = this.manager.getProxyServer().getCommandManager() diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 81cc5265..3d9f3362 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -100,7 +100,7 @@ - +