diff --git a/pom.xml b/pom.xml index 1d5c02f..b675bcd 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ https://www.spigotmc.org/resources/ - Forwards commands from Bukkit to BungeeCord to execute it there + Forwards commands from Bukkit to BungeeCord (Or Velocity) to execute it there @@ -25,6 +25,7 @@ bukkit bungee + velocity universal diff --git a/velocity/pom.xml b/velocity/pom.xml new file mode 100644 index 0000000..04a5268 --- /dev/null +++ b/velocity/pom.xml @@ -0,0 +1,35 @@ + + 4.0.0 + + + com.github.games647 + commandforward + 0.4.0 + ../pom.xml + + + + commandforward.velocity + jar + + + CommandForwardVelocity + + + + + velocitypowered-repo + https://nexus.velocitypowered.com/repository/maven-public/ + + + + + + com.velocitypowered + velocity-api + 3.1.0 + provided + + + diff --git a/velocity/src/main/java/com/github/games647/commandforward/velocity/CommandForwardVelocity.java b/velocity/src/main/java/com/github/games647/commandforward/velocity/CommandForwardVelocity.java new file mode 100644 index 0000000..ebe0b33 --- /dev/null +++ b/velocity/src/main/java/com/github/games647/commandforward/velocity/CommandForwardVelocity.java @@ -0,0 +1,84 @@ +package com.github.games647.commandforward.velocity; + +import com.google.inject.Inject; +import com.velocitypowered.api.command.CommandSource; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.messages.ChannelIdentifier; +import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; +import com.velocitypowered.api.proxy.server.RegisteredServer; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.slf4j.Logger; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * + * Velocity support for CommandForward plugin + * Since Velocity supports BungeeCord plugin- + * messaging channels now + * + * @author Alijk + * @since 2022-02-13 + * + */ +@Plugin( + id = "commandforward", + name = "CommandForward", + version = "0.4.0", + description = "Forwards commands from Bukkit to BungeeCord (Or Velocity) to execute it there", + authors = {"games647", "https://github.com/games647/CommandForward/graphs/contributors"} +) +public class CommandForwardVelocity { + + private final ChannelIdentifier MESSAGE_CHANNEL = MinecraftChannelIdentifier.from("commandforward:cmd"); + + private static Optional instance; + private final ProxyServer proxyServer; + private final Logger logger; + + private final List lobbies = new ArrayList<>(); + private final List bedwars = new ArrayList<>(); + + @Inject + public CommandForwardVelocity(ProxyServer proxyServer, Logger logger, @DataDirectory Path dataDirectory) { + instance = Optional.of(this); + this.proxyServer = proxyServer; + this.logger = logger; + } + + @Subscribe + public void onProxyInit(ProxyInitializeEvent event) { + // Register the custom messaging channel + proxyServer.getChannelRegistrar().register(MESSAGE_CHANNEL); + // Register an event handler to catch messages for it + proxyServer.getEventManager().register(this, new MessageListener(MESSAGE_CHANNEL)); + + } + + /** + * Print an error message + * + * @param source Sender that execute the current command + * @param message Message to send to command sender + */ + private void sendErrorMessage(CommandSource source, String message) { + Component textComponent = Component.text(String.format("[%s] %s", "CommandForward", message), NamedTextColor.RED); + source.sendMessage(textComponent); + } + + public static CommandForwardVelocity getInstance() { + return instance.orElseThrow(IllegalAccessError::new); + } + + public ProxyServer getProxyServer() { + return proxyServer; + } +} diff --git a/velocity/src/main/java/com/github/games647/commandforward/velocity/MessageListener.java b/velocity/src/main/java/com/github/games647/commandforward/velocity/MessageListener.java new file mode 100644 index 0000000..8c1eeda --- /dev/null +++ b/velocity/src/main/java/com/github/games647/commandforward/velocity/MessageListener.java @@ -0,0 +1,57 @@ +package com.github.games647.commandforward.velocity; + +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteStreams; +import com.velocitypowered.api.command.CommandManager; +import com.velocitypowered.api.command.CommandSource; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.PluginMessageEvent; +import com.velocitypowered.api.plugin.PluginManager; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ServerConnection; +import com.velocitypowered.api.proxy.messages.ChannelIdentifier; + +public class MessageListener { + private final ChannelIdentifier identifier; + + public MessageListener(ChannelIdentifier identifier){ + this.identifier = identifier; + } + + @Subscribe + public void onPluginMessageEvent(PluginMessageEvent event){ + // Received plugin message, check channel identifier matches + if(event.getIdentifier().equals(identifier)){ + // Since this message was meant for this listener set it to handled + // We do this so the message doesn't get routed through. + event.setResult(PluginMessageEvent.ForwardResult.handled()); + + if(event.getSource() instanceof ServerConnection){ + // Read the data written to the message + Player p = ((ServerConnection) event.getSource()).getPlayer(); + ByteArrayDataInput in = ByteStreams.newDataInput(event.getData()); + parseMessage(p, in); + } + } + } + + private void parseMessage(CommandSource source, ByteArrayDataInput dataInput) { + final boolean isPlayer = dataInput.readBoolean(); + final String command = dataInput.readUTF(); + final String arguments = dataInput.readUTF(); + final CommandSource invoker = (isPlayer) ? source : CommandForwardVelocity.getInstance().getProxyServer().getConsoleCommandSource(); + + invokeCommand(invoker, dataInput.readBoolean(), command, arguments); + } + + private void invokeCommand(CommandSource invoker, boolean isOp, String command, String arguments) { + PluginManager pluginManager = CommandForwardVelocity.getInstance().getProxyServer().getPluginManager(); + CommandManager commandManager = CommandForwardVelocity.getInstance().getProxyServer().getCommandManager(); + + // TODO implement isOp handle progress + + commandManager.executeAsync(invoker, command + " " + arguments); + } + + +}