From 83ba6b5ab53f869bd3e15739a33f61db8c5dc65f Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 10 Jul 2022 20:58:48 -0400 Subject: [PATCH] Extensions have their own command --- .../downstream/ServerDefineCommandsEvent.java | 4 +- .../lifecycle/GeyserDefineCommandsEvent.java | 42 ----------- .../bungeecord/GeyserBungeePlugin.java | 7 +- .../command/GeyserBungeeCommandExecutor.java | 7 +- .../platform/spigot/GeyserSpigotInjector.java | 4 +- .../platform/spigot/GeyserSpigotPlugin.java | 13 ++-- .../command/GeyserSpigotCommandExecutor.java | 5 +- .../spigot/src/main/resources/plugin.yml | 5 +- .../platform/sponge/GeyserSpongePlugin.java | 7 +- .../command/GeyserSpongeCommandExecutor.java | 10 +-- .../velocity/GeyserVelocityPlugin.java | 7 +- .../GeyserVelocityCommandExecutor.java | 6 +- .../geyser/command/GeyserCommandExecutor.java | 6 +- .../geyser/command/GeyserCommandManager.java | 75 +++++++++++-------- .../geyser/command/defaults/HelpCommand.java | 12 ++- .../BedrockCommandRequestTranslator.java | 7 +- 16 files changed, 101 insertions(+), 116 deletions(-) delete mode 100644 api/geyser/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCommandsEvent.java diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/downstream/ServerDefineCommandsEvent.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/downstream/ServerDefineCommandsEvent.java index 06412eb4c..2ab1b9611 100644 --- a/api/geyser/src/main/java/org/geysermc/geyser/api/event/downstream/ServerDefineCommandsEvent.java +++ b/api/geyser/src/main/java/org/geysermc/geyser/api/event/downstream/ServerDefineCommandsEvent.java @@ -33,7 +33,9 @@ import org.geysermc.geyser.api.event.connection.ConnectionEvent; import java.util.Set; /** - * Called when the downstream server defines the commands available on the server. + * Called when the Java server defines the commands available on the server. + *
+ * This event is mapped to the existence of Brigadier on the server. */ public class ServerDefineCommandsEvent extends ConnectionEvent implements Cancellable { private final Set commands; diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCommandsEvent.java b/api/geyser/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCommandsEvent.java deleted file mode 100644 index e506c0ca0..000000000 --- a/api/geyser/src/main/java/org/geysermc/geyser/api/event/lifecycle/GeyserDefineCommandsEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * @author GeyserMC - * @link https://github.com/GeyserMC/Geyser - */ - -package org.geysermc.geyser.api.event.lifecycle; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.geysermc.geyser.api.command.Command; -import org.geysermc.geyser.api.command.CommandManager; -import org.geysermc.geyser.api.event.Event; - -import java.util.Map; - -/** - * Called when commands are defined within Geyser. - * - * @param commandManager the command manager - * @param commands an immutable view of the default commands - */ -public record GeyserDefineCommandsEvent(@NonNull CommandManager commandManager, @NonNull Map commands) implements Event { -} diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java index d98349eac..7b937ac6b 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/GeyserBungeePlugin.java @@ -86,7 +86,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { InetSocketAddress javaAddr = listener.getHost(); // By default this should be localhost but may need to be changed in some circumstances - if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) { + if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) { this.geyserConfig.setAutoconfiguredRemote(true); // Don't use localhost if not listening on all interfaces if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) { @@ -109,7 +109,7 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { return; } - if (geyserConfig.getRemote().getAuthType() == AuthType.FLOODGATE && getProxy().getPluginManager().getPlugin("floodgate") == null) { + if (geyserConfig.getRemote().authType() == AuthType.FLOODGATE && getProxy().getPluginManager().getPlugin("floodgate") == null) { geyserLogger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.disabling")); return; } else if (geyserConfig.isAutoconfiguredRemote() && getProxy().getPluginManager().getPlugin("floodgate") != null) { @@ -134,7 +134,8 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { this.geyserBungeePingPassthrough = new GeyserBungeePingPassthrough(getProxy()); } - this.getProxy().getPluginManager().registerCommand(this, new GeyserBungeeCommandExecutor(geyser)); + this.getProxy().getPluginManager().registerCommand(this, new GeyserBungeeCommandExecutor("geyser", geyser, geyserCommandManager.getCommands())); + this.getProxy().getPluginManager().registerCommand(this, new GeyserBungeeCommandExecutor("geyserext", geyser, geyserCommandManager.commands())); } @Override diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandExecutor.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandExecutor.java index d022074fd..6575f047c 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandExecutor.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandExecutor.java @@ -37,14 +37,15 @@ import org.geysermc.geyser.text.GeyserLocale; import java.util.Arrays; import java.util.Collections; +import java.util.Map; public class GeyserBungeeCommandExecutor extends Command implements TabExecutor { private final GeyserCommandExecutor commandExecutor; - public GeyserBungeeCommandExecutor(GeyserImpl geyser) { - super("geyser"); + public GeyserBungeeCommandExecutor(String name, GeyserImpl geyser, Map commands) { + super(name); - this.commandExecutor = new GeyserCommandExecutor(geyser); + this.commandExecutor = new GeyserCommandExecutor(geyser, commands); } @Override diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java index 0fd8d849b..c1d3b6871 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java @@ -170,8 +170,8 @@ public class GeyserSpigotInjector extends GeyserInjector { */ private void workAroundWeirdBug(GeyserBootstrap bootstrap) { MinecraftProtocol protocol = new MinecraftProtocol(); - LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().getAddress(), - bootstrap.getGeyserConfig().getRemote().getPort(), this.serverSocketAddress, + LocalSession session = new LocalSession(bootstrap.getGeyserConfig().getRemote().address(), + bootstrap.getGeyserConfig().getRemote().port(), this.serverSocketAddress, InetAddress.getLoopbackAddress().getHostAddress(), protocol, protocol.createHelper()); session.connect(); } diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java index fed5dd6b9..6e36b817d 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotPlugin.java @@ -43,7 +43,6 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.adapters.spigot.SpigotAdapters; import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.api.network.AuthType; -import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandManager; import org.geysermc.geyser.configuration.GeyserConfiguration; import org.geysermc.geyser.dump.BootstrapDumpInfo; @@ -125,7 +124,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { } // By default this should be localhost but may need to be changed in some circumstances - if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) { + if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) { geyserConfig.setAutoconfiguredRemote(true); // Don't use localhost if not listening on all interfaces if (!Bukkit.getIp().equals("0.0.0.0") && !Bukkit.getIp().equals("")) { @@ -148,7 +147,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { return; } - if (geyserConfig.getRemote().getAuthType() == AuthType.FLOODGATE && Bukkit.getPluginManager().getPlugin("floodgate") == null) { + if (geyserConfig.getRemote().authType() == AuthType.FLOODGATE && Bukkit.getPluginManager().getPlugin("floodgate") == null) { geyserLogger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.disabling")); this.getPluginLoader().disablePlugin(this); return; @@ -249,8 +248,10 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { geyserLogger.debug("Using default world manager: " + this.geyserWorldManager.getClass()); } - PluginCommand pluginCommand = this.getCommand("geyser"); - pluginCommand.setExecutor(new GeyserSpigotCommandExecutor(geyser)); + PluginCommand geyserCommand = this.getCommand("geyser"); + geyserCommand.setExecutor(new GeyserSpigotCommandExecutor(geyser, geyserCommandManager.getCommands())); + PluginCommand geyserExtCommand = this.getCommand("geyserext"); + geyserExtCommand.setExecutor(new GeyserSpigotCommandExecutor(geyser, geyserCommandManager.getCommands())); if (!INITIALIZED) { // Register permissions so they appear in, for example, LuckPerms' UI @@ -277,7 +278,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { boolean brigadierSupported = CommodoreProvider.isSupported(); geyserLogger.debug("Brigadier supported? " + brigadierSupported); if (brigadierSupported) { - GeyserBrigadierSupport.loadBrigadier(this, pluginCommand); + GeyserBrigadierSupport.loadBrigadier(this, geyserCommand); } // Check to ensure the current setup can support the protocol version Geyser uses diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandExecutor.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandExecutor.java index b5a6ee887..52779db23 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandExecutor.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandExecutor.java @@ -38,11 +38,12 @@ import org.geysermc.geyser.text.GeyserLocale; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; public class GeyserSpigotCommandExecutor extends GeyserCommandExecutor implements TabExecutor { - public GeyserSpigotCommandExecutor(GeyserImpl geyser) { - super(geyser); + public GeyserSpigotCommandExecutor(GeyserImpl geyser, Map commands) { + super(geyser, commands); } @Override diff --git a/bootstrap/spigot/src/main/resources/plugin.yml b/bootstrap/spigot/src/main/resources/plugin.yml index e28b8981d..0f6398b49 100644 --- a/bootstrap/spigot/src/main/resources/plugin.yml +++ b/bootstrap/spigot/src/main/resources/plugin.yml @@ -8,4 +8,7 @@ api-version: 1.13 commands: geyser: description: The main command for Geyser. - usage: /geyser \ No newline at end of file + usage: /geyser + geyserext: + description: The command any extensions can register to. + usage: /geyserext \ No newline at end of file diff --git a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java index 4e088161d..312dfb087 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/GeyserSpongePlugin.java @@ -99,14 +99,14 @@ public class GeyserSpongePlugin implements GeyserBootstrap { // Don't change the ip if its listening on all interfaces // By default this should be 127.0.0.1 but may need to be changed in some circumstances - if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) { + if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) { this.geyserConfig.setAutoconfiguredRemote(true); geyserConfig.getRemote().setPort(javaAddr.getPort()); } } if (geyserConfig.getBedrock().isCloneRemotePort()) { - geyserConfig.getBedrock().setPort(geyserConfig.getRemote().getPort()); + geyserConfig.getBedrock().setPort(geyserConfig.getRemote().port()); } this.geyserLogger = new GeyserSpongeLogger(logger, geyserConfig.isDebugMode()); @@ -121,7 +121,8 @@ public class GeyserSpongePlugin implements GeyserBootstrap { this.geyserCommandManager = new GeyserSpongeCommandManager(Sponge.getCommandManager(), geyser); this.geyserCommandManager.init(); - Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(geyser), "geyser"); + Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(geyser, geyserCommandManager.getCommands()), "geyser"); + Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(geyser, geyserCommandManager.commands()), "geyserext"); } @Override diff --git a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandExecutor.java b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandExecutor.java index 485c06c41..3598ea8c2 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandExecutor.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandExecutor.java @@ -26,6 +26,7 @@ package org.geysermc.geyser.platform.sponge.command; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandExecutor; import org.geysermc.geyser.command.GeyserCommandSource; @@ -40,15 +41,12 @@ import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import java.util.*; public class GeyserSpongeCommandExecutor extends GeyserCommandExecutor implements CommandCallable { - public GeyserSpongeCommandExecutor(GeyserImpl geyser) { - super(geyser); + public GeyserSpongeCommandExecutor(GeyserImpl geyser, Map commands) { + super(geyser, commands); } @Override diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java index 0b228941b..739e99d43 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/GeyserVelocityPlugin.java @@ -102,7 +102,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { InetSocketAddress javaAddr = proxyServer.getBoundAddress(); // By default this should be localhost but may need to be changed in some circumstances - if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) { + if (this.geyserConfig.getRemote().address().equalsIgnoreCase("auto")) { this.geyserConfig.setAutoconfiguredRemote(true); // Don't use localhost if not listening on all interfaces if (!javaAddr.getHostString().equals("0.0.0.0") && !javaAddr.getHostString().equals("")) { @@ -128,7 +128,7 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { } catch (ClassNotFoundException ignored) { } - if (geyserConfig.getRemote().getAuthType() == AuthType.FLOODGATE && proxyServer.getPluginManager().getPlugin("floodgate").isEmpty()) { + if (geyserConfig.getRemote().authType() == AuthType.FLOODGATE && proxyServer.getPluginManager().getPlugin("floodgate").isEmpty()) { geyserLogger.severe(GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.not_installed") + " " + GeyserLocale.getLocaleStringLog("geyser.bootstrap.floodgate.disabling")); return; @@ -148,7 +148,8 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { this.geyserCommandManager = new GeyserVelocityCommandManager(geyser); this.geyserCommandManager.init(); - this.commandManager.register("geyser", new GeyserVelocityCommandExecutor(geyser)); + this.commandManager.register("geyser", new GeyserVelocityCommandExecutor(geyser, geyserCommandManager.getCommands())); + this.commandManager.register("geyserext", new GeyserVelocityCommandExecutor(geyser, geyserCommandManager.commands())); if (geyserConfig.isLegacyPingPassthrough()) { this.geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser); } else { diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandExecutor.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandExecutor.java index b3c4221df..c77a3daef 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandExecutor.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandExecutor.java @@ -27,6 +27,7 @@ package org.geysermc.geyser.platform.velocity.command; import com.velocitypowered.api.command.SimpleCommand; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.command.GeyserCommand; import org.geysermc.geyser.command.GeyserCommandExecutor; import org.geysermc.geyser.command.GeyserCommandSource; @@ -37,11 +38,12 @@ import org.geysermc.geyser.text.GeyserLocale; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; public class GeyserVelocityCommandExecutor extends GeyserCommandExecutor implements SimpleCommand { - public GeyserVelocityCommandExecutor(GeyserImpl geyser) { - super(geyser); + public GeyserVelocityCommandExecutor(GeyserImpl geyser, Map commands) { + super(geyser, commands); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserCommandExecutor.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandExecutor.java index 3d08600d1..a9b1c734f 100644 --- a/core/src/main/java/org/geysermc/geyser/command/GeyserCommandExecutor.java +++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandExecutor.java @@ -37,15 +37,16 @@ import java.util.List; import java.util.Map; /** - * Represents helper functions for listening to {@code /geyser} commands. + * Represents helper functions for listening to {@code /geyser} or {@code /geyserext} commands. */ @AllArgsConstructor public class GeyserCommandExecutor { protected final GeyserImpl geyser; + private final Map commands; public GeyserCommand getCommand(String label) { - return (GeyserCommand) geyser.commandManager().commands().get(label); + return (GeyserCommand) commands.get(label); } @Nullable @@ -78,7 +79,6 @@ public class GeyserCommandExecutor { } List availableCommands = new ArrayList<>(); - Map commands = geyser.commandManager().getCommands(); // Only show commands they have permission to use for (Map.Entry entry : commands.entrySet()) { diff --git a/core/src/main/java/org/geysermc/geyser/command/GeyserCommandManager.java b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandManager.java index c6b9cbdd2..4fd5ba411 100644 --- a/core/src/main/java/org/geysermc/geyser/command/GeyserCommandManager.java +++ b/core/src/main/java/org/geysermc/geyser/command/GeyserCommandManager.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.command; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.checkerframework.checker.nullness.qual.NonNull; @@ -34,7 +35,6 @@ import org.geysermc.geyser.api.command.Command; import org.geysermc.geyser.api.command.CommandExecutor; import org.geysermc.geyser.api.command.CommandManager; import org.geysermc.geyser.api.command.CommandSource; -import org.geysermc.geyser.api.event.lifecycle.GeyserDefineCommandsEvent; import org.geysermc.geyser.command.defaults.*; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; @@ -42,91 +42,104 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collections; -import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; @RequiredArgsConstructor public abstract class GeyserCommandManager extends CommandManager { @Getter - private final Map commands = new HashMap<>(); + private final Map commands = new Object2ObjectOpenHashMap<>(12); + private final Map extensionCommands = new Object2ObjectOpenHashMap<>(0); private final GeyserImpl geyser; public void init() { - register(new HelpCommand(geyser, "help", "geyser.commands.help.desc", "geyser.command.help")); - register(new ListCommand(geyser, "list", "geyser.commands.list.desc", "geyser.command.list")); - register(new ReloadCommand(geyser, "reload", "geyser.commands.reload.desc", "geyser.command.reload")); - register(new OffhandCommand(geyser, "offhand", "geyser.commands.offhand.desc", "geyser.command.offhand")); - register(new DumpCommand(geyser, "dump", "geyser.commands.dump.desc", "geyser.command.dump")); - register(new VersionCommand(geyser, "version", "geyser.commands.version.desc", "geyser.command.version")); - register(new SettingsCommand(geyser, "settings", "geyser.commands.settings.desc", "geyser.command.settings")); - register(new StatisticsCommand(geyser, "statistics", "geyser.commands.statistics.desc", "geyser.command.statistics")); - register(new AdvancementsCommand("advancements", "geyser.commands.advancements.desc", "geyser.command.advancements")); - register(new AdvancedTooltipsCommand("tooltips", "geyser.commands.advancedtooltips.desc", "geyser.command.tooltips")); - register(new ExtensionsCommand(geyser, "extensions", "geyser.commands.extensions.desc", "geyser.command.extensions")); + registerBuiltInCommand(new HelpCommand(geyser, "help", "geyser.commands.help.desc", "geyser.command.help", "geyser", commands)); + registerBuiltInCommand(new ListCommand(geyser, "list", "geyser.commands.list.desc", "geyser.command.list")); + registerBuiltInCommand(new ReloadCommand(geyser, "reload", "geyser.commands.reload.desc", "geyser.command.reload")); + registerBuiltInCommand(new OffhandCommand(geyser, "offhand", "geyser.commands.offhand.desc", "geyser.command.offhand")); + registerBuiltInCommand(new DumpCommand(geyser, "dump", "geyser.commands.dump.desc", "geyser.command.dump")); + registerBuiltInCommand(new VersionCommand(geyser, "version", "geyser.commands.version.desc", "geyser.command.version")); + registerBuiltInCommand(new SettingsCommand(geyser, "settings", "geyser.commands.settings.desc", "geyser.command.settings")); + registerBuiltInCommand(new StatisticsCommand(geyser, "statistics", "geyser.commands.statistics.desc", "geyser.command.statistics")); + registerBuiltInCommand(new AdvancementsCommand("advancements", "geyser.commands.advancements.desc", "geyser.command.advancements")); + registerBuiltInCommand(new AdvancedTooltipsCommand("tooltips", "geyser.commands.advancedtooltips.desc", "geyser.command.tooltips")); if (GeyserImpl.getInstance().getPlatformType() == PlatformType.STANDALONE) { - register(new StopCommand(geyser, "stop", "geyser.commands.stop.desc", "geyser.command.stop")); + registerBuiltInCommand(new StopCommand(geyser, "stop", "geyser.commands.stop.desc", "geyser.command.stop")); } - this.geyser.eventBus().fire(new GeyserDefineCommandsEvent(this, this.commands())); + register(new HelpCommand(geyser, "help", "geyser.commands.exthelp.desc", "geyser.command.exthelp", "geyserext", extensionCommands)); + } + + /** + * For internal Geyser commands + */ + public void registerBuiltInCommand(GeyserCommand command) { + register(command, this.commands); } @Override public void register(@NonNull Command command) { - this.commands.put(command.name(), command); - this.geyser.getLogger().debug(GeyserLocale.getLocaleStringLog("geyser.commands.registered", command.name())); + register(command, this.extensionCommands); + } + + private void register(Command command, Map commands) { + commands.put(command.name(), command); + geyser.getLogger().debug(GeyserLocale.getLocaleStringLog("geyser.commands.registered", command.name())); if (command.aliases().isEmpty()) { return; } for (String alias : command.aliases()) { - this.commands.put(alias, command); + commands.put(alias, command); } } @Override public void unregister(@NonNull Command command) { - this.commands.remove(command.name(), command); + this.extensionCommands.remove(command.name(), command); if (command.aliases().isEmpty()) { return; } for (String alias : command.aliases()) { - this.commands.remove(alias, command); + this.extensionCommands.remove(alias, command); } } @NotNull @Override public Map commands() { - return Collections.unmodifiableMap(this.commands); + return Collections.unmodifiableMap(this.extensionCommands); } - public void runCommand(GeyserCommandSource sender, String command) { - if (!command.startsWith("geyser ")) - return; + public boolean runCommand(GeyserCommandSource sender, String command) { + boolean extensionCommand = command.startsWith("geyserext "); + if (!command.startsWith("geyser ") && !extensionCommand) { + return false; + } - command = command.trim().replace("geyser ", ""); + command = command.trim().replace(extensionCommand ? "geyserext " : "geyser ", ""); String label; String[] args; if (!command.contains(" ")) { - label = command.toLowerCase(); + label = command.toLowerCase(Locale.ROOT); args = new String[0]; } else { - label = command.substring(0, command.indexOf(" ")).toLowerCase(); + label = command.substring(0, command.indexOf(" ")).toLowerCase(Locale.ROOT); String argLine = command.substring(command.indexOf(" ") + 1); args = argLine.contains(" ") ? argLine.split(" ") : new String[] { argLine }; } - Command cmd = commands.get(label); + Command cmd = (extensionCommand ? this.extensionCommands : this.commands).get(label); if (cmd == null) { geyser.getLogger().error(GeyserLocale.getLocaleStringLog("geyser.commands.invalid")); - return; + return false; } if (cmd instanceof GeyserCommand) { @@ -140,6 +153,8 @@ public abstract class GeyserCommandManager extends CommandManager { } } } + + return true; } /** 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 84a0730b8..81f34b759 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 @@ -39,10 +39,15 @@ import java.util.Map; public class HelpCommand extends GeyserCommand { private final GeyserImpl geyser; + private final String baseCommand; + private final Map commands; - public HelpCommand(GeyserImpl geyser, String name, String description, String permission) { + public HelpCommand(GeyserImpl geyser, String name, String description, String permission, + String baseCommand, Map commands) { super(name, description, permission); this.geyser = geyser; + this.baseCommand = baseCommand; + this.commands = commands; this.setAliases(Collections.singletonList("?")); } @@ -61,8 +66,7 @@ public class HelpCommand extends GeyserCommand { String header = GeyserLocale.getPlayerLocaleString("geyser.commands.help.header", sender.locale(), page, maxPage); sender.sendMessage(header); - Map cmds = geyser.commandManager().getCommands(); - for (Map.Entry entry : cmds.entrySet()) { + for (Map.Entry entry : commands.entrySet()) { Command cmd = entry.getValue(); // Standalone hack-in since it doesn't have a concept of permissions @@ -72,7 +76,7 @@ public class HelpCommand extends GeyserCommand { continue; } - sender.sendMessage(ChatColor.YELLOW + "/geyser " + entry.getKey() + ChatColor.WHITE + ": " + + sender.sendMessage(ChatColor.YELLOW + "/" + baseCommand + " " + entry.getKey() + ChatColor.WHITE + ": " + GeyserLocale.getPlayerLocaleString(cmd.description(), sender.locale())); } } diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java index e5840ba0d..3301f7b9f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java @@ -28,7 +28,6 @@ package org.geysermc.geyser.translator.protocol.bedrock; import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket; import org.geysermc.common.PlatformType; import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.command.GeyserCommandManager; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -40,10 +39,8 @@ public class BedrockCommandRequestTranslator extends PacketTranslator