From cb99b184ede1f452ec820c48e6601d3458d86572 Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Thu, 28 May 2020 07:14:49 -0400 Subject: [PATCH] Allow plugins to mutate available commands sent to the client. This is the first unstable API being introduced and is primarily to get feedback on the system. --- api/build.gradle | 1 + .../command/PlayerAvailableCommandsEvent.java | 37 +++++++++++++++++++ .../backend/BackendPlaySessionHandler.java | 7 +++- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/com/velocitypowered/api/event/command/PlayerAvailableCommandsEvent.java diff --git a/api/build.gradle b/api/build.gradle index b156d61fc..2680d18ce 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -26,6 +26,7 @@ dependencies { compile "org.slf4j:slf4j-api:${slf4jVersion}" compile 'com.google.inject:guice:4.2.2' compile "org.checkerframework:checker-qual:${checkerFrameworkVersion}" + compile 'com.mojang:brigadier:1.0.17' compile "org.spongepowered:configurate-hocon:${configurateVersion}" compile "org.spongepowered:configurate-yaml:${configurateVersion}" diff --git a/api/src/main/java/com/velocitypowered/api/event/command/PlayerAvailableCommandsEvent.java b/api/src/main/java/com/velocitypowered/api/event/command/PlayerAvailableCommandsEvent.java new file mode 100644 index 000000000..c60528c4c --- /dev/null +++ b/api/src/main/java/com/velocitypowered/api/event/command/PlayerAvailableCommandsEvent.java @@ -0,0 +1,37 @@ +package com.velocitypowered.api.event.command; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.mojang.brigadier.tree.RootCommandNode; +import com.velocitypowered.api.annotations.UnstableApi; +import com.velocitypowered.api.proxy.Player; + +/** + * Allows plugins to modify the packet indicating commands available on the server to a + * Minecraft 1.13+ client. + */ +@UnstableApi +public class PlayerAvailableCommandsEvent { + + private final Player player; + private final RootCommandNode rootNode; + + /** + * Constructs an available commands event. + * @param player the targeted player + * @param rootNode the Brigadier root node + */ + public PlayerAvailableCommandsEvent(Player player, + RootCommandNode rootNode) { + this.player = checkNotNull(player, "player"); + this.rootNode = checkNotNull(rootNode, "rootNode"); + } + + public Player getPlayer() { + return player; + } + + public RootCommandNode getRootNode() { + return rootNode; + } +} diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java index 747006dce..7bde50a23 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java @@ -7,6 +7,7 @@ import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.tree.LiteralCommandNode; +import com.velocitypowered.api.event.command.PlayerAvailableCommandsEvent; import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.proxy.messages.ChannelIdentifier; import com.velocitypowered.proxy.VelocityServer; @@ -175,7 +176,11 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler { .build(); commands.getRootNode().addChild(root); } - return false; + + server.getEventManager().fire( + new PlayerAvailableCommandsEvent(serverConn.getPlayer(), commands.getRootNode())) + .thenAcceptAsync(event -> playerConnection.write(commands), playerConnection.eventLoop()); + return true; } @Override