✨ fix-commodore (#27)
This commit is contained in:
parent
8f8f98b189
commit
c3469706ab
14 changed files with 435 additions and 11 deletions
10
build.gradle
10
build.gradle
|
|
@ -21,6 +21,16 @@ checkstyle {
|
|||
configFile file('config/checkstyle/checkstyle.xml')
|
||||
}
|
||||
|
||||
gradle.taskGraph.whenReady {
|
||||
gradle.taskGraph.allTasks.each {
|
||||
if (it.project.name.contains('example')) {
|
||||
it.onlyIf {
|
||||
project.hasProperty('compile-examples')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'checkstyle'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// 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.annotations.specifier;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation used to make {@link cloud.commandframework.arguments.standard.StringArgument string arguments} greedy
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Greedy {
|
||||
}
|
||||
|
|
@ -55,6 +55,10 @@ public final class StandardParameters {
|
|||
* The command should be hidden from help menus, etc
|
||||
*/
|
||||
public static final ParserParameter<Boolean> HIDDEN = create("hidden", TypeToken.get(Boolean.class));
|
||||
/**
|
||||
* Indicates that a string argument should be greedy
|
||||
*/
|
||||
public static final ParserParameter<Boolean> GREEDY = create("greedy", TypeToken.get(Boolean.class));
|
||||
|
||||
private StandardParameters() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
//
|
||||
package cloud.commandframework.arguments.parser;
|
||||
|
||||
import cloud.commandframework.annotations.specifier.Greedy;
|
||||
import cloud.commandframework.arguments.standard.UUIDArgument;
|
||||
import cloud.commandframework.annotations.specifier.Completions;
|
||||
import cloud.commandframework.annotations.specifier.Range;
|
||||
|
|
@ -101,9 +102,15 @@ public final class StandardParserRegistry<C> implements ParserRegistry<C> {
|
|||
(double) options.get(StandardParameters.RANGE_MAX, Double.MAX_VALUE)));
|
||||
this.registerParserSupplier(TypeToken.get(Character.class), options -> new CharArgument.CharacterParser<C>());
|
||||
/* Make this one less awful */
|
||||
this.registerParserSupplier(TypeToken.get(String.class), options -> new StringArgument.StringParser<C>(
|
||||
StringArgument.StringMode.SINGLE, (context, s) ->
|
||||
Arrays.asList(options.get(StandardParameters.COMPLETIONS, new String[0]))));
|
||||
this.registerParserSupplier(TypeToken.get(String.class), options -> {
|
||||
final boolean greedy = options.get(StandardParameters.GREEDY, false);
|
||||
final StringArgument.StringMode stringMode = greedy
|
||||
? StringArgument.StringMode.GREEDY
|
||||
: StringArgument.StringMode.SINGLE;
|
||||
return new StringArgument.StringParser<C>(
|
||||
stringMode,
|
||||
(context, s) -> Arrays.asList(options.get(StandardParameters.COMPLETIONS, new String[0])));
|
||||
});
|
||||
/* Add options to this */
|
||||
this.registerParserSupplier(TypeToken.get(Boolean.class), options -> new BooleanArgument.BooleanParser<>(false));
|
||||
this.registerParserSupplier(TypeToken.get(UUID.class), options -> new UUIDArgument.UUIDParser<>());
|
||||
|
|
@ -276,4 +283,15 @@ public final class StandardParserRegistry<C> implements ParserRegistry<C> {
|
|||
|
||||
}
|
||||
|
||||
|
||||
private static final class GreedyMapper implements BiFunction<@NonNull Greedy, @NonNull TypeToken<?>,
|
||||
@NonNull ParserParameters> {
|
||||
|
||||
@Override
|
||||
public @NonNull ParserParameters apply(@NonNull final Greedy greedy, @NonNull final TypeToken<?> typeToken) {
|
||||
return ParserParameters.single(StandardParameters.GREEDY, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ You can check whether or not the running server supports Brigadier, by using `bu
|
|||
|
||||
## cloud-paper
|
||||
|
||||
An example plugin using the `cloud-paper` API can be found [here](https://github.com/Sauilitired/cloud/tree/master/examples/example-bukkit).
|
||||
|
||||
`cloud-paper`works on all Bukkit derivatives and has graceful fallbacks for cases where Paper specific features are missing. It is initialized the same way as the Bukkit manager, except `PaperCommandManager`is used instead. When using Paper 1.15+ Brigadier mappings are available even without commodore present.
|
||||
|
||||
### dependency
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ public final class CloudBrigadierManager<C, S> {
|
|||
* @param label Command label
|
||||
* @param cloudCommand Cloud command instance
|
||||
* @param permissionChecker Permission checker
|
||||
* @param forceRegister Whether or not to force register an executor at every node
|
||||
* @param executor Command executor
|
||||
* @return Literal command node
|
||||
*/
|
||||
|
|
@ -263,6 +264,7 @@ public final class CloudBrigadierManager<C, S> {
|
|||
final @NonNull Command<C> cloudCommand,
|
||||
final @NonNull BiPredicate<@NonNull S,
|
||||
@NonNull CommandPermission> permissionChecker,
|
||||
final boolean forceRegister,
|
||||
final com.mojang.brigadier.@NonNull Command<S> executor) {
|
||||
final CommandTree.Node<CommandArgument<C, ?>> node = this.commandManager
|
||||
.getCommandTree().getNamedNode(cloudCommand.getArguments().get(0).getName());
|
||||
|
|
@ -272,10 +274,13 @@ public final class CloudBrigadierManager<C, S> {
|
|||
.requires(sender -> permissionChecker.test(sender, (CommandPermission) node.getNodeMeta()
|
||||
.getOrDefault("permission",
|
||||
Permission.empty())));
|
||||
if (forceRegister || (node.getValue() != null && node.getValue().getOwningCommand() != null)) {
|
||||
literalArgumentBuilder.executes(executor);
|
||||
}
|
||||
literalArgumentBuilder.executes(executor);
|
||||
final LiteralCommandNode<S> constructedRoot = literalArgumentBuilder.build();
|
||||
for (final CommandTree.Node<CommandArgument<C, ?>> child : node.getChildren()) {
|
||||
constructedRoot.addChild(this.constructCommandNode(true, child,
|
||||
constructedRoot.addChild(this.constructCommandNode(forceRegister, child,
|
||||
permissionChecker, executor, provider).build());
|
||||
}
|
||||
return constructedRoot;
|
||||
|
|
|
|||
|
|
@ -72,14 +72,16 @@ public class BukkitPluginRegistrationHandler<C> implements CommandRegistrationHa
|
|||
public final boolean registerCommand(final @NonNull Command<?> command) {
|
||||
/* We only care about the root command argument */
|
||||
final CommandArgument<?, ?> commandArgument = command.getArguments().get(0);
|
||||
if (this.registeredCommands.containsKey(commandArgument)) {
|
||||
if (!(this.bukkitCommandManager.getCommandRegistrationHandler() instanceof CloudCommodoreManager)
|
||||
&& this.registeredCommands.containsKey(commandArgument)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String label;
|
||||
final String prefixedLabel = String.format("%s:%s", this.bukkitCommandManager.getOwningPlugin().getName(),
|
||||
commandArgument.getName()).toLowerCase();
|
||||
if (bukkitCommands.containsKey(commandArgument.getName())) {
|
||||
if (!(this.bukkitCommandManager.getCommandRegistrationHandler() instanceof CloudCommodoreManager)
|
||||
&& bukkitCommands.containsKey(commandArgument.getName())) {
|
||||
label = prefixedLabel;
|
||||
} else {
|
||||
label = commandArgument.getName();
|
||||
|
|
|
|||
|
|
@ -26,11 +26,17 @@ package cloud.commandframework.bukkit;
|
|||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.brigadier.CloudBrigadierManager;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import cloud.commandframework.permission.CommandPermission;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import me.lucko.commodore.Commodore;
|
||||
import me.lucko.commodore.CommodoreProvider;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@SuppressWarnings("ALL")
|
||||
class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
||||
|
|
@ -57,9 +63,28 @@ class CloudCommodoreManager<C> extends BukkitPluginRegistrationHandler<C> {
|
|||
final @NonNull BukkitCommand<C> bukkitCommand) {
|
||||
final com.mojang.brigadier.Command<?> cmd = o -> 1;
|
||||
final LiteralCommandNode<?> literalCommandNode = this.brigadierManager
|
||||
.createLiteralCommandNode(label, command, (o, p) -> true, cmd);
|
||||
this.commodore.register(bukkitCommand, literalCommandNode, p ->
|
||||
this.commandManager.hasPermission(commandManager.getCommandSenderMapper().apply(p),
|
||||
command.getCommandPermission()));
|
||||
.<Object>createLiteralCommandNode(label, command, (o, p) -> {
|
||||
final CommandSender sender = this.commodore.getBukkitSender(o);
|
||||
return this.commandManager.hasPermission(this.commandManager.getCommandSenderMapper().apply(sender),
|
||||
(CommandPermission) p);
|
||||
}, false, cmd);
|
||||
final CommandNode existingNode = this.commodore.getDispatcher().findNode(Collections.singletonList(label));
|
||||
if (existingNode != null) {
|
||||
this.mergeChildren(existingNode, literalCommandNode);
|
||||
} else {
|
||||
this.commodore.register(literalCommandNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeChildren(@Nullable final CommandNode<?> existingNode, @Nullable final CommandNode<?> node) {
|
||||
for (final CommandNode child : node.getChildren()) {
|
||||
final CommandNode<?> existingChild = existingNode.getChild(child.getName());
|
||||
if (existingChild == null) {
|
||||
existingNode.addChild(child);
|
||||
} else {
|
||||
this.mergeChildren(existingChild, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,4 +66,14 @@ public abstract class EntitySelector {
|
|||
public @NonNull String getSelector() {
|
||||
return this.selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the selector selected at least one entity
|
||||
*
|
||||
* @return {@code true} if at least one entity was selected, else {@code false}
|
||||
*/
|
||||
public boolean hasAny() {
|
||||
return !this.entities.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ final class VelocityPluginRegistrationHandler<C> implements CommandRegistrationH
|
|||
this.brigadierManager.createLiteralCommandNode(command.getArguments().get(0).getName(), (Command<C>) command,
|
||||
(c, p) -> this.manager.hasPermission(
|
||||
this.manager.getCommandSenderMapper()
|
||||
.apply(c), p),
|
||||
.apply(c), p), true,
|
||||
commandContext -> {
|
||||
final CommandSource source = commandContext.getSource();
|
||||
final String input = commandContext.getInput();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,276 @@
|
|||
//
|
||||
// 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.bukkit;
|
||||
|
||||
import cloud.commandframework.Command;
|
||||
import cloud.commandframework.CommandTree;
|
||||
import cloud.commandframework.Description;
|
||||
import cloud.commandframework.MinecraftHelp;
|
||||
import cloud.commandframework.annotations.AnnotationParser;
|
||||
import cloud.commandframework.annotations.Argument;
|
||||
import cloud.commandframework.annotations.CommandDescription;
|
||||
import cloud.commandframework.annotations.CommandMethod;
|
||||
import cloud.commandframework.annotations.CommandPermission;
|
||||
import cloud.commandframework.annotations.Confirmation;
|
||||
import cloud.commandframework.annotations.Flag;
|
||||
import cloud.commandframework.annotations.specifier.Greedy;
|
||||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ParserParameters;
|
||||
import cloud.commandframework.arguments.parser.StandardParameters;
|
||||
import cloud.commandframework.bukkit.BukkitCommandManager;
|
||||
import cloud.commandframework.bukkit.BukkitCommandMetaBuilder;
|
||||
import cloud.commandframework.bukkit.CloudBukkitCapabilities;
|
||||
import cloud.commandframework.bukkit.arguments.selector.SingleEntitySelector;
|
||||
import cloud.commandframework.bukkit.parsers.WorldArgument;
|
||||
import cloud.commandframework.bukkit.parsers.selector.SingleEntitySelectorArgument;
|
||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||
import cloud.commandframework.extra.confirmation.CommandConfirmationManager;
|
||||
import cloud.commandframework.meta.CommandMeta;
|
||||
import cloud.commandframework.paper.PaperCommandManager;
|
||||
import cloud.commandframework.types.tuples.Triplet;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Example plugin class
|
||||
*/
|
||||
public final class ExamplePlugin extends JavaPlugin {
|
||||
|
||||
private BukkitCommandManager<CommandSender> manager;
|
||||
private BukkitAudiences bukkitAudiences;
|
||||
private MinecraftHelp<CommandSender> minecraftHelp;
|
||||
private CommandConfirmationManager<CommandSender> confirmationManager;
|
||||
private AnnotationParser<CommandSender> annotationParser;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
//
|
||||
// This is a function that will provide a command execution coordinator that parses and executes commands
|
||||
// asynchronously
|
||||
//
|
||||
// final Function<CommandTree<CommandSender>, CommandExecutionCoordinator<CommandSender>> executionCoordinatorFunction =
|
||||
// AsynchronousCommandExecutionCoordinator.<CommandSender>newBuilder().build();
|
||||
//
|
||||
// However, in this example it is fine for us to run everything synchronously
|
||||
//
|
||||
final Function<CommandTree<CommandSender>, CommandExecutionCoordinator<CommandSender>> executionCoordinatorFunction =
|
||||
CommandExecutionCoordinator.simpleCoordinator();
|
||||
//
|
||||
// This function maps the command sender type of our choice to the bukkit command sender.
|
||||
// However, in this example we use the Bukkit command sender, and so we just need to map it
|
||||
// to itself
|
||||
//
|
||||
final Function<CommandSender, CommandSender> mapperFunction = Function.identity();
|
||||
try {
|
||||
this.manager = new PaperCommandManager<>(
|
||||
/* Owning plugin */ this,
|
||||
/* Coordinator function */ executionCoordinatorFunction,
|
||||
/* Command Sender -> C */ mapperFunction,
|
||||
/* C -> Command Sender */ mapperFunction
|
||||
);
|
||||
} catch (final Exception e) {
|
||||
this.getLogger().severe("Failed to initialize the command manager");
|
||||
/* Disable the plugin */
|
||||
this.getServer().getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
//
|
||||
// Create a BukkitAudiences instance (adventure) in order to use the minecraft-extras
|
||||
// help system
|
||||
//
|
||||
this.bukkitAudiences = BukkitAudiences.create(this);
|
||||
//
|
||||
// Create the Minecraft help menu system
|
||||
//
|
||||
this.minecraftHelp = new MinecraftHelp<>(
|
||||
/* Help Prefix */ "/example help",
|
||||
/* Audience mapper */ this.bukkitAudiences::sender,
|
||||
/* Manager */ this.manager
|
||||
);
|
||||
//
|
||||
// Register Brigadier mappings
|
||||
//
|
||||
if (manager.queryCapability(CloudBukkitCapabilities.BRIGADIER)) {
|
||||
manager.registerBrigadier();
|
||||
}
|
||||
//
|
||||
// Register asynchronous completions
|
||||
//
|
||||
if (manager.queryCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) {
|
||||
((PaperCommandManager<CommandSender>) this.manager).registerAsynchronousCompletions();
|
||||
}
|
||||
//
|
||||
// Create the confirmation manager. This allows us to require certain commands to be
|
||||
// confirmed before they can be executed
|
||||
//
|
||||
this.confirmationManager = new CommandConfirmationManager<>(
|
||||
/* Timeout */ 30L,
|
||||
/* Timeout unit */ TimeUnit.SECONDS,
|
||||
/* Action when confirmation is required */ context -> context.getCommandContext().getSender().sendMessage(
|
||||
ChatColor.RED + "Confirmation required. Confirm using /example confirm."),
|
||||
/* Action when no confirmation is pending */ sender -> sender.sendMessage(
|
||||
ChatColor.RED + "You don't have any pending commands.")
|
||||
);
|
||||
//
|
||||
// Register the confirmation processor. This will enable confirmations for commands that require it
|
||||
//
|
||||
this.confirmationManager.registerConfirmationProcessor(manager);
|
||||
//
|
||||
// Create the annotation parser. This allows you to define commands using methods annotated with
|
||||
// @CommandMethod
|
||||
//
|
||||
final Function<ParserParameters, CommandMeta> commandMetaFunction = p ->
|
||||
BukkitCommandMetaBuilder.builder()
|
||||
// This will allow you to decorate commands with descriptions
|
||||
.withDescription(p.get(StandardParameters.DESCRIPTION, "No description"))
|
||||
.build();
|
||||
this.annotationParser = new AnnotationParser<>(
|
||||
/* Manager */ this.manager,
|
||||
/* Command sender type */ CommandSender.class,
|
||||
/* Mapper for command meta instances */ commandMetaFunction
|
||||
);
|
||||
//
|
||||
// Create the commands
|
||||
//
|
||||
this.constructCommands();
|
||||
}
|
||||
|
||||
private void constructCommands() {
|
||||
//
|
||||
// Parse all @CommandMethod-annotated methods
|
||||
//
|
||||
this.annotationParser.parse(this);
|
||||
//
|
||||
// Base command builder
|
||||
//
|
||||
final Command.Builder<CommandSender> builder = this.manager.commandBuilder("example");
|
||||
//
|
||||
// Add a confirmation command
|
||||
//
|
||||
this.manager.command(builder.literal("confirm")
|
||||
.meta("description", "Confirm a pending command")
|
||||
.handler(this.confirmationManager.createConfirmationExecutionHandler()));
|
||||
//
|
||||
// Create a world argument
|
||||
//
|
||||
final CommandArgument<CommandSender, World> worldArgument = WorldArgument.of("world");
|
||||
//
|
||||
// Create a teleportation command
|
||||
//
|
||||
this.manager.command(builder.literal("teleport")
|
||||
.literal("me")
|
||||
// Require a player sender
|
||||
.withSenderType(Player.class)
|
||||
.argument(worldArgument, Description.of("World name"))
|
||||
.argumentTriplet(
|
||||
"coords",
|
||||
TypeToken.get(Vector.class),
|
||||
Triplet.of("x", "y", "z"),
|
||||
Triplet.of(Integer.class, Integer.class, Integer.class),
|
||||
triplet -> new Vector(triplet.getFirst(), triplet.getSecond(), triplet.getThird()),
|
||||
Description.of("Coordinates"))
|
||||
.handler(context -> {
|
||||
final Player player = (Player) context.getSender();
|
||||
final World world = context.get(worldArgument);
|
||||
final Vector coords = context.get("coords");
|
||||
final Location location = coords.toLocation(world);
|
||||
player.teleport(location);
|
||||
}))
|
||||
.command(builder.literal("teleport")
|
||||
.literal("entity")
|
||||
.withSenderType(Player.class)
|
||||
.argument(SingleEntitySelectorArgument.of("entity"),
|
||||
Description.of("Entity to teleport"))
|
||||
.literal("here")
|
||||
.handler(commandContext -> {
|
||||
final Player player = (Player) commandContext.getSender();
|
||||
final SingleEntitySelector singleEntitySelector = commandContext.get("entity");
|
||||
if (singleEntitySelector.hasAny()) {
|
||||
singleEntitySelector.getEntity().teleport(player);
|
||||
player.sendMessage(ChatColor.GREEN + "The entity was teleported to you!");
|
||||
} else {
|
||||
player.sendMessage(ChatColor.RED + "No entity matched your query.");
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@CommandMethod("example help [query]")
|
||||
@CommandDescription("Help menu")
|
||||
private void commandHelp(final @NonNull CommandSender sender,
|
||||
final @Argument("query") @Greedy String query) {
|
||||
this.minecraftHelp.queryCommands(query == null ? "" : query, sender);
|
||||
}
|
||||
|
||||
@Confirmation
|
||||
@CommandMethod("example clear")
|
||||
@CommandDescription("Clear your inventory")
|
||||
@CommandPermission("example.clear")
|
||||
private void commandClear(final @NonNull Player player) {
|
||||
player.getInventory().clear();
|
||||
this.bukkitAudiences.player(player)
|
||||
.sendMessage(Component.text("Your inventory has been cleared", NamedTextColor.GOLD));
|
||||
}
|
||||
|
||||
@CommandMethod("example give <material> <amount>")
|
||||
@CommandDescription("Give yourself an item")
|
||||
private void commandGive(final @NonNull Player player,
|
||||
final @NonNull @Argument("material") Material material,
|
||||
final @Argument("amount") int number,
|
||||
final @Nullable @Flag("color") ChatColor nameColor) {
|
||||
final ItemStack itemStack = new ItemStack(material, number);
|
||||
String itemName = String.format("%s's %s",
|
||||
player.getName(),
|
||||
material.name()
|
||||
.toLowerCase()
|
||||
.replace('_', ' '));
|
||||
if (nameColor != null) {
|
||||
itemName = nameColor + itemName;
|
||||
}
|
||||
final ItemMeta meta = itemStack.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(itemName);
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
player.getInventory().addItem(itemStack);
|
||||
player.sendMessage(ChatColor.GREEN + String.format("You have been given %d x %s", number, material));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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.
|
||||
//
|
||||
|
||||
/**
|
||||
* Bukkit example plugin
|
||||
*/
|
||||
package cloud.commandframework.examples.bukkit;
|
||||
4
examples/example-bukkit/src/main/resources/plugin.yml
Normal file
4
examples/example-bukkit/src/main/resources/plugin.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
name: ExamplePlugin
|
||||
version: 1.0.0
|
||||
api-version: 1.13
|
||||
main: cloud.commandframework.examples.bukkit.ExamplePlugin
|
||||
|
|
@ -12,6 +12,7 @@ include(':cloud-minecraft-extras')
|
|||
include(':cloud-cloudburst')
|
||||
include(':cloud-javacord')
|
||||
include(':cloud-jda')
|
||||
include(':example-bukkit')
|
||||
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')
|
||||
|
|
@ -21,3 +22,5 @@ project(':cloud-minecraft-extras').projectDir = file('cloud-minecraft/cloud-mine
|
|||
project(':cloud-cloudburst').projectDir = file('cloud-minecraft/cloud-cloudburst')
|
||||
project(':cloud-javacord').projectDir = file('cloud-discord/cloud-javacord')
|
||||
project(':cloud-jda').projectDir = file('cloud-discord/cloud-jda')
|
||||
project(':example-bukkit').projectDir = file('examples/example-bukkit')
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue