Netty WIP

Implementing ByteBuf backed In/OutPacket first in a separate branch
This commit is contained in:
P0nk
2021-06-15 22:12:23 +02:00
parent 4dc0935391
commit 23bad12f8c
14 changed files with 301 additions and 66 deletions

View File

@@ -24,6 +24,7 @@ package net;
import client.MapleClient;
import config.YamlConfig;
import constants.net.ServerConstants;
import net.netty.InitializationVector;
import net.server.Server;
import net.server.audit.LockCollector;
import net.server.audit.locks.MonitoredLockType;
@@ -130,10 +131,8 @@ public class MapleServerHandler extends IoHandlerAdapter {
FilePrinter.print(FilePrinter.SESSION, "IoSession with " + session.getRemoteAddress() + " opened on " + sdf.format(Calendar.getInstance().getTime()), false);
}
byte[] ivRecv = {70, 114, 122, 82};
byte[] ivSend = {82, 48, 120, 115};
ivRecv[3] = (byte) (Math.random() * 255);
ivSend[3] = (byte) (Math.random() * 255);
final InitializationVector ivSend = InitializationVector.generateSend();
final InitializationVector ivRecv = InitializationVector.generateReceive();
MapleAESOFB sendCypher = new MapleAESOFB(ivSend, (short) (0xFFFF - ServerConstants.VERSION));
MapleAESOFB recvCypher = new MapleAESOFB(ivRecv, ServerConstants.VERSION);
MapleClient client = new MapleClient(sendCypher, recvCypher, session);

View File

@@ -0,0 +1,28 @@
package net.netty;
import constants.net.ServerConstants;
import tools.MapleAESOFB;
public class ClientCyphers {
private final MapleAESOFB send;
private final MapleAESOFB receive;
private ClientCyphers(MapleAESOFB send, MapleAESOFB receive) {
this.send = send;
this.receive = receive;
}
public static ClientCyphers generateNew() {
MapleAESOFB send = new MapleAESOFB(InitializationVector.generateSend(), ServerConstants.VERSION);
MapleAESOFB receive = new MapleAESOFB(InitializationVector.generateReceive(), ServerConstants.VERSION);
return new ClientCyphers(send, receive);
}
public MapleAESOFB getSendCypher() {
return send;
}
public MapleAESOFB getReceiveCypher() {
return receive;
}
}

View File

@@ -0,0 +1,20 @@
package net.netty;
import client.MapleClient;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ClientInitializer extends ChannelInitializer<SocketChannel> {
private static final Logger log = LoggerFactory.getLogger(ClientInitializer.class);
@Override
public void initChannel(SocketChannel socketChannel) {
final String clientIp = socketChannel.remoteAddress().getHostName();
log.debug("Client initiated new connection from: {}", clientIp);
MapleClient client = new MapleClient(ClientCyphers.generateNew());
socketChannel.pipeline().addLast("MapleClient", client);
}
}

View File

@@ -0,0 +1,4 @@
package net.netty;
public class InPacket {
}

View File

@@ -0,0 +1,27 @@
package net.netty;
public class InitializationVector {
private final byte[] bytes;
private InitializationVector(byte[] bytes) {
this.bytes = bytes;
}
public byte[] getBytes() {
return bytes;
}
public static InitializationVector generateSend() {
byte[] ivSend = {82, 48, 120, getRandomByte()};
return new InitializationVector(ivSend);
}
public static InitializationVector generateReceive() {
byte[] ivRecv = {70, 114, 122, getRandomByte()};
return new InitializationVector(ivRecv);
}
private static byte getRandomByte() {
return (byte) (Math.random() * 255);
}
}

View File

@@ -0,0 +1,14 @@
package net.netty;
public class InvalidPacketHeaderException extends RuntimeException {
private final int header;
public InvalidPacketHeaderException(String message, int header) {
super(message);
this.header = header;
}
public int getHeader() {
return header;
}
}

View File

@@ -0,0 +1,5 @@
package net.netty;
public interface OutPacket {
byte[] getBytes();
}

View File

@@ -0,0 +1,48 @@
package net.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder;
import net.mina.MapleCustomEncryption;
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.checkPacket(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(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;
}
}

View File

@@ -0,0 +1,28 @@
package net.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import net.mina.MapleCustomEncryption;
import tools.MapleAESOFB;
public class PacketEncoder extends MessageToByteEncoder<OutPacket> {
private final MapleAESOFB sendCypher;
public PacketEncoder(MapleAESOFB sendCypher) {
this.sendCypher = sendCypher;
}
@Override
protected void encode(ChannelHandlerContext ctx, OutPacket in, ByteBuf out) {
byte[] packet = in.getBytes();
out.writeBytes(getEncodedHeader(packet.length));
MapleCustomEncryption.encryptData(packet);
sendCypher.crypt(packet);
out.writeBytes(packet);
}
private byte[] getEncodedHeader(int length) {
return sendCypher.getPacketHeader(length);
}
}