Netty WIP
Implementing ByteBuf backed In/OutPacket first in a separate branch
This commit is contained in:
@@ -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);
|
||||
|
||||
28
src/main/java/net/netty/ClientCyphers.java
Normal file
28
src/main/java/net/netty/ClientCyphers.java
Normal 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;
|
||||
}
|
||||
}
|
||||
20
src/main/java/net/netty/ClientInitializer.java
Normal file
20
src/main/java/net/netty/ClientInitializer.java
Normal 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);
|
||||
}
|
||||
}
|
||||
4
src/main/java/net/netty/InPacket.java
Normal file
4
src/main/java/net/netty/InPacket.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package net.netty;
|
||||
|
||||
public class InPacket {
|
||||
}
|
||||
27
src/main/java/net/netty/InitializationVector.java
Normal file
27
src/main/java/net/netty/InitializationVector.java
Normal 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);
|
||||
}
|
||||
}
|
||||
14
src/main/java/net/netty/InvalidPacketHeaderException.java
Normal file
14
src/main/java/net/netty/InvalidPacketHeaderException.java
Normal 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;
|
||||
}
|
||||
}
|
||||
5
src/main/java/net/netty/OutPacket.java
Normal file
5
src/main/java/net/netty/OutPacket.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package net.netty;
|
||||
|
||||
public interface OutPacket {
|
||||
byte[] getBytes();
|
||||
}
|
||||
48
src/main/java/net/netty/PacketDecoder.java
Normal file
48
src/main/java/net/netty/PacketDecoder.java
Normal 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;
|
||||
}
|
||||
}
|
||||
28
src/main/java/net/netty/PacketEncoder.java
Normal file
28
src/main/java/net/netty/PacketEncoder.java
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user