1package com.osroyale.net.codec.game;
3import com.osroyale.net.codec.IsaacCipher;
4import com.osroyale.net.packet.GamePacket;
5import com.osroyale.net.packet.PacketListener;
6import com.osroyale.net.packet.PacketRepository;
7import com.osroyale.net.packet.PacketType;
8import io.netty.buffer.ByteBuf;
9import io.netty.buffer.Unpooled;
10import io.netty.channel.ChannelHandlerContext;
11import io.netty.handler.codec.ByteToMessageDecoder;
12import org.apache.logging.log4j.LogManager;
13import org.apache.logging.log4j.Logger;
59 * The
class that reads packets from the client into {@link GamePacket}
's.
63public final class GamePacketDecoder extends ByteToMessageDecoder {
68 private static final Logger logger = LogManager.getLogger(GamePacketDecoder.class);
73 private final IsaacCipher decryptor;
88 private PacketType type = PacketType.EMPTY;
93 private State state = State.OPCODE;
95 public GamePacketDecoder(IsaacCipher decryptor) {
96 this.decryptor = decryptor;
100 protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
101 if (state == State.OPCODE) {
102 decodeOpcode(in, out);
103 } else if (state == State.SIZE) {
106 decodePayload(in, out);
116 private void decodeOpcode(ByteBuf in, List<Object> out) {
117 if (in.isReadable()) {
118 opcode = (in.readByte() - decryptor.getKey()) & 0xFF;
119 type = PacketRepository.lookupType(opcode);
120 size = PacketRepository.lookupSize(opcode);
121 if (type == PacketType.EMPTY) {
122 state = State.OPCODE;
123 out.add(new GamePacket(opcode, type, Unpooled.EMPTY_BUFFER));
124 } else if (type == PacketType.FIXED) {
125 state = State.PAYLOAD;
126 } else if (type == PacketType.VAR_BYTE || type == PacketType.VAR_SHORT) {
129 throw new IllegalStateException(String.format("Illegal packet type=%s", type.name()));
139 private void decodeSize(ByteBuf in) {
140 if (in.isReadable()) {
141 size = in.readUnsignedByte();
143 state = State.PAYLOAD;
154 private void decodePayload(ByteBuf in, List<Object> out) {
155 if (in.isReadable(size)) {
156 final PacketListener listener = PacketRepository.lookupListener(opcode);
158 if (listener != null) {
159 final ByteBuf payload = in.readBytes(size);
160 final GamePacket packet = new GamePacket(opcode, type, payload);
165 logger.info("No listener for client -> server packet={}", opcode);
168 state = State.OPCODE;