CompressionDecoder.java

net.minecraft.network.CompressionDecoder

信息

  • 全限定名:net.minecraft.network.CompressionDecoder
  • 类型:public class
  • 包:net.minecraft.network
  • 源码路径:src/main/java/net/minecraft/network/CompressionDecoder.java
  • 起始行号:L12
  • 继承:ByteToMessageDecoder
  • 职责:

    TODO

字段/常量

  • MAXIMUM_COMPRESSED_LENGTH

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L13
    • 说明:

      TODO

  • MAXIMUM_UNCOMPRESSED_LENGTH

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L14
    • 说明:

      TODO

  • inflater

    • 类型: Inflater
    • 修饰符: private final
    • 源码定位: L15
    • 说明:

      TODO

  • threshold

    • 类型: int
    • 修饰符: private
    • 源码定位: L16
    • 说明:

      TODO

  • validateDecompressed

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L17
    • 说明:

      TODO

内部类/嵌套类型

构造器

public CompressionDecoder(int threshold, boolean validateDecompressed) @ L19

  • 构造器名:CompressionDecoder
  • 源码定位:L19
  • 修饰符:public

参数:

  • threshold: int
  • validateDecompressed: boolean

说明:

TODO

方法

下面的方法块按源码顺序生成。

protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) @ L25

  • 方法名:decode
  • 源码定位:L25
  • 返回类型:void
  • 修饰符:protected

参数:

  • ctx: ChannelHandlerContext
  • in: ByteBuf
  • out: List

    说明:

    TODO

    private void setupInflaterInput(ByteBuf in) @ L48

    • 方法名:setupInflaterInput
    • 源码定位:L48
    • 返回类型:void
    • 修饰符:private

    参数:

    • in: ByteBuf

    说明:

    TODO

    private ByteBuf inflate(ChannelHandlerContext ctx, int uncompressedLength) @ L62

    • 方法名:inflate
    • 源码定位:L62
    • 返回类型:ByteBuf
    • 修饰符:private

    参数:

    • ctx: ChannelHandlerContext
    • uncompressedLength: int

    说明:

    TODO

    public void setThreshold(int threshold, boolean validateDecompressed) @ L87

    • 方法名:setThreshold
    • 源码定位:L87
    • 返回类型:void
    • 修饰符:public

    参数:

    • threshold: int
    • validateDecompressed: boolean

    说明:

    TODO

    代码

    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 threshold, boolean validateDecompressed) {
            this.threshold = threshold;
            this.validateDecompressed = validateDecompressed;
            this.inflater = new Inflater();
        }
     
        @Override
        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()));
            } else {
                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 > 8388608) {
                        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
                    );
                } else {
                    output.writerIndex(output.writerIndex() + actualUncompressedLength);
                    return output;
                }
            } catch (Exception var7) {
                output.release();
                throw var7;
            }
        }
     
        public void setThreshold(int threshold, boolean validateDecompressed) {
            this.threshold = threshold;
            this.validateDecompressed = validateDecompressed;
        }
    }

    引用的其他类

    • VarInt
      • 引用位置: 方法调用
      • 关联成员: VarInt.read()