diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
index 7042cb109..a1932e2d4 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
@@ -56,6 +56,7 @@ import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse.Offer;
import com.velocitypowered.proxy.protocol.packet.title.GenericTitlePacket;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
+import com.velocitypowered.proxy.util.CharacterUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
@@ -153,6 +154,12 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
}
String msg = packet.getMessage();
+ if (CharacterUtil.containsIllegalCharacters(msg)) {
+ player.disconnect(Component.translatable("velocity.error.illegal-chat-characters",
+ NamedTextColor.RED));
+ return true;
+ }
+
if (msg.startsWith("/")) {
String originalCommand = msg.substring(1);
server.getCommandManager().callCommandEvent(player, msg.substring(1))
@@ -629,4 +636,5 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
}
}
}
+
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/util/CharacterUtil.java b/proxy/src/main/java/com/velocitypowered/proxy/util/CharacterUtil.java
new file mode 100644
index 000000000..169d34d70
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/util/CharacterUtil.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.velocitypowered.proxy.util;
+
+public final class CharacterUtil {
+
+ /**
+ * Checks if a character is allowed.
+ * @param c character to check
+ * @return true if the character is allowed
+ */
+ public static boolean isAllowedCharacter(char c) {
+ // 167 = §, 127 = DEL
+ // https://minecraft.fandom.com/wiki/Multiplayer#Chat
+ return c != 167 && c >= ' ' && c != 127;
+ }
+
+ /**
+ * It is not possible to send certain characters in the chat like:
+ * section symbol, DEL, and all characters below space.
+ * Checks if a message contains illegal characters.
+ * @param message the message to check
+ * @return true if the message contains illegal characters
+ */
+ public static boolean containsIllegalCharacters(String message) {
+ for (int i = 0; i < message.length(); i++) {
+ if (!isAllowedCharacter(message.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/proxy/src/main/resources/com/velocitypowered/proxy/l10n/messages.properties b/proxy/src/main/resources/com/velocitypowered/proxy/l10n/messages.properties
index ee8e6cc2b..0ecb0010f 100644
--- a/proxy/src/main/resources/com/velocitypowered/proxy/l10n/messages.properties
+++ b/proxy/src/main/resources/com/velocitypowered/proxy/l10n/messages.properties
@@ -29,6 +29,7 @@ velocity.error.modern-forwarding-needs-new-client=This server is only compatible
velocity.error.modern-forwarding-failed=Your server did not send a forwarding request to the proxy. Make sure the server is configured for Velocity forwarding.
velocity.error.moved-to-new-server=You were kicked from {0}: {1}
velocity.error.no-available-servers=There are no available servers to connect you to. Try again later or contact an admin.
+velocity.error.illegal-chat-characters=Illegal characters in chat
# Commands
velocity.command.generic-error=An error occurred while running this command.
@@ -65,4 +66,4 @@ velocity.command.dump-send-error=An error occurred while communicating with the
velocity.command.dump-success=Created an anonymised report containing useful information about this proxy. If a developer requested it, you may share the following link with them:
velocity.command.dump-will-expire=This link will expire in a few days.
velocity.command.dump-server-error=An error occurred on the Velocity servers and the dump could not be completed. Please contact the Velocity staff about this problem and provide the details about this error from the Velocity console or server log.
-velocity.command.dump-offline=Likely cause: Invalid system DNS settings or no internet connection
\ No newline at end of file
+velocity.command.dump-offline=Likely cause: Invalid system DNS settings or no internet connection
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/util/CharacterUtilTest.java b/proxy/src/test/java/com/velocitypowered/proxy/util/CharacterUtilTest.java
new file mode 100644
index 000000000..0b5616166
--- /dev/null
+++ b/proxy/src/test/java/com/velocitypowered/proxy/util/CharacterUtilTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.velocitypowered.proxy.util;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+class CharacterUtilTest {
+
+ private static final String CHARACTERS = "!\\\"#$%&'()*+,-./0123456789:;<=>?"
+ + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_'abcdefghijklmnopqrstuvwxyz¡«»";
+ private static final String NON_ASCII_CHARACTERS = "速度ъगꯀ▀";
+
+ @Test
+ void testCharacter() {
+ assertTrue(CharacterUtil.isAllowedCharacter('a'));
+ assertTrue(CharacterUtil.isAllowedCharacter(' '));
+
+ assertFalse(CharacterUtil.isAllowedCharacter('\u00A7')); // §
+ assertFalse(CharacterUtil.isAllowedCharacter('\u007F')); // DEL
+ assertFalse(CharacterUtil.isAllowedCharacter((char) 0));
+ }
+
+ @Test
+ public void testMessage() {
+ assertFalse(CharacterUtil.containsIllegalCharacters(""));
+ assertFalse(CharacterUtil.containsIllegalCharacters(" "));
+ assertFalse(CharacterUtil.containsIllegalCharacters("Velocity"));
+ assertFalse(CharacterUtil.containsIllegalCharacters(CHARACTERS));
+ assertFalse(CharacterUtil.containsIllegalCharacters(NON_ASCII_CHARACTERS));
+
+ assertTrue(CharacterUtil.containsIllegalCharacters("§cVelocity"));
+ assertTrue(CharacterUtil.containsIllegalCharacters("§"));
+ }
+}