Split into 1 LoginServer and 1 ChannelServer per channel. There is still a lot of cleanup and refactoring to be done. Currently, the reliance on IoSession holding client state is the most pressing issue to be addressed.
51 lines
1.6 KiB
Java
51 lines
1.6 KiB
Java
package net.netty;
|
|
|
|
import io.netty.buffer.ByteBuf;
|
|
import io.netty.buffer.Unpooled;
|
|
import io.netty.channel.ChannelHandlerContext;
|
|
import io.netty.handler.codec.ReplayingDecoder;
|
|
import net.mina.MapleCustomEncryption;
|
|
import net.packet.ByteBufInPacket;
|
|
import tools.MapleAESOFB;
|
|
|
|
import java.util.List;
|
|
|
|
public class PacketDecoder extends ReplayingDecoder<Void> {
|
|
private final MapleAESOFB receiveCypher;
|
|
|
|
public PacketDecoder(MapleAESOFB receiveCypher) {
|
|
this.receiveCypher = receiveCypher;
|
|
}
|
|
|
|
@Override
|
|
protected void decode(ChannelHandlerContext context, ByteBuf in, List<Object> out) {
|
|
final int header = in.readInt();
|
|
|
|
if (!receiveCypher.isValidHeader(header)) {
|
|
throw new InvalidPacketHeaderException("Attempted to decode a packet with an invalid header", header);
|
|
}
|
|
|
|
int packetLength = decodePacketLength(header);
|
|
byte[] packet = new byte[packetLength];
|
|
in.readBytes(packet);
|
|
receiveCypher.crypt(packet);
|
|
MapleCustomEncryption.decryptData(packet);
|
|
out.add(new ByteBufInPacket(Unpooled.wrappedBuffer(packet)));
|
|
// TODO conditionally log the packet
|
|
}
|
|
|
|
/**
|
|
* @param header Packet header - the first 4 bytes of the packet
|
|
* @return Packet size in bytes
|
|
*/
|
|
private static int decodePacketLength(byte[] header) {
|
|
return (((header[1] ^ header[3]) & 0xFF) << 8) | ((header[0] ^ header[2]) & 0xFF);
|
|
}
|
|
|
|
private static int decodePacketLength(int header) {
|
|
int length = ((header >>> 16) ^ (header & 0xFFFF));
|
|
length = ((length << 8) & 0xFF00) | ((length >>> 8) & 0xFF);
|
|
return length;
|
|
}
|
|
}
|