Add a confirmation system.
This commit is contained in:
parent
77cbf15faa
commit
3f59a81836
8 changed files with 266 additions and 3 deletions
|
|
@ -32,7 +32,9 @@ import com.intellectualsites.commands.arguments.parser.ArgumentParser;
|
||||||
import com.intellectualsites.commands.arguments.parser.ParserParameters;
|
import com.intellectualsites.commands.arguments.parser.ParserParameters;
|
||||||
import com.intellectualsites.commands.arguments.parser.StandardParameters;
|
import com.intellectualsites.commands.arguments.parser.StandardParameters;
|
||||||
import com.intellectualsites.commands.execution.CommandExecutionHandler;
|
import com.intellectualsites.commands.execution.CommandExecutionHandler;
|
||||||
|
import com.intellectualsites.commands.extra.confirmation.CommandConfirmationManager;
|
||||||
import com.intellectualsites.commands.meta.CommandMeta;
|
import com.intellectualsites.commands.meta.CommandMeta;
|
||||||
|
import com.intellectualsites.commands.meta.SimpleCommandMeta;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
@ -140,10 +142,15 @@ public final class AnnotationParser<C> {
|
||||||
/* Determine command name */
|
/* Determine command name */
|
||||||
final String commandToken = commandMethod.value().split(" ")[0].split("\\|")[0];
|
final String commandToken = commandMethod.value().split(" ")[0].split("\\|")[0];
|
||||||
@SuppressWarnings("ALL") final CommandManager manager = this.manager;
|
@SuppressWarnings("ALL") final CommandManager manager = this.manager;
|
||||||
|
final SimpleCommandMeta.Builder metaBuilder = SimpleCommandMeta.builder()
|
||||||
|
.with(this.metaFactory.apply(method.getAnnotations()));
|
||||||
|
if (method.isAnnotationPresent(Confirmation.class)) {
|
||||||
|
metaBuilder.with(CommandConfirmationManager.CONFIRMATION_REQUIRED_META, "true");
|
||||||
|
}
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
Command.Builder builder = manager.commandBuilder(commandToken,
|
Command.Builder builder = manager.commandBuilder(commandToken,
|
||||||
tokens.get(commandToken).getMinor(),
|
tokens.get(commandToken).getMinor(),
|
||||||
this.metaFactory.apply(method.getAnnotations()));
|
metaBuilder.build());
|
||||||
final Collection<ArgumentParameterPair> arguments = this.argumentExtractor.apply(method);
|
final Collection<ArgumentParameterPair> arguments = this.argumentExtractor.apply(method);
|
||||||
final Map<String, CommandArgument<C, ?>> commandArguments = Maps.newHashMap();
|
final Map<String, CommandArgument<C, ?>> commandArguments = Maps.newHashMap();
|
||||||
final Map<CommandArgument<C, ?>, String> argumentDescriptions = Maps.newHashMap();
|
final Map<CommandArgument<C, ?>, String> argumentDescriptions = Maps.newHashMap();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2020 Alexander Söderberg
|
||||||
|
//
|
||||||
|
// 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 com.intellectualsites.commands.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require confirmation for the command
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
public @interface Confirmation {
|
||||||
|
}
|
||||||
|
|
@ -58,7 +58,7 @@ import java.util.stream.Collectors;
|
||||||
* These arguments may be {@link StaticArgument literals} or variables. Command may either be required
|
* These arguments may be {@link StaticArgument literals} or variables. Command may either be required
|
||||||
* or optional, with the requirement that no optional argument precedes a required argument.
|
* or optional, with the requirement that no optional argument precedes a required argument.
|
||||||
* <p>
|
* <p>
|
||||||
* The {@link Command commands} are stored in this tree and the nodes of tree consists of the command
|
* The {@link Command commands} are stored in this tree and the nodes of tree consists of the command
|
||||||
* {@link CommandArgument arguments}. Each leaf node of the tree should containing a fully parsed
|
* {@link CommandArgument arguments}. Each leaf node of the tree should containing a fully parsed
|
||||||
* {@link Command}. It is thus possible to walk the tree and determine whether or not the supplied
|
* {@link Command}. It is thus possible to walk the tree and determine whether or not the supplied
|
||||||
* input from a command sender constitutes a proper command.
|
* input from a command sender constitutes a proper command.
|
||||||
|
|
@ -548,7 +548,7 @@ public final class CommandTree<C> {
|
||||||
public Node<CommandArgument<C, ?>> getNamedNode(@Nullable final String name) {
|
public Node<CommandArgument<C, ?>> getNamedNode(@Nullable final String name) {
|
||||||
for (final Node<CommandArgument<C, ?>> node : this.getRootNodes()) {
|
for (final Node<CommandArgument<C, ?>> node : this.getRootNodes()) {
|
||||||
if (node.getValue() != null && node.getValue() instanceof StaticArgument) {
|
if (node.getValue() != null && node.getValue() instanceof StaticArgument) {
|
||||||
final StaticArgument<C> staticArgument = (StaticArgument<C>) node.getValue();
|
@SuppressWarnings("unchecked") final StaticArgument<C> staticArgument = (StaticArgument<C>) node.getValue();
|
||||||
for (final String alias : staticArgument.getAliases()) {
|
for (final String alias : staticArgument.getAliases()) {
|
||||||
if (alias.equalsIgnoreCase(name)) {
|
if (alias.equalsIgnoreCase(name)) {
|
||||||
return node;
|
return node;
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@ public final class StandardParameters {
|
||||||
* Command description
|
* Command description
|
||||||
*/
|
*/
|
||||||
public static final ParserParameter<String> DESCRIPTION = create("description", TypeToken.of(String.class));
|
public static final ParserParameter<String> DESCRIPTION = create("description", TypeToken.of(String.class));
|
||||||
|
/**
|
||||||
|
* Command confirmation
|
||||||
|
*/
|
||||||
|
public static final ParserParameter<Boolean> CONFIRMATION = create("confirmation", TypeToken.of(Boolean.class));
|
||||||
/**
|
/**
|
||||||
* Command completions
|
* Command completions
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,160 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2020 Alexander Söderberg
|
||||||
|
//
|
||||||
|
// 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 com.intellectualsites.commands.extra.confirmation;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.intellectualsites.commands.CommandManager;
|
||||||
|
import com.intellectualsites.commands.execution.CommandExecutionHandler;
|
||||||
|
import com.intellectualsites.commands.execution.postprocessor.CommandPostprocessingContext;
|
||||||
|
import com.intellectualsites.commands.execution.postprocessor.CommandPostprocessor;
|
||||||
|
import com.intellectualsites.commands.meta.SimpleCommandMeta;
|
||||||
|
import com.intellectualsites.services.types.ConsumerService;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager for the command confirmation system that enables the ability to add "confirmation" requirements to commands,
|
||||||
|
* such that they need to be confirmed in order to be executed.
|
||||||
|
* <p>
|
||||||
|
* To use the confirmation system, the confirmation post processor needs to be added. To to this, use
|
||||||
|
* {@link #registerConfirmationProcessor(CommandManager)}. After this is done, a confirmation command has
|
||||||
|
* been added. To do this, create a command builder and attach {@link #createConfirmationExecutionHandler()}.
|
||||||
|
* <p>
|
||||||
|
* To require a command to be confirmed, use {@link #decorate(SimpleCommandMeta.Builder)} on the command meta builder.
|
||||||
|
*
|
||||||
|
* @param <C> Command sender type
|
||||||
|
*/
|
||||||
|
public class CommandConfirmationManager<C> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meta data stored for commands that require confirmation
|
||||||
|
*/
|
||||||
|
public static final String CONFIRMATION_REQUIRED_META = "__REQUIRE_CONFIRMATION__";
|
||||||
|
|
||||||
|
private final Consumer<CommandPostprocessingContext<C>> notifier;
|
||||||
|
private final Consumer<C> errorNotifier;
|
||||||
|
private final Cache<C, CommandPostprocessingContext<C>> pendingCommands;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new confirmation manager instance
|
||||||
|
*
|
||||||
|
* @param timeout Timeout value
|
||||||
|
* @param timeoutTimeUnit Timeout time unit
|
||||||
|
* @param notifier Notifier that gets called when a command gets added to the queue
|
||||||
|
* @param errorNotifier Notifier that gets called when someone tries to confirm a command with nothing in the queue
|
||||||
|
*/
|
||||||
|
public CommandConfirmationManager(final long timeout,
|
||||||
|
@Nonnull final TimeUnit timeoutTimeUnit,
|
||||||
|
@Nonnull final Consumer<CommandPostprocessingContext<C>> notifier,
|
||||||
|
@Nonnull final Consumer<C> errorNotifier) {
|
||||||
|
this.notifier = notifier;
|
||||||
|
this.errorNotifier = errorNotifier;
|
||||||
|
this.pendingCommands = CacheBuilder.newBuilder().expireAfterWrite(timeout, timeoutTimeUnit).concurrencyLevel(1).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void notifyConsumer(@Nonnull final CommandPostprocessingContext<C> context) {
|
||||||
|
this.notifier.accept(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPending(@Nonnull final CommandPostprocessingContext<C> context) {
|
||||||
|
this.pendingCommands.put(context.getCommandContext().getSender(), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a pending context if one is stored for the sender
|
||||||
|
*
|
||||||
|
* @param sender Sender
|
||||||
|
* @return Optional containing the post processing context if one has been stored, else {@link Optional#empty()}
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public Optional<CommandPostprocessingContext<C>> getPending(@Nonnull final C sender) {
|
||||||
|
return Optional.ofNullable(this.pendingCommands.getIfPresent(sender));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorate a simple command meta builder, to require confirmation for a command
|
||||||
|
*
|
||||||
|
* @param builder Command meta builder
|
||||||
|
* @return Builder instance
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public SimpleCommandMeta.Builder decorate(@Nonnull final SimpleCommandMeta.Builder builder) {
|
||||||
|
return builder.with(CONFIRMATION_REQUIRED_META, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the confirmation processor in the command manager
|
||||||
|
*
|
||||||
|
* @param manager Command manager
|
||||||
|
*/
|
||||||
|
public void registerConfirmationProcessor(@Nonnull final CommandManager<C> manager) {
|
||||||
|
manager.registerCommandPostProcessor(new CommandConfirmationPostProcessor());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an execution handler for a confirmation command
|
||||||
|
*
|
||||||
|
* @return Handler for a confirmation command
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public CommandExecutionHandler<C> createConfirmationExecutionHandler() {
|
||||||
|
return context -> {
|
||||||
|
final Optional<CommandPostprocessingContext<C>> pending = this.getPending(context.getSender());
|
||||||
|
if (pending.isPresent()) {
|
||||||
|
final CommandPostprocessingContext<C> postprocessingContext = pending.get();
|
||||||
|
postprocessingContext.getCommand()
|
||||||
|
.getCommandExecutionHandler()
|
||||||
|
.execute(postprocessingContext.getCommandContext());
|
||||||
|
} else {
|
||||||
|
this.errorNotifier.accept(context.getSender());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final class CommandConfirmationPostProcessor implements CommandPostprocessor<C> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(@Nonnull final CommandPostprocessingContext<C> context) {
|
||||||
|
if (!context.getCommand()
|
||||||
|
.getCommandMeta()
|
||||||
|
.getOrDefault(CONFIRMATION_REQUIRED_META, "false")
|
||||||
|
.equals("true")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Add it to the "queue" */
|
||||||
|
addPending(context);
|
||||||
|
/* Notify the consumer that a confirmation is required */
|
||||||
|
notifyConsumer(context);
|
||||||
|
/* Interrupt */
|
||||||
|
ConsumerService.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
//
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2020 Alexander Söderberg
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirmation system
|
||||||
|
*/
|
||||||
|
package com.intellectualsites.commands.extra.confirmation;
|
||||||
|
|
@ -107,6 +107,18 @@ public class SimpleCommandMeta extends CommandMeta {
|
||||||
private Builder() {
|
private Builder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all values from another command meta instance
|
||||||
|
*
|
||||||
|
* @param commandMeta Existing instance
|
||||||
|
* @return Builder instance
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public Builder with(@Nonnull final CommandMeta commandMeta) {
|
||||||
|
commandMeta.getAll().forEach(this::with);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a new key-value pair in the meta map
|
* Store a new key-value pair in the meta map
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ package com.intellectualsites.commands;
|
||||||
import com.intellectualsites.commands.annotations.AnnotationParser;
|
import com.intellectualsites.commands.annotations.AnnotationParser;
|
||||||
import com.intellectualsites.commands.annotations.Argument;
|
import com.intellectualsites.commands.annotations.Argument;
|
||||||
import com.intellectualsites.commands.annotations.CommandMethod;
|
import com.intellectualsites.commands.annotations.CommandMethod;
|
||||||
|
import com.intellectualsites.commands.annotations.Confirmation;
|
||||||
import com.intellectualsites.commands.annotations.Description;
|
import com.intellectualsites.commands.annotations.Description;
|
||||||
import com.intellectualsites.commands.annotations.specifier.Completions;
|
import com.intellectualsites.commands.annotations.specifier.Completions;
|
||||||
import com.intellectualsites.commands.annotations.specifier.Range;
|
import com.intellectualsites.commands.annotations.specifier.Range;
|
||||||
|
|
@ -43,6 +44,7 @@ import com.intellectualsites.commands.bukkit.CloudBukkitCapabilities;
|
||||||
import com.intellectualsites.commands.bukkit.parsers.WorldArgument;
|
import com.intellectualsites.commands.bukkit.parsers.WorldArgument;
|
||||||
import com.intellectualsites.commands.execution.AsynchronousCommandExecutionCoordinator;
|
import com.intellectualsites.commands.execution.AsynchronousCommandExecutionCoordinator;
|
||||||
import com.intellectualsites.commands.execution.CommandExecutionCoordinator;
|
import com.intellectualsites.commands.execution.CommandExecutionCoordinator;
|
||||||
|
import com.intellectualsites.commands.extra.confirmation.CommandConfirmationManager;
|
||||||
import com.intellectualsites.commands.meta.SimpleCommandMeta;
|
import com.intellectualsites.commands.meta.SimpleCommandMeta;
|
||||||
import com.intellectualsites.commands.paper.PaperCommandManager;
|
import com.intellectualsites.commands.paper.PaperCommandManager;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
|
|
@ -61,6 +63,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
@ -100,6 +103,14 @@ public final class BukkitTest extends JavaPlugin {
|
||||||
getLogger().warning("Failed to register asynchronous command completions: " + e.getMessage());
|
getLogger().warning("Failed to register asynchronous command completions: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final CommandConfirmationManager<CommandSender> confirmationManager = new CommandConfirmationManager<>(
|
||||||
|
30,
|
||||||
|
TimeUnit.SECONDS,
|
||||||
|
c -> c.getCommandContext().getSender().sendMessage(ChatColor.RED + "Oh no. Confirm using /cloud confirm!"),
|
||||||
|
c -> c.sendMessage(ChatColor.RED + "You don't have any pending commands!")
|
||||||
|
);
|
||||||
|
confirmationManager.registerConfirmationProcessor(mgr);
|
||||||
|
|
||||||
final AnnotationParser<CommandSender> annotationParser
|
final AnnotationParser<CommandSender> annotationParser
|
||||||
= new AnnotationParser<>(mgr, CommandSender.class, p ->
|
= new AnnotationParser<>(mgr, CommandSender.class, p ->
|
||||||
BukkitCommandMetaBuilder.builder().withDescription(p.get(StandardParameters.DESCRIPTION,
|
BukkitCommandMetaBuilder.builder().withDescription(p.get(StandardParameters.DESCRIPTION,
|
||||||
|
|
@ -185,6 +196,9 @@ public final class BukkitTest extends JavaPlugin {
|
||||||
.build())
|
.build())
|
||||||
.command(mgr.commandBuilder("annotationass").handler(c -> c.getSender()
|
.command(mgr.commandBuilder("annotationass").handler(c -> c.getSender()
|
||||||
.sendMessage(ChatColor.YELLOW + "Du e en ananas!")).build())
|
.sendMessage(ChatColor.YELLOW + "Du e en ananas!")).build())
|
||||||
|
.command(mgr.commandBuilder("cloud")
|
||||||
|
.literal("confirm")
|
||||||
|
.handler(confirmationManager.createConfirmationExecutionHandler()).build())
|
||||||
.command(mgr.commandBuilder("cloud")
|
.command(mgr.commandBuilder("cloud")
|
||||||
.literal("help")
|
.literal("help")
|
||||||
.argument(StringArgument.<CommandSender>newBuilder("query").greedy()
|
.argument(StringArgument.<CommandSender>newBuilder("query").greedy()
|
||||||
|
|
@ -207,6 +221,7 @@ public final class BukkitTest extends JavaPlugin {
|
||||||
player.sendMessage(ChatColor.GOLD + "Your input was: " + ChatColor.AQUA + input + ChatColor.GREEN + " (" + number + ")");
|
player.sendMessage(ChatColor.GOLD + "Your input was: " + ChatColor.AQUA + input + ChatColor.GREEN + " (" + number + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Confirmation
|
||||||
@CommandMethod("cloud debug")
|
@CommandMethod("cloud debug")
|
||||||
private void doHelp() {
|
private void doHelp() {
|
||||||
final Set<CloudBukkitCapabilities> capabilities = this.mgr.queryCapabilities();
|
final Set<CloudBukkitCapabilities> capabilities = this.mgr.queryCapabilities();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue