From acd53a451964f71c3a284fb1aa72a8b6a275f354 Mon Sep 17 00:00:00 2001 From: Konicai <71294714+Konicai@users.noreply.github.com> Date: Mon, 4 Sep 2023 21:02:40 -0400 Subject: [PATCH] Refactor command abstraction and implement `/geyser` as help --- .../geyser/command/GeyserCommand.java | 39 +++++++++++-- .../defaults/AdvancedTooltipsCommand.java | 25 ++++----- .../command/defaults/AdvancementsCommand.java | 12 ++-- .../defaults/ConnectionTestCommand.java | 9 +-- .../geyser/command/defaults/DumpCommand.java | 8 +-- .../command/defaults/ExtensionsCommand.java | 8 --- .../geyser/command/defaults/HelpCommand.java | 15 +++-- .../geyser/command/defaults/ListCommand.java | 19 +++---- .../command/defaults/OffhandCommand.java | 9 ++- .../command/defaults/ReloadCommand.java | 16 ++---- .../command/defaults/SettingsCommand.java | 12 ++-- .../command/defaults/StatisticsCommand.java | 17 +++--- .../geyser/command/defaults/StopCommand.java | 9 +-- .../command/defaults/VersionCommand.java | 9 --- .../command/GeyserExtensionCommand.java | 56 +++++++++++-------- 15 files changed, 137 insertions(+), 126 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java index 2c92ec06de2..dd7b19b3341 100644 --- a/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommand.java @@ -27,6 +27,7 @@ import cloud.commandframework.Command; import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import cloud.commandframework.meta.CommandMeta; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -35,7 +36,6 @@ import java.util.Collections; import java.util.List; -import java.util.Objects; public abstract class GeyserCommand implements org.geysermc.geyser.api.command.Command { @@ -153,20 +153,49 @@ public final List aliases() { return Collections.unmodifiableList(aliases); } + /** + * @return the first (literal) argument of this command, which comes before {@link #name()}. + */ public String rootCommand() { return "geyser"; } + /** + * Creates a new command builder with {@link #rootCommand()}, {@link #name()}, and {@link #aliases()} built on it. + * The Applicable from {@link #meta()} is also applied to the builder. + */ @Contract(value = "_ -> new", pure = true) - public Command.Builder builder(CommandManager manager) { + public final Command.Builder baseBuilder(CommandManager manager) { return manager.commandBuilder(rootCommand()) .literal(name, aliases.toArray(new String[0])) + .permission(permission) + .apply(meta()); + } + + /** + * @return an Applicable that applies {@link #BEDROCK_ONLY} and {@link #PLAYER_ONLY} as meta, + * according to {@link #isBedrockOnly()} and {@link #isExecutableOnConsole()} (respectively). + */ + public Command.Builder.Applicable meta() { + return builder -> builder .meta(BEDROCK_ONLY, isBedrockOnly()) - .meta(PLAYER_ONLY, !isExecutableOnConsole()) - .permission(permission); + .meta(PLAYER_ONLY, !isExecutableOnConsole()); } + /** + * Registers this command to the given command manager. + * This method may be overridden to register more than one command. + *

+ * The default implementation is that {@link #baseBuilder(CommandManager)} with {@link #execute(CommandContext)} + * applied as the handler is registered to the manager. + */ public void register(CommandManager manager) { - manager.command(builder(manager)); + manager.command(baseBuilder(manager).handler(this::execute)); } + + /** + * Executes this command + * @param context the context with which this command should be executed + */ + public abstract void execute(CommandContext context); } \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancedTooltipsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancedTooltipsCommand.java index d9875adb86e..5a683b31f1d 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancedTooltipsCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancedTooltipsCommand.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandSource; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.ChatColor; import org.geysermc.geyser.text.MinecraftLocale; @@ -40,16 +40,15 @@ public AdvancedTooltipsCommand(String name, String description, String permissio } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(context -> context.getSender().connection().ifPresent(session -> { - String onOrOff = session.isAdvancedTooltips() ? "off" : "on"; - session.setAdvancedTooltips(!session.isAdvancedTooltips()); - session.sendMessage(ChatColor.BOLD + ChatColor.YELLOW - + MinecraftLocale.getLocaleString("debug.prefix", session.locale()) - + " " + ChatColor.RESET - + MinecraftLocale.getLocaleString("debug.advanced_tooltips." + onOrOff, session.locale())); - session.getInventoryTranslator().updateInventory(session, session.getPlayerInventory()); - })); + public void execute(CommandContext context) { + GeyserSession session = context.getSender().connection().orElseThrow(); + + String onOrOff = session.isAdvancedTooltips() ? "off" : "on"; + session.setAdvancedTooltips(!session.isAdvancedTooltips()); + session.sendMessage(ChatColor.BOLD + ChatColor.YELLOW + + MinecraftLocale.getLocaleString("debug.prefix", session.locale()) + + " " + ChatColor.RESET + + MinecraftLocale.getLocaleString("debug.advanced_tooltips." + onOrOff, session.locale())); + session.getInventoryTranslator().updateInventory(session, session.getPlayerInventory()); } } diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancementsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancementsCommand.java index e15a3fef07c..a9047ef5a06 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancementsCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/AdvancementsCommand.java @@ -25,11 +25,11 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandSource; +import org.geysermc.geyser.session.GeyserSession; public class AdvancementsCommand extends GeyserCommand { @@ -38,10 +38,8 @@ public AdvancementsCommand(String name, String description, String permission) { } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(context -> - context.getSender().connection().ifPresent(session -> - session.getAdvancementsCache().buildAndShowMenuForm())); + public void execute(CommandContext context) { + GeyserSession session = context.getSender().connection().orElseThrow(); + session.getAdvancementsCache().buildAndShowMenuForm(); } } diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/ConnectionTestCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/ConnectionTestCommand.java index 483d11b2be0..6901a12e1e4 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/ConnectionTestCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/ConnectionTestCommand.java @@ -53,17 +53,18 @@ public ConnectionTestCommand(GeyserImpl geyser, String name, String description, } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) + public void register(CommandManager manager) { + manager.command(baseBuilder(manager) .argument(StringArgument.of(ADDRESS)) .argument(IntegerArgument.builder(PORT) .asOptionalWithDefault(19132) .withMax(65535).withMin(0) .build()) - .handler(this::execute); + .handler(this::execute)); } - private void execute(CommandContext context) { + @Override + public void execute(CommandContext context) { GeyserCommandSource source = context.getSender(); String address = context.get(ADDRESS); int port = context.get(PORT); diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/DumpCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/DumpCommand.java index 5898e5c190c..881fa297e8b 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/DumpCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/DumpCommand.java @@ -58,15 +58,14 @@ public class DumpCommand extends GeyserCommand { public DumpCommand(GeyserImpl geyser, String name, String description, String permission) { super(name, description, permission, TriState.NOT_SET); - this.geyser = geyser; } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) + public void register(CommandManager manager) { + manager.command(baseBuilder(manager) .argument(createArgument()) - .handler(this::execute); + .handler(this::execute)); } private StringArrayArgument createArgument() { @@ -74,6 +73,7 @@ private StringArrayArgument createArgument() { return StringArrayArgument.optional(ARGUMENTS, (context, input) -> SUGGESTIONS); } + @Override public void execute(CommandContext context) { GeyserCommandSource source = context.getSender(); String[] args = context.getOrDefault(ARGUMENTS, new String[0]); diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/ExtensionsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/ExtensionsCommand.java index 923d9f0b94a..2b4b325397c 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/ExtensionsCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/ExtensionsCommand.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; import cloud.commandframework.context.CommandContext; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.extension.Extension; @@ -44,16 +42,10 @@ public class ExtensionsCommand extends GeyserCommand { public ExtensionsCommand(GeyserImpl geyser, String name, String description, String permission) { super(name, description, permission, TriState.TRUE); - this.geyser = geyser; } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(this::execute); - } - public void execute(CommandContext context) { GeyserCommandSource source = context.getSender(); diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java index d43384177d8..08329014933 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/HelpCommand.java @@ -49,17 +49,22 @@ public HelpCommand(GeyserImpl geyser, String name, String description, String pe super(name, description, permission, TriState.TRUE); this.baseCommand = baseCommand; this.commands = commands.values(); - this.aliases = Collections.singletonList("?"); } @Override - public cloud.commandframework.Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(this::execute); + public void register(CommandManager manager) { + super.register(manager); + + // Also register just `/geyser` + manager.command(manager.commandBuilder(rootCommand()) + .permission(permission()) + .apply(meta()) + .handler(this::execute)); } - private void execute(CommandContext context) { + @Override + public void execute(CommandContext context) { GeyserCommandSource source = context.getSender(); boolean bedrockPlayer = source.connection().isPresent(); diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java index 6f5a5ac4ea1..d5b1112ee1c 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java @@ -25,8 +25,7 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; @@ -42,21 +41,17 @@ public class ListCommand extends GeyserCommand { public ListCommand(GeyserImpl geyser, String name, String description, String permission) { super(name, description, permission, TriState.NOT_SET); - this.geyser = geyser; } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(context -> { - GeyserCommandSource source = context.getSender(); + public void execute(CommandContext context) { + GeyserCommandSource source = context.getSender(); - String message = GeyserLocale.getPlayerLocaleString("geyser.commands.list.message", source.locale(), - geyser.getSessionManager().size(), - geyser.getSessionManager().getAllSessions().stream().map(GeyserSession::bedrockUsername).collect(Collectors.joining(" "))); + String message = GeyserLocale.getPlayerLocaleString("geyser.commands.list.message", source.locale(), + geyser.getSessionManager().size(), + geyser.getSessionManager().getAllSessions().stream().map(GeyserSession::bedrockUsername).collect(Collectors.joining(" "))); - source.sendMessage(message); - }); + source.sendMessage(message); } } diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java index a5798272569..af893d06cd1 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/OffhandCommand.java @@ -25,8 +25,7 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; @@ -40,8 +39,8 @@ public OffhandCommand(GeyserImpl geyser, String name, String description, String } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(context -> context.getSender().connection().ifPresent(GeyserSession::requestOffhandSwap)); + public void execute(CommandContext context) { + GeyserSession session = context.getSender().connection().orElseThrow(); + session.requestOffhandSwap(); } } diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/ReloadCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/ReloadCommand.java index 5331b9b1f92..a8ad4c6e31b 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/ReloadCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/ReloadCommand.java @@ -25,8 +25,7 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; @@ -43,14 +42,11 @@ public ReloadCommand(GeyserImpl geyser, String name, String description, String } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(context -> { - GeyserCommandSource source = context.getSender(); - source.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.reload.message", source.locale())); + public void execute(CommandContext context) { + GeyserCommandSource source = context.getSender(); + source.sendMessage(GeyserLocale.getPlayerLocaleString("geyser.commands.reload.message", source.locale())); - geyser.getSessionManager().disconnectAll("geyser.commands.reload.kick"); - geyser.reload(); - }); + geyser.getSessionManager().disconnectAll("geyser.commands.reload.kick"); + geyser.reload(); } } diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/SettingsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/SettingsCommand.java index 7bfd7f52372..a3ce3c69e9f 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/SettingsCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/SettingsCommand.java @@ -25,12 +25,12 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandSource; +import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.SettingsUtils; public class SettingsCommand extends GeyserCommand { @@ -40,10 +40,8 @@ public SettingsCommand(GeyserImpl geyser, String name, String description, Strin } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(context -> - context.getSender().connection().ifPresent(session -> - session.sendForm(SettingsUtils.buildForm(session)))); + public void execute(CommandContext context) { + GeyserSession session = context.getSender().connection().orElseThrow(); + session.sendForm(SettingsUtils.buildForm(session)); } } diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java index da7eb7209e0..646a8ceaa37 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/StatisticsCommand.java @@ -25,14 +25,14 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import com.github.steveice10.mc.protocol.data.game.ClientCommand; import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandSource; +import org.geysermc.geyser.session.GeyserSession; public class StatisticsCommand extends GeyserCommand { @@ -41,12 +41,11 @@ public StatisticsCommand(GeyserImpl geyser, String name, String description, Str } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(context -> context.getSender().connection().ifPresent(session -> { - session.setWaitingForStatistics(true); - ServerboundClientCommandPacket packet = new ServerboundClientCommandPacket(ClientCommand.STATS); - session.sendDownstreamPacket(packet); - })); + public void execute(CommandContext context) { + GeyserSession session = context.getSender().connection().orElseThrow(); + + session.setWaitingForStatistics(true); + ServerboundClientCommandPacket packet = new ServerboundClientCommandPacket(ClientCommand.STATS); + session.sendDownstreamPacket(packet); } } diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/StopCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/StopCommand.java index 0dd79e306ec..e2b7cdbb15e 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/StopCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/StopCommand.java @@ -25,8 +25,7 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; @@ -41,13 +40,11 @@ public class StopCommand extends GeyserCommand { public StopCommand(GeyserImpl geyser, String name, String description, String permission) { super(name, description, permission, TriState.NOT_SET); this.geyser = geyser; - this.aliases = Collections.singletonList("shutdown"); } @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(context -> geyser.getBootstrap().onDisable()); + public void execute(CommandContext context) { + geyser.getBootstrap().onDisable(); } } \ No newline at end of file diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java index 2491040e6d4..8fec5b23840 100644 --- a/core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java +++ b/core/src/main/java/org/geysermc/geyser/command/defaults/VersionCommand.java @@ -25,8 +25,6 @@ package org.geysermc.geyser.command.defaults; -import cloud.commandframework.Command; -import cloud.commandframework.CommandManager; import cloud.commandframework.context.CommandContext; import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec; import org.geysermc.geyser.Constants; @@ -51,16 +49,9 @@ public class VersionCommand extends GeyserCommand { public VersionCommand(GeyserImpl geyser, String name, String description, String permission) { super(name, description, permission, TriState.NOT_SET); - this.geyser = geyser; } - @Override - public Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .handler(this::execute); - } - public void execute(CommandContext context) { GeyserCommandSource source = context.getSender(); diff --git a/core/src/main/java/org/geysermc/geyser/extension/command/GeyserExtensionCommand.java b/core/src/main/java/org/geysermc/geyser/extension/command/GeyserExtensionCommand.java index bcc1382ef5a..a4d51f6fd0b 100644 --- a/core/src/main/java/org/geysermc/geyser/extension/command/GeyserExtensionCommand.java +++ b/core/src/main/java/org/geysermc/geyser/extension/command/GeyserExtensionCommand.java @@ -27,12 +27,13 @@ import cloud.commandframework.CommandManager; import cloud.commandframework.arguments.standard.StringArgument; +import cloud.commandframework.context.CommandContext; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.api.command.CommandExecutor; import org.geysermc.geyser.api.command.CommandSource; +import org.geysermc.geyser.api.connection.GeyserConnection; import org.geysermc.geyser.api.extension.Extension; import org.geysermc.geyser.api.util.TriState; import org.geysermc.geyser.command.GeyserCommand; @@ -167,31 +168,42 @@ public GeyserExtensionCommand build() { throw new IllegalArgumentException("Command executor was not defined for command " + name + " in extension " + extension.name()); } + // if the source type is a GeyserConnection then it is inherently bedrockOnly + final boolean bedrockOnly = GeyserConnection.class.isAssignableFrom(sourceType) || this.bedrockOnly; + // a similar check would exist for executableOnConsole, but there is not a logger type exposed in the api + GeyserExtensionCommand command = new GeyserExtensionCommand(extension, name, description, permission, permissionDefault, executableOnConsole, bedrockOnly) { + @Override + public void register(CommandManager manager) { + // todo: if we don't find a way to expose cloud in the api, we should implement a way + // to not have the [args] if its not necessary for this command. and maybe tab completion. + manager.command(baseBuilder(manager) + .argument(StringArgument.optional("args", StringArgument.StringMode.GREEDY)) + .handler(this::execute)); + } + @SuppressWarnings("unchecked") @Override - public cloud.commandframework.Command.Builder builder(CommandManager manager) { - return super.builder(manager) - .argument(StringArgument.optional("args", StringArgument.StringMode.GREEDY)) - .handler(context -> { - GeyserCommandSource source = context.getSender(); - String[] args = context.getOrDefault("args", "").split(" "); - - if (sourceType.isInstance(source)) { - executor.execute((T) source, this, args); - return; - } - - GeyserSession session = source.connection().orElse(null); - if (sourceType.isInstance(session)) { - executor.execute((T) session, this, args); - return; - } - - // todo: send sender message instead - GeyserImpl.getInstance().getLogger().warning("Ignoring command " + name + " due to no suitable sender."); - }); + public void execute(CommandContext context) { + GeyserCommandSource source = context.getSender(); + String[] args = context.getOrDefault("args", "").split(" "); + + if (sourceType.isInstance(source)) { + executor.execute((T) source, this, args); + return; + } + + GeyserSession session = source.connection().orElse(null); + if (sourceType.isInstance(session)) { + executor.execute((T) session, this, args); + return; + } + + // currently, the only subclass of CommandSource exposed in the api is GeyserConnection. + // when this command was registered, we enabled bedrockOnly if the sourceType was a GeyserConnection. + // as a result, SenderTypeProcessor should handle that case and this method shouldn't even be reached. + source.sendMessage("You must be a " + sourceType.getSimpleName() + " to run this command."); } @Override