package com.captainbern.minecraft.net.pipeline;
import com.captainbern.minecraft.net.codec.Codec;
import com.captainbern.minecraft.net.codec.CodecRegistrationEntry;
import com.captainbern.minecraft.net.packet.Packet;
import com.captainbern.minecraft.net.protocol.MinecraftProtocol;
import com.captainbern.minecraft.net.protocol.Side;
import com.captainbern.minecraft.net.util.ByteBufUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.EncoderException;
import io.netty.handler.codec.MessageToMessageCodec;
import java.util.List;
@SuppressWarnings("unchecked")
public class CodecHandler extends MessageToMessageCodec<ByteBuf, Packet> {
private final NetworkHandler networkHandler;
private final Side side;
public CodecHandler(NetworkHandler networkHandler) {
this.networkHandler = networkHandler;
this.side = this.networkHandler.getConnectionHandler().getSide();
}
@Override
protected void encode(ChannelHandlerContext channelHandlerContext, Packet packet, List<Object> list) throws Exception {
Class<? extends Packet> packetClass = packet.getClass();
CodecRegistrationEntry registrationEntry = this.networkHandler.getSession().getProtocol().getCodecRegistration(this.side, packetClass);
if (registrationEntry == null) {
throw new EncoderException("Failed to find a CodecRegistrationEntry for packet: " + packetClass.getName());
}
ByteBuf header = channelHandlerContext.alloc().buffer(8);
ByteBufUtils.writeVarInt(header, registrationEntry.getOpcode());
ByteBuf contents = channelHandlerContext.alloc().buffer();
contents = registrationEntry.getCodec().encode(contents, packet);
list.add(Unpooled.wrappedBuffer(header, contents));
}
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
Codec<?> codec = this.networkHandler.getSession().getProtocol().readHeader(this.side.opposite(), byteBuf);
Packet decoded = codec.decode(byteBuf);
if (byteBuf.readableBytes() > 0) {
MinecraftProtocol.getLogger().warn("Leftover bytes (" + byteBuf.readableBytes() + ") after decoding: \'" + decoded + "\'. (Protocol: \'" + this.networkHandler.getSession().getProtocol().getId() + "\')");
}
list.add(decoded);
}
}