From 1b05f9f15e3a7b05f95e7087ca60a9e8334d57e1 Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 30 Aug 2023 22:18:06 +0200 Subject: [PATCH] Register extension commands on Geyser-Fabric (#4080) * Register Extension commands on Geyser-Fabric * Allow Geyser commands to accept arguments aswell - e.g. geyser dump logs --- .../platform/fabric/GeyserFabricMod.java | 35 +++++++++++++++++-- .../fabric/command/FabricCommandSender.java | 2 +- .../command/GeyserFabricCommandExecutor.java | 7 +++- 3 files changed, 39 insertions(+), 5 deletions(-) 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; } }