From 12fb0b6d6d67f93d8ba1c0ca7f920778e495e627 Mon Sep 17 00:00:00 2001 From: Redned Date: Fri, 15 Jan 2021 21:50:35 -0600 Subject: [PATCH 1/3] Include 1.16.5 in README as a supported Java version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad001d63a..68f98c018 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here! -### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.201 and Minecraft Java v1.16.4. +### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.201 and Minecraft Java v1.16.4 - v1.16.5. ## Setting Up Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser. From da512da511efac6cebb6bb29d5a0e8e2bc514a43 Mon Sep 17 00:00:00 2001 From: RednedEpic Date: Fri, 15 Jan 2021 21:59:41 -0600 Subject: [PATCH 2/3] Include 1.16.5 in version command too --- .../src/main/java/org/geysermc/connector/GeyserConnector.java | 1 + .../org/geysermc/connector/command/defaults/VersionCommand.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index d61500e04..d1059627a 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -85,6 +85,7 @@ public class GeyserConnector { public static final String NAME = "Geyser"; public static final String GIT_VERSION = "DEV"; // A fallback for running in IDEs public static final String VERSION = "DEV"; // A fallback for running in IDEs + public static final String MINECRAFT_VERSION = "1.16.4 - 1.16.5"; /** * Oauth client ID for Microsoft authentication diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java index 1f807cf63..e0c445b3f 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java @@ -61,7 +61,7 @@ public class VersionCommand extends GeyserCommand { bedrockVersions = BedrockProtocol.DEFAULT_BEDROCK_CODEC.getMinecraftVersion(); } - sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.version", sender.getLocale(), GeyserConnector.NAME, GeyserConnector.VERSION, MinecraftConstants.GAME_VERSION, bedrockVersions)); + sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.version", sender.getLocale(), GeyserConnector.NAME, GeyserConnector.VERSION, GeyserConnector.MINECRAFT_VERSION, bedrockVersions)); // Disable update checking in dev mode //noinspection ConstantConditions - changes in production From 2d9baf1bfc46fd5d3da89bdbf26620423f74aafb Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sat, 16 Jan 2021 22:18:13 -0500 Subject: [PATCH 3/3] Send message to Java if command is Bedrock-only (#1834) * Send message to Java if command is Bedrock-only If a Java player attempts to use a Bedrock-only command, such as `geyser statistics`, they will get an error message stating that this command is only for Bedrock players. This commit also cleans up Velocity Adventure dependency usage. Issues were caused because of the way relocation works and because Velocity also uses Adventure. * Only look for a session if we have to * Update languages submodule --- .../command/GeyserBungeeCommandExecutor.java | 29 +++++++--- .../command/GeyserSpigotCommandExecutor.java | 35 +++++++----- .../command/GeyserSpongeCommandExecutor.java | 37 +++++++----- .../standalone/gui/GeyserStandaloneGUI.java | 6 +- bootstrap/velocity/pom.xml | 11 +++- .../GeyserVelocityPingPassthrough.java | 7 +-- .../GeyserVelocityCommandExecutor.java | 32 ++++++----- .../connector/command/CommandExecutor.java | 56 +++++++++++++++++++ .../connector/command/CommandManager.java | 11 +++- .../connector/command/GeyserCommand.java | 13 ++++- .../command/defaults/AdvancementsCommand.java | 28 ++-------- .../command/defaults/DumpCommand.java | 3 +- .../command/defaults/HelpCommand.java | 3 +- .../command/defaults/ListCommand.java | 2 +- .../command/defaults/OffhandCommand.java | 29 ++++------ .../command/defaults/ReloadCommand.java | 8 +-- .../command/defaults/SettingsCommand.java | 25 +++------ .../command/defaults/StatisticsCommand.java | 29 +++------- .../command/defaults/StopCommand.java | 5 +- .../command/defaults/VersionCommand.java | 6 +- .../BedrockCommandRequestTranslator.java | 2 +- connector/src/main/resources/languages | 2 +- 22 files changed, 222 insertions(+), 157 deletions(-) create mode 100644 connector/src/main/java/org/geysermc/connector/command/CommandExecutor.java diff --git a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/command/GeyserBungeeCommandExecutor.java b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/command/GeyserBungeeCommandExecutor.java index 2431f0a4e..b391d7b1c 100644 --- a/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/command/GeyserBungeeCommandExecutor.java +++ b/bootstrap/bungeecord/src/main/java/org/geysermc/platform/bungeecord/command/GeyserBungeeCommandExecutor.java @@ -30,7 +30,9 @@ import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.plugin.Command; import net.md_5.bungee.api.plugin.TabExecutor; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandExecutor; import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.LanguageUtils; import java.util.ArrayList; @@ -38,29 +40,42 @@ import java.util.Arrays; public class GeyserBungeeCommandExecutor extends Command implements TabExecutor { + private final CommandExecutor commandExecutor; private final GeyserConnector connector; public GeyserBungeeCommandExecutor(GeyserConnector connector) { super("geyser"); + this.commandExecutor = new CommandExecutor(connector); this.connector = connector; } @Override public void execute(CommandSender sender, String[] args) { if (args.length > 0) { - if (getCommand(args[0]) != null) { - if (!sender.hasPermission(getCommand(args[0]).getPermission())) { - BungeeCommandSender commandSender = new BungeeCommandSender(sender); + GeyserCommand command = this.commandExecutor.getCommand(args[0]); + if (command != null) { + BungeeCommandSender commandSender = new BungeeCommandSender(sender); + if (!sender.hasPermission(command.getPermission())) { String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale()); commandSender.sendMessage(ChatColor.RED + message); return; } - getCommand(args[0]).execute(new BungeeCommandSender(sender), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); + GeyserSession session = null; + if (command.isBedrockOnly()) { + session = this.commandExecutor.getGeyserSession(commandSender); + if (session == null) { + String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", commandSender.getLocale()); + + commandSender.sendMessage(ChatColor.RED + message); + return; + } + } + command.execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); } } else { - getCommand("help").execute(new BungeeCommandSender(sender), new String[0]); + this.commandExecutor.getCommand("help").execute(null, new BungeeCommandSender(sender), new String[0]); } } @@ -71,8 +86,4 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor } return new ArrayList<>(); } - - private GeyserCommand getCommand(String label) { - return connector.getCommandManager().getCommands().get(label); - } } diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java index 1db86856f..6cdcdae67 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/command/GeyserSpigotCommandExecutor.java @@ -25,40 +25,51 @@ package org.geysermc.platform.spigot.command; -import lombok.AllArgsConstructor; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandExecutor; import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.LanguageUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -@AllArgsConstructor -public class GeyserSpigotCommandExecutor implements TabExecutor { +public class GeyserSpigotCommandExecutor extends CommandExecutor implements TabExecutor { - private final GeyserConnector connector; + public GeyserSpigotCommandExecutor(GeyserConnector connector) { + super(connector); + } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (args.length > 0) { - if (getCommand(args[0]) != null) { - if (!sender.hasPermission(getCommand(args[0]).getPermission())) { - SpigotCommandSender commandSender = new SpigotCommandSender(sender); - String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale());; + GeyserCommand geyserCommand = getCommand(args[0]); + if (geyserCommand != null) { + SpigotCommandSender commandSender = new SpigotCommandSender(sender); + if (!sender.hasPermission(geyserCommand.getPermission())) { + String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale()); commandSender.sendMessage(ChatColor.RED + message); return true; } - getCommand(args[0]).execute(new SpigotCommandSender(sender), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); + GeyserSession session = null; + if (geyserCommand.isBedrockOnly()) { + session = getGeyserSession(commandSender); + if (session == null) { + sender.sendMessage(ChatColor.RED + LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", commandSender.getLocale())); + return true; + } + } + geyserCommand.execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); return true; } } else { - getCommand("help").execute(new SpigotCommandSender(sender), new String[0]); + getCommand("help").execute(null, new SpigotCommandSender(sender), new String[0]); return true; } return true; @@ -71,8 +82,4 @@ public class GeyserSpigotCommandExecutor implements TabExecutor { } return new ArrayList<>(); } - - private GeyserCommand getCommand(String label) { - return connector.getCommandManager().getCommands().get(label); - } } diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/command/GeyserSpongeCommandExecutor.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/command/GeyserSpongeCommandExecutor.java index 938d19928..8ef23b19e 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/command/GeyserSpongeCommandExecutor.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/command/GeyserSpongeCommandExecutor.java @@ -25,10 +25,12 @@ package org.geysermc.platform.sponge.command; -import lombok.AllArgsConstructor; import org.geysermc.connector.GeyserConnector; -import org.geysermc.connector.common.ChatColor; +import org.geysermc.connector.command.CommandExecutor; +import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.common.ChatColor; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.LanguageUtils; import org.spongepowered.api.command.CommandCallable; import org.spongepowered.api.command.CommandException; @@ -44,25 +46,36 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; -@AllArgsConstructor -public class GeyserSpongeCommandExecutor implements CommandCallable { +public class GeyserSpongeCommandExecutor extends CommandExecutor implements CommandCallable { - private GeyserConnector connector; + public GeyserSpongeCommandExecutor(GeyserConnector connector) { + super(connector); + } @Override - public CommandResult process(CommandSource source, String arguments) throws CommandException { + public CommandResult process(CommandSource source, String arguments) { String[] args = arguments.split(" "); if (args.length > 0) { - if (getCommand(args[0]) != null) { - if (!source.hasPermission(getCommand(args[0]).getPermission())) { + GeyserCommand command = getCommand(args[0]); + if (command != null) { + CommandSender commandSender = new SpongeCommandSender(source); + if (!source.hasPermission(command.getPermission())) { // Not ideal to use log here but we dont get a session source.sendMessage(Text.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail"))); return CommandResult.success(); } - getCommand(args[0]).execute(new SpongeCommandSender(source), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); + GeyserSession session = null; + if (command.isBedrockOnly()) { + session = getGeyserSession(commandSender); + if (session == null) { + source.sendMessage(Text.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.bedrock_only"))); + return CommandResult.success(); + } + } + getCommand(args[0]).execute(session, commandSender, args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]); } } else { - getCommand("help").execute(new SpongeCommandSender(source), new String[0]); + getCommand("help").execute(null, new SpongeCommandSender(source), new String[0]); } return CommandResult.success(); } @@ -94,8 +107,4 @@ public class GeyserSpongeCommandExecutor implements CommandCallable { public Text getUsage(CommandSource source) { return Text.of("/geyser help"); } - - private GeyserCommand getCommand(String label) { - return connector.getCommandManager().getCommands().get(label); - } } diff --git a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java index fb6a46f9f..3636dded8 100644 --- a/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java +++ b/bootstrap/standalone/src/main/java/org/geysermc/platform/standalone/gui/GeyserStandaloneGUI.java @@ -271,17 +271,17 @@ public class GeyserStandaloneGUI { JMenuItem commandButton = hasSubCommands ? new JMenu(command.getValue().getName()) : new JMenuItem(command.getValue().getName()); commandButton.getAccessibleContext().setAccessibleDescription(command.getValue().getDescription()); if (!hasSubCommands) { - commandButton.addActionListener(e -> command.getValue().execute(geyserStandaloneLogger, new String[]{ })); + commandButton.addActionListener(e -> command.getValue().execute(null, geyserStandaloneLogger, new String[]{ })); } else { // Add a submenu that's the same name as the menu can't be pressed JMenuItem otherCommandButton = new JMenuItem(command.getValue().getName()); otherCommandButton.getAccessibleContext().setAccessibleDescription(command.getValue().getDescription()); - otherCommandButton.addActionListener(e -> command.getValue().execute(geyserStandaloneLogger, new String[]{ })); + otherCommandButton.addActionListener(e -> command.getValue().execute(null, geyserStandaloneLogger, new String[]{ })); commandButton.add(otherCommandButton); // Add a menu option for all possible subcommands for (String subCommandName : command.getValue().getSubCommands()) { JMenuItem item = new JMenuItem(subCommandName); - item.addActionListener(e -> command.getValue().execute(geyserStandaloneLogger, new String[]{subCommandName})); + item.addActionListener(e -> command.getValue().execute(null, geyserStandaloneLogger, new String[]{subCommandName})); commandButton.add(item); } } diff --git a/bootstrap/velocity/pom.xml b/bootstrap/velocity/pom.xml index 5c0824def..58eee1f77 100644 --- a/bootstrap/velocity/pom.xml +++ b/bootstrap/velocity/pom.xml @@ -82,8 +82,8 @@ org.geysermc.platform.velocity.shaded.dom4j - net.kyori - org.geysermc.platform.velocity.shaded.kyori + net.kyori.adventure.text.serializer.gson.legacyimpl + org.geysermc.platform.velocity.shaded.kyori.legacyimpl @@ -105,6 +105,13 @@ io.netty:netty-codec:* org.slf4j:* org.ow2.asm:* + + net.kyori:adventure-api:* + net.kyori:examination-api:* + net.kyori:examination-string:* + net.kyori:adventure-text-serializer-gson:* + net.kyori:adventure-text-serializer-legacy:* + net.kyori:adventure-nbt:* diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPingPassthrough.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPingPassthrough.java index bab0e3505..bc10bc723 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPingPassthrough.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/GeyserVelocityPingPassthrough.java @@ -31,11 +31,10 @@ import com.velocitypowered.api.proxy.InboundConnection; import com.velocitypowered.api.proxy.ProxyServer; import com.velocitypowered.api.proxy.server.ServerPing; import lombok.AllArgsConstructor; -import net.kyori.text.serializer.legacy.LegacyComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.geysermc.connector.common.ping.GeyserPingInfo; import org.geysermc.connector.ping.IGeyserPingPassthrough; -import java.net.Inet4Address; import java.net.InetSocketAddress; import java.util.Optional; import java.util.concurrent.ExecutionException; @@ -50,13 +49,13 @@ public class GeyserVelocityPingPassthrough implements IGeyserPingPassthrough { ProxyPingEvent event; try { event = server.getEventManager().fire(new ProxyPingEvent(new GeyserInboundConnection(inetSocketAddress), ServerPing.builder() - .description(server.getConfiguration().getMotdComponent()).onlinePlayers(server.getPlayerCount()) + .description(server.getConfiguration().getMotd()).onlinePlayers(server.getPlayerCount()) .maximumPlayers(server.getConfiguration().getShowMaxPlayers()).build())).get(); } catch (ExecutionException | InterruptedException e) { throw new RuntimeException(e); } GeyserPingInfo geyserPingInfo = new GeyserPingInfo( - LegacyComponentSerializer.legacy().serialize(event.getPing().getDescription(), '§'), + LegacyComponentSerializer.legacy('§').serialize(event.getPing().getDescriptionComponent()), new GeyserPingInfo.Players( event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getMax(), event.getPing().getPlayers().orElseThrow(IllegalStateException::new).getOnline() diff --git a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/command/GeyserVelocityCommandExecutor.java b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/command/GeyserVelocityCommandExecutor.java index 4aab73e59..c8998d8fe 100644 --- a/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/command/GeyserVelocityCommandExecutor.java +++ b/bootstrap/velocity/src/main/java/org/geysermc/platform/velocity/command/GeyserVelocityCommandExecutor.java @@ -25,37 +25,47 @@ package org.geysermc.platform.velocity.command; -import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.command.SimpleCommand; -import lombok.AllArgsConstructor; import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.command.CommandExecutor; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; import org.geysermc.connector.common.ChatColor; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.LanguageUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -@AllArgsConstructor -public class GeyserVelocityCommandExecutor implements SimpleCommand { +public class GeyserVelocityCommandExecutor extends CommandExecutor implements SimpleCommand { - private final GeyserConnector connector; + public GeyserVelocityCommandExecutor(GeyserConnector connector) { + super(connector); + } @Override public void execute(Invocation invocation) { if (invocation.arguments().length > 0) { - if (getCommand(invocation.arguments()[0]) != null) { + GeyserCommand command = getCommand(invocation.arguments()[0]); + if (command != null) { + CommandSender sender = new VelocityCommandSender(invocation.source()); if (!invocation.source().hasPermission(getCommand(invocation.arguments()[0]).getPermission())) { - CommandSender sender = new VelocityCommandSender(invocation.source()); sender.sendMessage(ChatColor.RED + LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale())); return; } - getCommand(invocation.arguments()[0]).execute(new VelocityCommandSender(invocation.source()), invocation.arguments().length > 1 ? Arrays.copyOfRange(invocation.arguments(), 1, invocation.arguments().length) : new String[0]); + GeyserSession session = null; + if (command.isBedrockOnly()) { + session = getGeyserSession(sender); + if (session == null) { + sender.sendMessage(ChatColor.RED + LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.bedrock_only", sender.getLocale())); + return; + } + } + command.execute(session, sender, invocation.arguments().length > 1 ? Arrays.copyOfRange(invocation.arguments(), 1, invocation.arguments().length) : new String[0]); } } else { - getCommand("help").execute(new VelocityCommandSender(invocation.source()), new String[0]); + getCommand("help").execute(null, new VelocityCommandSender(invocation.source()), new String[0]); } } @@ -66,8 +76,4 @@ public class GeyserVelocityCommandExecutor implements SimpleCommand { } return new ArrayList<>(); } - - private GeyserCommand getCommand(String label) { - return connector.getCommandManager().getCommands().get(label); - } } diff --git a/connector/src/main/java/org/geysermc/connector/command/CommandExecutor.java b/connector/src/main/java/org/geysermc/connector/command/CommandExecutor.java new file mode 100644 index 000000000..751f51260 --- /dev/null +++ b/connector/src/main/java/org/geysermc/connector/command/CommandExecutor.java @@ -0,0 +1,56 @@ +/* + * 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.connector.command; + +import lombok.AllArgsConstructor; +import org.geysermc.connector.GeyserConnector; +import org.geysermc.connector.network.session.GeyserSession; + +/** + * Represents helper functions for listening to {@code /geyser} commands. + */ +@AllArgsConstructor +public class CommandExecutor { + + protected final GeyserConnector connector; + + public GeyserCommand getCommand(String label) { + return connector.getCommandManager().getCommands().get(label); + } + + public GeyserSession getGeyserSession(CommandSender sender) { + if (sender.isConsole()) { + return null; + } + + for (GeyserSession session : connector.getPlayers()) { + if (sender.getName().equals(session.getPlayerEntity().getUsername())) { + return session; + } + } + return null; + } +} diff --git a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java index d31983eb4..9f675ae81 100644 --- a/connector/src/main/java/org/geysermc/connector/command/CommandManager.java +++ b/connector/src/main/java/org/geysermc/connector/command/CommandManager.java @@ -29,6 +29,7 @@ import lombok.Getter; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.defaults.*; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.LanguageUtils; import java.util.*; @@ -89,7 +90,15 @@ public abstract class CommandManager { return; } - cmd.execute(sender, args); + if (sender instanceof GeyserSession) { + cmd.execute((GeyserSession) sender, sender, args); + } else { + if (!cmd.isBedrockOnly()) { + cmd.execute(null, sender, args); + } else { + connector.getLogger().error(LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.bedrock_only")); + } + } } /** diff --git a/connector/src/main/java/org/geysermc/connector/command/GeyserCommand.java b/connector/src/main/java/org/geysermc/connector/command/GeyserCommand.java index c606e2e7b..48fe2eb9a 100644 --- a/connector/src/main/java/org/geysermc/connector/command/GeyserCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/GeyserCommand.java @@ -28,7 +28,9 @@ package org.geysermc.connector.command; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; +import org.geysermc.connector.network.session.GeyserSession; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -47,7 +49,7 @@ public abstract class GeyserCommand { @Setter private List aliases = new ArrayList<>(); - public abstract void execute(CommandSender sender, String[] args); + public abstract void execute(@Nullable GeyserSession session, CommandSender sender, String[] args); /** * If false, hides the command from being shown on the Geyser Standalone GUI. @@ -75,4 +77,13 @@ public abstract class GeyserCommand { public boolean hasSubCommands() { return !getSubCommands().isEmpty(); } + + /** + * Used to send a deny message to Java players if this command can only be used by Bedrock players. + * + * @return true if this command can only be used by Bedrock players. + */ + public boolean isBedrockOnly() { + return false; + } } \ No newline at end of file diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/AdvancementsCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/AdvancementsCommand.java index 3067f3d53..2ef23381b 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/AdvancementsCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/AdvancementsCommand.java @@ -34,33 +34,12 @@ import org.geysermc.connector.network.session.cache.AdvancementsCache; public class AdvancementsCommand extends GeyserCommand { - private final GeyserConnector connector; - public AdvancementsCommand(GeyserConnector connector, String name, String description, String permission) { super(name, description, permission); - - this.connector = connector; } @Override - public void execute(CommandSender sender, String[] args) { - if (sender.isConsole()) { - return; - } - - // Make sure the sender is a Bedrock edition client - GeyserSession session = null; - if (sender instanceof GeyserSession) { - session = (GeyserSession) sender; - } else { - // Needed for Spigot - sender is not an instance of GeyserSession - for (GeyserSession otherSession : connector.getPlayers()) { - if (sender.getName().equals(otherSession.getPlayerEntity().getUsername())) { - session = otherSession; - break; - } - } - } + public void execute(GeyserSession session, CommandSender sender, String[] args) { if (session == null) return; SimpleFormWindow window = session.getAdvancementsCache().buildMenuForm(); @@ -71,4 +50,9 @@ public class AdvancementsCommand extends GeyserCommand { public boolean isExecutableOnConsole() { return false; } + + @Override + public boolean isBedrockOnly() { + return true; + } } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java index 5bc3efea7..97d09f7e0 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/DumpCommand.java @@ -33,6 +33,7 @@ import org.geysermc.connector.command.GeyserCommand; import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.common.serializer.AsteriskSerializer; import org.geysermc.connector.dump.DumpInfo; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.utils.WebUtils; @@ -54,7 +55,7 @@ public class DumpCommand extends GeyserCommand { } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(GeyserSession session, CommandSender sender, String[] args) { boolean showSensitive = false; boolean offlineDump = false; if (args.length >= 1) { diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java index 7ab3aec3c..c2716f206 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/HelpCommand.java @@ -29,6 +29,7 @@ import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; import org.geysermc.connector.common.ChatColor; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.LanguageUtils; import java.util.Collections; @@ -48,7 +49,7 @@ public class HelpCommand extends GeyserCommand { } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(GeyserSession session, CommandSender sender, String[] args) { int page = 1; int maxPage = 1; String header = LanguageUtils.getPlayerLocaleString("geyser.commands.help.header", sender.getLocale(), page, maxPage); diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/ListCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/ListCommand.java index f52ab7f36..8a000f80c 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/ListCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/ListCommand.java @@ -44,7 +44,7 @@ public class ListCommand extends GeyserCommand { } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(GeyserSession session, CommandSender sender, String[] args) { String message = ""; message = LanguageUtils.getPlayerLocaleString("geyser.commands.list.message", sender.getLocale(), connector.getPlayers().size(), diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java index d6916700b..4d7d74045 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/OffhandCommand.java @@ -45,32 +45,23 @@ public class OffhandCommand extends GeyserCommand { } @Override - public void execute(CommandSender sender, String[] args) { - if (sender.isConsole()) { + public void execute(GeyserSession session, CommandSender sender, String[] args) { + if (session == null) { return; } - // Make sure the sender is a Bedrock edition client - if (sender instanceof GeyserSession) { - GeyserSession session = (GeyserSession) sender; - ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0), - BlockFace.DOWN); - session.sendDownstreamPacket(releaseItemPacket); - return; - } - // Needed for Spigot - sender is not an instance of GeyserSession - for (GeyserSession session : connector.getPlayers()) { - if (sender.getName().equals(session.getPlayerEntity().getUsername())) { - ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0), - BlockFace.DOWN); - session.sendDownstreamPacket(releaseItemPacket); - break; - } - } + ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0), + BlockFace.DOWN); + session.sendDownstreamPacket(releaseItemPacket); } @Override public boolean isExecutableOnConsole() { return false; } + + @Override + public boolean isBedrockOnly() { + return true; + } } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java index 798dd7a77..2f1c7dc9b 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/ReloadCommand.java @@ -34,7 +34,7 @@ import org.geysermc.connector.utils.LanguageUtils; public class ReloadCommand extends GeyserCommand { - private GeyserConnector connector; + private final GeyserConnector connector; public ReloadCommand(GeyserConnector connector, String name, String description, String permission) { super(name, description, permission); @@ -42,7 +42,7 @@ public class ReloadCommand extends GeyserCommand { } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(GeyserSession session, CommandSender sender, String[] args) { if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) { return; } @@ -51,8 +51,8 @@ public class ReloadCommand extends GeyserCommand { sender.sendMessage(message); - for (GeyserSession session : connector.getPlayers()) { - session.disconnect(LanguageUtils.getPlayerLocaleString("geyser.commands.reload.kick", session.getLocale())); + for (GeyserSession otherSession : connector.getPlayers()) { + otherSession.disconnect(LanguageUtils.getPlayerLocaleString("geyser.commands.reload.kick", session.getLocale())); } connector.reload(); } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/SettingsCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/SettingsCommand.java index 5e28e985f..2aeee1377 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/SettingsCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/SettingsCommand.java @@ -33,30 +33,14 @@ import org.geysermc.connector.utils.SettingsUtils; public class SettingsCommand extends GeyserCommand { - private final GeyserConnector connector; - public SettingsCommand(GeyserConnector connector, String name, String description, String permission) { super(name, description, permission); - - this.connector = connector; } @Override - public void execute(CommandSender sender, String[] args) { - // Make sure the sender is a Bedrock edition client - GeyserSession session = null; - if (sender instanceof GeyserSession) { - session = (GeyserSession) sender; - } else { - // Needed for Spigot - sender is not an instance of GeyserSession - for (GeyserSession otherSession : connector.getPlayers()) { - if (sender.getName().equals(otherSession.getPlayerEntity().getUsername())) { - session = otherSession; - break; - } - } - } + public void execute(GeyserSession session, CommandSender sender, String[] args) { if (session == null) return; + SettingsUtils.buildForm(session); session.sendForm(session.getSettingsForm(), SettingsUtils.SETTINGS_FORM_ID); } @@ -65,4 +49,9 @@ public class SettingsCommand extends GeyserCommand { public boolean isExecutableOnConsole() { return false; } + + @Override + public boolean isBedrockOnly() { + return true; + } } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/StatisticsCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/StatisticsCommand.java index 920ec50c7..3502941d5 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/StatisticsCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/StatisticsCommand.java @@ -34,34 +34,14 @@ import org.geysermc.connector.network.session.GeyserSession; public class StatisticsCommand extends GeyserCommand { - private final GeyserConnector connector; - public StatisticsCommand(GeyserConnector connector, String name, String description, String permission) { super(name, description, permission); - - this.connector = connector; } @Override - public void execute(CommandSender sender, String[] args) { - if (sender.isConsole()) { - return; - } - - // Make sure the sender is a Bedrock edition client - GeyserSession session = null; - if (sender instanceof GeyserSession) { - session = (GeyserSession) sender; - } else { - // Needed for Spigot - sender is not an instance of GeyserSession - for (GeyserSession otherSession : connector.getPlayers()) { - if (sender.getName().equals(otherSession.getPlayerEntity().getUsername())) { - session = otherSession; - break; - } - } - } + public void execute(GeyserSession session, CommandSender sender, String[] args) { if (session == null) return; + session.setWaitingForStatistics(true); ClientRequestPacket clientRequestPacket = new ClientRequestPacket(ClientRequest.STATS); session.sendDownstreamPacket(clientRequestPacket); @@ -71,4 +51,9 @@ public class StatisticsCommand extends GeyserCommand { public boolean isExecutableOnConsole() { return false; } + + @Override + public boolean isBedrockOnly() { + return true; + } } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java index b192c9e9a..b00e44b72 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/StopCommand.java @@ -29,12 +29,13 @@ import org.geysermc.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; +import org.geysermc.connector.network.session.GeyserSession; import java.util.Collections; public class StopCommand extends GeyserCommand { - private GeyserConnector connector; + private final GeyserConnector connector; public StopCommand(GeyserConnector connector, String name, String description, String permission) { super(name, description, permission); @@ -44,7 +45,7 @@ public class StopCommand extends GeyserCommand { } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(GeyserSession session, CommandSender sender, String[] args) { if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) { return; } diff --git a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java index e0c445b3f..226a770a6 100644 --- a/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java +++ b/connector/src/main/java/org/geysermc/connector/command/defaults/VersionCommand.java @@ -32,6 +32,7 @@ import org.geysermc.connector.command.CommandSender; import org.geysermc.connector.command.GeyserCommand; import org.geysermc.connector.common.ChatColor; import org.geysermc.connector.network.BedrockProtocol; +import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; import org.geysermc.connector.utils.WebUtils; @@ -44,15 +45,12 @@ import java.util.Properties; public class VersionCommand extends GeyserCommand { - public GeyserConnector connector; - public VersionCommand(GeyserConnector connector, String name, String description, String permission) { super(name, description, permission); - this.connector = connector; } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(GeyserSession session, CommandSender sender, String[] args) { String bedrockVersions; List supportedCodecs = BedrockProtocol.SUPPORTED_BEDROCK_CODECS; if (supportedCodecs.size() > 1) { diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java index 6ff29f5cc..a9ed15cef 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/bedrock/BedrockCommandRequestTranslator.java @@ -43,7 +43,7 @@ public class BedrockCommandRequestTranslator extends PacketTranslator