diff --git a/src/main/java/net/minestom/server/utils/PacketUtils.java b/src/main/java/net/minestom/server/utils/PacketUtils.java index 5086ef955..26f087efa 100644 --- a/src/main/java/net/minestom/server/utils/PacketUtils.java +++ b/src/main/java/net/minestom/server/utils/PacketUtils.java @@ -198,18 +198,16 @@ public final class PacketUtils { final int compressionThreshold = MinecraftServer.getCompressionThreshold(); final boolean compression = compressionThreshold > 0; - final int hardcodedVarIntSize = 3; - if (compression) { // Dummy varint - final int packetLengthIndex = Utils.writeEmptyVarInt(buffer, hardcodedVarIntSize); - final int dataLengthIndex = Utils.writeEmptyVarInt(buffer, hardcodedVarIntSize); + final int packetLengthIndex = Utils.writeEmptyVarIntHeader(buffer); + final int dataLengthIndex = Utils.writeEmptyVarIntHeader(buffer); // Write packet final int contentIndex = buffer.writerIndex(); writePacket(buffer, serverPacket); final int afterIndex = buffer.writerIndex(); - final int packetSize = (afterIndex - dataLengthIndex) - hardcodedVarIntSize; + final int packetSize = (afterIndex - dataLengthIndex) - Utils.VARINT_HEADER_SIZE; if (packetSize >= compressionThreshold) { // Packet large enough @@ -221,30 +219,30 @@ public final class PacketUtils { compress(deflater, uncompressedCopy, buffer); uncompressedCopy.release(); - final int totalPacketLength = buffer.writerIndex() - contentIndex + hardcodedVarIntSize; + final int totalPacketLength = buffer.writerIndex() - contentIndex + Utils.VARINT_HEADER_SIZE; // Update header values - Utils.overrideVarInt(buffer, packetLengthIndex, hardcodedVarIntSize, totalPacketLength); - Utils.overrideVarInt(buffer, dataLengthIndex, hardcodedVarIntSize, packetSize); + Utils.overrideVarIntHeader(buffer, packetLengthIndex, totalPacketLength); + Utils.overrideVarIntHeader(buffer, dataLengthIndex, packetSize); } else { // Packet too small, just override header values - final int totalPacketLength = packetSize + hardcodedVarIntSize; - Utils.overrideVarInt(buffer, packetLengthIndex, hardcodedVarIntSize, totalPacketLength); - Utils.overrideVarInt(buffer, dataLengthIndex, hardcodedVarIntSize, 0); // -> Uncompressed + final int totalPacketLength = packetSize + Utils.VARINT_HEADER_SIZE; + Utils.overrideVarIntHeader(buffer, packetLengthIndex, totalPacketLength); + Utils.overrideVarIntHeader(buffer, dataLengthIndex, 0); // -> Uncompressed } } else { // No compression // Write dummy varint - final int index = Utils.writeEmptyVarInt(buffer, hardcodedVarIntSize); + final int index = Utils.writeEmptyVarIntHeader(buffer); // Write packet id + payload writePacket(buffer, serverPacket); // Rewrite dummy varint to packet length final int afterIndex = buffer.writerIndex(); - final int packetSize = (afterIndex - index) - hardcodedVarIntSize; - Utils.overrideVarInt(buffer, index, hardcodedVarIntSize, packetSize); + final int packetSize = (afterIndex - index) - Utils.VARINT_HEADER_SIZE; + Utils.overrideVarIntHeader(buffer, index, packetSize); } } diff --git a/src/main/java/net/minestom/server/utils/Utils.java b/src/main/java/net/minestom/server/utils/Utils.java index aef87a28b..b83755aa9 100644 --- a/src/main/java/net/minestom/server/utils/Utils.java +++ b/src/main/java/net/minestom/server/utils/Utils.java @@ -10,6 +10,9 @@ import java.util.UUID; public final class Utils { + // Do NOT modify + public static final int VARINT_HEADER_SIZE = 3; + private Utils() { } @@ -44,31 +47,26 @@ public final class Utils { } while (value != 0); } - public static void overrideVarInt(@NotNull ByteBuf buffer, int startIndex, int length, int value) { + public static void overrideVarIntHeader(@NotNull ByteBuf buffer, int startIndex, int value) { final int indexCache = buffer.writerIndex(); buffer.writerIndex(startIndex); - writeVarIntBuf(buffer, value); - final int loopEnd = startIndex + length; - for (int i = startIndex; i < loopEnd; i++) { - byte b = buffer.getByte(i); - boolean last = i == loopEnd - 1; - if (last) { - b &= ~(1 << 7); - } else { - b |= 1 << 7; + for (int i = 0; i < VARINT_HEADER_SIZE; i++) { + byte temp = (byte) (value & 0b01111111); + value >>>= 7; + if (value != 0 || i != VARINT_HEADER_SIZE - 1) { + temp |= 0b10000000; } - buffer.setByte(i, b); + + buffer.writeByte(temp); } buffer.writerIndex(indexCache); } - public static int writeEmptyVarInt(@NotNull ByteBuf buffer, int length) { + public static int writeEmptyVarIntHeader(@NotNull ByteBuf buffer) { final int index = buffer.writerIndex(); - for (int i = 0; i < length; i++) { - buffer.writeByte(0); - } + buffer.writeMedium(0); return index; } diff --git a/src/main/java/net/minestom/server/utils/binary/BinaryWriter.java b/src/main/java/net/minestom/server/utils/binary/BinaryWriter.java index 08e1400f2..98f717f1a 100644 --- a/src/main/java/net/minestom/server/utils/binary/BinaryWriter.java +++ b/src/main/java/net/minestom/server/utils/binary/BinaryWriter.java @@ -1,6 +1,7 @@ package net.minestom.server.utils.binary; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import net.kyori.adventure.text.Component; import net.minestom.server.MinecraftServer; @@ -170,9 +171,9 @@ public class BinaryWriter extends OutputStream { * @param string the string to write */ public void writeSizedString(@NotNull String string) { - final byte[] bytes = string.getBytes(StandardCharsets.UTF_8); - writeVarInt(bytes.length); - writeBytes(bytes); + final int utf8Bytes = ByteBufUtil.utf8Bytes(string); + writeVarInt(utf8Bytes); + buffer.writeCharSequence(string, StandardCharsets.UTF_8); } /**