From 3061481a1aa2128f21977668d9fcbde0313dffd5 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 26 Dec 2021 14:57:17 -0500 Subject: [PATCH 1/3] Add a commands.yml file for specifying custom command descriptions --- .gitignore | 1 + .../bungeecord/GeyserBungeePlugin.java | 18 ++---- .../command/GeyserBungeeCommandManager.java | 41 ------------- .../platform/spigot/GeyserSpigotPlugin.java | 7 +-- .../command/GeyserSpigotCommandManager.java | 11 +++- .../platform/sponge/GeyserSpongePlugin.java | 6 +- .../command/GeyserSpongeCommandManager.java | 14 ++++- .../standalone/GeyserStandaloneBootstrap.java | 17 ++---- .../standalone/gui/GeyserStandaloneGUI.java | 10 ++-- .../velocity/GeyserVelocityPlugin.java | 8 --- .../command/GeyserVelocityCommandManager.java | 41 ------------- .../org/geysermc/geyser/GeyserBootstrap.java | 10 +++- .../java/org/geysermc/geyser/GeyserImpl.java | 8 +-- .../geyser/command/CommandManager.java | 57 +++++++++++++++---- .../CustomCommandsConfiguration.java | 24 ++++---- core/src/main/resources/commands.yml | 15 +++++ 16 files changed, 123 insertions(+), 165 deletions(-) delete mode 100644 bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandManager.java delete mode 100644 bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandManager.java rename bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserCommandManager.java => core/src/main/java/org/geysermc/geyser/configuration/CustomCommandsConfiguration.java (73%) create mode 100644 core/src/main/resources/commands.yml diff --git a/.gitignore b/.gitignore index 85f8a6e9e96..1af6f2565c7 100644 --- a/.gitignore +++ b/.gitignore @@ -238,6 +238,7 @@ nbdist/ ### Geyser ### run/ config.yml +commands.yml logs/ public-key.pem locales/ 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 36e6ffb1d8a..997a72ccb79 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 @@ -28,18 +28,16 @@ import net.md_5.bungee.api.config.ListenerInfo; import net.md_5.bungee.api.plugin.Plugin; import org.geysermc.common.PlatformType; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserBootstrap; -import org.geysermc.geyser.command.CommandManager; -import org.geysermc.geyser.session.auth.AuthType; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.configuration.GeyserConfiguration; import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough; import org.geysermc.geyser.ping.IGeyserPingPassthrough; -import org.geysermc.geyser.util.FileUtils; -import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.platform.bungeecord.command.GeyserBungeeCommandExecutor; -import org.geysermc.geyser.platform.bungeecord.command.GeyserBungeeCommandManager; +import org.geysermc.geyser.session.auth.AuthType; +import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.geyser.util.FileUtils; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -53,7 +51,6 @@ public class GeyserBungeePlugin extends Plugin implements GeyserBootstrap { - private GeyserBungeeCommandManager geyserCommandManager; private GeyserBungeeConfiguration geyserConfig; private GeyserBungeeInjector geyserInjector; private GeyserBungeeLogger geyserLogger; @@ -125,8 +122,6 @@ public void onEnable() { this.geyserInjector = new GeyserBungeeInjector(this); this.geyserInjector.initializeLocalChannel(this); - this.geyserCommandManager = new GeyserBungeeCommandManager(geyser); - if (geyserConfig.isLegacyPingPassthrough()) { this.geyserBungeePingPassthrough = GeyserLegacyPingPassthrough.init(geyser); } else { @@ -156,11 +151,6 @@ public GeyserBungeeLogger getGeyserLogger() { return geyserLogger; } - @Override - public CommandManager getGeyserCommandManager() { - return this.geyserCommandManager; - } - @Override public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserBungeePingPassthrough; diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandManager.java b/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandManager.java deleted file mode 100644 index 06e5da71e82..00000000000 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/geyser/platform/bungeecord/command/GeyserBungeeCommandManager.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019-2021 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.platform.bungeecord.command; - -import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.command.CommandManager; - -public class GeyserBungeeCommandManager extends CommandManager { - - public GeyserBungeeCommandManager(GeyserImpl geyser) { - super(geyser); - } - - @Override - public String getDescription(String command) { - return ""; // no support for command descriptions in bungee - } -} 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 12a27190d2a..cb5f666a488 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 @@ -63,7 +63,6 @@ import java.util.logging.Level; public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { - private GeyserSpigotCommandManager geyserCommandManager; private GeyserSpigotConfiguration geyserConfig; private GeyserSpigotInjector geyserInjector; private GeyserSpigotLogger geyserLogger; @@ -160,8 +159,6 @@ public void onEnable() { this.geyserSpigotPingPassthrough = new GeyserSpigotPingPassthrough(geyserLogger); } - this.geyserCommandManager = new GeyserSpigotCommandManager(geyser); - boolean isViaVersion = Bukkit.getPluginManager().getPlugin("ViaVersion") != null; if (isViaVersion) { try { @@ -265,8 +262,8 @@ public GeyserSpigotLogger getGeyserLogger() { } @Override - public CommandManager getGeyserCommandManager() { - return this.geyserCommandManager; + public CommandManager createGeyserCommandManager(GeyserImpl geyser) { + return new GeyserSpigotCommandManager(geyser); } @Override diff --git a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandManager.java b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandManager.java index 13ba3691ca9..37ab4859123 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/geyser/platform/spigot/command/GeyserSpigotCommandManager.java @@ -31,6 +31,7 @@ import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.CommandManager; +import javax.annotation.Nonnull; import java.lang.reflect.Field; public class GeyserSpigotCommandManager extends CommandManager { @@ -52,8 +53,14 @@ public GeyserSpigotCommandManager(GeyserImpl geyser) { } @Override + @Nonnull public String getDescription(String command) { - Command cmd = COMMAND_MAP.getCommand(command.replace("/", "")); - return cmd != null ? cmd.getDescription() : ""; + String description = super.getDescription(command); + if (description.isEmpty()) { + Command cmd = COMMAND_MAP.getCommand(command.replace("/", "")); + return cmd != null ? cmd.getDescription() : ""; + } else { + return description; + } } } 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 f20f94a79ed..f1c6936fd38 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 @@ -62,7 +62,6 @@ public class GeyserSpongePlugin implements GeyserBootstrap { @ConfigDir(sharedRoot = false) private File configDir; - private GeyserSpongeCommandManager geyserCommandManager; private GeyserSpongeConfiguration geyserConfig; private GeyserSpongeLogger geyserLogger; private IGeyserPingPassthrough geyserSpongePingPassthrough; @@ -119,7 +118,6 @@ public void onEnable() { this.geyserSpongePingPassthrough = new GeyserSpongePingPassthrough(); } - this.geyserCommandManager = new GeyserSpongeCommandManager(Sponge.getCommandManager(), geyser); Sponge.getCommandManager().register(this, new GeyserSpongeCommandExecutor(geyser), "geyser"); } @@ -139,8 +137,8 @@ public GeyserSpongeLogger getGeyserLogger() { } @Override - public CommandManager getGeyserCommandManager() { - return this.geyserCommandManager; + public CommandManager createGeyserCommandManager(GeyserImpl geyser) { + return new GeyserSpongeCommandManager(Sponge.getCommandManager(), geyser); } @Override diff --git a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandManager.java b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandManager.java index d6cc967a431..58cc1827a1e 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandManager.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/geyser/platform/sponge/command/GeyserSpongeCommandManager.java @@ -31,6 +31,8 @@ import org.spongepowered.api.command.CommandMapping; import org.spongepowered.api.text.Text; +import javax.annotation.Nonnull; + public class GeyserSpongeCommandManager extends CommandManager { private final org.spongepowered.api.command.CommandManager handle; @@ -41,9 +43,15 @@ public GeyserSpongeCommandManager(org.spongepowered.api.command.CommandManager h } @Override + @Nonnull public String getDescription(String command) { - return handle.get(command).map(CommandMapping::getCallable) - .map(callable -> callable.getShortDescription(Sponge.getServer().getConsole()).orElse(Text.EMPTY)) - .orElse(Text.EMPTY).toPlain(); + String description = super.getDescription(command); + if (description.isEmpty()) { + return handle.get(command).map(CommandMapping::getCallable) + .map(callable -> callable.getShortDescription(Sponge.getServer().getConsole()).orElse(Text.EMPTY)) + .orElse(Text.EMPTY).toPlain(); + } else { + return description; + } } } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java index b599550e35c..99e8e4d3f5b 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/GeyserStandaloneBootstrap.java @@ -39,18 +39,16 @@ import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.geysermc.common.PlatformType; -import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.GeyserBootstrap; -import org.geysermc.geyser.command.CommandManager; +import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.configuration.GeyserConfiguration; import org.geysermc.geyser.configuration.GeyserJacksonConfiguration; import org.geysermc.geyser.dump.BootstrapDumpInfo; import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough; import org.geysermc.geyser.ping.IGeyserPingPassthrough; -import org.geysermc.geyser.util.FileUtils; -import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.platform.standalone.command.GeyserCommandManager; import org.geysermc.geyser.platform.standalone.gui.GeyserStandaloneGUI; +import org.geysermc.geyser.text.GeyserLocale; +import org.geysermc.geyser.util.FileUtils; import java.io.File; import java.io.IOException; @@ -63,7 +61,6 @@ public class GeyserStandaloneBootstrap implements GeyserBootstrap { - private GeyserCommandManager geyserCommandManager; private GeyserStandaloneConfiguration geyserConfig; private GeyserStandaloneLogger geyserLogger; private IGeyserPingPassthrough geyserPingPassthrough; @@ -215,10 +212,9 @@ public void onEnable() { logger.get().setLevel(geyserConfig.isDebugMode() ? Level.DEBUG : Level.INFO); geyser = GeyserImpl.start(PlatformType.STANDALONE, this); - geyserCommandManager = new GeyserCommandManager(geyser); if (gui != null) { - gui.setupInterface(geyserLogger, geyserCommandManager); + gui.setupInterface(geyserLogger, geyser.getCommandManager()); } geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser); @@ -259,11 +255,6 @@ public GeyserStandaloneLogger getGeyserLogger() { return geyserLogger; } - @Override - public CommandManager getGeyserCommandManager() { - return geyserCommandManager; - } - @Override public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserPingPassthrough; diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java index 56d21198614..d08dbcae454 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/gui/GeyserStandaloneGUI.java @@ -26,11 +26,11 @@ package org.geysermc.geyser.platform.standalone.gui; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.command.CommandManager; import org.geysermc.geyser.command.GeyserCommand; +import org.geysermc.geyser.platform.standalone.GeyserStandaloneLogger; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; -import org.geysermc.geyser.platform.standalone.GeyserStandaloneLogger; -import org.geysermc.geyser.platform.standalone.command.GeyserCommandManager; import javax.swing.*; import javax.swing.table.DefaultTableModel; @@ -253,13 +253,13 @@ public void write(byte[] b) { * Add all the Geyser commands to the commands menu, and setup the debug mode toggle * * @param geyserStandaloneLogger The current logger - * @param geyserCommandManager The commands manager + * @param commandManager The commands manager */ - public void setupInterface(GeyserStandaloneLogger geyserStandaloneLogger, GeyserCommandManager geyserCommandManager) { + public void setupInterface(GeyserStandaloneLogger geyserStandaloneLogger, CommandManager commandManager) { commandsMenu.removeAll(); optionsMenu.removeAll(); - for (Map.Entry command : geyserCommandManager.getCommands().entrySet()) { + for (Map.Entry command : commandManager.getCommands().entrySet()) { // Remove the offhand command and any alias commands to prevent duplicates in the list if (!command.getValue().isExecutableOnConsole() || command.getValue().getAliases().contains(command.getKey())) { continue; 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 8106192ac3b..3e00bac5f60 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 @@ -43,7 +43,6 @@ import org.geysermc.geyser.ping.GeyserLegacyPingPassthrough; import org.geysermc.geyser.ping.IGeyserPingPassthrough; import org.geysermc.geyser.platform.velocity.command.GeyserVelocityCommandExecutor; -import org.geysermc.geyser.platform.velocity.command.GeyserVelocityCommandManager; import org.geysermc.geyser.session.auth.AuthType; import org.geysermc.geyser.text.GeyserLocale; import org.geysermc.geyser.util.FileUtils; @@ -70,7 +69,6 @@ public class GeyserVelocityPlugin implements GeyserBootstrap { @Inject private CommandManager commandManager; - private GeyserVelocityCommandManager geyserCommandManager; private GeyserVelocityConfiguration geyserConfig; private GeyserVelocityInjector geyserInjector; private GeyserVelocityLogger geyserLogger; @@ -144,7 +142,6 @@ public void onEnable() { this.geyserInjector = new GeyserVelocityInjector(proxyServer); // Will be initialized after the proxy has been bound - this.geyserCommandManager = new GeyserVelocityCommandManager(geyser); this.commandManager.register("geyser", new GeyserVelocityCommandExecutor(geyser)); if (geyserConfig.isLegacyPingPassthrough()) { this.geyserPingPassthrough = GeyserLegacyPingPassthrough.init(geyser); @@ -173,11 +170,6 @@ public GeyserVelocityLogger getGeyserLogger() { return geyserLogger; } - @Override - public org.geysermc.geyser.command.CommandManager getGeyserCommandManager() { - return this.geyserCommandManager; - } - @Override public IGeyserPingPassthrough getGeyserPingPassthrough() { return geyserPingPassthrough; diff --git a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandManager.java b/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandManager.java deleted file mode 100644 index 33f0d77c24c..00000000000 --- a/bootstrap/velocity/src/main/java/org/geysermc/geyser/platform/velocity/command/GeyserVelocityCommandManager.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019-2021 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.platform.velocity.command; - -import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.command.CommandManager; - -public class GeyserVelocityCommandManager extends CommandManager { - - public GeyserVelocityCommandManager(GeyserImpl geyser) { - super(geyser); - } - - @Override - public String getDescription(String command) { - return ""; // no support for command descriptions in velocity - } -} diff --git a/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java b/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java index 8797d972a00..acdaaf3d2aa 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java @@ -31,6 +31,7 @@ import org.geysermc.geyser.level.GeyserWorldManager; import org.geysermc.geyser.level.WorldManager; import org.geysermc.geyser.ping.IGeyserPingPassthrough; +import org.jetbrains.annotations.Contract; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -68,11 +69,14 @@ public interface GeyserBootstrap { GeyserLogger getGeyserLogger(); /** - * Returns the current CommandManager + * Creates a command manager for {@link GeyserImpl to use}. * - * @return The current CommandManager + * @return a new CommandManager instance */ - CommandManager getGeyserCommandManager(); + @Contract("_ -> new") + default CommandManager createGeyserCommandManager(GeyserImpl geyser) { + return new CommandManager(geyser); + } /** * Returns the current PingPassthrough manager diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java index bac5e0735ab..a62d701fad1 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java @@ -118,6 +118,8 @@ public class GeyserImpl implements GeyserApi { private final ScheduledExecutorService scheduledThread; + private final CommandManager commandManager; + private final BedrockServer bedrockServer; private final PlatformType platformType; private final GeyserBootstrap bootstrap; @@ -150,6 +152,8 @@ private GeyserImpl(PlatformType platformType, GeyserBootstrap bootstrap) { this.scheduledThread = Executors.newSingleThreadScheduledExecutor(new DefaultThreadFactory("Geyser Scheduled Thread")); + this.commandManager = bootstrap.createGeyserCommandManager(this); + logger.setDebug(config.isDebugMode()); /* Initialize translators and registries */ @@ -480,10 +484,6 @@ public GeyserConfiguration getConfig() { return bootstrap.getGeyserConfig(); } - public CommandManager getCommandManager() { - return bootstrap.getGeyserCommandManager(); - } - public WorldManager getWorldManager() { return bootstrap.getWorldManager(); } diff --git a/core/src/main/java/org/geysermc/geyser/command/CommandManager.java b/core/src/main/java/org/geysermc/geyser/command/CommandManager.java index 5e4fe3dd504..0d989cf871c 100644 --- a/core/src/main/java/org/geysermc/geyser/command/CommandManager.java +++ b/core/src/main/java/org/geysermc/geyser/command/CommandManager.java @@ -25,20 +25,30 @@ package org.geysermc.geyser.command; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; - import org.geysermc.common.PlatformType; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.command.defaults.*; +import org.geysermc.geyser.configuration.CustomCommandsConfiguration; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.text.GeyserLocale; -import java.util.*; - -public abstract class CommandManager { +import javax.annotation.Nonnull; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +public class CommandManager { @Getter private final Map commands = new HashMap<>(); + @Getter + private final Map commandDescriptionOverrides; private final GeyserImpl geyser; @@ -58,6 +68,32 @@ public CommandManager(GeyserImpl geyser) { if (GeyserImpl.getInstance().getPlatformType() == PlatformType.STANDALONE) { registerCommand(new StopCommand(geyser, "stop", "geyser.commands.stop.desc", "geyser.command.stop")); } + + // Read or create command overrides + ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()); + + File commandsFile = geyser.getBootstrap().getConfigFolder().resolve("commands.yml").toFile(); + if (!commandsFile.exists()) { + try (InputStream stream = geyser.getBootstrap().getResource("commands.yml")) { + Files.copy(stream, commandsFile.toPath()); + } catch (IOException e) { + geyser.getLogger().error("Unable to load commands.yml template from jar!", e); + } + } + CustomCommandsConfiguration commandsConfiguration; + try { + commandsConfiguration = objectMapper.readValue(commandsFile, CustomCommandsConfiguration.class); + } catch (IOException e) { + geyser.getLogger().error("Unable to load commands configuration!", e); + commandsConfiguration = new CustomCommandsConfiguration(); + } + + this.commandDescriptionOverrides = new Object2ObjectOpenHashMap<>(); + for (CustomCommandsConfiguration.CustomCommandEntry entry : commandsConfiguration.getDescriptions()) { + for (String name : entry.getCommands()) { + commandDescriptionOverrides.put(name, entry.getDescription()); + } + } } public void registerCommand(GeyserCommand command) { @@ -105,18 +141,15 @@ public void runCommand(CommandSender sender, String command) { } } - /** - * @return a list of all subcommands under {@code /geyser}. - */ - public List getCommandNames() { - return Arrays.asList(geyser.getCommandManager().getCommands().keySet().toArray(new String[0])); - } - /** * Returns the description of the given command * * @param command Command to get the description for * @return Command description */ - public abstract String getDescription(String command); + @Nonnull + public String getDescription(String command) { + // Most platforms don't have an option to get the description, so we rely on our overrides instead + return commandDescriptionOverrides.getOrDefault(command, ""); + } } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserCommandManager.java b/core/src/main/java/org/geysermc/geyser/configuration/CustomCommandsConfiguration.java similarity index 73% rename from bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserCommandManager.java rename to core/src/main/java/org/geysermc/geyser/configuration/CustomCommandsConfiguration.java index 83da038a1cc..035cb8a2ebe 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/geyser/platform/standalone/command/GeyserCommandManager.java +++ b/core/src/main/java/org/geysermc/geyser/configuration/CustomCommandsConfiguration.java @@ -23,19 +23,23 @@ * @link https://github.com/GeyserMC/Geyser */ -package org.geysermc.geyser.platform.standalone.command; +package org.geysermc.geyser.configuration; -import org.geysermc.geyser.GeyserImpl; -import org.geysermc.geyser.command.CommandManager; +import lombok.Getter; +import lombok.ToString; -public class GeyserCommandManager extends CommandManager { +import java.util.Collections; +import java.util.List; - public GeyserCommandManager(GeyserImpl geyser) { - super(geyser); - } +@Getter +@ToString +public class CustomCommandsConfiguration { + private List descriptions = Collections.emptyList(); - @Override - public String getDescription(String command) { - return ""; // this is not sent over the protocol, so we return none + @Getter + @ToString + public static class CustomCommandEntry { + private String description; + private List commands; } } diff --git a/core/src/main/resources/commands.yml b/core/src/main/resources/commands.yml new file mode 100644 index 00000000000..28310f3a659 --- /dev/null +++ b/core/src/main/resources/commands.yml @@ -0,0 +1,15 @@ +# Specify custom command descriptions. +# On platforms that have their own command descriptions, any entry here will override what the platform provides. +descriptions: [ + { + description: "This is an example command description setup for Bedrock players", + # Each command here will have the above command description applied. + commands: [ + "foo", "bar" + ] + }, + { + description: "The main command for Geyser.", + commands: ["geyser"] + } +] \ No newline at end of file From 0425aeae3af76a85df12ca8e237f47bd202e52a9 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 26 Dec 2021 14:59:18 -0500 Subject: [PATCH 2/3] Quick Javadoc fix --- core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java b/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java index acdaaf3d2aa..814012258c9 100644 --- a/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java +++ b/core/src/main/java/org/geysermc/geyser/GeyserBootstrap.java @@ -69,7 +69,7 @@ public interface GeyserBootstrap { GeyserLogger getGeyserLogger(); /** - * Creates a command manager for {@link GeyserImpl to use}. + * Creates a command manager for {@link GeyserImpl} to use. * * @return a new CommandManager instance */ From ee560cafc4181eb911d94504d7346b8c2c76c5cf Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 26 Dec 2021 15:07:49 -0500 Subject: [PATCH 3/3] Command description map does not need a getter --- .../main/java/org/geysermc/geyser/command/CommandManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/org/geysermc/geyser/command/CommandManager.java b/core/src/main/java/org/geysermc/geyser/command/CommandManager.java index 0d989cf871c..664ebbfedbb 100644 --- a/core/src/main/java/org/geysermc/geyser/command/CommandManager.java +++ b/core/src/main/java/org/geysermc/geyser/command/CommandManager.java @@ -47,7 +47,6 @@ public class CommandManager { @Getter private final Map commands = new HashMap<>(); - @Getter private final Map commandDescriptionOverrides; private final GeyserImpl geyser;