Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-16 21:10:30 +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:
Ursprung
3d9a166892
Commit
37a4199d43
@ -36,12 +36,13 @@ import com.velocitypowered.proxy.VelocityServer;
|
|||||||
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
import com.velocitypowered.proxy.connection.client.HandshakeSessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.client.LoginSessionHandler;
|
import com.velocitypowered.proxy.connection.client.LoginSessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.client.StatusSessionHandler;
|
import com.velocitypowered.proxy.connection.client.StatusSessionHandler;
|
||||||
|
import com.velocitypowered.proxy.network.Connections;
|
||||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherDecoder;
|
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherEncoder;
|
import com.velocitypowered.proxy.protocol.netty.MinecraftCipherEncoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftCompressDecoder;
|
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.MinecraftDecoder;
|
||||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
||||||
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
import com.velocitypowered.proxy.util.except.QuietDecoderException;
|
||||||
@ -402,8 +403,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
} else {
|
} else {
|
||||||
MinecraftCompressDecoder decoder = (MinecraftCompressDecoder) channel.pipeline()
|
MinecraftCompressDecoder decoder = (MinecraftCompressDecoder) channel.pipeline()
|
||||||
.get(COMPRESSION_DECODER);
|
.get(COMPRESSION_DECODER);
|
||||||
MinecraftCompressEncoder encoder = (MinecraftCompressEncoder) channel.pipeline()
|
MinecraftCompressorAndLengthEncoder encoder =
|
||||||
.get(COMPRESSION_ENCODER);
|
(MinecraftCompressorAndLengthEncoder) channel.pipeline().get(COMPRESSION_ENCODER);
|
||||||
if (decoder != null && encoder != null) {
|
if (decoder != null && encoder != null) {
|
||||||
decoder.setThreshold(threshold);
|
decoder.setThreshold(threshold);
|
||||||
encoder.setThreshold(threshold);
|
encoder.setThreshold(threshold);
|
||||||
@ -411,9 +412,10 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
int level = server.getConfiguration().getCompressionLevel();
|
int level = server.getConfiguration().getCompressionLevel();
|
||||||
VelocityCompressor compressor = Natives.compress.get().create(level);
|
VelocityCompressor compressor = Natives.compress.get().create(level);
|
||||||
|
|
||||||
encoder = new MinecraftCompressEncoder(threshold, compressor);
|
encoder = new MinecraftCompressorAndLengthEncoder(threshold, compressor);
|
||||||
decoder = new MinecraftCompressDecoder(threshold, compressor);
|
decoder = new MinecraftCompressDecoder(threshold, compressor);
|
||||||
|
|
||||||
|
channel.pipeline().remove(FRAME_ENCODER);
|
||||||
channel.pipeline().addBefore(MINECRAFT_DECODER, COMPRESSION_DECODER, decoder);
|
channel.pipeline().addBefore(MINECRAFT_DECODER, COMPRESSION_DECODER, decoder);
|
||||||
channel.pipeline().addBefore(MINECRAFT_ENCODER, COMPRESSION_ENCODER, encoder);
|
channel.pipeline().addBefore(MINECRAFT_ENCODER, COMPRESSION_ENCODER, encoder);
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,14 @@ import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
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 int threshold;
|
||||||
private final VelocityCompressor compressor;
|
private final VelocityCompressor compressor;
|
||||||
|
|
||||||
public MinecraftCompressEncoder(int threshold, VelocityCompressor compressor) {
|
public MinecraftCompressorAndLengthEncoder(int threshold, VelocityCompressor compressor) {
|
||||||
this.threshold = threshold;
|
this.threshold = threshold;
|
||||||
this.compressor = compressor;
|
this.compressor = compressor;
|
||||||
}
|
}
|
||||||
@ -39,16 +40,31 @@ public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> {
|
|||||||
int uncompressed = msg.readableBytes();
|
int uncompressed = msg.readableBytes();
|
||||||
if (uncompressed < threshold) {
|
if (uncompressed < threshold) {
|
||||||
// Under the threshold, there is nothing to do.
|
// Under the threshold, there is nothing to do.
|
||||||
|
ProtocolUtils.writeVarInt(out, uncompressed + 1);
|
||||||
ProtocolUtils.writeVarInt(out, 0);
|
ProtocolUtils.writeVarInt(out, 0);
|
||||||
out.writeBytes(msg);
|
out.writeBytes(msg);
|
||||||
} else {
|
} 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);
|
ByteBuf compatibleIn = MoreByteBufUtils.ensureCompatible(ctx.alloc(), compressor, msg);
|
||||||
try {
|
try {
|
||||||
compressor.deflate(compatibleIn, out);
|
compressor.deflate(compatibleIn, tmpBuf);
|
||||||
} finally {
|
} finally {
|
||||||
compatibleIn.release();
|
compatibleIn.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProtocolUtils.writeVarInt(out, tmpBuf.readableBytes());
|
||||||
|
out.writeBytes(tmpBuf);
|
||||||
|
} finally {
|
||||||
|
tmpBuf.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren