diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java index c7e25f528..a40598e43 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/ProtocolUtils.java @@ -147,6 +147,16 @@ public enum ProtocolUtils { } } + /** + * Writes all integers as 3 bytes Minecraft-style VarInt to the specified {@code buf}. + * @param buf the buffer to read from + * @param value the integer to write + */ + public static void writeVarIntAs3Bytes(ByteBuf buf, int value) { + int w = (value & 0x7F | 0x80) << 16 | ((value >>> 7) & 0x7F | 0x80) << 8 | (value >>> 14); + buf.writeMedium(w); + } + public static String readString(ByteBuf buf) { return readString(buf, DEFAULT_MAX_STRING_SIZE); } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftCompressorAndLengthEncoder.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftCompressorAndLengthEncoder.java index 6684ee35d..73cea902b 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftCompressorAndLengthEncoder.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/netty/MinecraftCompressorAndLengthEncoder.java @@ -17,6 +17,8 @@ package com.velocitypowered.proxy.protocol.netty; +import static com.velocitypowered.proxy.protocol.netty.MinecraftVarintLengthEncoder.IS_JAVA_CIPHER; + import com.velocitypowered.natives.compression.VelocityCompressor; import com.velocitypowered.natives.util.MoreByteBufUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils; @@ -50,36 +52,37 @@ public class MinecraftCompressorAndLengthEncoder extends MessageToByteEncoder { public static final MinecraftVarintLengthEncoder INSTANCE = new MinecraftVarintLengthEncoder(); - private static final boolean IS_JAVA_CIPHER = Natives.cipher.get() == JavaVelocityCipher.FACTORY; + public static final boolean IS_JAVA_CIPHER = Natives.cipher.get() == JavaVelocityCipher.FACTORY; private MinecraftVarintLengthEncoder() { } diff --git a/proxy/src/test/java/com/velocitypowered/proxy/protocol/ProtocolUtilsTest.java b/proxy/src/test/java/com/velocitypowered/proxy/protocol/ProtocolUtilsTest.java index 57cd8f7da..58530a4a3 100644 --- a/proxy/src/test/java/com/velocitypowered/proxy/protocol/ProtocolUtilsTest.java +++ b/proxy/src/test/java/com/velocitypowered/proxy/protocol/ProtocolUtilsTest.java @@ -71,6 +71,20 @@ public class ProtocolUtilsTest { assertEquals(test, ProtocolUtils.readVarIntSafely(buf)); } + @Test + void test3Bytes() { + ByteBuf buf = Unpooled.buffer(5); + for (int i = 0; i < 2097152; i += 31) { + writeReadTest3Bytes(buf, i); + } + } + + private void writeReadTest3Bytes(ByteBuf buf, int test) { + buf.clear(); + ProtocolUtils.writeVarIntAs3Bytes(buf, test); + assertEquals(test, ProtocolUtils.readVarInt(buf)); + } + @Test void testBytesWrittenAtBitBoundaries() { ByteBuf varintNew = Unpooled.buffer(5);