94 lines
3.5 KiB
Java
94 lines
3.5 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* io.netty.buffer.ByteBuf
|
|
* io.netty.channel.ChannelHandlerContext
|
|
* io.netty.handler.codec.ByteToMessageDecoder
|
|
* io.netty.handler.codec.DecoderException
|
|
*/
|
|
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;
|
|
import net.minecraft.network.VarInt;
|
|
|
|
public class CompressionDecoder
|
|
extends ByteToMessageDecoder {
|
|
public static final int MAXIMUM_COMPRESSED_LENGTH = 0x200000;
|
|
public static final int MAXIMUM_UNCOMPRESSED_LENGTH = 0x800000;
|
|
private final Inflater inflater;
|
|
private int threshold;
|
|
private boolean validateDecompressed;
|
|
|
|
public CompressionDecoder(int threshold, boolean validateDecompressed) {
|
|
this.threshold = threshold;
|
|
this.validateDecompressed = validateDecompressed;
|
|
this.inflater = new Inflater();
|
|
}
|
|
|
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
|
int uncompressedLength = VarInt.read(in);
|
|
if (uncompressedLength == 0) {
|
|
out.add(in.readBytes(in.readableBytes()));
|
|
return;
|
|
}
|
|
if (this.validateDecompressed) {
|
|
if (uncompressedLength < this.threshold) {
|
|
throw new DecoderException("Badly compressed packet - size of " + uncompressedLength + " is below server threshold of " + this.threshold);
|
|
}
|
|
if (uncompressedLength > 0x800000) {
|
|
throw new DecoderException("Badly compressed packet - size of " + uncompressedLength + " is larger than protocol maximum of 8388608");
|
|
}
|
|
}
|
|
this.setupInflaterInput(in);
|
|
ByteBuf output = this.inflate(ctx, uncompressedLength);
|
|
this.inflater.reset();
|
|
out.add(output);
|
|
}
|
|
|
|
private void setupInflaterInput(ByteBuf in) {
|
|
ByteBuffer input;
|
|
if (in.nioBufferCount() > 0) {
|
|
input = in.nioBuffer();
|
|
in.skipBytes(in.readableBytes());
|
|
} else {
|
|
input = ByteBuffer.allocateDirect(in.readableBytes());
|
|
in.readBytes(input);
|
|
input.flip();
|
|
}
|
|
this.inflater.setInput(input);
|
|
}
|
|
|
|
private ByteBuf inflate(ChannelHandlerContext ctx, int uncompressedLength) throws DataFormatException {
|
|
ByteBuf output = ctx.alloc().directBuffer(uncompressedLength);
|
|
try {
|
|
ByteBuffer nioBuffer = output.internalNioBuffer(0, uncompressedLength);
|
|
int pos = nioBuffer.position();
|
|
this.inflater.inflate(nioBuffer);
|
|
int actualUncompressedLength = nioBuffer.position() - pos;
|
|
if (actualUncompressedLength != uncompressedLength) {
|
|
throw new DecoderException("Badly compressed packet - actual length of uncompressed payload " + actualUncompressedLength + " is does not match declared size " + uncompressedLength);
|
|
}
|
|
output.writerIndex(output.writerIndex() + actualUncompressedLength);
|
|
return output;
|
|
}
|
|
catch (Exception e) {
|
|
output.release();
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
public void setThreshold(int threshold, boolean validateDecompressed) {
|
|
this.threshold = threshold;
|
|
this.validateDecompressed = validateDecompressed;
|
|
}
|
|
}
|
|
|