.
This commit is contained in:
parent
4373584285
commit
5b5cb04f8b
46 changed files with 744 additions and 334 deletions
|
|
@ -6,8 +6,11 @@ import de.kentoj.scrow.bukkit.services.command.CommandManager;
|
|||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ScrowAPI {
|
||||
|
|
@ -18,6 +21,8 @@ public class ScrowAPI {
|
|||
private static EconomyService economyService;
|
||||
@Getter
|
||||
private static CommandManager commandManager;
|
||||
@Getter
|
||||
private static Scheduler minecraftScheduler;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void setDatabase(@Nullable MongoDatabase database) {
|
||||
|
|
@ -33,5 +38,10 @@ public class ScrowAPI {
|
|||
public static void setCommandManager(CommandManager commandManager) {
|
||||
ScrowAPI.commandManager = commandManager;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void setMinecraftScheduler(Scheduler minecraftScheduler) {
|
||||
ScrowAPI.minecraftScheduler = minecraftScheduler;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package de.kentoj.scrow.bukkit.services.command;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.arg.ArgumentType;
|
||||
import de.kentoj.scrow.bukkit.services.command.type.ArgumentType;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
// TODO convert to interface
|
||||
@Value
|
||||
public class CommandArgument<T> {
|
||||
int index;
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.services.command;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface CommandContext {
|
||||
|
||||
CommandSender getSender();
|
||||
|
||||
Player getSenderPlayer();
|
||||
|
||||
Entity getSenderEntity();
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.services.command;
|
||||
|
||||
public interface CommandExecutionContext extends CommandContext {
|
||||
|
||||
<T> T getArg(String key);
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
package de.kentoj.scrow.bukkit.services.command;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
|
||||
public interface CommandExecutor {
|
||||
|
||||
/**
|
||||
* @return true on success, 1 on failure
|
||||
*/
|
||||
void execute(CommandExecutionContext ctx);
|
||||
void execute(CommandContext ctx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package de.kentoj.scrow.bukkit.services.command;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNode;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public interface CommandManager {
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.services.command;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.arg.ArgumentType;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
// TODO javadoc
|
||||
public interface CommandNode {
|
||||
|
||||
<T> void addArg(String name, ArgumentType<T> type, @Nullable Function<CommandContext, T> defaultValue);
|
||||
|
||||
default <T> void addArg(String name, ArgumentType<T> type) {
|
||||
addArg(name, type, null);
|
||||
}
|
||||
|
||||
void addSubCommand(CommandNode subCommand);
|
||||
|
||||
void setPermission(@Nullable Permission permission);
|
||||
|
||||
default void setPermission(String permission) {
|
||||
setPermission(new Permission(permission));
|
||||
}
|
||||
|
||||
@Nullable Permission getPermission();
|
||||
|
||||
@Nullable CommandArgument<?> getArg(int index);
|
||||
|
||||
List<CommandNode> getSubCommands();
|
||||
|
||||
String getName();
|
||||
|
||||
String[] getAliases();
|
||||
|
||||
String getDescription();
|
||||
|
||||
@Nullable CommandExecutor getExecutor();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package de.kentoj.scrow.bukkit.services.command;
|
||||
|
||||
public interface CommandReader {
|
||||
|
||||
boolean isEOF();
|
||||
|
||||
String readWord();
|
||||
|
||||
String readQuotedString();
|
||||
|
||||
int getCursor();
|
||||
|
||||
void setCursor(int cursor);
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.arg;
|
||||
|
||||
public interface ArgumentType<S> {
|
||||
|
||||
S parseInput(String str);
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.arg;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
// FIXME module stuff
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class PlayerArgumentType {
|
||||
|
||||
public static final ArgumentType<Player> player = str -> {
|
||||
if (str.length() == 36) {
|
||||
var uuid = UUID.fromString(str);
|
||||
return Bukkit.getPlayer(uuid);
|
||||
} else {
|
||||
return Bukkit.getPlayer(str);
|
||||
}
|
||||
};
|
||||
|
||||
public static final ArgumentType<OfflinePlayer> offlinePlayer = str -> {
|
||||
var uuid = UUID.fromString(str);
|
||||
return Bukkit.getOfflinePlayer(uuid);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.cmds2;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.type.ArgumentType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface CommandArgument<T> {
|
||||
|
||||
ArgumentType<T> getType();
|
||||
|
||||
@Nullable T getDefaultValue(CommandContext ctx);
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.cmds2;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface SuggestionProvider {
|
||||
|
||||
Set<String> suggest(CommandContext context);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.cmds2.node;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.type.ArgumentType;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public non-sealed interface ArgumentCommandNode extends CommandNode {
|
||||
|
||||
<T> ArgumentType<T> getArgument(String name);
|
||||
|
||||
void addArgument(String name, ArgumentType<?> arg);
|
||||
<T> void addArgument(String name, ArgumentType<T> arg, Function<CommandContext, T> getDefault);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.cmds2.node;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutor;
|
||||
import de.kentoj.scrow.bukkit.services.command.cmds2.SuggestionProvider;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public sealed interface CommandNode permits LiteralCommandNode, ArgumentCommandNode, RootCommandNode {
|
||||
|
||||
void setName(String name);
|
||||
String getName();
|
||||
|
||||
void addSubNode(CommandNode node);
|
||||
@Nullable CommandNode getSubNode(String rawArg);
|
||||
boolean hasNextNode();
|
||||
|
||||
void setExecutor(@Nullable CommandExecutor executor);
|
||||
@Nullable CommandExecutor getExecutor();
|
||||
|
||||
void setSuggestionProvider(SuggestionProvider suggestionProvider);
|
||||
SuggestionProvider getSuggestionProvider();
|
||||
|
||||
void setDescription(@Nullable String description);
|
||||
@Nullable String getDescription();
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.cmds2.node;
|
||||
|
||||
import org.bukkit.permissions.Permission;
|
||||
|
||||
public non-sealed interface LiteralCommandNode extends CommandNode {
|
||||
|
||||
Permission getRequiredPermission();
|
||||
|
||||
void setRequiredPermission(Permission permission);
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.cmds2.node;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public non-sealed interface RootCommandNode extends CommandNode, LiteralCommandNode {
|
||||
|
||||
Set<String> getAliases();
|
||||
|
||||
void setAliases(Set<String> aliases);
|
||||
|
||||
void addAliases(String... aliases);
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.context;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface CommandContext {
|
||||
|
||||
CommandSender getSender();
|
||||
|
||||
Player getSenderPlayer();
|
||||
|
||||
Entity getSenderEntity();
|
||||
|
||||
/**
|
||||
* @return Object that is parsed from the raw argument
|
||||
* @throws CommandSyntaxException if no value given and no default value supplied
|
||||
*/
|
||||
<T> T getArg(String key);
|
||||
|
||||
/**
|
||||
* @return string argument used at invocation
|
||||
*/
|
||||
@Nullable String getRawArgument(String key);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.exception;
|
||||
|
||||
/**
|
||||
* When a command has a syntax issue.
|
||||
* {@code CommandSyntaxException::getMessage} should return a user-friendly message explaining the issue.
|
||||
*/
|
||||
public class CommandSyntaxException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* @param message user-friendly message
|
||||
*/
|
||||
public CommandSyntaxException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message user-friendly message
|
||||
*/
|
||||
public CommandSyntaxException(String message, Throwable throwable) {
|
||||
super(message + ": " + throwable.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.node;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutor;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
// TODO javadoc
|
||||
public interface CommandNode {
|
||||
|
||||
void setPermission(@Nullable Permission permission);
|
||||
|
||||
default void setPermission(String permission) {
|
||||
setPermission(new Permission(permission));
|
||||
}
|
||||
|
||||
void setDescription(String description);
|
||||
|
||||
void setAliases(Set<String> aliases);
|
||||
|
||||
void addAlias(String... aliases);
|
||||
|
||||
void setExecutor(@Nullable CommandExecutor executor);
|
||||
|
||||
@Nullable Permission getPermission();
|
||||
|
||||
String getName();
|
||||
|
||||
Set<String> getAliases();
|
||||
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* Function that should be called when invoking this command.
|
||||
* The executor shall only be called when this node is the last CommandNode in the invocation.
|
||||
* <pre>
|
||||
* - RootCommand(CommandNode)
|
||||
* - has executor
|
||||
* - has sub-command(CommandNode)
|
||||
* - has executor
|
||||
* </pre>
|
||||
* In this case, the sub-command is optional. If the sub-command is used, the sub-command's executor will be used.
|
||||
* Else the RootCommand's executor will be used.
|
||||
*/
|
||||
@Nullable CommandExecutor getExecutor();
|
||||
|
||||
default boolean hasExecutor() {
|
||||
return getExecutor() != null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.node;
|
||||
|
||||
public interface CommandNodeFactory {
|
||||
|
||||
CommandNodeWithSubCommand createNodeWithSubCommands(String name);
|
||||
|
||||
CommandNodeWithArguments createNodeWithArguments(String name);
|
||||
|
||||
CommandNode createRootNode(String name);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.node;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class CommandNodeRepository {
|
||||
|
||||
private static CommandNodeFactory commandNodeFactory;
|
||||
|
||||
public static CommandNodeWithArguments withArguments(String name) {
|
||||
return commandNodeFactory.createNodeWithArguments(name);
|
||||
}
|
||||
|
||||
public static CommandNodeWithSubCommand withSubCommands(String name) {
|
||||
return commandNodeFactory.createNodeWithSubCommands(name);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void setCommandNodeFactory(CommandNodeFactory commandNodeFactory) {
|
||||
CommandNodeRepository.commandNodeFactory = commandNodeFactory;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.node;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandArgument;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.type.ArgumentType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A CommandNode which can have arguments
|
||||
*/
|
||||
public interface CommandNodeWithArguments extends CommandNode {
|
||||
|
||||
/**
|
||||
* Adds an argument to the node.
|
||||
* @param defaultValue Function returning a defaultValue if no value is given at invocation. \
|
||||
* May be null if the argument should be required and not optional.
|
||||
* @throws IllegalStateException if the previous argument is optional(defaultValue is set) and this is not.
|
||||
*/
|
||||
<T> void addArg(String name, ArgumentType<T> type, @Nullable Function<CommandContext, T> defaultValue);
|
||||
|
||||
/**
|
||||
* Adds a required argument to the node
|
||||
* @throws IllegalStateException if the previous argument is optional(defaultValue is set) and this is not.
|
||||
*/
|
||||
default <T> void addArg(String name, ArgumentType<T> type) {
|
||||
addArg(name, type, null);
|
||||
}
|
||||
|
||||
@Nullable CommandArgument<?> getArg(int index);
|
||||
|
||||
@Nullable CommandArgument<?> getArg(String name);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.node;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A CommandNode which can have sub-commands
|
||||
*/
|
||||
public interface CommandNodeWithSubCommand extends CommandNode {
|
||||
|
||||
List<CommandNode> getSubCommands();
|
||||
|
||||
void addSubCommand(CommandNode subCommand);
|
||||
|
||||
/**
|
||||
* @return SubCommand node where a name or alias matches label
|
||||
*/
|
||||
@Nullable CommandNode getSubCommand(String label);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.type;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandReader;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface ArgumentType<T> {
|
||||
|
||||
/**
|
||||
* @throws CommandSyntaxException if the given value may not be used
|
||||
*/
|
||||
void checkValue(CommandContext ctx, T value, String rawValue) throws CommandSyntaxException;
|
||||
|
||||
Set<String> getDefaultSuggestions(CommandContext ctx);
|
||||
|
||||
T parseInput(CommandReader reader);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package de.kentoj.scrow.bukkit.services.command.type;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandReader;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
// TODO add livingEntity
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class EntityArgumentType {
|
||||
|
||||
private static final ArgumentType<Player> player = new ArgumentType<>() {
|
||||
@Override
|
||||
public void checkValue(CommandContext ctx, Player value, String rawValue) throws CommandSyntaxException {
|
||||
if (value == null)
|
||||
throw new CommandSyntaxException("Player is not online -- " + rawValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getDefaultSuggestions(CommandContext ctx) {
|
||||
return Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player parseInput(CommandReader reader) {
|
||||
final var word = reader.readWord();
|
||||
if (word.length() == 36) {
|
||||
var uuid = UUID.fromString(word);
|
||||
return Bukkit.getPlayer(uuid);
|
||||
} else {
|
||||
return Bukkit.getPlayerExact(word);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static ArgumentType<Player> player() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
package de.kentoj.scrow.bukkit;
|
||||
|
||||
import de.kentoj.scrow.bukkit.friends.casd.FriendCommand;
|
||||
import de.kentoj.scrow.bukkit.friends.command.LaunchCommand;
|
||||
import me.lucko.commodore.CommodoreProvider;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
|
@ -13,7 +10,7 @@ public class CoreImplPlugin extends JavaPlugin {
|
|||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
ScrowAPISurface.initScrowAPI(false);
|
||||
ScrowAPISurface.initScrowAPI(this, false);
|
||||
|
||||
{
|
||||
ScrowAPI.getCommandManager().register(new LaunchCommand(), this);
|
||||
|
|
|
|||
|
|
@ -5,21 +5,30 @@ import com.mongodb.MongoClientSettings;
|
|||
import com.mongodb.reactivestreams.client.MongoClient;
|
||||
import com.mongodb.reactivestreams.client.MongoClients;
|
||||
import de.kentoj.scrow.bukkit.command.bukkit.CommandManagerImpl;
|
||||
import de.kentoj.scrow.bukkit.command.node.CommandNodeFactoryImpl;
|
||||
import de.kentoj.scrow.bukkit.economy.InMemoryEconomyService;
|
||||
import de.kentoj.scrow.bukkit.economy.MongoEconomyService;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeRepository;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.bson.UuidRepresentation;
|
||||
import org.bson.codecs.configuration.CodecRegistries;
|
||||
import org.bson.codecs.pojo.PojoCodecProvider;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ScrowAPISurface {
|
||||
|
||||
private static @Nullable MongoClient databaseClient = null;
|
||||
|
||||
public static void initScrowAPI(boolean enableDatabase) {
|
||||
public static void initScrowAPI(Plugin plugin, boolean enableDatabase) {
|
||||
ScrowAPI.setMinecraftScheduler(Schedulers.fromExecutor(cmd -> {
|
||||
Bukkit.getScheduler().runTask(plugin, cmd);
|
||||
}));
|
||||
|
||||
if (enableDatabase) {
|
||||
var pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build();
|
||||
var codecRegistry = CodecRegistries.fromRegistries(
|
||||
|
|
@ -39,6 +48,7 @@ public class ScrowAPISurface {
|
|||
new MongoEconomyService(ScrowAPI.getDatabase()) : new InMemoryEconomyService()
|
||||
);
|
||||
|
||||
CommandNodeRepository.setCommandNodeFactory(new CommandNodeFactoryImpl());
|
||||
ScrowAPI.setCommandManager(new CommandManagerImpl());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package de.kentoj.scrow.bukkit.cmds2;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.cmds2.node.ArgumentCommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.cmds2.node.CommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.cmds2.node.LiteralCommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.cmds2.node.RootCommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BukkitCommand extends Command {
|
||||
|
||||
private final RootCommandNode rootCommandNode;
|
||||
|
||||
protected BukkitCommand(RootCommandNode rootCommandNode) {
|
||||
super(rootCommandNode.getName());
|
||||
this.rootCommandNode = rootCommandNode;
|
||||
|
||||
if (rootCommandNode.getDescription() != null) {
|
||||
super.setDescription(rootCommandNode.getDescription());
|
||||
}
|
||||
if (rootCommandNode.getAliases() != null) {
|
||||
super.setAliases(rootCommandNode.getAliases().stream().toList());
|
||||
}
|
||||
// TODO usage string?
|
||||
}
|
||||
|
||||
private void processCommand(@NotNull CommandSender sender, @NotNull String commandLabel,
|
||||
@NotNull String[] args) throws CommandSyntaxException {
|
||||
CommandNode node = rootCommandNode;
|
||||
int argsIndex = 0;
|
||||
|
||||
while (node.hasNextNode()) {
|
||||
if (args.length - 1 < argsIndex) {
|
||||
if (node)
|
||||
}
|
||||
|
||||
if (node instanceof LiteralCommandNode literal) {
|
||||
|
||||
node = literal.getSubNode(args[argsIndex]);
|
||||
if (node == null) {
|
||||
throw new CommandSyntaxException("Invalid argument -- " + args[argsIndex])
|
||||
}
|
||||
} else if (node instanceof ArgumentCommandNode) {
|
||||
|
||||
}
|
||||
|
||||
argsIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package de.kentoj.scrow.bukkit.cmds2;
|
||||
|
||||
import de.kentoj.scrow.bukkit.ScrowAPI;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutor;
|
||||
import de.kentoj.scrow.bukkit.services.command.cmds2.node.ArgumentCommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.cmds2.node.LiteralCommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.type.EntityArgumentType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
public class CoinsCommand implements CommandExecutor {
|
||||
|
||||
public CoinsCommand() {
|
||||
final ArgumentCommandNode node = null;
|
||||
node.addArgument("player", EntityArgumentType.player(), CommandContext::getSenderPlayer);
|
||||
node.setExecutor(this::displayCoins);
|
||||
|
||||
final LiteralCommandNode setLiteral;
|
||||
node.addSubNode(setLiteral);
|
||||
setLiteral
|
||||
{
|
||||
final ArgumentCommandNode specifyPlayerNode = null /* TODO */;
|
||||
|
||||
node.addSubNode(specifyPlayerNode);
|
||||
specifyPlayerNode.addArgument("player", EntityArgumentType.player(), CommandContext::getSenderPlayer);
|
||||
specifyPlayerNode.setExecutor(this::setCoins);
|
||||
}
|
||||
}
|
||||
|
||||
private void displayCoins(CommandContext ctx) {
|
||||
final Player player = ctx.getArg("player");
|
||||
|
||||
ScrowAPI.getEconomyService()
|
||||
.getCoins(player.getUniqueId())
|
||||
.subscribeOn(Schedulers.boundedElastic())
|
||||
.publishOn(ScrowAPI.getMinecraftScheduler())
|
||||
.subscribe(coins -> {
|
||||
player.sendMessage("You have " + coins + "$");
|
||||
}, err -> {
|
||||
player.sendMessage("Error fetching coins: " + err.getMessage());
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Failed fetching coins for " + player.getUniqueId(), err);
|
||||
});
|
||||
}
|
||||
|
||||
public void setCoins(CommandContext ctx) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutor;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandArgument;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.arg.ArgumentType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class AbstractCommandNode implements CommandNode {
|
||||
|
||||
private final List<CommandNode> subCommands = new ArrayList<>();
|
||||
private final List<CommandArgument<?>> args = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
@Getter
|
||||
private final String[] aliases;
|
||||
@Getter
|
||||
private @Nullable Permission permission = null;
|
||||
@Getter
|
||||
@Setter(value = AccessLevel.PROTECTED)
|
||||
private @Nullable String description;
|
||||
@Getter
|
||||
@Setter(value = AccessLevel.PROTECTED)
|
||||
private @Nullable CommandExecutor executor = null;
|
||||
|
||||
public AbstractCommandNode(String name, String... aliases) {
|
||||
this.name = name;
|
||||
this.aliases = aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void addArg(String name, ArgumentType<T> type, Function<CommandContext, T> defaultValue) {
|
||||
var index = args.size();
|
||||
if (index > 0) {
|
||||
boolean isPreviousArgumentOptional = args.get(index - 1).getDefaultValue() != null;
|
||||
boolean isNewArgumentOptional = defaultValue != null;
|
||||
if (isPreviousArgumentOptional && !isNewArgumentOptional) {
|
||||
// TODO document in javadoc
|
||||
throw new IllegalStateException("an optional argument(an argument with a defaultValue set) may not be followed by a required argument");
|
||||
}
|
||||
}
|
||||
args.add(new CommandArgument<>(index, name, type, defaultValue));
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSubCommand(CommandNode subCommand) {
|
||||
subCommands.add(subCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermission(@Nullable Permission permission) {
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CommandArgument<?> getArg(int index) {
|
||||
return args.stream()
|
||||
.filter(ra -> ra.getIndex() == index)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CommandNode> getSubCommands() {
|
||||
return ImmutableList.copyOf(subCommands);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package de.kentoj.scrow.bukkit.command;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
|
|
|||
|
|
@ -1,21 +1,48 @@
|
|||
package de.kentoj.scrow.bukkit.command;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutionContext;
|
||||
import de.kentoj.scrow.bukkit.command.bukkit.ArgumentData;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandArgument;
|
||||
import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandExecutionContextImpl extends CommandContextImpl implements CommandExecutionContext {
|
||||
public class CommandExecutionContextImpl extends CommandContextImpl implements CommadContext {
|
||||
|
||||
private final Map<String, Object> args;
|
||||
private final Map<String, ArgumentData> argumentDataMap;
|
||||
|
||||
public CommandExecutionContextImpl(CommandSender sender, Map<String, Object> args) {
|
||||
public CommandExecutionContextImpl(CommandSender sender, Map<String, ArgumentData> argumentDataMap) {
|
||||
super(sender);
|
||||
this.args = args;
|
||||
this.argumentDataMap = argumentDataMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getRawArgument(String key) {
|
||||
var data = argumentDataMap.get(key);
|
||||
if (data.getRawValue() == null) {
|
||||
if (data.getArgument().getDefaultValue() == null) {
|
||||
throw new CommandSyntaxException("usage: missing arg value for " + key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return data.getRawValue();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getArg(String key) {
|
||||
return (T) args.get(key);
|
||||
var data = argumentDataMap.get(key);
|
||||
var arg = (CommandArgument<T>) data.getArgument();
|
||||
var raw = getRawArgument(key);
|
||||
|
||||
T value;
|
||||
if (raw != null) {
|
||||
value = arg.getType().parseInput(raw);
|
||||
} else {
|
||||
value = arg.getDefaultValue().apply(this);
|
||||
}
|
||||
|
||||
arg.getType().checkValue(this, value, raw);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package de.kentoj.scrow.bukkit.command.bukkit;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandArgument;
|
||||
import lombok.Value;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Value
|
||||
public class ArgumentData {
|
||||
CommandArgument<?> argument;
|
||||
@Nullable String rawValue;
|
||||
}
|
||||
|
|
@ -1,36 +1,34 @@
|
|||
package de.kentoj.scrow.bukkit.command.bukkit;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNode;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class BukkitCommand extends Command {
|
||||
|
||||
private static final CommandProcessor commandProcessor = new CommandProcessor();
|
||||
|
||||
private final CommandNode rootCommandNode;
|
||||
|
||||
protected BukkitCommand(CommandNode rootCommandNode, @NotNull String name, @NotNull String description, @NotNull String usageMessage, @NotNull List<String> aliases) {
|
||||
super(name, description, usageMessage, aliases);
|
||||
protected BukkitCommand(CommandNode rootCommandNode, @NotNull String name, @NotNull String description, @NotNull String usageMessage, @NotNull Set<String> aliases) {
|
||||
super(name, description, usageMessage, aliases.stream().toList());
|
||||
this.rootCommandNode = rootCommandNode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
||||
final Runnable runnable;
|
||||
final var commandProcessor = new CommandProcessor(rootCommandNode, sender, args);
|
||||
|
||||
try {
|
||||
runnable = commandProcessor.toRunnable(rootCommandNode, sender, args);
|
||||
} catch (CommandProcessException e) {
|
||||
sender.sendMessage(e.getMessage());
|
||||
commandProcessor.process();
|
||||
} catch (CommandSyntaxException e) {
|
||||
sender.sendMessage("error: " + e.getMessage());
|
||||
return true;
|
||||
} catch (IllegalStateException e) {
|
||||
throw new RuntimeException("failed processing command " + rootCommandNode.getName(), e);
|
||||
}
|
||||
|
||||
runnable.run();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
package de.kentoj.scrow.bukkit.command.bukkit;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandManager;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNode;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CommandManagerImpl implements CommandManager {
|
||||
|
||||
private final CommandMap commandMap;
|
||||
|
|
@ -25,8 +23,8 @@ public class CommandManagerImpl implements CommandManager {
|
|||
|
||||
@Override
|
||||
public void register(CommandNode rootCommandNode, Plugin plugin) {
|
||||
var bukkitCmd = toBukkitCommand(rootCommandNode);
|
||||
commandMap.register(plugin.getName(), bukkitCmd);
|
||||
var bukkitCommand = toBukkitCommand(rootCommandNode);
|
||||
commandMap.register(plugin.getName(), bukkitCommand);
|
||||
}
|
||||
|
||||
private Command toBukkitCommand(CommandNode commandNode) {
|
||||
|
|
@ -35,7 +33,7 @@ public class CommandManagerImpl implements CommandManager {
|
|||
commandNode.getName(),
|
||||
commandNode.getDescription(),
|
||||
"",
|
||||
Arrays.stream(commandNode.getAliases()).toList()
|
||||
commandNode.getAliases()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.command.bukkit;
|
||||
|
||||
public class CommandProcessException extends RuntimeException {
|
||||
public CommandProcessException(String message) {
|
||||
super(message);
|
||||
}
|
||||
public CommandProcessException(String message, Throwable throwable) {
|
||||
super(message + ": " + throwable.getMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,78 +1,62 @@
|
|||
package de.kentoj.scrow.bukkit.command.bukkit;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import de.kentoj.scrow.bukkit.command.CommandContextImpl;
|
||||
import de.kentoj.scrow.bukkit.command.CommandExecutionContextImpl;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandArgument;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutor;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.exception.CommandSyntaxException;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithArguments;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithSubCommand;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class CommandProcessor {
|
||||
|
||||
public Runnable toRunnable(final CommandNode rootCommandNode, final CommandSender sender, final String[] args) throws CommandProcessException {
|
||||
final var argToValueFunMap = new HashMap<String, Function<CommandContext, ?>>();
|
||||
CommandNode lastNode = rootCommandNode;
|
||||
private final Map<String, ArgumentData> argumentDataMap = new HashMap<>();
|
||||
|
||||
private CommandNode node;
|
||||
private final CommandSender sender;
|
||||
private final String[] args;
|
||||
|
||||
public void process() throws CommandSyntaxException {
|
||||
for (int cursor = 0; true; cursor++) {
|
||||
final var arg = lastNode.getArg(cursor);
|
||||
if (arg != null) {
|
||||
final var valueFun = getArgValueFun(cursor, arg);
|
||||
argToValueFunMap.put(arg.getName(), valueFun);
|
||||
} else {
|
||||
if (lastNode.getSubCommands().isEmpty()) break;
|
||||
final var subcommand = getSubCommand(lastNode, args[cursor]);
|
||||
if (args.length - 1 < cursor) {
|
||||
if (node.getExecutor() == null) throw new CommandSyntaxException("Incomplete command");
|
||||
execute(node.getExecutor());
|
||||
return;
|
||||
}
|
||||
|
||||
if (node instanceof CommandNodeWithArguments nodeWA) {
|
||||
final var arg = nodeWA.getArg(cursor);
|
||||
assert arg != null;
|
||||
final var data = new ArgumentData(arg, args[cursor]);
|
||||
argumentDataMap.put(arg.getName(), data);
|
||||
} else if (node instanceof CommandNodeWithSubCommand nodeWS) {
|
||||
if (nodeWS.getSubCommands().isEmpty()) break;
|
||||
final var subcommand = nodeWS.getSubCommand(args[cursor]);
|
||||
if (subcommand == null) {
|
||||
final var subcommands = lastNode.getSubCommands().stream().map(CommandNode::getName).toList();
|
||||
throw new CommandProcessException("Illegal argument -- " + args[cursor] + "\nExpected arguments: " + String.join(", ", subcommands));
|
||||
final var subcommands = nodeWS.getSubCommands().stream().map(CommandNode::getName).toList();
|
||||
throw new CommandSyntaxException("Illegal argument -- " + args[cursor] + "\nExpected arguments: " + String.join(", ", subcommands));
|
||||
}
|
||||
|
||||
lastNode = subcommand;
|
||||
this.node = nodeWS;
|
||||
}
|
||||
}
|
||||
if (lastNode.getExecutor() == null) throw new IllegalStateException("Last CommandNode must have an executor");
|
||||
|
||||
final CommandNode finalLastNode = lastNode;
|
||||
return () -> {
|
||||
var ctx = new CommandExecutionContextImpl(sender, remap(argToValueFunMap, sender));
|
||||
finalLastNode.getExecutor().execute(ctx);
|
||||
};
|
||||
if (node.getExecutor() == null) throw new IllegalStateException("Last CommandNode must have an executor");
|
||||
execute(node.getExecutor());
|
||||
}
|
||||
|
||||
private Map<String, Object> remap(Map<String, Function<CommandContext, ?>> argToValueFunMap, CommandSender sender) {
|
||||
var ctx = new CommandContextImpl(sender);
|
||||
return argToValueFunMap.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
ent -> ent.getValue().apply(ctx)
|
||||
));
|
||||
}
|
||||
|
||||
private Function<CommandContext, ?> getArgValueFun(int argIndex, CommandArgument<?> arg) throws CommandProcessException {
|
||||
if (args.length - 1 < argIndex) {
|
||||
if (arg.getDefaultValue() == null)
|
||||
throw new CommandProcessException("usage: missing arg value for " + arg.getName());
|
||||
return arg.getDefaultValue();
|
||||
} else {
|
||||
return __ -> arg.getType().parseInput(args[argIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
private @Nullable CommandNode getSubCommand(CommandNode commandNode, String label) {
|
||||
return commandNode.getSubCommands()
|
||||
.stream()
|
||||
.filter(c -> Arrays.stream(c.getAliases()).toList().contains(label))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
private void execute(CommandExecutor executor) {
|
||||
var ctx = new CommandExecutionContextImpl(sender, argumentDataMap);
|
||||
executor.execute(ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package de.kentoj.scrow.bukkit.command.node;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeFactory;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithArguments;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithSubCommand;
|
||||
|
||||
public class CommandNodeFactoryImpl implements CommandNodeFactory {
|
||||
@Override
|
||||
public CommandNodeWithSubCommand createNodeWithSubCommands(String name) {
|
||||
return new CommandNodeWithSubCommandImpl(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandNodeWithArguments createNodeWithArguments(String name) {
|
||||
return new CommandNodeWithArgumentsImpl(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandNode createRootNode(String name) {
|
||||
return new CommandNodeImpl(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package de.kentoj.scrow.bukkit.command.node;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutor;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
public class CommandNodeImpl implements CommandNode {
|
||||
|
||||
private final String name;
|
||||
|
||||
@Setter
|
||||
private Set<String> aliases = new HashSet<>();
|
||||
@Setter
|
||||
private @Nullable Permission permission = null;
|
||||
@Setter
|
||||
private @Nullable String description;
|
||||
@Setter
|
||||
private @Nullable CommandExecutor executor = null;
|
||||
|
||||
public CommandNodeImpl(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAlias(String... aliases) {
|
||||
this.aliases.addAll(Arrays.asList(aliases));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package de.kentoj.scrow.bukkit.command.node;
|
||||
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandArgument;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithArguments;
|
||||
import de.kentoj.scrow.bukkit.services.command.type.ArgumentType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CommandNodeWithArgumentsImpl extends CommandNodeImpl implements CommandNodeWithArguments {
|
||||
|
||||
private final List<CommandArgument<?>> args = new ArrayList<>();
|
||||
|
||||
public CommandNodeWithArgumentsImpl(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void addArg(String name, ArgumentType<T> type, Function<CommandContext, T> defaultValue) {
|
||||
var index = args.size();
|
||||
if (index > 0) {
|
||||
boolean isPreviousArgumentOptional = args.get(index - 1).getDefaultValue() != null;
|
||||
boolean isNewArgumentOptional = defaultValue != null;
|
||||
if (isPreviousArgumentOptional && !isNewArgumentOptional) {
|
||||
throw new IllegalStateException("an optional argument(an argument with a defaultValue set) may not be followed by a required argument");
|
||||
}
|
||||
}
|
||||
args.add(new CommandArgument<>(index, name, type, defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CommandArgument<?> getArg(String name) {
|
||||
return args.stream()
|
||||
.filter(ra -> ra.getName().equals(name))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CommandArgument<?> getArg(int index) {
|
||||
return args.stream()
|
||||
.filter(ra -> ra.getIndex() == index)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package de.kentoj.scrow.bukkit.command.node;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithSubCommand;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CommandNodeWithSubCommandImpl extends CommandNodeImpl implements CommandNodeWithSubCommand {
|
||||
|
||||
@Getter
|
||||
private final List<CommandNode> subCommands = new ArrayList<>();
|
||||
|
||||
public CommandNodeWithSubCommandImpl(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSubCommand(CommandNode subCommand) {
|
||||
subCommands.add(subCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable CommandNode getSubCommand(String label) {
|
||||
return subCommands.stream()
|
||||
.filter(n -> n.getName().equals(label) || n.getAliases().contains(label))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.friends.casd;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.LiteralMessage;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import com.mojang.brigadier.tree.ArgumentCommandNode;
|
||||
import de.kentoj.scrow.bukkit.util.command.PlayerArgument;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class FriendAddCommand implements Command<Object> {
|
||||
|
||||
@Override
|
||||
public int run(CommandContext<Object> ctx) throws CommandSyntaxException {
|
||||
final Player player = PlayerArgument.resolve(ctx, "player");
|
||||
if (player == null) {
|
||||
throw new SimpleCommandExceptionType(new LiteralMessage("Player is not online")).create();
|
||||
}
|
||||
|
||||
player.setVelocity(new Vector(0, 2, 0));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.friends.casd;
|
||||
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
|
||||
public class FriendCommand {
|
||||
|
||||
public static LiteralArgumentBuilder<Object> create() {
|
||||
return LiteralArgumentBuilder.literal("friends")
|
||||
.then(LiteralArgumentBuilder.literal("add"))
|
||||
.then(LiteralArgumentBuilder.literal("list"))
|
||||
.then(LiteralArgumentBuilder.literal("requests"))
|
||||
.then(LiteralArgumentBuilder.literal("remove"))
|
||||
.then(LiteralArgumentBuilder.literal("jump"))
|
||||
.then(LiteralArgumentBuilder.literal("accept"))
|
||||
.then(LiteralArgumentBuilder.literal("deny"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
package de.kentoj.scrow.bukkit.friends.casd;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class FriendCommandExecutor implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package de.kentoj.scrow.bukkit.friends.command;
|
||||
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeRepository;
|
||||
import de.kentoj.scrow.bukkit.services.command.node.CommandNodeWithSubCommand;
|
||||
|
||||
public class FriendCommand {
|
||||
|
||||
private final CommandNodeWithSubCommand node = CommandNodeRepository.withSubCommands("friend");
|
||||
|
||||
public FriendCommand() {
|
||||
this.node.addAlias("f");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +1,22 @@
|
|||
package de.kentoj.scrow.bukkit.friends.command;
|
||||
|
||||
import de.kentoj.scrow.bukkit.command.AbstractCommandNode;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutionContext;
|
||||
import de.kentoj.scrow.bukkit.command.node.CommandNodeWithArgumentsImpl;
|
||||
import de.kentoj.scrow.bukkit.services.command.CommandExecutor;
|
||||
import de.kentoj.scrow.bukkit.services.command.arg.PlayerArgumentType;
|
||||
import de.kentoj.scrow.bukkit.services.command.context.CommandContext;
|
||||
import de.kentoj.scrow.bukkit.services.command.type.EntityArgumentType;
|
||||
import net.md_5.bungee.api.chat.TranslatableComponent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class LaunchCommand extends AbstractCommandNode implements CommandExecutor {
|
||||
public class LaunchCommand extends CommandNodeWithArgumentsImpl implements CommandExecutor {
|
||||
|
||||
public LaunchCommand() {
|
||||
super("launch", "lunch");
|
||||
super("launch");
|
||||
this.setDescription("launches a player in the air");
|
||||
this.setPermission(new Permission("bukkitcore.cmd.launch"));
|
||||
|
||||
this.addArg("player", PlayerArgumentType.player, CommandContext::getSenderPlayer);
|
||||
this.addArg("player", EntityArgumentType.player(), CommandContext::getSenderPlayer);
|
||||
this.setExecutor(this);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue