blob: 8217985c00c8fbcc8aaf2dd15875f9a4263ea250 [file] [log] [blame] [raw]
package net.glowstone.net.pipeline;
import com.flowpowered.network.Codec;
import com.flowpowered.network.Codec.CodecRegistration;
import com.flowpowered.network.Message;
import com.flowpowered.network.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 net.glowstone.i18n.ConsoleMessages;
import net.glowstone.net.protocol.GlowProtocol;
import java.util.List;
/**
* Experimental pipeline component.
*/
public final class CodecsHandler extends MessageToMessageCodec<ByteBuf, Message> {
private final GlowProtocol protocol;
public CodecsHandler(GlowProtocol protocol) {
this.protocol = protocol;
}
@Override
protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> out)
throws Exception {
// find codec
Class<? extends Message> clazz = msg.getClass();
CodecRegistration reg = protocol.getCodecRegistration(clazz);
if (reg == null) {
throw new EncoderException("Unknown message type: " + clazz + ".");
}
// write header
ByteBuf headerBuf = ctx.alloc().buffer(8);
ByteBufUtils.writeVarInt(headerBuf, reg.getOpcode());
// write body
ByteBuf messageBuf = ctx.alloc().buffer();
messageBuf = reg.getCodec().encode(messageBuf, msg);
out.add(Unpooled.wrappedBuffer(headerBuf, messageBuf));
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)
throws Exception {
// find codec and read header
Codec<?> codec = protocol.newReadHeader(msg);
// read body
Message decoded = codec.decode(msg);
if (msg.readableBytes() > 0) {
ConsoleMessages.Warn.Net.MESSAGE_TOO_LONG.log(msg.readableBytes(), decoded);
}
out.add(decoded);
}
}