From 565e81ed3ecb85a48ece4db47e49a2cefd5c5801 Mon Sep 17 00:00:00 2001 From: Joo200 Date: Wed, 4 Oct 2023 18:36:32 +0200 Subject: [PATCH 1/2] feat: forward cancelled chat and commands to backend --- .../chat/session/SessionChatHandler.java | 18 ++++++++++++++++- .../chat/session/SessionCommandHandler.java | 20 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatHandler.java index 6beaf14395..4a2e2a8f5a 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionChatHandler.java @@ -22,10 +22,16 @@ import com.velocitypowered.api.event.EventManager; import com.velocitypowered.api.event.player.PlayerChatEvent; +import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; +import com.velocitypowered.proxy.protocol.MinecraftPacket; +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.chat.ChatHandler; import com.velocitypowered.proxy.protocol.packet.chat.ChatQueue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -46,6 +52,14 @@ public Class packetClass() { return SessionPlayerChat.class; } + private MinecraftPacket tellBackend(SessionPlayerChat packet) { + ByteBuf buf = Unpooled.buffer(); + packet.encode(buf, ProtocolUtils.Direction.SERVERBOUND, player.getProtocolVersion()); + PluginMessage copied = new PluginMessage("velocity:chat_cancelled", buf); + logger.debug("Forwarding cancelled chat to backend server: " + packet.getMessage()); + return copied; + } + @Override public void handlePlayerChatInternal(SessionPlayerChat packet) { ChatQueue chatQueue = this.player.getChatQueue(); @@ -56,7 +70,9 @@ public void handlePlayerChatInternal(SessionPlayerChat packet) { .thenApply(pme -> { PlayerChatEvent.ChatResult chatResult = pme.getResult(); if (!chatResult.isAllowed()) { - if (packet.isSigned()) { + if (player.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_20_2) >= 0) { + return tellBackend(packet); + } else if (packet.isSigned()) { invalidCancel(logger, player); } return null; diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java index 558531b72a..9cca4fb094 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java @@ -21,9 +21,15 @@ import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.connection.client.ConnectedPlayer; +import com.velocitypowered.proxy.protocol.MinecraftPacket; +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.chat.ChatAcknowledgement; import com.velocitypowered.proxy.protocol.packet.chat.CommandHandler; import java.util.concurrent.CompletableFuture; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; public class SessionCommandHandler implements CommandHandler { @@ -41,12 +47,22 @@ public Class packetClass() { return SessionPlayerCommand.class; } + private MinecraftPacket tellBackend(CommandExecuteEvent event, SessionPlayerCommand packet) { + ByteBuf buf = Unpooled.buffer(); + packet.encode(buf, ProtocolUtils.Direction.SERVERBOUND, player.getProtocolVersion()); + PluginMessage copied = new PluginMessage("velocity:command_cancelled", buf); + logger.debug("Forwarding cancelled command to backend server: " + event.getCommand()); + return copied; + } + @Override public void handlePlayerCommandInternal(SessionPlayerCommand packet) { queueCommandResult(this.server, this.player, event -> { CommandExecuteEvent.CommandResult result = event.getResult(); if (result == CommandExecuteEvent.CommandResult.denied()) { - if (packet.isSigned()) { + if (player.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_20_2) >= 0) { + return CompletableFuture.completedFuture(tellBackend(event, packet)); + } else if (packet.isSigned()) { logger.fatal("A plugin tried to deny a command with signable component(s). " + "This is not supported. " + "Disconnecting player " + player.getUsername() + ". Command packet: " + packet); @@ -111,7 +127,7 @@ public void handlePlayerCommandInternal(SessionPlayerCommand packet) { if (player.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_19_3) >= 0) { return new ChatAcknowledgement(packet.lastSeenMessages.getOffset()); } - return null; + return tellBackend(event, packet); }); }, packet.command, packet.timeStamp); } From c2924dfd79d16d28f5825371c2ccb30b82aaafb0 Mon Sep 17 00:00:00 2001 From: Joo200 Date: Thu, 12 Oct 2023 22:13:22 +0200 Subject: [PATCH 2/2] Removed version checks SessionCommandHandler is only generated for versions greater 1.19.3 --- .../packet/chat/session/SessionCommandHandler.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java index 9cca4fb094..c42c4ae02d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/chat/session/SessionCommandHandler.java @@ -71,10 +71,7 @@ public void handlePlayerCommandInternal(SessionPlayerCommand packet) { + "Contact your network administrator.")); } // We seemingly can't actually do this if signed args exist, if not, we can probs keep stuff happy - if (player.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_19_3) >= 0) { - return CompletableFuture.completedFuture(new ChatAcknowledgement(packet.lastSeenMessages.getOffset())); - } - return CompletableFuture.completedFuture(null); + return CompletableFuture.completedFuture(new ChatAcknowledgement(packet.lastSeenMessages.getOffset())); } String commandToRun = result.getCommand().orElse(packet.command); @@ -124,10 +121,7 @@ public void handlePlayerCommandInternal(SessionPlayerCommand packet) { .toServer(); } } - if (player.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_19_3) >= 0) { - return new ChatAcknowledgement(packet.lastSeenMessages.getOffset()); - } - return tellBackend(event, packet); + return new ChatAcknowledgement(packet.lastSeenMessages.getOffset()); }); }, packet.command, packet.timeStamp); }