RuneHive-Game
Loading...
Searching...
No Matches
GamePacketDecoder.java
Go to the documentation of this file.
1package com.runehive.net.codec.game;
2
3import com.runehive.net.codec.IsaacCipher;
4import com.runehive.net.packet.GamePacket;
5import com.runehive.net.packet.PacketListener;
6import com.runehive.net.packet.PacketRepository;
7import com.runehive.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
17/**
18 * The class that reads packets from the client into {@link GamePacket}'s.
19 *
20 * @author nshusa
21 */
22public final class GamePacketDecoder extends ByteToMessageDecoder {
23
24 /**
25 * The single logger for this class.
26 */
27 private static final Logger logger = LogManager.getLogger(GamePacketDecoder.class);
28
29 /**
30 * The isaac random used to decrypt a packets opcode.
31 */
32 private final IsaacCipher decryptor;
33
34 /**
35 * The current packet opcode.
36 */
37 private int opcode;
38
39 /**
40 * The current packet size.
41 */
42 private int size;
43
44 /**
45 * The current packet type.
46 */
48
49 /**
50 * The current state of this class.
51 */
53
55 this.decryptor = decryptor;
56 }
57
58 @Override
59 protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
60 if (state == State.OPCODE) {
61 decodeOpcode(in, out);
62 } else if (state == State.SIZE) {
63 decodeSize(in);
64 } else {
65 decodePayload(in, out);
66 }
67 }
68
69 /**
70 * Decodes the packet identifier.
71 *
72 * @param in The payload from the client.
73 * @param out The collection of upstream messages.
74 */
75 private void decodeOpcode(ByteBuf in, List<Object> out) {
76 if (in.isReadable()) {
77 opcode = (in.readByte() - decryptor.getKey()) & 0xFF;
80 if (type == PacketType.EMPTY) {
82 out.add(new GamePacket(opcode, type, Unpooled.EMPTY_BUFFER));
83 } else if (type == PacketType.FIXED) {
85 } else if (type == PacketType.VAR_BYTE || type == PacketType.VAR_SHORT) {
87 } else {
88 throw new IllegalStateException(String.format("Illegal packet type=%s", type.name()));
89 }
90 }
91 }
92
93 /**
94 * Decodes the packets size.
95 *
96 * @param in The payload from the client.
97 */
98 private void decodeSize(ByteBuf in) {
99 if (in.isReadable()) {
100 size = in.readUnsignedByte();
101 if (size != 0) {
103 }
104 }
105 }
106
107 /**
108 * Decodes the packets payload.
109 *
110 * @param in The payload from the client.
111 * @param out The collection of upstream messages.
112 */
113 private void decodePayload(ByteBuf in, List<Object> out) {
114 if (in.isReadable(size)) {
116
117 if (listener != null) {
118 final ByteBuf payload = in.readBytes(size);
119 final GamePacket packet = new GamePacket(opcode, type, payload);
120 packet.retain();
121 out.add(packet);
122 } else {
123 in.skipBytes(size);
124 logger.info("No listener for client -> server packet={}", opcode);
125 }
126
128 }
129 }
130
131 /**
132 * Represents the current state of this class.
133 */
134 private enum State {
138 }
139
140}
An implementation of an ISAAC cipher.
PacketType type
The current packet type.
void decode(ChannelHandlerContext ctx, ByteBuf in, List< Object > out)
void decodePayload(ByteBuf in, List< Object > out)
Decodes the packets payload.
final IsaacCipher decryptor
The isaac random used to decrypt a packets opcode.
static final Logger logger
The single logger for this class.
State state
The current state of this class.
void decodeSize(ByteBuf in)
Decodes the packets size.
void decodeOpcode(ByteBuf in, List< Object > out)
Decodes the packet identifier.
Represents a single game packet.
The repository that stores packets sizes and listeners for how to execute the packets.
static PacketListener lookupListener(final int opcode)
Looks up the listener for this packet.
static PacketType lookupType(int opcode)
The method that looks up the packets type.
static int lookupSize(int opcode)
Looks up the reference size of a packet.
Represents the current state of this class.
Represents a type of packet.
VAR_SHORT
A variable packet where the size is indicated by a short.
FIXED
A fixed size packet where the size never changes.
VAR_BYTE
A variable packet where the size is indicated by a byte.