From f20bede62a516a11a468d27d3f1adde2085762bc Mon Sep 17 00:00:00 2001 From: Liyan Zhao Date: Thu, 30 Mar 2023 20:29:57 +0800 Subject: [PATCH] Fix wrong redirect behavior (MC-256419) (#124) * Fix wrong redirect behavior * Set foundCommand to `true` if redirect modifier returns no result. --- .../mojang/brigadier/CommandDispatcher.java | 3 +- .../brigadier/CommandDispatcherTest.java | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mojang/brigadier/CommandDispatcher.java b/src/main/java/com/mojang/brigadier/CommandDispatcher.java index ca24830b..ef1f1237 100644 --- a/src/main/java/com/mojang/brigadier/CommandDispatcher.java +++ b/src/main/java/com/mojang/brigadier/CommandDispatcher.java @@ -231,7 +231,6 @@ public int execute(final ParseResults parse) throws CommandSyntaxException { if (child != null) { forked |= context.isForked(); if (child.hasNodes()) { - foundCommand = true; final RedirectModifier modifier = context.getRedirectModifier(); if (modifier == null) { if (next == null) { @@ -248,6 +247,8 @@ public int execute(final ParseResults parse) throws CommandSyntaxException { for (final S source : results) { next.add(child.copyFor(source)); } + } else { + foundCommand = true; } } catch (final CommandSyntaxException ex) { consumer.onCommandComplete(context, false, 0); diff --git a/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java b/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java index f2bab4a9..b69184bb 100644 --- a/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java +++ b/src/test/java/com/mojang/brigadier/CommandDispatcherTest.java @@ -4,6 +4,7 @@ package com.mojang.brigadier; import com.google.common.collect.Lists; +import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContextBuilder; import com.mojang.brigadier.exceptions.CommandSyntaxException; @@ -14,6 +15,9 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import java.util.Collections; +import java.util.concurrent.atomic.AtomicBoolean; + import static com.mojang.brigadier.arguments.IntegerArgumentType.integer; import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal; import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument; @@ -326,6 +330,37 @@ public void testExecuteRedirected() throws Exception { verify(command).run(argThat(hasProperty("source", is(source2)))); } + @Test + public void testIncompleteRedirectShouldThrow() { + final LiteralCommandNode foo = subject.register(literal("foo") + .then(literal("bar") + .then(argument("value", integer()).executes(context -> IntegerArgumentType.getInteger(context, "value")))) + .then(literal("awa").executes(context -> 2))); + final LiteralCommandNode baz = subject.register(literal("baz").redirect(foo)); + try { + int result = subject.execute("baz bar", source); + fail("Should have thrown an exception"); + } catch (CommandSyntaxException e) { + assertThat(e.getType(), is(CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand())); + } + } + + @Test + public void testRedirectModifierEmptyResult() { + final LiteralCommandNode foo = subject.register(literal("foo") + .then(literal("bar") + .then(argument("value", integer()).executes(context -> IntegerArgumentType.getInteger(context, "value")))) + .then(literal("awa").executes(context -> 2))); + final RedirectModifier emptyModifier = context -> Collections.emptyList(); + final LiteralCommandNode baz = subject.register(literal("baz").fork(foo, emptyModifier)); + try { + int result = subject.execute("baz bar 100", source); + assertThat(result, is(0)); // No commands executed, so result is 0 + } catch (CommandSyntaxException e) { + fail("Should not throw an exception"); + } + } + @Test public void testExecuteOrphanedSubcommand() throws Exception { subject.register(literal("foo").then(