From 3773df24ce81173242bff99a2a9991f7a88a66b2 Mon Sep 17 00:00:00 2001 From: Jason <11360596+jpenilla@users.noreply.github.com> Date: Wed, 25 Aug 2021 17:20:24 -0500 Subject: [PATCH] Vanilla command permission fixes (fixes #6085) (#6490) Fixes permission checks for vanilla commands which don't have a requirement, as well as for namespaced vanilla commands. --- build-data/paper.at | 3 + ...-brigadier-child-sorting-performance.patch | 4 +- ...752-Vanilla-command-permission-fixes.patch | 78 +++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 patches/server/0752-Vanilla-command-permission-fixes.patch diff --git a/build-data/paper.at b/build-data/paper.at index 59c32f006c..09fa424d9f 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -237,3 +237,6 @@ public-f net.minecraft.world.level.chunk.DataLayer # Add methods to get translation keys public org.bukkit.craftbukkit.inventory.CraftMetaFirework public org.bukkit.craftbukkit.inventory.CraftMetaFirework getNBT(Lorg/bukkit/FireworkEffect$Type;)I + +# Vanilla command permission fixes +public-f com.mojang.brigadier.tree.CommandNode requirement diff --git a/patches/server/0438-Optimize-brigadier-child-sorting-performance.patch b/patches/server/0438-Optimize-brigadier-child-sorting-performance.patch index 42f1eb780d..cf8129ab7c 100644 --- a/patches/server/0438-Optimize-brigadier-child-sorting-performance.patch +++ b/patches/server/0438-Optimize-brigadier-child-sorting-performance.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optimize brigadier child sorting performance diff --git a/src/main/java/com/mojang/brigadier/tree/CommandNode.java b/src/main/java/com/mojang/brigadier/tree/CommandNode.java -index b8d646864a24bba376661cfd87901012416c669d..aa3a1795850a419f624f14bd7c4daab0020779d0 100644 +index 2dd09c97e00d877f5f3beed9583d3fdabc88e181..74af1b6158394d66fe470f9b7db741871f2bb534 100644 --- a/src/main/java/com/mojang/brigadier/tree/CommandNode.java +++ b/src/main/java/com/mojang/brigadier/tree/CommandNode.java @@ -26,7 +26,7 @@ import java.util.stream.Collectors; @@ -16,7 +16,7 @@ index b8d646864a24bba376661cfd87901012416c669d..aa3a1795850a419f624f14bd7c4daab0 + 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; @@ -107,7 +107,7 @@ public abstract class CommandNode implements Comparable> { } } diff --git a/patches/server/0752-Vanilla-command-permission-fixes.patch b/patches/server/0752-Vanilla-command-permission-fixes.patch new file mode 100644 index 0000000000..332369c5f0 --- /dev/null +++ b/patches/server/0752-Vanilla-command-permission-fixes.patch @@ -0,0 +1,78 @@ +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/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java +index a6f10d47bc4e2cadcc3e06cffa011ed7fb97c68d..cc0aff09e03586f97d79c8db6e1e52d9f192b4b1 100644 +--- a/src/main/java/net/minecraft/commands/Commands.java ++++ b/src/main/java/net/minecraft/commands/Commands.java +@@ -204,6 +204,13 @@ public class Commands { + PublishCommand.register(this.dispatcher); + } + ++ // Paper start ++ for (final CommandNode node : this.dispatcher.getRoot().getChildren()) { ++ if (node.getRequirement() == com.mojang.brigadier.builder.ArgumentBuilder.defaultRequirement()) { ++ node.requirement = stack -> stack.getBukkitSender().hasPermission(org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(node)); ++ } ++ } ++ // Paper end + this.dispatcher.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 0377c706c9aec6f367e83f859f9a3432ad5bba4a..e9d1fb479855194da5a05e86861848158736cbb4 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) {