From c34b63c8c67ac1837246776869181b561ec3cea0 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Tue, 6 Oct 2020 18:43:02 -0400 Subject: [PATCH] Add proper commands support --- bootstrap/fabric/build.gradle | 3 + .../platform/fabric/GeyserFabricDumpInfo.java | 30 +++++++++ .../platform/fabric/GeyserFabricMod.java | 21 +++++- .../fabric/command/FabricCommandSender.java | 65 +++++++++++++++++++ .../command/GeyserFabricCommandExecutor.java | 54 +++++++++++++++ .../platform/fabric/command/ModInfo.java | 53 +++++++++++++++ 6 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/FabricCommandSender.java create mode 100644 bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/GeyserFabricCommandExecutor.java create mode 100644 bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/ModInfo.java diff --git a/bootstrap/fabric/build.gradle b/bootstrap/fabric/build.gradle index 8377dab43..059b59d42 100644 --- a/bootstrap/fabric/build.gradle +++ b/bootstrap/fabric/build.gradle @@ -23,6 +23,9 @@ dependencies { // You may need to force-disable transitiveness on them. implementation 'org.geysermc:connector:1.1.0' + + compileOnly 'org.projectlombok:lombok:1.18.4' + annotationProcessor 'org.projectlombok:lombok:1.18.4' } repositories { diff --git a/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/GeyserFabricDumpInfo.java b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/GeyserFabricDumpInfo.java index cd35e77f2..2c9917de9 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/GeyserFabricDumpInfo.java +++ b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/GeyserFabricDumpInfo.java @@ -25,7 +25,37 @@ package org.geysermc.platform.fabric; +import lombok.Getter; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.minecraft.server.MinecraftServer; +import org.geysermc.connector.common.serializer.AsteriskSerializer; import org.geysermc.connector.dump.BootstrapDumpInfo; +import org.geysermc.platform.fabric.command.ModInfo; +import java.util.ArrayList; +import java.util.List; + +@Getter public class GeyserFabricDumpInfo extends BootstrapDumpInfo { + + private String serverIP; + private int serverPort; + private List mods; + + public GeyserFabricDumpInfo(MinecraftServer server) { + super(); + if (AsteriskSerializer.showSensitive || (server.getServerIp() == null || server.getServerIp().equals("") || server.getServerIp().equals("0.0.0.0"))) { + this.serverIP = server.getServerIp(); + } else { + this.serverIP = "***"; + } + this.serverPort = server.getServerPort(); + this.mods = new ArrayList<>(); + + for (ModContainer mod : FabricLoader.getInstance().getAllMods()) { + this.mods.add(new ModInfo(mod)); + } + } + } diff --git a/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/GeyserFabricMod.java b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/GeyserFabricMod.java index f008cb069..ea5210bbc 100644 --- a/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/GeyserFabricMod.java +++ b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/GeyserFabricMod.java @@ -25,16 +25,20 @@ package org.geysermc.platform.fabric; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; import net.fabricmc.api.DedicatedServerModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.command.ServerCommandSource; import org.apache.logging.log4j.LogManager; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserLogger; import org.geysermc.connector.bootstrap.GeyserBootstrap; import org.geysermc.connector.command.CommandManager; +import org.geysermc.connector.command.GeyserCommand; import org.geysermc.connector.common.PlatformType; import org.geysermc.connector.configuration.GeyserConfiguration; import org.geysermc.connector.dump.BootstrapDumpInfo; @@ -42,11 +46,13 @@ import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; +import org.geysermc.platform.fabric.command.GeyserFabricCommandExecutor; import org.geysermc.platform.fabric.command.GeyserFabricCommandManager; import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.util.Map; import java.util.UUID; @Environment(EnvType.SERVER) @@ -54,6 +60,7 @@ public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBoo private GeyserConnector connector; private Path dataFolder; + private MinecraftServer server; private GeyserFabricCommandManager geyserCommandManager; private GeyserFabricConfiguration geyserConfig; @@ -87,6 +94,7 @@ public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBoo ServerLifecycleEvents.SERVER_STARTED.register((server) -> { // Required to do this so we can get the proper IP and port if needed + this.server = server; if (this.geyserConfig.getRemote().getAddress().equalsIgnoreCase("auto")) { this.geyserConfig.setAutoconfiguredRemote(true); String ip = server.getServerIp(); @@ -106,6 +114,17 @@ public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBoo this.geyserPingPassthrough = GeyserLegacyPingPassthrough.init(connector); this.geyserCommandManager = new GeyserFabricCommandManager(connector); + + // Start command building + // Set just "geyser" as the help command + LiteralArgumentBuilder builder = net.minecraft.server.command.CommandManager.literal("geyser") + .executes(new GeyserFabricCommandExecutor(connector, "help")); + for (Map.Entry command : connector.getCommandManager().getCommands().entrySet()) { + // Register all subcommands as valid + builder.then(net.minecraft.server.command.CommandManager.literal( + command.getKey()).executes(new GeyserFabricCommandExecutor(connector, command.getKey()))); + } + server.getCommandManager().getDispatcher().register(builder); }); // Register onDisable so players are properly kicked @@ -146,6 +165,6 @@ public class GeyserFabricMod implements DedicatedServerModInitializer, GeyserBoo @Override public BootstrapDumpInfo getDumpInfo() { - return new GeyserFabricDumpInfo(); + return new GeyserFabricDumpInfo(server); } } diff --git a/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/FabricCommandSender.java b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/FabricCommandSender.java new file mode 100644 index 000000000..b73f85562 --- /dev/null +++ b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/FabricCommandSender.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020 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.platform.fabric.command; + +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.text.LiteralText; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandSender; + +public class FabricCommandSender implements CommandSender { + + private final ServerCommandSource source; + + public FabricCommandSender(ServerCommandSource source) { + this.source = source; + } + + @Override + public String getName() { + return source.getName(); + } + + @Override + public void sendMessage(String message) { + try { + source.getPlayer().sendMessage(new LiteralText(message), false); + } catch (CommandSyntaxException e) { // why + GeyserConnector.getInstance().getLogger().info(message); + } + } + + @Override + public boolean isConsole() { + try { + source.getPlayer(); + return false; + } catch (CommandSyntaxException e) { + return true; + } + } +} diff --git a/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/GeyserFabricCommandExecutor.java b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/GeyserFabricCommandExecutor.java new file mode 100644 index 000000000..290e452c6 --- /dev/null +++ b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/GeyserFabricCommandExecutor.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 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.platform.fabric.command; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.context.CommandContext; +import net.minecraft.server.command.ServerCommandSource; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.GeyserCommand; + +public class GeyserFabricCommandExecutor implements Command { + + private final String commandName; + private final GeyserConnector connector; + + public GeyserFabricCommandExecutor(GeyserConnector connector, String commandName) { + this.commandName = commandName; + this.connector = connector; + } + + @Override + public int run(CommandContext context) { + ServerCommandSource source = (ServerCommandSource) context.getSource(); + getCommand(commandName).execute(new FabricCommandSender(source), new String[0]); + return 0; + } + + private GeyserCommand getCommand(String label) { + return connector.getCommandManager().getCommands().get(label); + } +} diff --git a/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/ModInfo.java b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/ModInfo.java new file mode 100644 index 000000000..722fd2ded --- /dev/null +++ b/bootstrap/fabric/src/main/java/org/geysermc/platform/fabric/command/ModInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 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.platform.fabric.command; + +import lombok.Getter; +import net.fabricmc.loader.api.ModContainer; + +import java.util.ArrayList; +import java.util.List; + +/** + * A wrapper for Fabric mod information to be presented in a Geyser dump + */ +@Getter +public class ModInfo { + + private String name; + private String id; + private String version; + private List authors; + + public ModInfo(ModContainer mod) { + this.name = mod.getMetadata().getName(); + this.id = mod.getMetadata().getId(); + this.authors = new ArrayList<>(); + mod.getMetadata().getAuthors().forEach((person) -> this.authors.add(person.getName())); + this.version = mod.getMetadata().getVersion().getFriendlyString(); + } + +}