This commit is contained in:
kento2 2026-02-16 17:54:10 +01:00
parent 4879257f47
commit 4373584285
32 changed files with 492 additions and 199 deletions

View file

@ -20,6 +20,7 @@ dependencies {
api("me.lucko:commodore:2.2")
api("org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT")
api("net.kyori:adventure-platform-bukkit:4.4.1")
}
tasks.findByName("shadowJar")?.let {

View file

@ -2,6 +2,7 @@ package de.kentoj.scrow.bukkit;
import com.mongodb.reactivestreams.client.MongoDatabase;
import de.kentoj.scrow.bukkit.services.EconomyService;
import de.kentoj.scrow.bukkit.services.command.CommandManager;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@ -15,6 +16,8 @@ public class ScrowAPI {
private static @Nullable MongoDatabase database;
@Getter
private static EconomyService economyService;
@Getter
private static CommandManager commandManager;
@ApiStatus.Internal
public static void setDatabase(@Nullable MongoDatabase database) {
@ -25,5 +28,10 @@ public class ScrowAPI {
public static void setEconomyService(EconomyService economyService) {
ScrowAPI.economyService = economyService;
}
@ApiStatus.Internal
public static void setCommandManager(CommandManager commandManager) {
ScrowAPI.commandManager = commandManager;
}
}

View file

@ -0,0 +1,14 @@
package de.kentoj.scrow.bukkit.services.command;
import de.kentoj.scrow.bukkit.services.command.arg.ArgumentType;
import lombok.Value;
import java.util.function.Function;
@Value
public class CommandArgument<T> {
int index;
String name;
ArgumentType<T> type;
Function<CommandContext, T> defaultValue;
}

View file

@ -1,16 +1,14 @@
package de.kentoj.scrow.bukkit.services.old;
package de.kentoj.scrow.bukkit.services.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public interface CmdContext {
public interface CommandContext {
CommandSender getSender();
Player getSenderPlayer();
Entity getSenderEntity();
<T> T getArg(String key);
}

View file

@ -0,0 +1,6 @@
package de.kentoj.scrow.bukkit.services.command;
public interface CommandExecutionContext extends CommandContext {
<T> T getArg(String key);
}

View file

@ -1,9 +1,9 @@
package de.kentoj.scrow.bukkit.services.old;
package de.kentoj.scrow.bukkit.services.command;
public interface CommandExecutor {
/**
* @return true on success, 1 on failure
*/
boolean execute(CmdContext ctx);
void execute(CommandExecutionContext ctx);
}

View file

@ -0,0 +1,8 @@
package de.kentoj.scrow.bukkit.services.command;
import org.bukkit.plugin.Plugin;
public interface CommandManager {
void register(CommandNode rootCommandNode, Plugin plugin);
}

View file

@ -0,0 +1,40 @@
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();
}

View file

@ -0,0 +1,6 @@
package de.kentoj.scrow.bukkit.services.command.arg;
public interface ArgumentType<S> {
S parseInput(String str);
}

View file

@ -1,4 +1,4 @@
package de.kentoj.scrow.bukkit.services.old.arg;
package de.kentoj.scrow.bukkit.services.command.arg;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@ -10,9 +10,9 @@ import java.util.UUID;
// FIXME module stuff
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PlayerArgType {
public class PlayerArgumentType {
public static final CmdArg<Player> player = str -> {
public static final ArgumentType<Player> player = str -> {
if (str.length() == 36) {
var uuid = UUID.fromString(str);
return Bukkit.getPlayer(uuid);
@ -21,7 +21,7 @@ public class PlayerArgType {
}
};
public static final CmdArg<OfflinePlayer> offlinePlayer = str -> {
public static final ArgumentType<OfflinePlayer> offlinePlayer = str -> {
var uuid = UUID.fromString(str);
return Bukkit.getOfflinePlayer(uuid);
};

View file

@ -1,9 +0,0 @@
package de.kentoj.scrow.bukkit.services.old;
import org.bukkit.command.Command;
import org.bukkit.plugin.Plugin;
public interface CommandsService {
void register(Plugin plugin, Command command);
}

View file

@ -1,11 +0,0 @@
package de.kentoj.scrow.bukkit.services.old;
import de.kentoj.scrow.bukkit.services.old.arg.CmdArg;
import lombok.Value;
@Value
public class RegisteredCmdArg<T> {
int index;
String key;
CmdArg<T> arg;
}

View file

@ -1,21 +0,0 @@
package de.kentoj.scrow.bukkit.services.old;
import org.bukkit.permissions.Permission;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public interface SCommand {
@Nullable Permission getPermission();
RegisteredCmdArg<?> getArg(int index);
List<SCommand> getSubCommands();
String[] getLabels();
String getDescription();
@Nullable CommandExecutor getExecutor();
}

View file

@ -1,6 +0,0 @@
package de.kentoj.scrow.bukkit.services.old.arg;
public interface CmdArg<S> {
S parseInput(String str);
}

View file

@ -0,0 +1,15 @@
package de.kentoj.scrow.bukkit.util.chat;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.Audiences;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ErrorMessage {
}

View file

@ -0,0 +1,30 @@
package de.kentoj.scrow.bukkit.util.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 lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.UUID;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class PlayerArgument {
public static Player resolve(CommandContext<Object> ctx, String argumentName) throws CommandSyntaxException {
var str = ctx.getArgument(argumentName, String.class);
boolean isUUID = str.length() == 36;
return isUUID ? Bukkit.getPlayer(parseUUID(str)) : Bukkit.getPlayerExact(str);
}
private static UUID parseUUID(String string) throws CommandSyntaxException {
try {
return UUID.fromString(string);
} catch (IllegalArgumentException ex) {
throw new SimpleCommandExceptionType(new LiteralMessage("Invalid UUID")).create();
}
}
}

View file

@ -1,5 +1,9 @@
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;
@ -10,6 +14,11 @@ public class CoreImplPlugin extends JavaPlugin {
@Override
public void onEnable() {
ScrowAPISurface.initScrowAPI(false);
{
ScrowAPI.getCommandManager().register(new LaunchCommand(), this);
}
{
var playerId = UUID.randomUUID();
var economyService = ScrowAPI.getEconomyService();

View file

@ -4,6 +4,7 @@ import com.mongodb.ConnectionString;
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.economy.InMemoryEconomyService;
import de.kentoj.scrow.bukkit.economy.MongoEconomyService;
import lombok.AccessLevel;
@ -37,6 +38,8 @@ public class ScrowAPISurface {
ScrowAPI.getDatabase() != null ?
new MongoEconomyService(ScrowAPI.getDatabase()) : new InMemoryEconomyService()
);
ScrowAPI.setCommandManager(new CommandManagerImpl());
}
public static void destroyScrowAPI() {

View file

@ -0,0 +1,79 @@
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);
}
}

View file

@ -1,69 +0,0 @@
package de.kentoj.scrow.bukkit.command;
import com.google.common.collect.ImmutableList;
import de.kentoj.scrow.bukkit.services.old.CommandExecutor;
import de.kentoj.scrow.bukkit.services.old.RegisteredCmdArg;
import de.kentoj.scrow.bukkit.services.old.SCommand;
import de.kentoj.scrow.bukkit.services.old.arg.CmdArg;
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;
public abstract class AbstractSCommand implements SCommand {
private final List<SCommand> subCommands = new ArrayList<>();
private final List<RegisteredCmdArg<?>> args = new ArrayList<>();
@Getter
private final String[] labels;
@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 AbstractSCommand(String... labels) {
this.labels = labels;
}
protected <T> void addArg(String key, CmdArg<T> arg) {
}
protected <T> void addArg(String key, CmdArg<T> arg, T defaultValue) {
var index = args.size();
args.add(new RegisteredCmdArg<>(index, key, arg));
}
@Override
public RegisteredCmdArg<?> getArg(int index) {
//noinspection OptionalGetWithoutIsPresent
return args.stream()
.filter(ra -> ra.getIndex() == index)
.findFirst()
.get();
}
public void addSubCommand(SCommand subCommand) {
subCommands.add(subCommand);
}
protected void setPermission(@Nullable Permission permission) {
this.permission = permission;
}
protected void setPermission(String permission) {
setPermission(new Permission(permission));
}
public List<SCommand> getSubCommands() {
return ImmutableList.copyOf(subCommands);
}
}

View file

@ -1,18 +1,15 @@
package de.kentoj.scrow.bukkit.command;
import de.kentoj.scrow.bukkit.services.old.CmdContext;
import de.kentoj.scrow.bukkit.services.command.CommandContext;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.Map;
@RequiredArgsConstructor
public class CmdContextImpl implements CmdContext {
public class CommandContextImpl implements CommandContext {
private final Map<String, Object> args;
@Getter
private final CommandSender sender;
@ -25,9 +22,4 @@ public class CmdContextImpl implements CmdContext {
public Entity getSenderEntity() {
return (Entity) sender;
}
@SuppressWarnings("unchecked")
public <T> T getArg(String key) {
return (T) args.get(key);
}
}

View file

@ -0,0 +1,21 @@
package de.kentoj.scrow.bukkit.command;
import de.kentoj.scrow.bukkit.services.command.CommandExecutionContext;
import org.bukkit.command.CommandSender;
import java.util.Map;
public class CommandExecutionContextImpl extends CommandContextImpl implements CommandExecutionContext {
private final Map<String, Object> args;
public CommandExecutionContextImpl(CommandSender sender, Map<String, Object> args) {
super(sender);
this.args = args;
}
@SuppressWarnings("unchecked")
public <T> T getArg(String key) {
return (T) args.get(key);
}
}

View file

@ -1,29 +0,0 @@
package de.kentoj.scrow.bukkit.command;
import de.kentoj.scrow.bukkit.services.old.CmdContext;
import de.kentoj.scrow.bukkit.services.old.SCommand;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public class CommandProcessor implements CommandExecutor {
public CmdContext process(SCommand scommand, String[] strArgs, CommandSender sender) {
Map<String, Object> args = new HashMap<>();
for (int i = 0; i < strArgs.length; i++) {
var arg = scommand.getArg(i);
var value = arg.getArg().parseInput(strArgs[i]);
args.put(arg.getKey(), value);
}
return new CmdContextImpl(args, sender);
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
return false;
}
}

View file

@ -1,26 +0,0 @@
package de.kentoj.scrow.bukkit.command;
import de.kentoj.scrow.bukkit.services.old.CommandExecutor;
import de.kentoj.scrow.bukkit.services.old.arg.PlayerArgType;
import de.kentoj.scrow.bukkit.services.old.CmdContext;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.util.Vector;
public class LaunchCommand extends AbstractSCommand implements CommandExecutor {
public LaunchCommand() {
super("launch");
setPermission(new Permission("corebukkit.cmd.launch"));
setExecutor(this);
addArg("player", PlayerArgType.player);
addArg("factor", IntRangeType.range(1, 5), 1);
}
@Override
public boolean execute(CmdContext ctx) {
final Player player = ctx.getArg("player");
player.setVelocity(new Vector(0, 1, 0));
return true;
}
}

View file

@ -0,0 +1,36 @@
package de.kentoj.scrow.bukkit.command.bukkit;
import de.kentoj.scrow.bukkit.services.command.CommandNode;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.List;
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);
this.rootCommandNode = rootCommandNode;
}
@Override
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
final Runnable runnable;
try {
runnable = commandProcessor.toRunnable(rootCommandNode, sender, args);
} catch (CommandProcessException e) {
sender.sendMessage(e.getMessage());
return true;
} catch (IllegalStateException e) {
throw new RuntimeException("failed processing command " + rootCommandNode.getName(), e);
}
runnable.run();
return true;
}
}

View file

@ -0,0 +1,41 @@
package de.kentoj.scrow.bukkit.command.bukkit;
import de.kentoj.scrow.bukkit.services.command.CommandManager;
import de.kentoj.scrow.bukkit.services.command.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;
public CommandManagerImpl() {
try {
var field = Bukkit.getPluginManager().getClass().getDeclaredField("commandMap");
field.setAccessible(true);
commandMap = (CommandMap) field.get(Bukkit.getPluginManager());
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@Override
public void register(CommandNode rootCommandNode, Plugin plugin) {
var bukkitCmd = toBukkitCommand(rootCommandNode);
commandMap.register(plugin.getName(), bukkitCmd);
}
private Command toBukkitCommand(CommandNode commandNode) {
return new BukkitCommand(
commandNode,
commandNode.getName(),
commandNode.getDescription(),
"",
Arrays.stream(commandNode.getAliases()).toList()
);
}
}

View file

@ -0,0 +1,10 @@
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());
}
}

View file

@ -0,0 +1,78 @@
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 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
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;
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 (subcommand == null) {
final var subcommands = lastNode.getSubCommands().stream().map(CommandNode::getName).toList();
throw new CommandProcessException("Illegal argument -- " + args[cursor] + "\nExpected arguments: " + String.join(", ", subcommands));
}
lastNode = subcommand;
}
}
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);
};
}
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);
}
}

View file

@ -0,0 +1,28 @@
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;
}
}

View file

@ -1,22 +1,19 @@
package de.kentoj.scrow.bukkit.friends;
package de.kentoj.scrow.bukkit.friends.casd;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
public class FriendsCommand {
public class FriendCommand {
public static Command<?> createCommand() {
public static LiteralArgumentBuilder<Object> create() {
return LiteralArgumentBuilder.literal("friends")
.then(LiteralArgumentBuilder.literal("add")
.then(RequiredArgumentBuilder.argument("player", StringArgumentType.word())))
.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"))
.build().getCommand();
.then(LiteralArgumentBuilder.literal("deny"));
}
}

View file

@ -0,0 +1,13 @@
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;
}
}

View file

@ -0,0 +1,31 @@
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.services.command.CommandExecutor;
import de.kentoj.scrow.bukkit.services.command.arg.PlayerArgumentType;
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 LaunchCommand() {
super("launch", "lunch");
this.setDescription("launches a player in the air");
this.setPermission(new Permission("bukkitcore.cmd.launch"));
this.addArg("player", PlayerArgumentType.player, CommandContext::getSenderPlayer);
this.setExecutor(this);
}
@Override
public void execute(CommandExecutionContext ctx) {
final Player player = ctx.getArg("player");
player.spigot().sendMessage(new TranslatableComponent(""));
player.setVelocity(new Vector(0, 2, 0));
player.sendMessage("Launched " + player.getName() + ".");
}
}