From edc5249244702a73ef4cf484039044ad8887d3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Wed, 14 Oct 2020 20:09:18 +0200 Subject: [PATCH] :sparkles: Improve the velocity module --- CHANGELOG.md | 9 +- .../velocity/CloudInjectionModule.java | 88 +++++++ .../velocity/VelocityCaptionKeys.java | 63 +++++ .../velocity/VelocityCommandManager.java | 23 +- .../velocity/arguments/PlayerArgument.java | 224 ++++++++++++++++++ .../velocity/arguments/package-info.java | 28 +++ examples/example-velocity/build.gradle | 17 ++ .../velocity/ExampleVelocityPlugin.java | 99 ++++++++ .../examples/velocity/package-info.java | 28 +++ settings.gradle | 2 + 10 files changed, 579 insertions(+), 2 deletions(-) create mode 100644 cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/CloudInjectionModule.java create mode 100644 cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityCaptionKeys.java create mode 100644 cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/arguments/PlayerArgument.java create mode 100644 cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/arguments/package-info.java create mode 100644 examples/example-velocity/build.gradle create mode 100644 examples/example-velocity/src/main/java/cloud/commandframework/examples/velocity/ExampleVelocityPlugin.java create mode 100644 examples/example-velocity/src/main/java/cloud/commandframework/examples/velocity/package-info.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d2d57bc..fc168e57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added + - Added ExampleVelocityPlugin + - Added CloudInjectionModule to cloud-velocity + - Added PlayerArgument to cloud-velocity + ## [1.0.2] - 2020-10-18 ### Fixed - Fixed quoted parsing in StringArgument - Fixed wrong suggestions following invalid literals - Fixes chained optionals not allowing the command to be executed when more than one optional is omitted - + ### Changed - Updated adventure-api from 4.0.0 to 4.1.1 - Updated Velocity module for breaking API changes (sendMessage needs an Identity) diff --git a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/CloudInjectionModule.java b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/CloudInjectionModule.java new file mode 100644 index 00000000..5cb07966 --- /dev/null +++ b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/CloudInjectionModule.java @@ -0,0 +1,88 @@ +// +// 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.CommandTree; +import cloud.commandframework.execution.CommandExecutionCoordinator; +import com.google.inject.AbstractModule; +import com.google.inject.Key; +import com.google.inject.util.Types; +import com.velocitypowered.api.command.CommandSource; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.lang.reflect.Type; +import java.util.function.Function; + +/** + * Injection module that allows for {@link VelocityCommandManager} to be injectable + * + * @param Command sender type + */ +public final class CloudInjectionModule extends AbstractModule { + + private final Class commandSenderType; + private final Function<@NonNull CommandTree, @NonNull CommandExecutionCoordinator> commandExecutionCoordinator; + private final Function<@NonNull CommandSource, @NonNull C> commandSenderMapper; + private final Function<@NonNull C, @NonNull CommandSource> backwardsCommandSenderMapper; + + /** + * Create a new child injection module + * + * @param commandSenderType Your command sender type + * @param commandExecutionCoordinator Command execution coordinator + * @param commandSenderMapper Mapper from command source to the custom command sender type + * @param backwardsCommandSenderMapper Mapper from the custom command sender type to a velocity command source + */ + public CloudInjectionModule( + final @NonNull Class commandSenderType, + final @NonNull Function<@NonNull CommandTree, @NonNull CommandExecutionCoordinator> commandExecutionCoordinator, + final @NonNull Function<@NonNull CommandSource, @NonNull C> commandSenderMapper, + final @NonNull Function<@NonNull C, @NonNull CommandSource> backwardsCommandSenderMapper + ) { + this.commandSenderType = commandSenderType; + this.commandExecutionCoordinator = commandExecutionCoordinator; + this.commandSenderMapper = commandSenderMapper; + this.backwardsCommandSenderMapper = backwardsCommandSenderMapper; + } + + @Override + protected void configure() { + final Type commandTreeType = Types.newParameterizedType(CommandTree.class, this.commandSenderType); + final Type commandExecutionCoordinatorType = Types.newParameterizedType(CommandExecutionCoordinator.class, + this.commandSenderType); + final Type executorFunction = Types.newParameterizedType(Function.class, commandTreeType, + commandExecutionCoordinatorType); + final Key executorFunctionKey = Key.get(executorFunction); + this.bind(executorFunctionKey).toInstance(this.commandExecutionCoordinator); + final Type commandSenderMapperFunction = Types.newParameterizedType(Function.class, CommandSource.class, + this.commandSenderType); + final Key commandSenderMapperFunctionKey = Key.get(commandSenderMapperFunction); + this.bind(commandSenderMapperFunctionKey).toInstance(this.commandSenderMapper); + final Type backwardsCommandSenderMapperFunction = Types.newParameterizedType(Function.class, this.commandSenderType, + CommandSource.class); + final Key backwardsCommandSenderMapperFunctionKey = Key.get(backwardsCommandSenderMapperFunction); + this.bind(backwardsCommandSenderMapperFunctionKey).toInstance(this.backwardsCommandSenderMapper); + } + +} diff --git a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityCaptionKeys.java b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityCaptionKeys.java new file mode 100644 index 00000000..3fa8ce35 --- /dev/null +++ b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityCaptionKeys.java @@ -0,0 +1,63 @@ +// +// 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.captions.Caption; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; + +/** + * Velocity specific {@link Caption caption keys} + */ +public final class VelocityCaptionKeys { + + private static final Collection RECOGNIZED_CAPTIONS = new LinkedList<>(); + + /** + * Variables: {input} + */ + public static final Caption ARGUMENT_PARSE_FAILURE_PLAYER = of("argument.parse.failure.player"); + + private VelocityCaptionKeys() { + } + + private static @NonNull Caption of(final @NonNull String key) { + final Caption caption = Caption.of(key); + RECOGNIZED_CAPTIONS.add(caption); + return caption; + } + + /** + * Get an immutable collection containing all standard caption keys + * + * @return Immutable collection of keys + */ + public static @NonNull Collection<@NonNull Caption> getVelocityCaptionKeys() { + return Collections.unmodifiableCollection(RECOGNIZED_CAPTIONS); + } + +} diff --git a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityCommandManager.java b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityCommandManager.java index a1d7c6d6..d186504b 100644 --- a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityCommandManager.java +++ b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/VelocityCommandManager.java @@ -25,9 +25,13 @@ package cloud.commandframework.velocity; import cloud.commandframework.CommandManager; import cloud.commandframework.CommandTree; +import cloud.commandframework.captions.FactoryDelegatingCaptionRegistry; import cloud.commandframework.execution.CommandExecutionCoordinator; import cloud.commandframework.meta.CommandMeta; import cloud.commandframework.meta.SimpleCommandMeta; +import com.google.inject.Inject; +import com.google.inject.Module; +import com.google.inject.Singleton; import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.proxy.ProxyServer; import org.checkerframework.checker.nullness.qual.NonNull; @@ -35,12 +39,21 @@ import org.checkerframework.checker.nullness.qual.NonNull; import java.util.function.Function; /** - * {@link CommandManager} implementation for Velocity + * {@link CommandManager} implementation for Velocity. + *

+ * This can be injected if {@link CloudInjectionModule} is registered in the + * injector. This can be achieved by using {@link com.google.inject.Injector#createChildInjector(Module...)} * * @param Command sender type */ +@Singleton public class VelocityCommandManager extends CommandManager { + /** + * Default caption for {@link VelocityCaptionKeys#ARGUMENT_PARSE_FAILURE_PLAYER} + */ + public static final String ARGUMENT_PARSE_FAILURE_PLAYER = "'{input}' is not a valid player"; + private final ProxyServer proxyServer; private final Function commandSenderMapper; private final Function backwardsCommandSenderMapper; @@ -53,6 +66,7 @@ public class VelocityCommandManager extends CommandManager { * @param commandSenderMapper Function that maps {@link CommandSource} to the command sender type * @param backwardsCommandSenderMapper Function that maps the command sender type to {@link CommandSource} */ + @Inject public VelocityCommandManager( final @NonNull ProxyServer proxyServer, final @NonNull Function<@NonNull CommandTree, @NonNull CommandExecutionCoordinator> commandExecutionCoordinator, @@ -64,6 +78,13 @@ public class VelocityCommandManager extends CommandManager { this.proxyServer = proxyServer; this.commandSenderMapper = commandSenderMapper; this.backwardsCommandSenderMapper = backwardsCommandSenderMapper; + /* Register default captions */ + if (this.getCaptionRegistry() instanceof FactoryDelegatingCaptionRegistry) { + final FactoryDelegatingCaptionRegistry factoryDelegatingCaptionRegistry = (FactoryDelegatingCaptionRegistry) + this.getCaptionRegistry(); + factoryDelegatingCaptionRegistry.registerMessageFactory(VelocityCaptionKeys.ARGUMENT_PARSE_FAILURE_PLAYER, + (context, key) -> ARGUMENT_PARSE_FAILURE_PLAYER); + } } @Override diff --git a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/arguments/PlayerArgument.java b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/arguments/PlayerArgument.java new file mode 100644 index 00000000..69fd4474 --- /dev/null +++ b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/arguments/PlayerArgument.java @@ -0,0 +1,224 @@ +// +// 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.arguments; + +import cloud.commandframework.arguments.CommandArgument; +import cloud.commandframework.arguments.parser.ArgumentParseResult; +import cloud.commandframework.arguments.parser.ArgumentParser; +import cloud.commandframework.captions.CaptionVariable; +import cloud.commandframework.context.CommandContext; +import cloud.commandframework.exceptions.parsing.ParserException; +import cloud.commandframework.velocity.VelocityCaptionKeys; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import io.leangen.geantyref.TypeToken; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.function.BiFunction; +import java.util.stream.Collectors; + +/** + * Argument parser for {@link Player players} + * + * @param Command sender type + */ +public final class PlayerArgument extends CommandArgument { + + private PlayerArgument( + final @NonNull ProxyServer proxyServer, + final boolean required, + final @NonNull String name, + final @Nullable BiFunction, String, List> suggestionsProvider, + final @NonNull Collection<@NonNull BiFunction<@NonNull CommandContext, @NonNull Queue<@NonNull String>, + @NonNull ArgumentParseResult>> argumentPreprocessors + ) { + super( + required, + name, + new PlayerParser<>(proxyServer), + "", + TypeToken.get(Player.class), + suggestionsProvider, + argumentPreprocessors + ); + } + + /** + * Create a new argument builder + * + * @param name Argument name + * @param proxyServer Proxy server instance + * @param Command sender type + * @return Constructed builder + */ + public static CommandArgument.@NonNull Builder newBuilder( + final @NonNull String name, + final @NonNull ProxyServer proxyServer + ) { + return new Builder( + name, + proxyServer + ).withParser( + new PlayerParser<>( + proxyServer + ) + ); + } + + /** + * Create a new required player argument + * + * @param name Argument name + * @param proxyServer Proxy server instance + * @param Command sender type + * @return Created argument + */ + public static @NonNull CommandArgument of( + final @NonNull String name, + final @NonNull ProxyServer proxyServer + ) { + return PlayerArgument.newBuilder(name, proxyServer).asRequired().build(); + } + + /** + * Create a new optional player argument + * + * @param name Argument name + * @param proxyServer Proxy server instance + * @param Command sender type + * @return Created argument + */ + public static @NonNull CommandArgument optional( + final @NonNull String name, + final @NonNull ProxyServer proxyServer + ) { + return PlayerArgument.newBuilder(name, proxyServer).asOptional().build(); + } + + + public static final class Builder extends CommandArgument.Builder { + + private final ProxyServer proxyServer; + + private Builder( + final @NonNull String name, + final @NonNull ProxyServer proxyServer + ) { + super(TypeToken.get(Player.class), name); + this.proxyServer = proxyServer; + } + + @Override + public @NonNull CommandArgument<@NonNull C, @NonNull Player> build() { + return new PlayerArgument<>( + this.proxyServer, + this.isRequired(), + this.getName(), + this.getSuggestionsProvider(), + new LinkedList<>() + ); + } + + } + + + public static final class PlayerParser implements ArgumentParser { + + private final ProxyServer proxyServer; + + /** + * Create a new player parser + * + * @param proxyServer Proxy server instance + */ + public PlayerParser( + @NonNull final ProxyServer proxyServer + ) { + this.proxyServer = proxyServer; + } + + @Override + public @NonNull ArgumentParseResult<@NonNull Player> parse( + @NonNull final CommandContext<@NonNull C> commandContext, + @NonNull final Queue<@NonNull String> inputQueue + ) { + final String input = inputQueue.peek(); + if (input == null) { + return ArgumentParseResult.failure( + new NullPointerException( + "No input was provided" + ) + ); + } + final Player player = this.proxyServer.getPlayer(input).orElse(null); + if (player == null) { + return ArgumentParseResult.failure( + new PlayerParseException( + input, + commandContext + ) + ); + } + inputQueue.remove(); + return ArgumentParseResult.success(player); + } + + @Override + public @NonNull List<@NonNull String> suggestions( + final @NonNull CommandContext commandContext, + final @NonNull String input + ) { + return this.proxyServer.getAllPlayers().stream().map(Player::getUsername).collect(Collectors.toList()); + } + + @Override + public boolean isContextFree() { + return true; + } + + } + + + public static final class PlayerParseException extends ParserException { + + private PlayerParseException( + final @NonNull String input, + final @NonNull CommandContext context + ) { + super( + PlayerParser.class, + context, + VelocityCaptionKeys.ARGUMENT_PARSE_FAILURE_PLAYER, + CaptionVariable.of("input", input) + ); + } + + } + +} diff --git a/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/arguments/package-info.java b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/arguments/package-info.java new file mode 100644 index 00000000..5caff6c5 --- /dev/null +++ b/cloud-minecraft/cloud-velocity/src/main/java/cloud/commandframework/velocity/arguments/package-info.java @@ -0,0 +1,28 @@ +// +// 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. +// + +/** + * Velocity specific argument types + */ +package cloud.commandframework.velocity.arguments; diff --git a/examples/example-velocity/build.gradle b/examples/example-velocity/build.gradle new file mode 100644 index 00000000..fbc9b352 --- /dev/null +++ b/examples/example-velocity/build.gradle @@ -0,0 +1,17 @@ +apply plugin: "com.github.johnrengelman.shadow" + +shadowJar { + dependencies { + exclude(dependency('com.velocitypowered:velocity-api')) + } +} + +build.dependsOn(shadowJar) + +dependencies { + api project(':cloud-velocity') + api project(':cloud-minecraft-extras') + api project(':cloud-annotations') + compileOnly('com.velocitypowered:velocity-api:1.1.0-SNAPSHOT') + annotationProcessor('com.velocitypowered:velocity-api:1.1.0-SNAPSHOT') +} diff --git a/examples/example-velocity/src/main/java/cloud/commandframework/examples/velocity/ExampleVelocityPlugin.java b/examples/example-velocity/src/main/java/cloud/commandframework/examples/velocity/ExampleVelocityPlugin.java new file mode 100644 index 00000000..c5c5f889 --- /dev/null +++ b/examples/example-velocity/src/main/java/cloud/commandframework/examples/velocity/ExampleVelocityPlugin.java @@ -0,0 +1,99 @@ +// +// 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.examples.velocity; + +import cloud.commandframework.execution.CommandExecutionCoordinator; +import cloud.commandframework.velocity.CloudInjectionModule; +import cloud.commandframework.velocity.VelocityCommandManager; +import cloud.commandframework.velocity.arguments.PlayerArgument; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.TypeLiteral; +import com.velocitypowered.api.command.CommandSource; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import net.kyori.adventure.identity.Identity; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.function.Function; +import java.util.logging.Logger; + +@Plugin( + id = "example-plugin", + name = "Cloud example plugin", + version = "1.1.0-SNAPSHOT" +) +public final class ExampleVelocityPlugin { + + @Inject + private ProxyServer server; + @Inject + private Logger logger; + @Inject + private Injector injector; + + /** + * Listener that listeners for the initialization event + * + * @param event Initialization event + */ + @Subscribe + public void onProxyInitialization(final @NonNull ProxyInitializeEvent event) { + final Injector childInjector = injector.createChildInjector( + new CloudInjectionModule<>( + CommandSource.class, + CommandExecutionCoordinator.simpleCoordinator(), + Function.identity(), + Function.identity() + ) + ); + final VelocityCommandManager commandManager = childInjector.getInstance( + Key.get(new TypeLiteral>() { + }) + ); + commandManager.command( + commandManager.commandBuilder("example") + .argument(PlayerArgument.of("player", this.server)) + .handler(context -> { + final Player player = context.get("player"); + context.getSender().sendMessage( + Identity.nil(), + Component.text().append( + Component.text("Selected ", NamedTextColor.GOLD) + ).append( + Component.text(player.getUsername(), NamedTextColor.AQUA) + ).build() + ); + } + ) + ); + } + +} diff --git a/examples/example-velocity/src/main/java/cloud/commandframework/examples/velocity/package-info.java b/examples/example-velocity/src/main/java/cloud/commandframework/examples/velocity/package-info.java new file mode 100644 index 00000000..e1911f03 --- /dev/null +++ b/examples/example-velocity/src/main/java/cloud/commandframework/examples/velocity/package-info.java @@ -0,0 +1,28 @@ +// +// 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. +// + +/** + * Example velocity plugin + */ +package cloud.commandframework.examples.velocity; diff --git a/settings.gradle b/settings.gradle index 0cd9f479..78841ac6 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,6 +15,7 @@ include(':example-bukkit') include(':example-javacord') include(':cloud-tasks') include(':cloud-sponge') +include(':example-velocity') project(':cloud-bukkit').projectDir = file('cloud-minecraft/cloud-bukkit') project(':cloud-paper').projectDir = file('cloud-minecraft/cloud-paper') project(':cloud-brigadier').projectDir = file('cloud-minecraft/cloud-brigadier') @@ -27,3 +28,4 @@ project(':cloud-jda').projectDir = file('cloud-discord/cloud-jda') project(':example-bukkit').projectDir = file('examples/example-bukkit') project(':example-javacord').projectDir = file('examples/example-javacord') project(':cloud-sponge').projectDir = file('cloud-minecraft/cloud-sponge') +project(':example-velocity').projectDir = file('examples/example-velocity')