Don't auto-create any brig redirects (#11954)
This commit is contained in:
@@ -124,7 +124,7 @@ public abstract class ApiMirrorRootNode extends RootCommandNode<CommandSourceSta
|
||||
}
|
||||
|
||||
converted = this.unwrapArgumentWrapper(pureArgumentNode, customArgumentType, customArgumentType.getNativeType(), suggestionProvider);
|
||||
} else if (pureArgumentType instanceof final VanillaArgumentProviderImpl.NativeWrapperArgumentType<?,?> nativeWrapperArgumentType) {
|
||||
} else if (pureArgumentType instanceof final VanillaArgumentProviderImpl.NativeWrapperArgumentType<?, ?> nativeWrapperArgumentType) {
|
||||
converted = this.unwrapArgumentWrapper(pureArgumentNode, nativeWrapperArgumentType, nativeWrapperArgumentType, null); // "null" for suggestion provider so it uses the argument type's suggestion provider
|
||||
|
||||
/*
|
||||
@@ -140,6 +140,8 @@ public abstract class ApiMirrorRootNode extends RootCommandNode<CommandSourceSta
|
||||
// Unknown argument type was passed
|
||||
throw new IllegalArgumentException("Custom unknown argument type was passed, should be wrapped inside an CustomArgumentType.");
|
||||
}
|
||||
} else if (pureNode == this) {
|
||||
return (CommandNode) this.getDispatcher().getRoot();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown command node passed. Don't know how to unwrap this.");
|
||||
}
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
package io.papermc.paper.command.brigadier;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import io.papermc.paper.command.brigadier.bukkit.BukkitBrigForwardingMap;
|
||||
import io.papermc.paper.command.brigadier.bukkit.BukkitCommandNode;
|
||||
import java.util.Map;
|
||||
import net.minecraft.commands.CommandSource;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.craftbukkit.command.VanillaCommandWrapper;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public final class PaperBrigadier {
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
@@ -40,7 +35,8 @@ public final class PaperBrigadier {
|
||||
throw new IllegalArgumentException("Unsure how to wrap a " + node);
|
||||
}
|
||||
|
||||
if (!(node instanceof PluginCommandNode pluginCommandNode)) {
|
||||
final PluginCommandMeta meta;
|
||||
if ((meta = node.pluginCommandMeta) == null) {
|
||||
return new VanillaCommandWrapper(null, node);
|
||||
}
|
||||
CommandNode<CommandSourceStack> argumentCommandNode = node;
|
||||
@@ -49,8 +45,8 @@ public final class PaperBrigadier {
|
||||
}
|
||||
|
||||
Map<CommandNode<CommandSourceStack>, String> map = PaperCommands.INSTANCE.getDispatcherInternal().getSmartUsage(argumentCommandNode, DUMMY);
|
||||
String usage = map.isEmpty() ? pluginCommandNode.getUsageText() : pluginCommandNode.getUsageText() + " " + String.join("\n" + pluginCommandNode.getUsageText() + " ", map.values());
|
||||
return new PluginVanillaCommandWrapper(pluginCommandNode.getName(), pluginCommandNode.getDescription(), usage, pluginCommandNode.getAliases(), node, pluginCommandNode.getPlugin());
|
||||
String usage = map.isEmpty() ? node.getUsageText() : node.getUsageText() + " " + String.join("\n" + node.getUsageText() + " ", map.values());
|
||||
return new PluginVanillaCommandWrapper(node.getName(), meta.description(), usage, meta.aliases(), node, meta.plugin());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -70,4 +66,19 @@ public final class PaperBrigadier {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <S> LiteralCommandNode<S> copyLiteral(final String newLiteral, final LiteralCommandNode<S> source) {
|
||||
// logic copied from LiteralCommandNode#createBuilder
|
||||
final LiteralArgumentBuilder<S> copyBuilder = LiteralArgumentBuilder.<S>literal(newLiteral)
|
||||
.requires(source.getRequirement())
|
||||
.forward(source.getRedirect(), source.getRedirectModifier(), source.isFork());
|
||||
if (source.getCommand() != null) {
|
||||
copyBuilder.executes(source.getCommand());
|
||||
}
|
||||
|
||||
for (final CommandNode<S> child : source.getChildren()) {
|
||||
copyBuilder.then(child);
|
||||
}
|
||||
return copyBuilder.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,23 +21,20 @@ import java.util.Set;
|
||||
import net.minecraft.commands.CommandBuildContext;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@DefaultQualifier(NonNull.class)
|
||||
@NullMarked
|
||||
public class PaperCommands implements Commands, PaperRegistrar<LifecycleEventOwner> {
|
||||
|
||||
public static final PaperCommands INSTANCE = new PaperCommands();
|
||||
|
||||
private @Nullable LifecycleEventOwner currentContext;
|
||||
private @MonotonicNonNull CommandDispatcher<CommandSourceStack> dispatcher;
|
||||
private @MonotonicNonNull CommandBuildContext buildContext;
|
||||
private @Nullable CommandDispatcher<CommandSourceStack> dispatcher;
|
||||
private @Nullable CommandBuildContext buildContext;
|
||||
private boolean invalid = false;
|
||||
|
||||
@Override
|
||||
@@ -93,65 +90,47 @@ public class PaperCommands implements Commands, PaperRegistrar<LifecycleEventOwn
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Unmodifiable Set<String> registerWithFlags(@NotNull final PluginMeta pluginMeta, @NotNull final LiteralCommandNode<CommandSourceStack> node, @org.jetbrains.annotations.Nullable final String description, @NotNull final Collection<String> aliases, @NotNull final Set<CommandRegistrationFlag> flags) {
|
||||
final boolean hasFlattenRedirectFlag = flags.contains(CommandRegistrationFlag.FLATTEN_ALIASES);
|
||||
public @Unmodifiable Set<String> registerWithFlags(final PluginMeta pluginMeta, final LiteralCommandNode<CommandSourceStack> node, final @Nullable String description, final Collection<String> aliases, final Set<CommandRegistrationFlag> flags) {
|
||||
final PluginCommandMeta meta = new PluginCommandMeta(pluginMeta, description);
|
||||
final String identifier = pluginMeta.getName().toLowerCase(Locale.ROOT);
|
||||
final String literal = node.getLiteral();
|
||||
final PluginCommandNode pluginLiteral = new PluginCommandNode(identifier + ":" + literal, pluginMeta, node, description); // Treat the keyed version of the command as the root
|
||||
final LiteralCommandNode<CommandSourceStack> pluginLiteral = PaperBrigadier.copyLiteral(identifier + ":" + literal, node);
|
||||
|
||||
final Set<String> registeredLabels = new HashSet<>(aliases.size() * 2 + 2);
|
||||
|
||||
if (this.registerIntoDispatcher(pluginLiteral, true)) {
|
||||
registeredLabels.add(pluginLiteral.getLiteral());
|
||||
}
|
||||
if (this.registerRedirect(literal, pluginMeta, pluginLiteral, description, true, hasFlattenRedirectFlag)) { // Plugin commands should override vanilla commands
|
||||
if (this.registerIntoDispatcher(node, true)) { // Plugin commands should override vanilla commands
|
||||
registeredLabels.add(literal);
|
||||
}
|
||||
|
||||
// Add aliases
|
||||
final List<String> registeredAliases = new ArrayList<>(aliases.size() * 2);
|
||||
for (final String alias : aliases) {
|
||||
if (this.registerRedirect(alias, pluginMeta, pluginLiteral, description, false, hasFlattenRedirectFlag)) {
|
||||
if (this.registerCopy(alias, pluginLiteral, meta)) {
|
||||
registeredAliases.add(alias);
|
||||
}
|
||||
if (this.registerRedirect(identifier + ":" + alias, pluginMeta, pluginLiteral, description, false, hasFlattenRedirectFlag)) {
|
||||
if (this.registerCopy(identifier + ":" + alias, pluginLiteral, meta)) {
|
||||
registeredAliases.add(identifier + ":" + alias);
|
||||
}
|
||||
}
|
||||
|
||||
if (!registeredAliases.isEmpty()) {
|
||||
pluginLiteral.setAliases(registeredAliases);
|
||||
}
|
||||
pluginLiteral.pluginCommandMeta = new PluginCommandMeta(pluginMeta, description, registeredAliases);
|
||||
|
||||
registeredLabels.addAll(registeredAliases);
|
||||
return registeredLabels.isEmpty() ? Collections.emptySet() : Collections.unmodifiableSet(registeredLabels);
|
||||
}
|
||||
|
||||
private boolean registerRedirect(final String aliasLiteral, final PluginMeta plugin, final PluginCommandNode redirectTo, final @Nullable String description, final boolean override, boolean hasFlattenRedirectFlag) {
|
||||
final LiteralCommandNode<CommandSourceStack> redirect;
|
||||
if (redirectTo.getChildren().isEmpty() || hasFlattenRedirectFlag) {
|
||||
redirect = Commands.literal(aliasLiteral)
|
||||
.executes(redirectTo.getCommand())
|
||||
.requires(redirectTo.getRequirement())
|
||||
.build();
|
||||
|
||||
for (final CommandNode<CommandSourceStack> child : redirectTo.getChildren()) {
|
||||
redirect.addChild(child);
|
||||
}
|
||||
} else {
|
||||
redirect = Commands.literal(aliasLiteral)
|
||||
.executes(redirectTo.getCommand())
|
||||
.redirect(redirectTo)
|
||||
.requires(redirectTo.getRequirement())
|
||||
.build();
|
||||
}
|
||||
|
||||
return this.registerIntoDispatcher(new PluginCommandNode(aliasLiteral, plugin, redirect, description), override);
|
||||
private boolean registerCopy(final String aliasLiteral, final LiteralCommandNode<CommandSourceStack> redirectTo, final PluginCommandMeta meta) {
|
||||
final LiteralCommandNode<CommandSourceStack> node = PaperBrigadier.copyLiteral(aliasLiteral, redirectTo);
|
||||
node.pluginCommandMeta = meta;
|
||||
return this.registerIntoDispatcher(node, false);
|
||||
}
|
||||
|
||||
private boolean registerIntoDispatcher(final PluginCommandNode node, boolean override) {
|
||||
final @Nullable CommandNode<CommandSourceStack> existingChild = this.getDispatcher().getRoot().getChild(node.getLiteral());
|
||||
if (existingChild != null && !(existingChild instanceof PluginCommandNode) && !(existingChild instanceof BukkitCommandNode)) {
|
||||
private boolean registerIntoDispatcher(final LiteralCommandNode<CommandSourceStack> node, boolean override) {
|
||||
final CommandNode<CommandSourceStack> existingChild = this.getDispatcher().getRoot().getChild(node.getLiteral());
|
||||
if (existingChild != null && existingChild.pluginCommandMeta == null && !(existingChild instanceof BukkitCommandNode)) {
|
||||
override = true; // override vanilla commands
|
||||
}
|
||||
if (existingChild == null || override) { // Avoid merging behavior. Maybe something to look into in the future
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package io.papermc.paper.command.brigadier;
|
||||
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@NullMarked
|
||||
public record PluginCommandMeta(PluginMeta pluginMeta, @Nullable String description, List<String> aliases) {
|
||||
|
||||
public PluginCommandMeta(final PluginMeta pluginMeta, final @Nullable String description) {
|
||||
this(pluginMeta, description, Collections.emptyList());
|
||||
}
|
||||
|
||||
public PluginCommandMeta {
|
||||
aliases = List.copyOf(aliases);
|
||||
}
|
||||
|
||||
public Plugin plugin() {
|
||||
return Objects.requireNonNull(Bukkit.getPluginManager().getPlugin(this.pluginMeta.getName()));
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package io.papermc.paper.command.brigadier;
|
||||
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PluginCommandNode extends LiteralCommandNode<CommandSourceStack> {
|
||||
|
||||
private final PluginMeta plugin;
|
||||
private final String description;
|
||||
private List<String> aliases = Collections.emptyList();
|
||||
|
||||
public PluginCommandNode(final @NotNull String literal, final @NotNull PluginMeta plugin, final @NotNull LiteralCommandNode<CommandSourceStack> rootLiteral, final @Nullable String description) {
|
||||
super(
|
||||
literal, rootLiteral.getCommand(), rootLiteral.getRequirement(),
|
||||
rootLiteral.getRedirect(), rootLiteral.getRedirectModifier(), rootLiteral.isFork()
|
||||
);
|
||||
this.plugin = plugin;
|
||||
this.description = description;
|
||||
|
||||
for (CommandNode<CommandSourceStack> argument : rootLiteral.getChildren()) {
|
||||
this.addChild(argument);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Plugin getPlugin() {
|
||||
return Objects.requireNonNull(Bukkit.getPluginManager().getPlugin(this.plugin.getName()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public void setAliases(List<String> aliases) {
|
||||
this.aliases = aliases;
|
||||
}
|
||||
|
||||
public List<String> getAliases() {
|
||||
return this.aliases;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user