mirror of
https://github.com/Minestom/Minestom.git
synced 2025-03-02 11:21:15 +01:00
Micro optimize packet header varint
This commit is contained in:
parent
3f1d1531ea
commit
85d01e5009
src/main/java/net/minestom/server/utils
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user