mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-05 22:52:13 -07:00
Supports the ability for commands to be registered internally (#12520)
This commit is contained in:
@@ -15,5 +15,9 @@ public enum CommandRegistrationFlag {
|
||||
* @deprecated This is the default behavior now.
|
||||
*/
|
||||
@Deprecated(since = "1.21.4")
|
||||
FLATTEN_ALIASES
|
||||
FLATTEN_ALIASES,
|
||||
/**
|
||||
* Prevents this command from being sent to the client.
|
||||
*/
|
||||
SERVER_ONLY
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@
|
||||
+ public CommandNode<net.minecraft.commands.CommandSourceStack> clientNode; // Paper - Brigadier API
|
||||
+ public CommandNode<io.papermc.paper.command.brigadier.CommandSourceStack> unwrappedCached = null; // Paper - Brigadier Command API
|
||||
+ public CommandNode<io.papermc.paper.command.brigadier.CommandSourceStack> wrappedCached = null; // Paper - Brigadier Command API
|
||||
+ public io.papermc.paper.command.brigadier.PluginCommandMeta pluginCommandMeta; // Paper - Brigadier Command API
|
||||
+ public io.papermc.paper.command.brigadier.APICommandMeta apiCommandMeta; // Paper - Brigadier Command API
|
||||
+ // CraftBukkit start
|
||||
+ public void removeCommand(String name) {
|
||||
+ this.children.remove(name);
|
||||
|
@@ -172,7 +172,7 @@
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -359,26 +_,120 @@
|
||||
@@ -359,26 +_,121 @@
|
||||
}
|
||||
|
||||
public void sendCommands(ServerPlayer player) {
|
||||
@@ -252,6 +252,7 @@
|
||||
+ }
|
||||
+ // Paper end - Brigadier API
|
||||
+ if (!org.spigotmc.SpigotConfig.sendNamespaced && commandNode.getName().contains(":")) continue; // Spigot
|
||||
+ if (commandNode.wrappedCached != null && commandNode.wrappedCached.apiCommandMeta != null && commandNode.wrappedCached.apiCommandMeta.serverSideOnly()) continue; // Paper
|
||||
if (commandNode.canUse(source)) {
|
||||
ArgumentBuilder<SharedSuggestionProvider, ?> argumentBuilder = (ArgumentBuilder) commandNode.createBuilder();
|
||||
+ // Paper start
|
||||
|
@@ -1,12 +1,13 @@
|
||||
--- a/net/minecraft/server/ReloadableServerResources.java
|
||||
+++ b/net/minecraft/server/ReloadableServerResources.java
|
||||
@@ -38,7 +_,8 @@
|
||||
@@ -38,7 +_,9 @@
|
||||
this.fullRegistryHolder = new ReloadableServerRegistries.Holder(registryAccess.compositeAccess());
|
||||
this.postponedTags = postponedTags;
|
||||
this.recipes = new RecipeManager(registries);
|
||||
- this.commands = new Commands(commandSelection, CommandBuildContext.simple(registries, enabledFeatures));
|
||||
+ this.commands = new Commands(commandSelection, CommandBuildContext.simple(registries, enabledFeatures), true); // Paper - Brigadier Command API - use modern alias registration
|
||||
+ io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setDispatcher(this.commands, CommandBuildContext.simple(registries, enabledFeatures)); // Paper - Brigadier Command API
|
||||
+ io.papermc.paper.command.PaperCommands.registerCommands(); // Paper
|
||||
this.advancements = new ServerAdvancementManager(registries);
|
||||
this.functionLibrary = new ServerFunctionLibrary(functionCompilationLevel, this.commands.getDispatcher());
|
||||
}
|
||||
|
@@ -1,10 +1,15 @@
|
||||
package io.papermc.paper.command;
|
||||
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import io.papermc.paper.command.brigadier.CommandRegistrationFlag;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.bukkit.command.Command;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
|
||||
@@ -15,16 +20,31 @@ public final class PaperCommands {
|
||||
}
|
||||
|
||||
private static final Map<String, Command> COMMANDS = new HashMap<>();
|
||||
static {
|
||||
|
||||
public static void registerCommands(final MinecraftServer server) {
|
||||
COMMANDS.put("paper", new PaperCommand("paper"));
|
||||
COMMANDS.put("callback", new CallbackCommand("callback"));
|
||||
COMMANDS.put("mspt", new MSPTCommand("mspt"));
|
||||
}
|
||||
|
||||
public static void registerCommands(final MinecraftServer server) {
|
||||
COMMANDS.forEach((s, command) -> {
|
||||
server.server.getCommandMap().register(s, "Paper", command);
|
||||
});
|
||||
server.server.getCommandMap().register("bukkit", new PaperPluginsCommand());
|
||||
}
|
||||
|
||||
public static void registerCommands() {
|
||||
// Paper commands go here
|
||||
}
|
||||
|
||||
private static void registerInternalCommand(final LiteralCommandNode<CommandSourceStack> node, final String description, final List<String> aliases, final Set<CommandRegistrationFlag> flags) {
|
||||
io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.registerWithFlagsInternal(
|
||||
null,
|
||||
"paper",
|
||||
"Paper",
|
||||
node,
|
||||
description,
|
||||
aliases,
|
||||
flags
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,31 @@
|
||||
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 APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String description, List<String> aliases, @Nullable String helpCommandNamespace, boolean serverSideOnly) {
|
||||
|
||||
public APICommandMeta(final @Nullable PluginMeta pluginMeta, final @Nullable String description) {
|
||||
this(pluginMeta, description, Collections.emptyList(), null, false);
|
||||
}
|
||||
|
||||
public APICommandMeta {
|
||||
aliases = List.copyOf(aliases);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Plugin plugin() {
|
||||
return this.pluginMeta == null ? null : Objects.requireNonNull(Bukkit.getPluginManager().getPlugin(this.pluginMeta.getName()));
|
||||
}
|
||||
|
||||
public APICommandMeta withAliases(List<String> registeredAliases) {
|
||||
return new APICommandMeta(this.pluginMeta, this.description, List.copyOf(registeredAliases), this.helpCommandNamespace, this.serverSideOnly);
|
||||
}
|
||||
}
|
@@ -35,8 +35,8 @@ public final class PaperBrigadier {
|
||||
throw new IllegalArgumentException("Unsure how to wrap a " + node);
|
||||
}
|
||||
|
||||
final PluginCommandMeta meta;
|
||||
if ((meta = node.pluginCommandMeta) == null) {
|
||||
final APICommandMeta meta;
|
||||
if ((meta = node.apiCommandMeta) == null) {
|
||||
return new VanillaCommandWrapper(node);
|
||||
}
|
||||
CommandNode<CommandSourceStack> argumentCommandNode = node;
|
||||
@@ -46,6 +46,12 @@ public final class PaperBrigadier {
|
||||
|
||||
Map<CommandNode<CommandSourceStack>, String> map = PaperCommands.INSTANCE.getDispatcherInternal().getSmartUsage(argumentCommandNode, DUMMY);
|
||||
String usage = map.isEmpty() ? node.getUsageText() : node.getUsageText() + " " + String.join("\n" + node.getUsageText() + " ", map.values());
|
||||
|
||||
// Internal command
|
||||
if (meta.pluginMeta() == null) {
|
||||
return new VanillaCommandWrapper(node.getName(), meta.description(), usage, meta.aliases(), node, meta.helpCommandNamespace());
|
||||
}
|
||||
|
||||
return new PluginVanillaCommandWrapper(node.getName(), meta.description(), usage, meta.aliases(), node, meta.plugin());
|
||||
}
|
||||
|
||||
|
@@ -91,10 +91,13 @@ public class PaperCommands implements Commands, PaperRegistrar<LifecycleEventOwn
|
||||
|
||||
@Override
|
||||
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);
|
||||
return registerWithFlagsInternal(pluginMeta, pluginMeta.getName().toLowerCase(Locale.ROOT), null, node, description, aliases, flags);
|
||||
}
|
||||
|
||||
public @Unmodifiable Set<String> registerWithFlagsInternal(final @Nullable PluginMeta pluginMeta, final String namespace, final @Nullable String helpNamespaceOverride, final LiteralCommandNode<CommandSourceStack> node, final @Nullable String description, final Collection<String> aliases, final Set<CommandRegistrationFlag> flags) {
|
||||
final APICommandMeta meta = new APICommandMeta(pluginMeta, description, List.of(), helpNamespaceOverride, flags.contains(CommandRegistrationFlag.SERVER_ONLY));
|
||||
final String literal = node.getLiteral();
|
||||
final LiteralCommandNode<CommandSourceStack> pluginLiteral = PaperBrigadier.copyLiteral(identifier + ":" + literal, node);
|
||||
final LiteralCommandNode<CommandSourceStack> pluginLiteral = PaperBrigadier.copyLiteral(namespace + ":" + literal, node);
|
||||
|
||||
final Set<String> registeredLabels = new HashSet<>(aliases.size() * 2 + 2);
|
||||
|
||||
@@ -111,27 +114,27 @@ public class PaperCommands implements Commands, PaperRegistrar<LifecycleEventOwn
|
||||
if (this.registerCopy(alias, pluginLiteral, meta)) {
|
||||
registeredAliases.add(alias);
|
||||
}
|
||||
if (this.registerCopy(identifier + ":" + alias, pluginLiteral, meta)) {
|
||||
registeredAliases.add(identifier + ":" + alias);
|
||||
if (this.registerCopy(namespace + ":" + alias, pluginLiteral, meta)) {
|
||||
registeredAliases.add(namespace + ":" + alias);
|
||||
}
|
||||
}
|
||||
|
||||
pluginLiteral.pluginCommandMeta = new PluginCommandMeta(pluginMeta, description, registeredAliases);
|
||||
node.pluginCommandMeta = pluginLiteral.pluginCommandMeta;
|
||||
pluginLiteral.apiCommandMeta = meta.withAliases(registeredAliases);
|
||||
node.apiCommandMeta = pluginLiteral.apiCommandMeta;
|
||||
|
||||
registeredLabels.addAll(registeredAliases);
|
||||
return registeredLabels.isEmpty() ? Collections.emptySet() : Collections.unmodifiableSet(registeredLabels);
|
||||
}
|
||||
|
||||
private boolean registerCopy(final String aliasLiteral, final LiteralCommandNode<CommandSourceStack> redirectTo, final PluginCommandMeta meta) {
|
||||
private boolean registerCopy(final String aliasLiteral, final LiteralCommandNode<CommandSourceStack> redirectTo, final APICommandMeta meta) {
|
||||
final LiteralCommandNode<CommandSourceStack> node = PaperBrigadier.copyLiteral(aliasLiteral, redirectTo);
|
||||
node.pluginCommandMeta = meta;
|
||||
node.apiCommandMeta = meta;
|
||||
return this.registerIntoDispatcher(node, false);
|
||||
}
|
||||
|
||||
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)) {
|
||||
if (existingChild != null && existingChild.apiCommandMeta == null && !(existingChild instanceof BukkitCommandNode)) {
|
||||
override = true; // override vanilla commands
|
||||
}
|
||||
if (existingChild == null || override) { // Avoid merging behavior. Maybe something to look into in the future
|
||||
|
@@ -1,26 +0,0 @@
|
||||
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()));
|
||||
}
|
||||
}
|
@@ -17,7 +17,7 @@ public class PluginVanillaCommandWrapper extends VanillaCommandWrapper implement
|
||||
private final List<String> aliases;
|
||||
|
||||
public PluginVanillaCommandWrapper(String name, String description, String usageMessage, List<String> aliases, CommandNode<CommandSourceStack> vanillaCommand, Plugin plugin) {
|
||||
super(name, description, usageMessage, aliases, vanillaCommand);
|
||||
super(name, description, usageMessage, aliases, vanillaCommand, null);
|
||||
this.plugin = plugin;
|
||||
this.aliases = aliases;
|
||||
}
|
||||
|
@@ -26,10 +26,12 @@ import org.bukkit.entity.minecart.CommandMinecart;
|
||||
public class VanillaCommandWrapper extends BukkitCommand { // Paper
|
||||
|
||||
public final CommandNode<CommandSourceStack> vanillaCommand;
|
||||
public final String helpCommandNamespace;
|
||||
|
||||
public VanillaCommandWrapper(String name, String description, String usageMessage, List<String> aliases, CommandNode<CommandSourceStack> vanillaCommand) {
|
||||
public VanillaCommandWrapper(String name, String description, String usageMessage, List<String> aliases, CommandNode<CommandSourceStack> vanillaCommand, String helpCommandNamespace) {
|
||||
super(name, description, usageMessage, aliases);
|
||||
this.vanillaCommand = vanillaCommand;
|
||||
this.helpCommandNamespace = helpCommandNamespace;
|
||||
}
|
||||
|
||||
Commands commands() {
|
||||
@@ -40,6 +42,7 @@ public class VanillaCommandWrapper extends BukkitCommand { // Paper
|
||||
super(vanillaCommand.getName(), "A Mojang provided command.", vanillaCommand.getUsageText(), Collections.emptyList());
|
||||
this.vanillaCommand = vanillaCommand;
|
||||
this.setPermission(VanillaCommandWrapper.getPermission(vanillaCommand));
|
||||
this.helpCommandNamespace = "Minecraft";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -199,18 +199,15 @@ public class SimpleHelpMap implements HelpMap {
|
||||
}
|
||||
|
||||
private String getCommandPluginName(Command command) {
|
||||
// Paper start - Move up
|
||||
if (command instanceof PluginIdentifiableCommand) {
|
||||
return ((PluginIdentifiableCommand) command).getPlugin().getName();
|
||||
}
|
||||
// Paper end
|
||||
if (command instanceof VanillaCommandWrapper) {
|
||||
return "Minecraft";
|
||||
if (command instanceof VanillaCommandWrapper wrapper) {
|
||||
return wrapper.helpCommandNamespace;
|
||||
}
|
||||
if (command instanceof BukkitCommand) {
|
||||
return "Bukkit";
|
||||
}
|
||||
// Paper - Move PluginIdentifiableCommand instanceof check to allow brig commands
|
||||
return null;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user