diff --git a/src/main/java/fr/maxlego08/menu/command/ZSubCommand.java b/src/main/java/fr/maxlego08/menu/command/ZSubCommand.java new file mode 100644 index 00000000..dec684c0 --- /dev/null +++ b/src/main/java/fr/maxlego08/menu/command/ZSubCommand.java @@ -0,0 +1,49 @@ +package fr.maxlego08.menu.command; + +import com.mojang.brigadier.builder.ArgumentBuilder; +import com.mojang.brigadier.tree.LiteralCommandNode; +import fr.robie.paperdispatch.command.SubCommand; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.List; + +/** + * Paper-Dispatch attaches an executor to every required argument node, so a command declaring + * several required arguments is also executable when only the first ones are typed. The command + * then runs with arguments that were never parsed and Brigadier throws + * {@code No such argument '...' exists on this command}. + *

+ * Only the last required argument may be executable, so this class removes the executor from all + * the previous ones just before the node is built. Brigadier then answers with its usual + * "incomplete command" error instead of running the command. + */ +public abstract class ZSubCommand extends SubCommand { + + private final List> requiredArgumentBuilders = new ArrayList<>(); + + protected ZSubCommand(T plugin, String name) { + super(plugin, name); + } + + protected ZSubCommand(T plugin, String name, String... aliases) { + super(plugin, name, aliases); + } + + @Override + protected void addRequiredArgument(ArgumentBuilder argument, ArgumentExecutor executor) { + super.addRequiredArgument(argument, executor); + // Paper-Dispatch may wrap the builder before this point, so only the instance received here + // is the one that will end up in the command tree. + this.requiredArgumentBuilders.add(argument); + } + + @Override + public LiteralCommandNode build() { + for (int index = 0; index < this.requiredArgumentBuilders.size() - 1; index++) { + this.requiredArgumentBuilders.get(index).executes(null); + } + return super.build(); + } +} diff --git a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuCreate.java b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuCreate.java index 5b802570..6dd5fbcc 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuCreate.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenuCreate.java @@ -4,15 +4,15 @@ import com.mojang.brigadier.arguments.StringArgumentType; import fr.maxlego08.menu.ZMenuPlugin; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.command.ZSubCommand; import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.common.utils.MessageUtils; import fr.robie.paperdispatch.command.CommandDispatch; import fr.robie.paperdispatch.command.CommandResultType; -import fr.robie.paperdispatch.command.SubCommand; import io.papermc.paper.command.brigadier.Commands; import org.jetbrains.annotations.NotNull; -public class CommandMenuCreate extends SubCommand { +public class CommandMenuCreate extends ZSubCommand { public CommandMenuCreate(ZMenuPlugin plugin) { super(plugin, "create"); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersAdd.java b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersAdd.java index 4d60a7b6..5b7b132e 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersAdd.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersAdd.java @@ -5,6 +5,7 @@ import fr.maxlego08.menu.api.players.Data; import fr.maxlego08.menu.api.players.DataManager; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.command.ZSubCommand; import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.common.utils.MessageUtils; import fr.maxlego08.menu.common.utils.command.NonSpaceStringArgumentType; @@ -13,14 +14,13 @@ import fr.robie.paperdispatch.cache.OfflinePlayerCache; import fr.robie.paperdispatch.command.CommandDispatch; import fr.robie.paperdispatch.command.CommandResultType; -import fr.robie.paperdispatch.command.SubCommand; import io.papermc.paper.command.brigadier.Commands; import org.jetbrains.annotations.NotNull; import java.util.Optional; import java.util.UUID; -public class CommandMenuPlayersAdd extends SubCommand { +public class CommandMenuPlayersAdd extends ZSubCommand { public CommandMenuPlayersAdd(ZMenuPlugin plugin) { super(plugin, "add"); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersGet.java b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersGet.java index 529b8c5f..9f0561b3 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersGet.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersGet.java @@ -5,20 +5,20 @@ import fr.maxlego08.menu.api.players.DataManager; import fr.maxlego08.menu.api.players.PlayerData; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.command.ZSubCommand; import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.common.utils.MessageUtils; import fr.maxlego08.menu.common.utils.command.NonSpaceStringArgumentType; import fr.robie.paperdispatch.argument.OfflinePlayerArgument; import fr.robie.paperdispatch.command.CommandDispatch; import fr.robie.paperdispatch.command.CommandResultType; -import fr.robie.paperdispatch.command.SubCommand; import io.papermc.paper.command.brigadier.Commands; import org.jetbrains.annotations.NotNull; import java.util.Optional; import java.util.UUID; -public class CommandMenuPlayersGet extends SubCommand { +public class CommandMenuPlayersGet extends ZSubCommand { public CommandMenuPlayersGet(ZMenuPlugin plugin) { super(plugin, "get"); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersRemove.java b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersRemove.java index 40a0cddb..88901006 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersRemove.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersRemove.java @@ -4,13 +4,13 @@ import fr.maxlego08.menu.api.players.DataManager; import fr.maxlego08.menu.api.players.PlayerData; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.command.ZSubCommand; import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.common.utils.MessageUtils; import fr.maxlego08.menu.common.utils.command.NonSpaceStringArgumentType; import fr.robie.paperdispatch.argument.OfflinePlayerArgument; import fr.robie.paperdispatch.command.CommandDispatch; import fr.robie.paperdispatch.command.CommandResultType; -import fr.robie.paperdispatch.command.SubCommand; import io.papermc.paper.command.brigadier.Commands; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; @@ -18,7 +18,7 @@ import java.util.Optional; import java.util.UUID; -public class CommandMenuPlayersRemove extends SubCommand { +public class CommandMenuPlayersRemove extends ZSubCommand { public CommandMenuPlayersRemove(ZMenuPlugin plugin) { super(plugin, "remove", "r"); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersSet.java b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersSet.java index de75eadf..afc74769 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersSet.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersSet.java @@ -6,6 +6,7 @@ import fr.maxlego08.menu.api.players.Data; import fr.maxlego08.menu.api.players.DataManager; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.command.ZSubCommand; import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.common.utils.MessageUtils; import fr.maxlego08.menu.common.utils.command.NonSpaceStringArgumentType; @@ -14,13 +15,12 @@ import fr.robie.paperdispatch.cache.OfflinePlayerCache; import fr.robie.paperdispatch.command.CommandDispatch; import fr.robie.paperdispatch.command.CommandResultType; -import fr.robie.paperdispatch.command.SubCommand; import io.papermc.paper.command.brigadier.Commands; import org.jetbrains.annotations.NotNull; import java.util.UUID; -public class CommandMenuPlayersSet extends SubCommand { +public class CommandMenuPlayersSet extends ZSubCommand { public CommandMenuPlayersSet(ZMenuPlugin plugin) { super(plugin, "set"); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersSubtract.java b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersSubtract.java index 01c2d37d..13c77116 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersSubtract.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/players/CommandMenuPlayersSubtract.java @@ -5,6 +5,7 @@ import fr.maxlego08.menu.api.players.Data; import fr.maxlego08.menu.api.players.DataManager; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.command.ZSubCommand; import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.common.utils.MessageUtils; import fr.maxlego08.menu.common.utils.command.NonSpaceStringArgumentType; @@ -13,14 +14,13 @@ import fr.robie.paperdispatch.cache.OfflinePlayerCache; import fr.robie.paperdispatch.command.CommandDispatch; import fr.robie.paperdispatch.command.CommandResultType; -import fr.robie.paperdispatch.command.SubCommand; import io.papermc.paper.command.brigadier.Commands; import org.jetbrains.annotations.NotNull; import java.util.Optional; import java.util.UUID; -public class CommandMenuPlayersSubtract extends SubCommand { +public class CommandMenuPlayersSubtract extends ZSubCommand { public CommandMenuPlayersSubtract(ZMenuPlugin plugin) { super(plugin, "subtract", "sub");