package net.scapeemulator.game.net.auto; import io.netty.buffer.ByteBuf; import io.netty.buffer.MessageBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import java.io.IOException; import net.scapeemulator.util.Base37Utils; import net.scapeemulator.util.ByteBufUtils; import net.scapeemulator.util.crypto.RsaKeySet; public final class AutoLoginDecoder extends ByteToMessageDecoder { public enum State { READ_SIZE, READ_PAYLOAD; } private State state = State.READ_SIZE; private int size; @Override public void decode(ChannelHandlerContext ctx, ByteBuf buf, MessageBuf<Object> out) throws IOException { if (state == State.READ_SIZE) { if (!buf.isReadable()) return; state = State.READ_PAYLOAD; size = buf.readUnsignedByte(); } if (state == State.READ_PAYLOAD) { if (buf.readableBytes() < size) return; int encryptedSize = buf.readUnsignedByte(); if (encryptedSize != size - 1) throw new IOException("Encrypted size mismatch."); ByteBuf secureBuffer = ByteBufUtils.rsa(buf.readBytes(encryptedSize), RsaKeySet.MODULUS, RsaKeySet.PRIVATE_KEY); int encryptedType = secureBuffer.readUnsignedByte(); if (encryptedType != 10) throw new IOException("Invalid encrypted block type."); secureBuffer.readUnsignedShort(); int version = secureBuffer.readUnsignedShort(); String username = Base37Utils.decodeBase37(secureBuffer.readLong()); secureBuffer.readInt(); String password = ByteBufUtils.readString(secureBuffer); secureBuffer.readInt(); out.add(new AutoLoginRequest(version, username, password)); } } }