minecraft-src/net/minecraft/network/Varint21FrameDecoder.java
2025-07-04 01:41:11 +03:00

64 lines
1.7 KiB
Java

package net.minecraft.network;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.CorruptedFrameException;
import java.util.List;
import org.jetbrains.annotations.Nullable;
/**
* Counterpart to {@link Varint21LengthFieldPrepender}. Decodes each frame ("packet") by first reading its length and then its data.
*/
public class Varint21FrameDecoder extends ByteToMessageDecoder {
private static final int MAX_VARINT21_BYTES = 3;
private final ByteBuf helperBuf = Unpooled.directBuffer(3);
@Nullable
private final BandwidthDebugMonitor monitor;
public Varint21FrameDecoder(@Nullable BandwidthDebugMonitor monitor) {
this.monitor = monitor;
}
@Override
protected void handlerRemoved0(ChannelHandlerContext channelHandlerContext) {
this.helperBuf.release();
}
private static boolean copyVarint(ByteBuf in, ByteBuf out) {
for (int i = 0; i < 3; i++) {
if (!in.isReadable()) {
return false;
}
byte b = in.readByte();
out.writeByte(b);
if (!VarInt.hasContinuationBit(b)) {
return true;
}
}
throw new CorruptedFrameException("length wider than 21-bit");
}
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) {
byteBuf.markReaderIndex();
this.helperBuf.clear();
if (!copyVarint(byteBuf, this.helperBuf)) {
byteBuf.resetReaderIndex();
} else {
int i = VarInt.read(this.helperBuf);
if (byteBuf.readableBytes() < i) {
byteBuf.resetReaderIndex();
} else {
if (this.monitor != null) {
this.monitor.onReceive(i + VarInt.getByteSize(i));
}
list.add(byteBuf.readBytes(i));
}
}
}
}