--- a/com/mojang/brigadier/tree/CommandNode.java +++ b/com/mojang/brigadier/tree/CommandNode.java @@ -3,6 +3,7 @@ package com.mojang.brigadier.tree; +// CHECKSTYLE:OFF import com.mojang.brigadier.AmbiguityConsumer; import com.mojang.brigadier.Command; import com.mojang.brigadier.RedirectModifier; @@ -22,6 +23,7 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; +import net.minecraft.commands.CommandSourceStack; public abstract class CommandNode implements Comparable> { private final Map> children = new LinkedHashMap<>(); @@ -32,6 +34,16 @@ private final RedirectModifier modifier; private final boolean forks; private Command command; + public CommandNode clientNode; // Paper - Brigadier API + public CommandNode unwrappedCached = null; // Paper - Brigadier Command API + public CommandNode wrappedCached = null; // Paper - Brigadier Command API + // CraftBukkit start + public void removeCommand(String name) { + this.children.remove(name); + this.literals.remove(name); + this.arguments.remove(name); + } + // CraftBukkit end protected CommandNode(final Command command, final Predicate requirement, final CommandNode redirect, final RedirectModifier modifier, final boolean forks) { this.command = command; @@ -61,7 +73,17 @@ return this.modifier; } - public boolean canUse(final S source) { + // CraftBukkit start + public synchronized boolean canUse(final S source) { + if (source instanceof CommandSourceStack) { + try { + ((CommandSourceStack) source).currentCommand.put(Thread.currentThread(), this); // Paper - Thread Safe Vanilla Command permission checking + return this.requirement.test(source); + } finally { + ((CommandSourceStack) source).currentCommand.remove(Thread.currentThread()); // Paper - Thread Safe Vanilla Command permission checking + } + } + // CraftBukkit end return this.requirement.test(source); } @@ -151,6 +173,12 @@ protected abstract String getSortedKey(); public Collection> getRelevantNodes(final StringReader input) { + // Paper start - prioritize mc commands in function parsing + return this.getRelevantNodes(input, null); + } + @org.jetbrains.annotations.ApiStatus.Internal + public Collection> getRelevantNodes(final StringReader input, final Object source) { + // Paper end - prioritize mc commands in function parsing if (this.literals.size() > 0) { final int cursor = input.getCursor(); while (input.canRead() && input.peek() != ' ') { @@ -158,7 +186,21 @@ } final String text = input.getString().substring(cursor, input.getCursor()); input.setCursor(cursor); - final LiteralCommandNode literal = this.literals.get(text); + // Paper start - prioritize mc commands in function parsing + LiteralCommandNode literal = null; + if (source instanceof CommandSourceStack css && css.source == net.minecraft.commands.CommandSource.NULL) { + if (!text.contains(":")) { + literal = this.literals.get("minecraft:" + text); + } + } else if (source instanceof CommandSourceStack css && css.source instanceof net.minecraft.world.level.BaseCommandBlock) { + if (css.getServer().server.getCommandBlockOverride(text) && !text.contains(":")) { + literal = this.literals.get("minecraft:" + text); + } + } + if (literal == null) { + literal = this.literals.get(text); + } + // Paper end - prioritize mc commands in function parsing if (literal != null) { return Collections.singleton(literal); } else { @@ -183,4 +225,11 @@ } public abstract Collection getExamples(); + // Paper start - Brigadier Command API + public void clearAll() { + this.children.clear(); + this.literals.clear(); + this.arguments.clear(); + } + // Paper end - Brigadier Command API }