diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java b/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java index 64b050ec5..0bbe73f16 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java +++ b/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/GeyserFabricMod.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.platform.fabric; +import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import net.fabricmc.api.EnvType; import net.fabricmc.api.ModInitializer; @@ -36,11 +37,12 @@ import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.server.MinecraftServer; import org.apache.logging.log4j.LogManager; -import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.GeyserBootstrap; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserLogger; import org.geysermc.geyser.api.command.Command; +import org.geysermc.geyser.api.extension.Extension; +import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandManager; import org.geysermc.geyser.configuration.GeyserConfiguration; @@ -161,9 +163,37 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { builder.then(Commands.literal(command.getKey()) .executes(executor) // Could also test for Bedrock but depending on when this is called it may backfire - .requires(executor::testPermission)); + .requires(executor::testPermission) + // Allows parsing of arguments; e.g. for /geyser dump logs or the connectiontest command + .then(Commands.argument("args", StringArgumentType.greedyString()) + .executes(context -> executor.runWithArgs(context, StringArgumentType.getString(context, "args"))) + .requires(executor::testPermission))); } server.getCommands().getDispatcher().register(builder); + + // Register extension commands + for (Map.Entry> extensionMapEntry : geyser.commandManager().extensionCommands().entrySet()) { + Map extensionCommands = extensionMapEntry.getValue(); + if (extensionCommands.isEmpty()) { + continue; + } + + // Register help command for just "/" + GeyserFabricCommandExecutor extensionHelpExecutor = new GeyserFabricCommandExecutor(geyser, + (GeyserCommand) extensionCommands.get("help")); + LiteralArgumentBuilder extCmdBuilder = Commands.literal(extensionMapEntry.getKey().description().id()).executes(extensionHelpExecutor); + + for (Map.Entry command : extensionCommands.entrySet()) { + GeyserFabricCommandExecutor executor = new GeyserFabricCommandExecutor(geyser, (GeyserCommand) command.getValue()); + extCmdBuilder.then(Commands.literal(command.getKey()) + .executes(executor) + .requires(executor::testPermission) + .then(Commands.argument("args", StringArgumentType.greedyString()) + .executes(context -> executor.runWithArgs(context, StringArgumentType.getString(context, "args"))) + .requires(executor::testPermission))); + } + server.getCommands().getDispatcher().register(extCmdBuilder); + } } @Override @@ -217,7 +247,6 @@ public class GeyserFabricMod implements ModInitializer, GeyserBootstrap { return this.server.getServerVersion(); } - @SuppressWarnings("ConstantConditions") // IDEA thinks that ip cannot be null @NotNull @Override public String getServerBindAddress() { diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSender.java b/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSender.java index 5973e04f1..6517ac133 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSender.java +++ b/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/FabricCommandSender.java @@ -75,6 +75,6 @@ public class FabricCommandSender implements GeyserCommandSource { @Override public boolean hasPermission(String permission) { - return Permissions.check(source, permission); + return Permissions.check(source, permission, source.getServer().getOperatorUserPermissionLevel()); } } diff --git a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java b/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java index 7600e4136..8da7c8512 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java +++ b/bootstrap/fabric/src/main/java/org/geysermc/geyser/platform/fabric/command/GeyserFabricCommandExecutor.java @@ -53,6 +53,10 @@ public class GeyserFabricCommandExecutor extends GeyserCommandExecutor implement @Override public int run(CommandContext context) { + return runWithArgs(context, ""); + } + + public int runWithArgs(CommandContext context, String args) { CommandSourceStack source = (CommandSourceStack) context.getSource(); FabricCommandSender sender = new FabricCommandSender(source); GeyserSession session = getGeyserSession(sender); @@ -68,7 +72,8 @@ public class GeyserFabricCommandExecutor extends GeyserCommandExecutor implement sender.sendMessage(ChatColor.RED + GeyserLocale.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", sender.locale())); return 0; } - command.execute(session, sender, new String[0]); + + command.execute(session, sender, args.split(" ")); return 0; } }