diff --git a/paper-server/patches/sources/com/mojang/brigadier/CommandDispatcher.java.patch b/paper-server/patches/sources/com/mojang/brigadier/CommandDispatcher.java.patch index acc12b7b56..ba95e196e5 100644 --- a/paper-server/patches/sources/com/mojang/brigadier/CommandDispatcher.java.patch +++ b/paper-server/patches/sources/com/mojang/brigadier/CommandDispatcher.java.patch @@ -8,7 +8,14 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContextBuilder; -@@ -303,9 +304,15 @@ +@@ -297,15 +298,21 @@ + List> potentials = null; + final int cursor = originalReader.getCursor(); + +- for (final CommandNode child : node.getRelevantNodes(originalReader)) { ++ for (final CommandNode child : node.getRelevantNodes(originalReader, source)) { // Paper - prioritize mc commands in function parsing + if (!child.canUse(source)) { + continue; } final CommandContextBuilder context = contextSoFar.copy(); final StringReader reader = new StringReader(originalReader); diff --git a/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch b/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch index da6f30a5d8..179686de6f 100644 --- a/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch +++ b/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch @@ -52,7 +52,43 @@ return this.requirement.test(source); } -@@ -183,4 +205,11 @@ +@@ -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(); diff --git a/paper-server/patches/sources/com/mojang/brigadier/tree/LiteralCommandNode.java.patch b/paper-server/patches/sources/com/mojang/brigadier/tree/LiteralCommandNode.java.patch new file mode 100644 index 0000000000..15d0b7b976 --- /dev/null +++ b/paper-server/patches/sources/com/mojang/brigadier/tree/LiteralCommandNode.java.patch @@ -0,0 +1,57 @@ +--- a/com/mojang/brigadier/tree/LiteralCommandNode.java ++++ b/com/mojang/brigadier/tree/LiteralCommandNode.java +@@ -23,11 +23,19 @@ + public class LiteralCommandNode extends CommandNode { + private final String literal; + private final String literalLowerCase; ++ private final String nonPrefixed; // Paper - prioritize mc commands in function parsing + + public LiteralCommandNode(final String literal, final Command command, final Predicate requirement, final CommandNode redirect, final RedirectModifier modifier, final boolean forks) { + super(command, requirement, redirect, modifier, forks); + this.literal = literal; + this.literalLowerCase = literal.toLowerCase(Locale.ROOT); ++ // Paper start - prioritize mc commands in function parsing ++ if (literal.startsWith("minecraft:")) { ++ this.nonPrefixed = literal.substring("minecraft:".length()); ++ } else { ++ this.nonPrefixed = null; ++ } ++ // Paper end - prioritize mc commands in function parsing + } + + public String getLiteral() { +@@ -42,7 +50,12 @@ + @Override + public void parse(final StringReader reader, final CommandContextBuilder contextBuilder) throws CommandSyntaxException { + final int start = reader.getCursor(); +- final int end = parse(reader); ++ // Paper start - prioritize mc commands in function parsing ++ int end = parse(reader, false); ++ if (end == -1 && this.nonPrefixed != null) { ++ end = parse(reader, true); ++ } ++ // Paper end - prioritize mc commands in function parsing + if (end > -1) { + contextBuilder.withNode(this, StringRange.between(start, end)); + return; +@@ -51,7 +64,10 @@ + throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.literalIncorrect().createWithContext(reader, literal); + } + +- private int parse(final StringReader reader) { ++ // Paper start - prioritize mc commands in function parsing ++ private int parse(final StringReader reader, final boolean secondPass) { ++ String literal = secondPass ? this.nonPrefixed : this.literal; ++ // Paper end - prioritize mc commands in function parsing + final int start = reader.getCursor(); + if (reader.canRead(literal.length())) { + final int end = start + literal.length(); +@@ -78,7 +94,7 @@ + + @Override + public boolean isValidInput(final String input) { +- return parse(new StringReader(input)) > -1; ++ return parse(new StringReader(input), false) > -1; // Paper - prioritize mc commands in function parsing + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch index 48fe9bfe7f..e54c063624 100644 --- a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch @@ -1,10 +1,9 @@ --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -138,6 +138,14 @@ - import net.minecraft.world.flag.FeatureFlags; +@@ -139,6 +139,14 @@ import net.minecraft.world.level.GameRules; import org.slf4j.Logger; -+ + +// CraftBukkit start +import com.google.common.base.Joiner; +import java.util.Collection; @@ -12,9 +11,10 @@ +import org.bukkit.event.player.PlayerCommandSendEvent; +import org.bukkit.event.server.ServerCommandEvent; +// CraftBukkit end - ++ public class Commands { + private static final ThreadLocal> CURRENT_EXECUTION_CONTEXT = new ThreadLocal(); @@ -151,6 +159,7 @@ private final com.mojang.brigadier.CommandDispatcher dispatcher = new com.mojang.brigadier.CommandDispatcher(); @@ -57,13 +57,10 @@ this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer()); } -@@ -262,30 +296,75 @@ +@@ -262,30 +296,72 @@ return new ParseResults(commandcontextbuilder1, parseResults.getReader(), parseResults.getExceptions()); } -- public void performPrefixedCommand(CommandSourceStack source, String command) { -- command = command.startsWith("/") ? command.substring(1) : command; -- this.performCommand(this.dispatcher.parse(command, source), command); + // CraftBukkit start + public void dispatchServerCommand(CommandSourceStack sender, String command) { + Joiner joiner = Joiner.on(" "); @@ -83,17 +80,16 @@ + + // Paper - Fix permission levels for command blocks + -+ // Handle vanilla commands; -+ if (sender.getLevel().getCraftServer().getCommandBlockOverride(args[0])) { -+ args[0] = "minecraft:" + args[0]; -+ } ++ // Handle vanilla commands; // Paper - handled in CommandNode/CommandDispatcher + + String newCommand = joiner.join(args); + this.performPrefixedCommand(sender, newCommand, newCommand); + } + // CraftBukkit end + -+ public void performPrefixedCommand(CommandSourceStack source, String command) { + public void performPrefixedCommand(CommandSourceStack source, String command) { +- command = command.startsWith("/") ? command.substring(1) : command; +- this.performCommand(this.dispatcher.parse(command, source), command); + // CraftBukkit start + this.performPrefixedCommand(source, command, command); } @@ -142,7 +138,7 @@ StackTraceElement[] astacktraceelement = exception.getStackTrace(); for (int i = 0; i < Math.min(astacktraceelement.length, 3); ++i) { -@@ -298,7 +377,7 @@ +@@ -298,7 +374,7 @@ })); if (SharedConstants.IS_RUNNING_IN_IDE) { commandlistenerwrapper.sendFailure(Component.literal(Util.describeError(exception))); @@ -151,7 +147,7 @@ } } finally { Profiler.get().pop(); -@@ -307,18 +386,22 @@ +@@ -307,18 +383,22 @@ } @Nullable @@ -180,7 +176,7 @@ }); if (i > 10) { -@@ -333,8 +416,18 @@ +@@ -333,7 +413,17 @@ } ichatmutablecomponent.append((Component) Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC)); @@ -190,17 +186,16 @@ + builder + .append(net.kyori.adventure.text.Component.newline()) + .append(io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); - } ++ } + org.bukkit.event.command.UnknownCommandEvent event = new org.bukkit.event.command.UnknownCommandEvent(commandlistenerwrapper.getBukkitSender(), s, org.spigotmc.SpigotConfig.unknownCommandMessage.isEmpty() ? null : builder.build()); + org.bukkit.Bukkit.getServer().getPluginManager().callEvent(event); + if (event.message() != null) { + commandlistenerwrapper.sendFailure(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false); + // Paper end - Add UnknownCommandEvent -+ } + } return null; - } -@@ -368,7 +461,7 @@ +@@ -368,7 +458,7 @@ executioncontext1.close(); } finally { @@ -209,7 +204,7 @@ } } else { callback.accept(executioncontext); -@@ -377,23 +470,121 @@ +@@ -377,23 +467,121 @@ } public void sendCommands(ServerPlayer player) { @@ -336,7 +331,7 @@ argumentbuilder.requires((icompletionprovider) -> { return true; }); -@@ -415,12 +606,12 @@ +@@ -415,12 +603,12 @@ argumentbuilder.redirect((CommandNode) resultNodes.get(argumentbuilder.getRedirect())); } @@ -351,7 +346,7 @@ } } } -@@ -481,7 +672,7 @@ +@@ -481,7 +669,7 @@ } private HolderLookup.RegistryLookup.Delegate createLookup(final HolderLookup.RegistryLookup original) {