3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-12-25 15:50:19 +01:00

Combine VarInt prefix encoding with compression

This saves us a memory copy in the common "there is no need to compress this packet" case.
Dieser Commit ist enthalten in:
Andrew Steinborn 2021-05-06 19:56:45 -04:00
Ursprung 3d9a166892
Commit 37a4199d43
2 geänderte Dateien mit 26 neuen und 8 gelöschten Zeilen

Datei anzeigen

@ -36,12 +36,13 @@ import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
import com.velocitypowered.proxy.connection.client.LoginSessionHandler;
import com.velocitypowered.proxy.connection.client.StatusSessionHandler;
import com.velocitypowered.proxy.network.Connections;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.StateRegistry;
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherDecoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherEncoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressDecoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressEncoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressorAndLengthEncoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
import com.velocitypowered.proxy.util.except.QuietDecoderException;
@ -402,8 +403,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
} else {
MinecraftCompressDecoder decoder = (MinecraftCompressDecoder) channel.pipeline()
.get(COMPRESSION_DECODER);
MinecraftCompressEncoder encoder = (MinecraftCompressEncoder) channel.pipeline()
.get(COMPRESSION_ENCODER);
MinecraftCompressorAndLengthEncoder encoder =
(MinecraftCompressorAndLengthEncoder) channel.pipeline().get(COMPRESSION_ENCODER);
if (decoder != null && encoder != null) {
decoder.setThreshold(threshold);
encoder.setThreshold(threshold);
@ -411,9 +412,10 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
int level = server.getConfiguration().getCompressionLevel();
VelocityCompressor compressor = Natives.compress.get().create(level);
encoder = new MinecraftCompressEncoder(threshold, compressor);
encoder = new MinecraftCompressorAndLengthEncoder(threshold, compressor);
decoder = new MinecraftCompressDecoder(threshold, compressor);
channel.pipeline().remove(FRAME_ENCODER);
channel.pipeline().addBefore(MINECRAFT_DECODER, COMPRESSION_DECODER, decoder);
channel.pipeline().addBefore(MINECRAFT_ENCODER, COMPRESSION_ENCODER, encoder);
}

Datei anzeigen

@ -23,13 +23,14 @@ import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import java.util.zip.DataFormatException;
public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> {
public class MinecraftCompressorAndLengthEncoder extends MessageToByteEncoder<ByteBuf> {
private int threshold;
private final VelocityCompressor compressor;
public MinecraftCompressEncoder(int threshold, VelocityCompressor compressor) {
public MinecraftCompressorAndLengthEncoder(int threshold, VelocityCompressor compressor) {
this.threshold = threshold;
this.compressor = compressor;
}
@ -39,16 +40,31 @@ public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> {
int uncompressed = msg.readableBytes();
if (uncompressed < threshold) {
// Under the threshold, there is nothing to do.
ProtocolUtils.writeVarInt(out, uncompressed + 1);
ProtocolUtils.writeVarInt(out, 0);
out.writeBytes(msg);
} else {
ProtocolUtils.writeVarInt(out, uncompressed);
handleCompressed(ctx, msg, out);
}
}
private void handleCompressed(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out)
throws DataFormatException {
int uncompressed = msg.readableBytes();
ByteBuf tmpBuf = MoreByteBufUtils.preferredBuffer(ctx.alloc(), compressor, uncompressed - 1);
try {
ProtocolUtils.writeVarInt(tmpBuf, uncompressed);
ByteBuf compatibleIn = MoreByteBufUtils.ensureCompatible(ctx.alloc(), compressor, msg);
try {
compressor.deflate(compatibleIn, out);
compressor.deflate(compatibleIn, tmpBuf);
} finally {
compatibleIn.release();
}
ProtocolUtils.writeVarInt(out, tmpBuf.readableBytes());
out.writeBytes(tmpBuf);
} finally {
tmpBuf.release();
}
}