diff --git a/examples/fabric/src/main/java/dev/rollczi/example/fabric/client/ClientExampleFabric.java b/examples/fabric/src/main/java/dev/rollczi/example/fabric/client/ClientExampleFabric.java index 02a3d37c8..3acefef18 100644 --- a/examples/fabric/src/main/java/dev/rollczi/example/fabric/client/ClientExampleFabric.java +++ b/examples/fabric/src/main/java/dev/rollczi/example/fabric/client/ClientExampleFabric.java @@ -9,6 +9,7 @@ public class ClientExampleFabric implements ClientModInitializer { public void onInitializeClient() { LiteFabricFactory.client() .commands(new ClientCommands()) + .settings(settings -> settings.inputInspectionDisplay("[....]")) .build(); } } diff --git a/examples/fabric/src/main/java/dev/rollczi/example/fabric/client/command/ClientCommands.java b/examples/fabric/src/main/java/dev/rollczi/example/fabric/client/command/ClientCommands.java index df98f10fa..8df410d76 100644 --- a/examples/fabric/src/main/java/dev/rollczi/example/fabric/client/command/ClientCommands.java +++ b/examples/fabric/src/main/java/dev/rollczi/example/fabric/client/command/ClientCommands.java @@ -9,7 +9,7 @@ import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.text.Text; -@Command(name = "litecommands") +@Command(name = "litecommands", aliases = "litecmd") public class ClientCommands { @Execute @@ -17,7 +17,7 @@ Text info() { return Text.of("Hello from LiteCommands!"); } - @Execute(name = "my") + @Execute(name = "my", aliases = "myName") Text myName(@Sender FabricClientCommandSource sender) { return sender.getPlayer().getName(); } diff --git a/examples/fabric/src/main/java/dev/rollczi/example/fabric/server/command/ExampleCommand.java b/examples/fabric/src/main/java/dev/rollczi/example/fabric/server/command/ExampleCommand.java index 0e41455d1..04c313072 100644 --- a/examples/fabric/src/main/java/dev/rollczi/example/fabric/server/command/ExampleCommand.java +++ b/examples/fabric/src/main/java/dev/rollczi/example/fabric/server/command/ExampleCommand.java @@ -9,14 +9,14 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; -@Command(name = "example") +@Command(name = "example", aliases = "tutorial") public class ExampleCommand { @Execute(name = "kick") void sendMessage(@Arg("player") ServerPlayerEntity player, @Join("reason") String reason) { player.networkHandler.disconnect(Text.of(reason)); } - @Execute(name = "message") + @Execute(name = "message", aliases = "msg") Text sendMessage(@Quoted @Arg String message) { return Text.of("You saied: " + message); } diff --git a/litecommands-annotations/src/dev/rollczi/litecommands/annotations/argument/profile/ProfileAnnotationProcessor.java b/litecommands-annotations/src/dev/rollczi/litecommands/annotations/argument/profile/ProfileAnnotationProcessor.java index 0f5a48601..63ea6a98f 100644 --- a/litecommands-annotations/src/dev/rollczi/litecommands/annotations/argument/profile/ProfileAnnotationProcessor.java +++ b/litecommands-annotations/src/dev/rollczi/litecommands/annotations/argument/profile/ProfileAnnotationProcessor.java @@ -10,6 +10,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Executable; import java.lang.reflect.Parameter; +import org.jetbrains.annotations.Nullable; public abstract class ProfileAnnotationProcessor> implements AnnotationProcessor { @@ -38,7 +39,7 @@ public AnnotationInvoker process(AnnotationInvoker invoker) { }); } - protected abstract PROFILE createProfile(Parameter parameter, A annotation, Argument argument); + protected abstract @Nullable PROFILE createProfile(Parameter parameter, A annotation, Argument argument); } diff --git a/litecommands-annotations/test/dev/rollczi/litecommands/annotations/key/KeyCombinationsTest.java b/litecommands-annotations/test/dev/rollczi/litecommands/annotations/key/KeyCombinationsTest.java new file mode 100644 index 000000000..8c8f1fa2f --- /dev/null +++ b/litecommands-annotations/test/dev/rollczi/litecommands/annotations/key/KeyCombinationsTest.java @@ -0,0 +1,40 @@ +package dev.rollczi.litecommands.annotations.key; + +import dev.rollczi.litecommands.annotations.argument.Arg; +import dev.rollczi.litecommands.annotations.argument.Key; +import dev.rollczi.litecommands.annotations.command.RootCommand; +import dev.rollczi.litecommands.annotations.execute.Execute; +import dev.rollczi.litecommands.argument.parser.ParseResult; +import dev.rollczi.litecommands.argument.parser.Parser; +import dev.rollczi.litecommands.unit.annotations.LiteTestSpec; +import org.junit.jupiter.api.Test; + +class KeyCombinationsTest extends LiteTestSpec { + + static class Faction {} + + static LiteTestConfig config = builder -> builder + .argumentParser(Faction.class, Parser.of((invocation, text) -> ParseResult.success(new Faction()))) + .advanced(); + + @RootCommand + static class TestCommand { + + @Execute(name = "keyed") + void keyed(@Arg("arg-name") @Key("faction") Faction argValue) {} + + @Execute(name = "undefined") + void undefined(@Arg("arg-name") Faction argValue) {} + + } + + @Test + void test() { + platform.execute("keyed factionValue") + .assertSuccess(); + + platform.execute("undefined factionValue") + .assertSuccess(); + } + +} diff --git a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricAbstractPlatform.java b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricAbstractPlatform.java index 529cce17a..a84b80d7b 100644 --- a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricAbstractPlatform.java +++ b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricAbstractPlatform.java @@ -1,20 +1,22 @@ package dev.rollczi.litecommands.fabric; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.tree.LiteralCommandNode; import dev.rollczi.litecommands.command.CommandRoute; import dev.rollczi.litecommands.platform.AbstractPlatform; import dev.rollczi.litecommands.platform.Platform; import dev.rollczi.litecommands.platform.PlatformInvocationListener; import dev.rollczi.litecommands.platform.PlatformSenderFactory; -import dev.rollczi.litecommands.platform.PlatformSettings; import dev.rollczi.litecommands.platform.PlatformSuggestionListener; import java.util.HashMap; import java.util.Map; import java.util.UUID; -public abstract class FabricAbstractPlatform extends AbstractPlatform implements Platform { +public abstract class FabricAbstractPlatform extends AbstractPlatform implements Platform { - protected final Map> fabricCommands = new HashMap<>(); + protected final Map> fabricCommands = new HashMap<>(); protected static boolean COMMAND_API_V2 = true; @@ -26,13 +28,22 @@ public abstract class FabricAbstractPlatform extends AbstractPlatform factory) { + protected FabricAbstractPlatform(LiteFabricSettings settings, PlatformSenderFactory factory) { super(settings, factory); registerEvents(); } protected abstract void registerEvents(); + protected void registerAllCommands(CommandDispatcher dispatcher) { + for (FabricCommand fabricCommand : fabricCommands.values()) { + LiteralCommandNode commandNode = dispatcher.register(fabricCommand.toLiteral()); + for (String alias : fabricCommand.getCommandRoute().getAliases()) { + dispatcher.register(LiteralArgumentBuilder.literal(alias).redirect(commandNode)); + } + } + } + @Override protected void hook(CommandRoute commandRoute, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook) { fabricCommands.put(commandRoute.getUniqueId(), createCommand(commandRoute, invocationHook, suggestionHook)); @@ -44,5 +55,8 @@ protected void unhook(CommandRoute commandRoute) { // TODO: unregister command from dispatcher } - protected abstract FabricAbstractCommand createCommand(CommandRoute commandRoute, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook); + protected FabricCommand createCommand(CommandRoute command, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook) { + return new FabricCommand<>(this.getSenderFactory(), settings, command, invocationHook, suggestionHook); + } + } diff --git a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricAbstractCommand.java b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricCommand.java similarity index 83% rename from litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricAbstractCommand.java rename to litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricCommand.java index 2d5847305..d03cd47c1 100644 --- a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricAbstractCommand.java +++ b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/FabricCommand.java @@ -14,6 +14,7 @@ import dev.rollczi.litecommands.invocation.Invocation; import dev.rollczi.litecommands.platform.PlatformInvocationListener; import dev.rollczi.litecommands.platform.PlatformSender; +import dev.rollczi.litecommands.platform.PlatformSenderFactory; import dev.rollczi.litecommands.platform.PlatformSuggestionListener; import dev.rollczi.litecommands.suggestion.Suggestion; import dev.rollczi.litecommands.suggestion.SuggestionResult; @@ -23,15 +24,17 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -public abstract class FabricAbstractCommand { - - private static final String FULL_ARGUMENTS = "[...]"; +public class FabricCommand { + private final PlatformSenderFactory senderFactory; + private final LiteFabricSettings settings; private final CommandRoute baseRoute; private final PlatformInvocationListener invocationHook; private final PlatformSuggestionListener suggestionHook; - protected FabricAbstractCommand(CommandRoute baseRoute, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook) { + public FabricCommand(PlatformSenderFactory senderFactory, LiteFabricSettings settings, CommandRoute baseRoute, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook) { + this.senderFactory = senderFactory; + this.settings = settings; this.baseRoute = baseRoute; this.invocationHook = invocationHook; this.suggestionHook = suggestionHook; @@ -64,7 +67,7 @@ private void appendRoute(LiteralArgumentBuilder baseLiteral, CommandRout @NotNull private RequiredArgumentBuilder createArguments() { return RequiredArgumentBuilder - .argument(FULL_ARGUMENTS, StringArgumentType.greedyString()) + .argument(settings.getInputInspectionDisplay(), StringArgumentType.greedyString()) .executes(context -> execute(context)) .suggests((context, builder) -> suggests(context, builder)); } @@ -72,7 +75,7 @@ private RequiredArgumentBuilder createArguments() { private int execute(CommandContext context) { RawCommand rawCommand = RawCommand.from(context.getInput()); ParseableInput parseableInput = rawCommand.toParseableInput(); - PlatformSender platformSender = createSender(context.getSource()); + PlatformSender platformSender = this.senderFactory.create(context.getSource()); Invocation invocation = new Invocation<>(context.getSource(), platformSender, baseRoute.getName(), rawCommand.getLabel(), parseableInput); invocationHook.execute(invocation, parseableInput); @@ -84,7 +87,7 @@ private int execute(CommandContext context) { String input = context.getInput(); RawCommand rawCommand = RawCommand.from(input); SuggestionInput suggestionInput = rawCommand.toSuggestionInput(); - PlatformSender platformSender = createSender(context.getSource()); + PlatformSender platformSender = this.senderFactory.create(context.getSource()); Invocation invocation = new Invocation<>(context.getSource(), platformSender, baseRoute.getName(), rawCommand.getLabel(), suggestionInput); SuggestionResult suggest = suggestionHook.suggest(invocation, suggestionInput); @@ -108,5 +111,7 @@ Text tooltip(String string) { return Text.literal(string); } - protected abstract PlatformSender createSender(SOURCE source); + public CommandRoute getCommandRoute() { + return baseRoute; + } } diff --git a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/LiteFabricFactory.java b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/LiteFabricFactory.java index 657326ff5..30d59894d 100644 --- a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/LiteFabricFactory.java +++ b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/LiteFabricFactory.java @@ -11,7 +11,6 @@ import dev.rollczi.litecommands.fabric.server.argument.PlayerArgument; import dev.rollczi.litecommands.fabric.server.argument.WorldArgument; import dev.rollczi.litecommands.message.MessageRegistry; -import dev.rollczi.litecommands.platform.PlatformSettings; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; @@ -33,7 +32,7 @@ private LiteFabricFactory() { * @deprecated Use {@link LiteFabricFactory#builder()} instead */ @Deprecated - public static > B create() { + public static > B create() { return builder(); } @@ -41,12 +40,12 @@ public static > B builder() { + public static > B builder() { return server(); } @SuppressWarnings("unchecked") - public static > B server() { + public static > B server() { return (B) LiteCommandsFactory.builder(ServerCommandSource.class, new FabricServerPlatform(new LiteFabricSettings())) .self((builder, internal) -> { MessageRegistry messages = internal.getMessageRegistry(); @@ -67,7 +66,7 @@ public static > B client() { + public static > B client() { return (B) LiteCommandsFactory.builder(FabricClientCommandSource.class, new FabricClientPlatform(new LiteFabricSettings())) .self((builder, internal) -> { MessageRegistry messages = internal.getMessageRegistry(); diff --git a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/LiteFabricSettings.java b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/LiteFabricSettings.java index c4468e796..602371467 100644 --- a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/LiteFabricSettings.java +++ b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/LiteFabricSettings.java @@ -1,6 +1,25 @@ package dev.rollczi.litecommands.fabric; import dev.rollczi.litecommands.platform.PlatformSettings; +import org.jetbrains.annotations.ApiStatus; public class LiteFabricSettings implements PlatformSettings { + + private String inputInspectionDisplay = "[...]"; + + String getInputInspectionDisplay() { + return this.inputInspectionDisplay; + } + + /** + * The name of the brigadier argument used to inspection, default is "[...]". + * Inspection sometimes displays while the player is typing the command. + * LiteCommands don't support brigadier suggestions, but we must provide a name for the default input argument. + */ + @ApiStatus.Experimental + public LiteFabricSettings inputInspectionDisplay(String name) { + this.inputInspectionDisplay = name; + return this; + } + } diff --git a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/client/FabricClientCommand.java b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/client/FabricClientCommand.java deleted file mode 100644 index 981f1663c..000000000 --- a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/client/FabricClientCommand.java +++ /dev/null @@ -1,22 +0,0 @@ -package dev.rollczi.litecommands.fabric.client; - -import dev.rollczi.litecommands.command.CommandRoute; -import dev.rollczi.litecommands.fabric.FabricAbstractCommand; -import dev.rollczi.litecommands.platform.PlatformInvocationListener; -import dev.rollczi.litecommands.platform.PlatformSender; -import dev.rollczi.litecommands.platform.PlatformSuggestionListener; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; - -@Environment(EnvType.CLIENT) -public class FabricClientCommand extends FabricAbstractCommand { - public FabricClientCommand(CommandRoute baseRoute, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook) { - super(baseRoute, invocationHook, suggestionHook); - } - - @Override - protected PlatformSender createSender(FabricClientCommandSource serverCommandSource) { - return new FabricClientSender(serverCommandSource); - } -} diff --git a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/client/FabricClientPlatform.java b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/client/FabricClientPlatform.java index c963b1a05..87b6e9166 100644 --- a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/client/FabricClientPlatform.java +++ b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/client/FabricClientPlatform.java @@ -1,11 +1,7 @@ package dev.rollczi.litecommands.fabric.client; -import dev.rollczi.litecommands.command.CommandRoute; -import dev.rollczi.litecommands.fabric.FabricAbstractCommand; import dev.rollczi.litecommands.fabric.FabricAbstractPlatform; -import dev.rollczi.litecommands.platform.PlatformInvocationListener; -import dev.rollczi.litecommands.platform.PlatformSettings; -import dev.rollczi.litecommands.platform.PlatformSuggestionListener; +import dev.rollczi.litecommands.fabric.LiteFabricSettings; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; @@ -14,7 +10,7 @@ @Environment(EnvType.CLIENT) public class FabricClientPlatform extends FabricAbstractPlatform { - public FabricClientPlatform(PlatformSettings settings) { + public FabricClientPlatform(LiteFabricSettings settings) { super(settings, source -> new FabricClientSender(source)); } @@ -24,14 +20,8 @@ protected void registerEvents() { throw new UnsupportedOperationException("The current 'fabric-api' does not include fabric-command-api-v2. Please update 'fabric-api'"); } ClientCommandRegistrationCallback.EVENT.register((dispatcher, commandRegistryAccess) -> { - for (FabricAbstractCommand fabricCommand : fabricCommands.values()) { - dispatcher.register(fabricCommand.toLiteral()); - } + this.registerAllCommands(dispatcher); }); } - @Override - protected FabricAbstractCommand createCommand(CommandRoute commandRoute, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook) { - return new FabricClientCommand(commandRoute, invocationHook, suggestionHook); - } } diff --git a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/server/FabricServerCommand.java b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/server/FabricServerCommand.java deleted file mode 100644 index 751d95be6..000000000 --- a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/server/FabricServerCommand.java +++ /dev/null @@ -1,19 +0,0 @@ -package dev.rollczi.litecommands.fabric.server; - -import dev.rollczi.litecommands.command.CommandRoute; -import dev.rollczi.litecommands.fabric.FabricAbstractCommand; -import dev.rollczi.litecommands.platform.PlatformInvocationListener; -import dev.rollczi.litecommands.platform.PlatformSender; -import dev.rollczi.litecommands.platform.PlatformSuggestionListener; -import net.minecraft.server.command.ServerCommandSource; - -public class FabricServerCommand extends FabricAbstractCommand { - public FabricServerCommand(CommandRoute baseRoute, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook) { - super(baseRoute, invocationHook, suggestionHook); - } - - @Override - protected PlatformSender createSender(ServerCommandSource serverCommandSource) { - return new FabricServerSender(serverCommandSource); - } -} diff --git a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/server/FabricServerPlatform.java b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/server/FabricServerPlatform.java index 47271526d..0c2bf6034 100644 --- a/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/server/FabricServerPlatform.java +++ b/litecommands-fabric/src/main/java/dev/rollczi/litecommands/fabric/server/FabricServerPlatform.java @@ -1,17 +1,12 @@ package dev.rollczi.litecommands.fabric.server; -import dev.rollczi.litecommands.command.CommandRoute; -import dev.rollczi.litecommands.fabric.FabricAbstractCommand; import dev.rollczi.litecommands.fabric.FabricAbstractPlatform; -import dev.rollczi.litecommands.fabric.client.FabricClientSender; -import dev.rollczi.litecommands.platform.PlatformInvocationListener; -import dev.rollczi.litecommands.platform.PlatformSettings; -import dev.rollczi.litecommands.platform.PlatformSuggestionListener; +import dev.rollczi.litecommands.fabric.LiteFabricSettings; import net.minecraft.server.command.ServerCommandSource; public class FabricServerPlatform extends FabricAbstractPlatform { - public FabricServerPlatform(PlatformSettings settings) { + public FabricServerPlatform(LiteFabricSettings settings) { super(settings, source -> new FabricServerSender(source)); } @@ -19,21 +14,13 @@ public FabricServerPlatform(PlatformSettings settings) { protected void registerEvents() { if (COMMAND_API_V2) { net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - for (FabricAbstractCommand fabricCommand : fabricCommands.values()) { - dispatcher.register(fabricCommand.toLiteral()); - } + this.registerAllCommands(dispatcher); }); } else { net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> { - for (FabricAbstractCommand fabricCommand : fabricCommands.values()) { - dispatcher.register(fabricCommand.toLiteral()); - } + this.registerAllCommands(dispatcher); }); } } - @Override - protected FabricAbstractCommand createCommand(CommandRoute commandRoute, PlatformInvocationListener invocationHook, PlatformSuggestionListener suggestionHook) { - return new FabricServerCommand(commandRoute, invocationHook, suggestionHook); - } }