Code/net/minecraft/network/CompressionDecoder.java

90 lines
3.3 KiB
Java
Raw Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.network;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.DecoderException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
public class CompressionDecoder extends ByteToMessageDecoder {
public static final int MAXIMUM_COMPRESSED_LENGTH = 2097152;
public static final int MAXIMUM_UNCOMPRESSED_LENGTH = 8388608;
private final Inflater inflater;
private int threshold;
private boolean validateDecompressed;
public CompressionDecoder(int p_182675_, boolean p_182676_) {
this.threshold = p_182675_;
this.validateDecompressed = p_182676_;
this.inflater = new Inflater();
}
@Override
protected void decode(ChannelHandlerContext p_129441_, ByteBuf p_129442_, List<Object> p_129443_) throws Exception {
if (p_129442_.readableBytes() != 0) {
int i = VarInt.read(p_129442_);
if (i == 0) {
p_129443_.add(p_129442_.readBytes(p_129442_.readableBytes()));
} else {
if (this.validateDecompressed) {
if (i < this.threshold) {
throw new DecoderException("Badly compressed packet - size of " + i + " is below server threshold of " + this.threshold);
}
if (i > 8388608) {
throw new DecoderException("Badly compressed packet - size of " + i + " is larger than protocol maximum of 8388608");
}
}
this.setupInflaterInput(p_129442_);
ByteBuf bytebuf = this.inflate(p_129441_, i);
this.inflater.reset();
p_129443_.add(bytebuf);
}
}
}
private void setupInflaterInput(ByteBuf p_299798_) {
ByteBuffer bytebuffer;
if (p_299798_.nioBufferCount() > 0) {
bytebuffer = p_299798_.nioBuffer();
p_299798_.skipBytes(p_299798_.readableBytes());
} else {
bytebuffer = ByteBuffer.allocateDirect(p_299798_.readableBytes());
p_299798_.readBytes(bytebuffer);
bytebuffer.flip();
}
this.inflater.setInput(bytebuffer);
}
private ByteBuf inflate(ChannelHandlerContext p_300050_, int p_298909_) throws DataFormatException {
ByteBuf bytebuf = p_300050_.alloc().directBuffer(p_298909_);
try {
ByteBuffer bytebuffer = bytebuf.internalNioBuffer(0, p_298909_);
int i = bytebuffer.position();
this.inflater.inflate(bytebuffer);
int j = bytebuffer.position() - i;
if (j != p_298909_) {
throw new DecoderException(
"Badly compressed packet - actual length of uncompressed payload " + j + " is does not match declared size " + p_298909_
);
} else {
bytebuf.writerIndex(bytebuf.writerIndex() + j);
return bytebuf;
}
} catch (Exception exception) {
bytebuf.release();
throw exception;
}
}
public void setThreshold(int p_182678_, boolean p_182679_) {
this.threshold = p_182678_;
this.validateDecompressed = p_182679_;
}
}