From 66f30a2cb6f477ec8ff9d9aa34ec015a6cd6891d Mon Sep 17 00:00:00 2001 From: chris Date: Wed, 29 May 2024 23:43:39 +0200 Subject: [PATCH] Ensure we send commands/chat the same way a Java client would (#4703) * Ensure we send commands/chat the same way a Java client would * yeet static import, move blank check --- .../BedrockCommandRequestTranslator.java | 12 ++++--- .../bedrock/BedrockTextTranslator.java | 11 ++++++- .../translator/text/MessageTranslator.java | 33 +++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java index 322d64cce..8d4df6f3f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockCommandRequestTranslator.java @@ -26,8 +26,8 @@ package org.geysermc.geyser.translator.protocol.bedrock; import org.cloudburstmc.protocol.bedrock.packet.CommandRequestPacket; -import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.GeyserImpl; +import org.geysermc.geyser.api.util.PlatformType; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -39,15 +39,17 @@ public class BedrockCommandRequestTranslator extends PacketTranslator { @Override public void translate(GeyserSession session, TextPacket packet) { - String message = MessageTranslator.convertToPlainText(packet.getMessage()); + // Java trims all messages, and then checks for the leading slash + String message = MessageTranslator.convertToPlainText( + MessageTranslator.normalizeSpace(packet.getMessage()) + ); if (message.isBlank()) { // Java Edition (as of 1.17.1) just doesn't pass on these messages, so... we won't either! return; } + if (message.startsWith("/")) { + // Yes, Java actually allows whitespaces before commands and will still see those as valid + BedrockCommandRequestTranslator.handleCommand(session, message.substring(1)); + return; + } + if (MessageTranslator.isTooLong(message, session)) { return; } diff --git a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java index 5a0121039..bf6fdd763 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/text/MessageTranslator.java @@ -387,6 +387,39 @@ public class MessageTranslator { return false; } + /** + * Normalizes whitespaces - a thing a vanilla client apparently does with commands and chat messages. + */ + public static String normalizeSpace(String string) { + if (string == null || string.isEmpty()) { + return string; + } + final int size = string.length(); + final char[] newChars = new char[size]; + int count = 0; + int whitespacesCount = 0; + boolean startWhitespaces = true; + for (int i = 0; i < size; i++) { + final char actualChar = string.charAt(i); + final boolean isWhitespace = Character.isWhitespace(actualChar); + if (isWhitespace) { + if (whitespacesCount == 0 && !startWhitespaces) { + newChars[count++] = ' '; + } + whitespacesCount++; + } else { + startWhitespaces = false; + // Replace non-breaking spaces with regular spaces for normalization + newChars[count++] = (actualChar == '\u00A0' ? ' ' : actualChar); + whitespacesCount = 0; + } + } + if (startWhitespaces) { + return ""; + } + return new String(newChars, 0, count - (whitespacesCount > 0 ? 1 : 0)).trim(); + } + public static void init() { // no-op }