refactor: change approach with <1.20.6 Paper commands

Fixes issues with custom arg types on Paper
dependabot/gradle/org.projectlombok-lombok-1.18.34 1.1.5
William 5 months ago
parent 1e7297c0b3
commit d399788b9f
No known key found for this signature in database

@ -1,4 +1,4 @@
name: UniformExample
version: 1.0
api-version: "1.19"
version: "1.0"
api-version: "1.20"
main: net.william278.uniform.UniformExample

@ -3,6 +3,6 @@ javaVersion=17
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
org.gradle.daemon=true
library_version=1.1.4
library_version=1.1.5
library_archive=uniform
library_description=Cross-platform wrapper for making Brigadier commands, based on BrigadierWrapper by Tofaa2, itself inspired by emortalmcs command system.

@ -21,82 +21,106 @@
package net.william278.uniform.paper;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent;
import com.google.common.collect.Sets;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import lombok.AllArgsConstructor;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestion;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.william278.uniform.BaseCommand;
import net.william278.uniform.Command;
import net.william278.uniform.CommandUser;
import net.william278.uniform.Uniform;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.function.Function;
@SuppressWarnings({"removal", "deprecation", "UnstableApiUsage"})
public class LegacyPaperCommand extends BaseCommand<BukkitBrigadierCommandSource> {
@SuppressWarnings("unused")
public class LegacyPaperCommand extends BaseCommand<CommandSender> {
static final Function<Object, CommandUser> USER_SUPPLIER = (user) -> new LegacyPaperCommandUser(
(BukkitBrigadierCommandSource) user
(CommandSender) user
);
public LegacyPaperCommand(@NotNull Command command) {
super(command);
}
public LegacyPaperCommand(@NotNull String name, @NotNull String description, @NotNull List<String> aliases) {
super(name, description, aliases);
}
public LegacyPaperCommand(@NotNull String name, @NotNull List<String> aliases) {
super(name, aliases);
}
public LegacyPaperCommand(@NotNull String name, @NotNull String description, @NotNull List<String> aliases) {
super(name, description, aliases);
@NotNull
Impl getImpl(@NotNull Uniform uniform) {
return new Impl(uniform, this);
}
@Override
public void addSubCommand(@NotNull Command command) {
addSubCommand(new LegacyPaperCommand(command));
static final class Impl extends org.bukkit.command.Command {
private static final int COMMAND_SUCCESS = com.mojang.brigadier.Command.SINGLE_SUCCESS;
private final CommandDispatcher<CommandSender> dispatcher = new CommandDispatcher<>();
public Impl(@NotNull Uniform uniform, @NotNull LegacyPaperCommand command) {
super(command.getName());
this.dispatcher.register(command.createBuilder());
this.setDescription(command.getDescription());
this.setAliases(command.getAliases());
}
@SuppressWarnings("deprecation")
@Override
public Uniform getUniform() {
return PaperUniform.INSTANCE;
public boolean execute(@NotNull CommandSender commandSender, @NotNull String alias, @NotNull String[] args) {
try {
return dispatcher.execute(getInput(args), commandSender) == COMMAND_SUCCESS;
} catch (CommandSyntaxException e) {
commandSender.sendMessage(Component
.translatable("command.context.parse_error", NamedTextColor.RED)
.args(
Component.text(e.getRawMessage().getString()),
Component.text(e.getCursor()),
Component.text(e.getContext())
));
return false;
} catch (CommandException e) {
commandSender.sendMessage(Component.text(e.getMessage(), NamedTextColor.RED));
return false;
}
}
@AllArgsConstructor
static class Registrar implements Listener {
@NotNull
private final JavaPlugin plugin;
@Override
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args)
throws IllegalArgumentException {
final String passed = getInput(args);
return dispatcher.getCompletionSuggestions(
dispatcher.parse(passed, sender),
passed.length() // Spigot API limitation - we can only TAB complete the full text length :(
)
.thenApply(suggestions -> suggestions.getList().stream().map(Suggestion::getText).toList())
.join();
}
@NotNull
private final Set<LegacyPaperCommand> commands;
@EventHandler
public void commandRegisterEvent(CommandRegisteredEvent<BukkitBrigadierCommandSource> event) {
commands.forEach(command -> {
// Register root command
final LiteralCommandNode<BukkitBrigadierCommandSource> built = command.build();
event.getRoot().addChild(built);
// Register aliases
final String namespace = plugin.getName().toLowerCase(Locale.ENGLISH).replaceAll("[^a-z0-9_-]", "");
final Set<String> aliases = Sets.newHashSet(command.getAliases());
command.getAliases().forEach(a -> aliases.add(namespace + ":" + a));
aliases.add(namespace + ":" + command.getName());
aliases.forEach(alias -> event.getRoot().addChild(
LiteralArgumentBuilder.<BukkitBrigadierCommandSource>literal(alias)
.requires(built.getRequirement()).executes(built.getCommand()).redirect(built)
.build()
));
});
commands.clear();
private String getInput(@NotNull String[] args) {
return args.length == 0 ? getName() : "%s %s".formatted(getName(), String.join(" ", args));
}
}
@Override
public void addSubCommand(@NotNull Command command) {
addSubCommand(new LegacyPaperCommand(command));
}
@Override
public Uniform getUniform() {
return PaperUniform.INSTANCE;
}
}

@ -21,44 +21,43 @@
package net.william278.uniform.paper;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import net.kyori.adventure.audience.Audience;
import net.william278.uniform.CommandUser;
import net.william278.uniform.Permission;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
@SuppressWarnings("removal")
public record LegacyPaperCommandUser(@NotNull BukkitBrigadierCommandSource source) implements CommandUser {
public record LegacyPaperCommandUser(@NotNull CommandSender sender) implements CommandUser {
@Override
@NotNull
public Audience getAudience() {
return source.getBukkitSender();
return sender;
}
@Override
@Nullable
public String getName() {
return source.getBukkitEntity() != null ? source.getBukkitEntity().getName() : null;
return sender.getName();
}
@Override
@Nullable
public UUID getUuid() {
return source.getBukkitEntity() != null ? source.getBukkitEntity().getUniqueId() : null;
return sender instanceof Player player ? player.getUniqueId() : null;
}
@Override
public boolean checkPermission(@NotNull Permission permission) {
if (source.getBukkitSender().isPermissionSet(permission.node())) {
return source.getBukkitSender().hasPermission(permission.node());
if (sender.isPermissionSet(permission.node())) {
return sender.hasPermission(permission.node());
}
return permission.defaultValue().check(
source.getBukkitSender().isOp() || source.getBukkitSender() instanceof ConsoleCommandSender
sender.isOp() || sender instanceof ConsoleCommandSender
);
}

@ -32,8 +32,10 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Locale;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
/**
* A class for registering commands with the Paper server's command manager
@ -44,27 +46,23 @@ public final class PaperUniform implements Uniform {
static PaperUniform INSTANCE;
private final Set<LegacyPaperCommand> legacyCommands = Sets.newHashSet();
private final Set<PaperCommand> commands = Sets.newHashSet();
private final boolean useModernApi = isUseModernApi();
private final JavaPlugin plugin;
@Getter
@Setter
Function<Object, CommandUser> commandUserSupplier;
private PaperUniform(@NotNull JavaPlugin plugin) {
this.plugin = plugin;
// Modern (1.20.6+) Lifecycle event based Paper Brigadier API
if (useModernApi) {
this.commandUserSupplier = PaperCommand.USER_SUPPLIER;
PaperCommand.register(plugin, commands);
return;
}
// Legacy (1.17-1.20.4) event-based Paper Brigadier API
this.commandUserSupplier = LegacyPaperCommand.USER_SUPPLIER;
plugin.getServer().getPluginManager().registerEvents(
new LegacyPaperCommand.Registrar(plugin, legacyCommands), plugin
);
}
/**
@ -100,13 +98,18 @@ public final class PaperUniform implements Uniform {
@SafeVarargs
@Override
public final <S, T extends BaseCommand<S>> void register(T... commands) {
Arrays.stream(commands).forEach(c -> {
// Mark as to be registered with modern API
final Stream<T> s = Arrays.stream(commands);
if (useModernApi) {
this.commands.add((PaperCommand) c);
} else {
this.legacyCommands.add((LegacyPaperCommand) c);
s.forEach(c -> this.commands.add((PaperCommand) c));
return;
}
});
// Register with the legacy API
plugin.getServer().getCommandMap().registerAll(
plugin.getName().toLowerCase(Locale.ENGLISH).replaceAll("[^a-z0-9_]", ""),
s.map(c -> (LegacyPaperCommand) c).map(c -> (org.bukkit.command.Command) c.getImpl(this)).toList()
);
}
/**

Loading…
Cancel
Save