Files
AquaDX/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.kt
2024-03-27 00:52:21 -04:00

66 lines
2.0 KiB
Kotlin

package icu.samnyan.aqua.sega.aimedb
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.ByteToMessageDecoder
import org.slf4j.LoggerFactory
/**
* A new decoder object will be created each time a new request comes in
*/
class AimeDbDecoder : ByteToMessageDecoder() {
companion object {
val logger = LoggerFactory.getLogger(AimeDbDecoder::class.java)
}
var length = 0
/**
* Decrypt the incoming request including frame management
* @param ctx ChannelHandlerContext
* @param input ByteBuf in
* @param out List<Object>
*/
override fun decode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList<Any>) {
if (input.readableBytes() < 16) return
if (length == 0) length = getLength(input)
if (length < 0 || input.readableBytes() < length) return
// Create a byte array to store the encrypted data
val d = input.readBytes(length)
val result = AimeDbEncryption.decrypt(d)
d.release()
val resultMap = mapOf(
"type" to result.getShortLE(0x04).toInt(),
"data" to result
)
logger.debug("AimeDB Request Type: " + resultMap["type"])
out.add(resultMap)
}
/**
* Get the length from request
*
* @param input the request
* @return int the length of this request
*/
private fun getLength(input: ByteBuf): Int = try {
val currentPos = input.readerIndex()
val result = AimeDbEncryption.decrypt(input)
// Check the header
val header = result.getByte(0).toInt()
assert(header == 0x3e) { "AimeDB: Invalid header $header" }
// Read the length from offset 6
result.getShortLE(currentPos + 6).toInt()
} catch (e: Exception) {
logger.info("AimeDB: Invalid request received")
logger.debug("AimeDB: Invalid request received: ${input.toString(Charsets.UTF_8)}")
-1
}
}