mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 16:37:38 +01:00
Fix compression
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
65df72fa82
commit
548cee55e0
@ -63,7 +63,6 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
private UUID bungeeUuid;
|
||||
private PlayerSkin bungeeSkin;
|
||||
|
||||
private final Object tickBufferLock = new Object();
|
||||
private final ByteBuffer tickBuffer = ByteBuffer.allocateDirect(Server.SOCKET_BUFFER_SIZE);
|
||||
private ByteBuffer cacheBuffer;
|
||||
|
||||
@ -170,8 +169,8 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
Check.stateCondition(compressed, "Compression is already enabled!");
|
||||
final int threshold = MinecraftServer.getCompressionThreshold();
|
||||
Check.stateCondition(threshold == 0, "Compression cannot be enabled because the threshold is equal to 0");
|
||||
this.compressed = true;
|
||||
writeAndFlush(new SetCompressionPacket(threshold));
|
||||
this.compressed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,13 +208,15 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
}
|
||||
|
||||
public void writeAndFlush(@NotNull ServerPacket packet) {
|
||||
attemptWrite(PacketUtils.createFramedPacket(packet));
|
||||
flush();
|
||||
synchronized (tickBuffer){
|
||||
PacketUtils.writeFramedPacket(tickBuffer, packet, compressed);
|
||||
flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void attemptWrite(ByteBuffer buffer) {
|
||||
buffer.flip();
|
||||
synchronized (tickBufferLock) {
|
||||
synchronized (tickBuffer) {
|
||||
try {
|
||||
this.tickBuffer.put(buffer);
|
||||
} catch (BufferOverflowException e) {
|
||||
@ -233,14 +234,14 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
synchronized (tickBufferLock) {
|
||||
synchronized (tickBuffer) {
|
||||
this.tickBuffer.flip();
|
||||
if (tickBuffer.remaining() == 0) {
|
||||
// Nothing to write
|
||||
return;
|
||||
}
|
||||
try {
|
||||
channel.write(tickBuffer);
|
||||
this.channel.write(tickBuffer);
|
||||
} catch (IOException e) {
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
}
|
||||
|
@ -130,58 +130,45 @@ public final class PacketUtils {
|
||||
sendGroupedPacket(players, packet, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a {@link ServerPacket} into a {@link ByteBuffer}.
|
||||
*
|
||||
* @param buf the recipient of {@code packet}
|
||||
* @param packet the packet to write into {@code buf}
|
||||
*/
|
||||
public static void writePacket(@NotNull ByteBuffer buf, @NotNull ServerPacket packet) {
|
||||
Utils.writeVarInt(buf, packet.getId());
|
||||
BinaryWriter writer = new BinaryWriter(buf);
|
||||
try {
|
||||
packet.write(writer);
|
||||
} catch (Exception e) {
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeFramedPacket(@NotNull ByteBuffer buffer,
|
||||
@NotNull ServerPacket serverPacket) {
|
||||
final int compressionThreshold = MinecraftServer.getCompressionThreshold();
|
||||
|
||||
// Index of the var-int containing the complete packet length
|
||||
final int packetLengthIndex = Utils.writeEmptyVarIntHeader(buffer);
|
||||
final int startIndex = buffer.position(); // Index where the content starts (after length)
|
||||
if (compressionThreshold > 0) {
|
||||
// Index of the uncompressed payload length
|
||||
final int dataLengthIndex = Utils.writeEmptyVarIntHeader(buffer);
|
||||
|
||||
// Write packet
|
||||
final int contentIndex = buffer.position();
|
||||
writePacket(buffer, serverPacket);
|
||||
final int packetSize = buffer.position() - contentIndex;
|
||||
|
||||
final int uncompressedLength = packetSize >= compressionThreshold ? packetSize : 0;
|
||||
Utils.writeVarIntHeader(buffer, dataLengthIndex, uncompressedLength);
|
||||
if (uncompressedLength > 0) {
|
||||
// Packet large enough, compress
|
||||
ByteBuffer uncompressedCopy = buffer.duplicate().position(contentIndex).limit(contentIndex + packetSize);
|
||||
buffer.position(contentIndex);
|
||||
|
||||
var deflater = COMPRESSOR.get();
|
||||
deflater.setInput(uncompressedCopy);
|
||||
deflater.finish();
|
||||
deflater.deflate(buffer);
|
||||
deflater.reset();
|
||||
}
|
||||
} else {
|
||||
// No compression, write packet id + payload
|
||||
writePacket(buffer, serverPacket);
|
||||
@NotNull ServerPacket packet,
|
||||
boolean compression) {
|
||||
if (!compression) {
|
||||
// Length + payload
|
||||
final int lengthIndex = Utils.writeEmptyVarIntHeader(buffer);
|
||||
Utils.writeVarInt(buffer, packet.getId());
|
||||
packet.write(new BinaryWriter(buffer));
|
||||
final int finalSize = buffer.position() - (lengthIndex + 3);
|
||||
Utils.writeVarIntHeader(buffer, lengthIndex, finalSize);
|
||||
return;
|
||||
}
|
||||
// Compressed format
|
||||
final int compressedIndex = Utils.writeEmptyVarIntHeader(buffer);
|
||||
final int uncompressedIndex = Utils.writeEmptyVarIntHeader(buffer);
|
||||
final int contentStart = buffer.position();
|
||||
|
||||
Utils.writeVarInt(buffer, packet.getId());
|
||||
packet.write(new BinaryWriter(buffer));
|
||||
final int packetSize = buffer.position() - contentStart;
|
||||
if (packetSize >= MinecraftServer.getCompressionThreshold()) {
|
||||
// Packet large enough, compress
|
||||
final int limitCache = buffer.limit();
|
||||
buffer.position(contentStart).limit(contentStart + packetSize);
|
||||
var uncompressedCopy = ByteBuffer.allocate(packetSize).put(buffer);
|
||||
buffer.position(contentStart).limit(limitCache);
|
||||
|
||||
var deflater = COMPRESSOR.get();
|
||||
deflater.setInput(uncompressedCopy.flip());
|
||||
deflater.finish();
|
||||
deflater.deflate(buffer);
|
||||
deflater.reset();
|
||||
|
||||
Utils.writeVarIntHeader(buffer, compressedIndex, (buffer.position() - contentStart) + 3);
|
||||
Utils.writeVarIntHeader(buffer, uncompressedIndex, packetSize);
|
||||
} else {
|
||||
Utils.writeVarIntHeader(buffer, compressedIndex, packetSize + 3);
|
||||
Utils.writeVarIntHeader(buffer, uncompressedIndex, 0);
|
||||
}
|
||||
// Total length
|
||||
final int totalPacketLength = buffer.position() - startIndex;
|
||||
Utils.writeVarIntHeader(buffer, packetLengthIndex, totalPacketLength);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -193,7 +180,7 @@ public final class PacketUtils {
|
||||
*/
|
||||
public static @NotNull ByteBuffer createFramedPacket(@NotNull ServerPacket serverPacket) {
|
||||
ByteBuffer packetBuf = ByteBuffer.allocate(2_000_000);
|
||||
writeFramedPacket(packetBuf, serverPacket);
|
||||
writeFramedPacket(packetBuf, serverPacket, MinecraftServer.getCompressionThreshold() > 0);
|
||||
return packetBuf;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user