From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Wed, 25 Aug 2021 13:19:53 -0700 Subject: [PATCH] Vanilla command permission fixes Fixes permission checks for vanilla commands which don't have a requirement, as well as for namespaced vanilla commands. diff --git a/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java b/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java index 899008b2980d13f1be6280cd8cb959c53a29bebf..f875507241ac6769545e91cd3285232b75b892f0 100644 --- a/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java +++ b/src/main/java/com/mojang/brigadier/builder/ArgumentBuilder.java @@ -14,9 +14,17 @@ import java.util.Collections; import java.util.function.Predicate; public abstract class ArgumentBuilder> { + // Paper start + private static final Predicate DEFAULT_REQUIREMENT = s -> true; + + @SuppressWarnings("unchecked") + public static Predicate defaultRequirement() { + return (Predicate) DEFAULT_REQUIREMENT; + } + // Paper end private final RootCommandNode arguments = new RootCommandNode<>(); private Command command; - private Predicate requirement = s -> true; + private Predicate requirement = defaultRequirement(); // Paper private CommandNode target; private RedirectModifier modifier = null; private boolean forks; diff --git a/src/main/java/com/mojang/brigadier/tree/CommandNode.java b/src/main/java/com/mojang/brigadier/tree/CommandNode.java index c0fac7369b111e65b896a15848ae22457e5e8914..fd310f5d009801492def4af943322a3b9859f9c6 100644 --- a/src/main/java/com/mojang/brigadier/tree/CommandNode.java +++ b/src/main/java/com/mojang/brigadier/tree/CommandNode.java @@ -30,7 +30,7 @@ public abstract class CommandNode implements Comparable> { private Map> children = Maps.newTreeMap(); //Paper - Switch to tree map for automatic sorting private Map> literals = Maps.newLinkedHashMap(); private Map> arguments = Maps.newLinkedHashMap(); - private final Predicate requirement; + public Predicate requirement; // Paper - Vanilla command permission fixes (private final -> public) private final CommandNode redirect; private final RedirectModifier modifier; private final boolean forks; diff --git a/src/main/java/net/minecraft/commands/CommandDispatcher.java b/src/main/java/net/minecraft/commands/CommandDispatcher.java index 4270a9bbc272706b5a88807d465a32e73d18b90f..3d255c2ed31d7267bb6cd789702063671d785018 100644 --- a/src/main/java/net/minecraft/commands/CommandDispatcher.java +++ b/src/main/java/net/minecraft/commands/CommandDispatcher.java @@ -197,6 +197,13 @@ public class CommandDispatcher { CommandPublish.a(this.b); } + // Paper start + for (final CommandNode node : this.dispatcher().getRoot().getChildren()) { + if (node.getRequirement() == com.mojang.brigadier.builder.ArgumentBuilder.defaultRequirement()) { + node.requirement = stack -> stack.base == ICommandListener.DUMMY || stack.getBukkitSender().hasPermission(org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(node)); + } + } + // Paper end this.b.findAmbiguities((commandnode, commandnode1, commandnode2, collection) -> { // CommandDispatcher.LOGGER.warn("Ambiguity between arguments {} and {} with inputs: {}", this.b.getPath(commandnode1), this.b.getPath(commandnode2), collection); // CraftBukkit }); diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java index 56a0665127c7c55049b8438c91e72b6881ed11e0..c87fa1b2378f25307fff6acbcbc178e5cafd50e4 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java +++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java @@ -87,7 +87,23 @@ public final class VanillaCommandWrapper extends BukkitCommand { } public static String getPermission(CommandNode vanillaCommand) { - return "minecraft.command." + ((vanillaCommand.getRedirect() == null) ? vanillaCommand.getName() : vanillaCommand.getRedirect().getName()); + // Paper start + final String commandName; + if (vanillaCommand.getRedirect() == null) { + commandName = vanillaCommand.getName(); + } else { + commandName = vanillaCommand.getRedirect().getName(); + } + return "minecraft.command." + stripDefaultNamespace(commandName); + } + + private static String stripDefaultNamespace(final String maybeNamespaced) { + final String prefix = "minecraft:"; + if (maybeNamespaced.startsWith(prefix)) { + return maybeNamespaced.substring(prefix.length()); + } + return maybeNamespaced; + // Paper end } private String toDispatcher(String[] args, String name) {