RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
GamePacketDecoder.java
1package com.osroyale.net.codec.game;
2
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;
14
15import java.util.List;
16
58
59 * The class that reads packets from the client into {@link GamePacket}'s.
60 *
61 * @author nshusa
62 */
63public final class GamePacketDecoder extends ByteToMessageDecoder {
64
68 private static final Logger logger = LogManager.getLogger(GamePacketDecoder.class);
69
73 private final IsaacCipher decryptor;
74
78 private int opcode;
79
83 private int size;
84
88 private PacketType type = PacketType.EMPTY;
89
93 private State state = State.OPCODE;
94
95 public GamePacketDecoder(IsaacCipher decryptor) {
96 this.decryptor = decryptor;
97 }
98
99 @Override
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) {
104 decodeSize(in);
105 } else {
106 decodePayload(in, out);
107 }
108 }
109
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) {
127 state = State.SIZE;
128 } else {
129 throw new IllegalStateException(String.format("Illegal packet type=%s", type.name()));
130 }
131 }
132 }
133
139 private void decodeSize(ByteBuf in) {
140 if (in.isReadable()) {
141 size = in.readUnsignedByte();
142 if (size != 0) {
143 state = State.PAYLOAD;
144 }
145 }
146 }
147
154 private void decodePayload(ByteBuf in, List<Object> out) {
155 if (in.isReadable(size)) {
156 final PacketListener listener = PacketRepository.lookupListener(opcode);
157
158 if (listener != null) {
159 final ByteBuf payload = in.readBytes(size);
160 final GamePacket packet = new GamePacket(opcode, type, payload);
161 packet.retain();
162 out.add(packet);
163 } else {
164 in.skipBytes(size);
165 logger.info("No listener for client -> server packet={}", opcode);
166 }
167
168 state = State.OPCODE;
169 }
170 }
171
175private enum State {
176 OPCODE,
177 SIZE,
178 PAYLOAD
179 }
180
181}