mirror of https://github.com/hykilpikonna/AquaDX
[O] Refactor AimeDB
parent
30a7fa7ead
commit
8f250e755e
|
@ -0,0 +1 @@
|
||||||
|
package icu.samnyan.aqua.sega.aimedb
|
|
@ -1,6 +1,5 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb
|
package icu.samnyan.aqua.sega.aimedb
|
||||||
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.exception.InvalidRequestException
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.Encryption
|
import icu.samnyan.aqua.sega.aimedb.util.Encryption
|
||||||
import io.netty.buffer.ByteBuf
|
import io.netty.buffer.ByteBuf
|
||||||
import io.netty.channel.ChannelHandlerContext
|
import io.netty.channel.ChannelHandlerContext
|
||||||
|
@ -25,7 +24,7 @@ class AimeDbDecoder : ByteToMessageDecoder() {
|
||||||
* @param ctx ChannelHandlerContext
|
* @param ctx ChannelHandlerContext
|
||||||
* @param input ByteBuf in
|
* @param input ByteBuf in
|
||||||
* @param out List<Object>
|
* @param out List<Object>
|
||||||
</Object> */
|
*/
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
override fun decode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList<Any>) {
|
override fun decode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList<Any>) {
|
||||||
if (input.readableBytes() < 16) return
|
if (input.readableBytes() < 16) return
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb;
|
|
||||||
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.impl.*;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Scope;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Scope("prototype")
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class AimeDbRequestHandler extends ChannelInboundHandlerAdapter {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(AimeDbRequestHandler.class);
|
|
||||||
|
|
||||||
private final CampaignHandler campaignHandler;
|
|
||||||
private final FeliCaLookupHandler feliCaLookupHandler;
|
|
||||||
private final FeliCaLookup2Handler feliCaLookup2Handler;
|
|
||||||
private final GoodbyeHandler goodbyeHandler;
|
|
||||||
private final HelloHandler helloHandler;
|
|
||||||
private final LogHandler logHandler;
|
|
||||||
private final LookupHandler lookupHandler;
|
|
||||||
private final Lookup2Handler lookup2Handler;
|
|
||||||
private final RegisterHandler registerHandler;
|
|
||||||
private final Unknown19Handler unknown19Handler;
|
|
||||||
private final TouchHandler touchHandler;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) throws Exception {
|
|
||||||
if (msg instanceof Map) {
|
|
||||||
int type = ((int) ((Map<?, ?>) msg).get("type"));
|
|
||||||
ByteBuf data = (ByteBuf) ((Map<?, ?>) msg).get("data");
|
|
||||||
switch (type) {
|
|
||||||
case 0x0001:
|
|
||||||
feliCaLookupHandler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x0004:
|
|
||||||
lookupHandler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x0005:
|
|
||||||
registerHandler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x0009:
|
|
||||||
logHandler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x000b:
|
|
||||||
campaignHandler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x000d:
|
|
||||||
touchHandler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x000f:
|
|
||||||
lookup2Handler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x0011:
|
|
||||||
feliCaLookup2Handler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x0013:
|
|
||||||
unknown19Handler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x0064:
|
|
||||||
helloHandler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
case 0x0066:
|
|
||||||
goodbyeHandler.handle(ctx, data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
|
||||||
logger.error("Error in AimeDB", cause);
|
|
||||||
ctx.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void channelInactive(@NotNull ChannelHandlerContext ctx) throws Exception {
|
|
||||||
super.channelInactive(ctx);
|
|
||||||
logger.debug("Connection closed");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
package icu.samnyan.aqua.sega.aimedb
|
||||||
|
|
||||||
|
import icu.samnyan.aqua.sega.general.model.Card
|
||||||
|
import icu.samnyan.aqua.sega.general.service.CardService
|
||||||
|
import io.netty.buffer.ByteBuf
|
||||||
|
import io.netty.buffer.ByteBufUtil
|
||||||
|
import io.netty.buffer.Unpooled
|
||||||
|
import io.netty.channel.ChannelHandlerContext
|
||||||
|
import io.netty.channel.ChannelInboundHandlerAdapter
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.context.annotation.Scope
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import kotlin.jvm.optionals.getOrNull
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author samnyan (privateamusement@protonmail.com)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Scope("prototype")
|
||||||
|
class AimeDbRequestHandler(
|
||||||
|
val cardService: CardService
|
||||||
|
): ChannelInboundHandlerAdapter() {
|
||||||
|
val logger: Logger = LoggerFactory.getLogger(AimeDbRequestHandler::class.java)
|
||||||
|
|
||||||
|
data class AimeBaseInfo(val gameId: String, val keychipId: String)
|
||||||
|
|
||||||
|
fun getBaseInfo(input: ByteBuf) = AimeBaseInfo(
|
||||||
|
gameId = input.toString(0x000a, 0x000e - 0x000a, StandardCharsets.US_ASCII),
|
||||||
|
keychipId = input.toString(0x0014, 0x001f - 0x0014, StandardCharsets.US_ASCII)
|
||||||
|
)
|
||||||
|
|
||||||
|
final val handlers = mapOf<Int, (ByteBuf) -> ByteBuf?>(
|
||||||
|
0x0001 to ::doFelicaLookup,
|
||||||
|
0x0004 to ::doLookup,
|
||||||
|
0x0005 to ::doRegister,
|
||||||
|
0x0009 to ::doLog,
|
||||||
|
0x000b to ::doCampaign,
|
||||||
|
0x000d to ::doTouch,
|
||||||
|
0x000f to ::doLookup2,
|
||||||
|
0x0011 to ::doFelicaLookup2,
|
||||||
|
0x0013 to ::doUnknown19,
|
||||||
|
0x0064 to ::doHello,
|
||||||
|
0x0066 to ::doGoodbye
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the incoming request
|
||||||
|
*/
|
||||||
|
override fun channelRead(ctx: ChannelHandlerContext, msg: Any) {
|
||||||
|
if (msg is Map<*, *>) {
|
||||||
|
val type = msg["type"] as Int
|
||||||
|
val data = msg["data"] as ByteBuf
|
||||||
|
val base = getBaseInfo(data)
|
||||||
|
val handler = handlers[type] ?: let {
|
||||||
|
logger.error("AimeDB: Unknown request type: ${type.toString(16)}")
|
||||||
|
ctx.flush()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("AimeDB: Request $handler for game ${base.gameId}, from keychip ${base.keychipId}")
|
||||||
|
|
||||||
|
val result = handler(data)
|
||||||
|
if (result != null) ctx.writeAndFlush(result)
|
||||||
|
else ctx.flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Deprecated in Netty 5") // TODO: Move this to ChannelInboundHandler
|
||||||
|
override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
|
||||||
|
logger.error("AimeDB: Error", cause)
|
||||||
|
ctx.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun channelInactive(ctx: ChannelHandlerContext) {
|
||||||
|
super.channelInactive(ctx)
|
||||||
|
logger.debug("AimeDB: Connection closed")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Felica Lookup v1: Return the Felica IDm as-is
|
||||||
|
*/
|
||||||
|
fun doFelicaLookup(msg: ByteBuf): ByteBuf {
|
||||||
|
val idm = msg.slice(0x0020, 0x0028 - 0x0020).getLong(0)
|
||||||
|
val pmm = msg.slice(0x0028, 0x0030 - 0x0028).getLong(0)
|
||||||
|
logger.info("> Felica Lookup v1 ($idm, $pmm)")
|
||||||
|
|
||||||
|
// Get the decimal represent of the hex value, same from minime
|
||||||
|
val accessCode = idm.toString().replace("-", "").padStart(20, '0')
|
||||||
|
|
||||||
|
logger.info("> Response: $accessCode")
|
||||||
|
return Unpooled.copiedBuffer(ByteArray(0x0030)).apply {
|
||||||
|
setShortLE(0x0004, 0x0003)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
setBytes(0x0024, ByteBufUtil.decodeHexDump(accessCode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Felica Lookup v2: Look up the card in the card repository, return the External ID
|
||||||
|
*/
|
||||||
|
fun doFelicaLookup2(msg: ByteBuf): ByteBuf {
|
||||||
|
val idm = msg.slice(0x0020, 0x0028 - 0x0020).getLong(0)
|
||||||
|
val pmm = msg.slice(0x0028, 0x0030 - 0x0028).getLong(0)
|
||||||
|
logger.info("> Felica Lookup v2 ($idm, $pmm)")
|
||||||
|
|
||||||
|
// Get the decimal represent of the hex value, same from minime
|
||||||
|
val accessCode = idm.toString().replace("-", "").padStart(20, '0')
|
||||||
|
val aimeId = cardService.getCardByAccessCode(accessCode).getOrNull()?.extId ?: -1
|
||||||
|
|
||||||
|
logger.info("Response: $accessCode, $aimeId")
|
||||||
|
return Unpooled.copiedBuffer(ByteArray(0x0140)).apply {
|
||||||
|
setShortLE(0x0004, 0x0012)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
setLongLE(0x0020, aimeId)
|
||||||
|
setIntLE(0x0024, -0x1) // 0xFFFFFFFF
|
||||||
|
setIntLE(0x0028, -0x1) // 0xFFFFFFFF
|
||||||
|
setBytes(0x002c, ByteBufUtil.decodeHexDump(accessCode))
|
||||||
|
setShortLE(0x0037, 0x0001)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup v1: Find the LUID in the database and return the External ID
|
||||||
|
*/
|
||||||
|
fun doLookup(msg: ByteBuf): ByteBuf {
|
||||||
|
val luid = ByteBufUtil.hexDump(msg.slice(0x0020, 0x002a - 0x0020))
|
||||||
|
logger.info("> Lookup v1 ($luid)")
|
||||||
|
|
||||||
|
val aimeId = cardService.getCardByAccessCode(luid).getOrNull()?.extId ?: -1
|
||||||
|
|
||||||
|
logger.info("> Response: $aimeId")
|
||||||
|
return Unpooled.copiedBuffer(ByteArray(0x0130)).apply {
|
||||||
|
setShortLE(0x0004, 0x0006)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
setLongLE(0x0020, aimeId)
|
||||||
|
setByte(0x0024, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doLookup2(msg: ByteBuf): ByteBuf {
|
||||||
|
val luid = ByteBufUtil.hexDump(msg.slice(0x0020, 0x002a - 0x0020))
|
||||||
|
logger.info("> Lookup v2 ($luid)")
|
||||||
|
|
||||||
|
val aimeId = cardService.getCardByAccessCode(luid).getOrNull()?.extId ?: -1
|
||||||
|
|
||||||
|
logger.info("Response: $aimeId")
|
||||||
|
return Unpooled.copiedBuffer(ByteArray(0x0130)).apply {
|
||||||
|
setShortLE(0x0004, 0x0010)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
setLongLE(0x0020, aimeId)
|
||||||
|
setByte(0x0024, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register: Register a new card by access code
|
||||||
|
*/
|
||||||
|
fun doRegister(msg: ByteBuf): ByteBuf {
|
||||||
|
val luid = ByteBufUtil.hexDump(msg.slice(0x0020, 0x002a - 0x0020))
|
||||||
|
logger.info("> Register ($luid)")
|
||||||
|
|
||||||
|
var status = 0
|
||||||
|
var aimeId = 0L
|
||||||
|
|
||||||
|
if (cardService.getCardByAccessCode(luid).isEmpty) {
|
||||||
|
val card: Card = cardService.registerByAccessCode(luid)
|
||||||
|
|
||||||
|
status = 1
|
||||||
|
aimeId = card.extId
|
||||||
|
}
|
||||||
|
else logger.warn("> Duplicated Aime Card Register detected, access code: $luid")
|
||||||
|
|
||||||
|
logger.info("> Response: $status, $aimeId")
|
||||||
|
return Unpooled.copiedBuffer(ByteArray(0x0030)).apply {
|
||||||
|
setShortLE(0x0004, 0x0006)
|
||||||
|
setShortLE(0x0008, status)
|
||||||
|
setLongLE(0x0020, aimeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log: Just log the request and return a status 1
|
||||||
|
*/
|
||||||
|
fun doLog(msg: ByteBuf) = Unpooled.copiedBuffer(ByteArray(0x0020)).apply {
|
||||||
|
setShortLE(0x0004, 0x000a)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Campaign: Just return a status 1
|
||||||
|
*/
|
||||||
|
fun doCampaign(msg: ByteBuf) = Unpooled.copiedBuffer(ByteArray(0x0200)).apply {
|
||||||
|
setShortLE(0x0004, 0x000c)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Touch: Just return a status 1
|
||||||
|
*/
|
||||||
|
fun doTouch(msg: ByteBuf): ByteBuf {
|
||||||
|
val aimeId = msg.getUnsignedIntLE(0x0020)
|
||||||
|
logger.info("> Touch ($aimeId)")
|
||||||
|
|
||||||
|
return Unpooled.copiedBuffer(ByteArray(0x0050)).apply {
|
||||||
|
setShortLE(0x0004, 0x000e)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
setShortLE(0x0020, 0x006f)
|
||||||
|
setShortLE(0x0024, 0x0001)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We don't know what this is, just return a status 1
|
||||||
|
*/
|
||||||
|
fun doUnknown19(msg: ByteBuf) = Unpooled.copiedBuffer(ByteArray(0x0040)).apply {
|
||||||
|
setShortLE(0x0004, 0x0014)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ping: Just return a status 1
|
||||||
|
*/
|
||||||
|
fun doHello(msg: ByteBuf) = Unpooled.copiedBuffer(ByteArray(0x0020)).apply {
|
||||||
|
setShortLE(0x0004, 0x0065)
|
||||||
|
setShortLE(0x0008, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doGoodbye(msg: ByteBuf) = null
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.exception;
|
package icu.samnyan.aqua.sega.aimedb;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
* @author samnyan (privateamusement@protonmail.com)
|
|
@ -1,13 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
public interface BaseHandler {
|
|
||||||
|
|
||||||
void handle(ChannelHandlerContext ctx, ByteBuf msg) throws JsonProcessingException;
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class CampaignHandler implements BaseHandler {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(CampaignHandler.class);
|
|
||||||
|
|
||||||
private final LogMapper logMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public CampaignHandler(LogMapper logMapper) {
|
|
||||||
this.logMapper = logMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ChannelHandlerContext ctx, ByteBuf msg) throws JsonProcessingException {
|
|
||||||
Map<String, Object> requestMap = AimeDbUtil.getBaseInfo(msg);
|
|
||||||
requestMap.put("type", "campaign");
|
|
||||||
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap));
|
|
||||||
|
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
|
||||||
resultMap.put("type", "campaign");
|
|
||||||
resultMap.put("status", 1);
|
|
||||||
|
|
||||||
logger.info("Response: " + logMapper.write(resultMap));
|
|
||||||
|
|
||||||
ByteBuf respSrc = Unpooled.copiedBuffer(new byte[0x0200]);
|
|
||||||
respSrc.setShortLE(0x0004, 0x000c);
|
|
||||||
respSrc.setShortLE(0x0008, (int) resultMap.get("status"));
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl
|
|
||||||
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper
|
|
||||||
import icu.samnyan.aqua.sega.general.dao.CardRepository
|
|
||||||
import io.netty.buffer.ByteBuf
|
|
||||||
import io.netty.buffer.ByteBufUtil
|
|
||||||
import io.netty.buffer.Unpooled
|
|
||||||
import io.netty.channel.ChannelHandlerContext
|
|
||||||
import org.slf4j.Logger
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
class FeliCaLookup2Handler(
|
|
||||||
val logMapper: LogMapper,
|
|
||||||
val cardRepository: CardRepository
|
|
||||||
) : BaseHandler {
|
|
||||||
val logger: Logger = LoggerFactory.getLogger(FeliCaLookup2Handler::class.java)
|
|
||||||
|
|
||||||
override fun handle(ctx: ChannelHandlerContext, msg: ByteBuf) {
|
|
||||||
val requestMap = AimeDbUtil.getBaseInfo(msg)
|
|
||||||
requestMap["type"] = "felica_lookup2"
|
|
||||||
requestMap["idm"] = msg.slice(0x0030, 0x0038 - 0x0030)
|
|
||||||
requestMap["pmm"] = msg.slice(0x0038, 0x0040 - 0x0038)
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap))
|
|
||||||
|
|
||||||
// Get the decimal represent of the hex value, same from minime
|
|
||||||
val accessCode = (requestMap["idm"] as ByteBuf).getLong(0).toString()
|
|
||||||
.replace("-", "") // Prevent negative overflow
|
|
||||||
.padStart(20, '0')
|
|
||||||
|
|
||||||
var aimeId: Long = -1
|
|
||||||
val card = cardRepository.findByLuid(accessCode)
|
|
||||||
if (card.isPresent) {
|
|
||||||
aimeId = card.get().extId
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("Response: $accessCode, $aimeId")
|
|
||||||
|
|
||||||
val respSrc = Unpooled.copiedBuffer(ByteArray(0x0140))
|
|
||||||
respSrc.setShortLE(0x0004, 0x0012)
|
|
||||||
respSrc.setShortLE(0x0008, 1)
|
|
||||||
respSrc.setLongLE(0x0020, aimeId)
|
|
||||||
respSrc.setIntLE(0x0024, -0x1)
|
|
||||||
respSrc.setIntLE(0x0028, -0x1)
|
|
||||||
respSrc.setBytes(0x002c, ByteBufUtil.decodeHexDump(accessCode))
|
|
||||||
respSrc.setShortLE(0x0037, 0x0001)
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl
|
|
||||||
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper
|
|
||||||
import io.netty.buffer.ByteBuf
|
|
||||||
import io.netty.buffer.ByteBufUtil
|
|
||||||
import io.netty.buffer.Unpooled
|
|
||||||
import io.netty.channel.ChannelHandlerContext
|
|
||||||
import org.slf4j.Logger
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
class FeliCaLookupHandler(val logMapper: LogMapper) : BaseHandler {
|
|
||||||
val logger: Logger = LoggerFactory.getLogger(FeliCaLookupHandler::class.java)
|
|
||||||
|
|
||||||
override fun handle(ctx: ChannelHandlerContext, msg: ByteBuf) {
|
|
||||||
val requestMap = AimeDbUtil.getBaseInfo(msg)
|
|
||||||
requestMap["type"] = "felica_lookup"
|
|
||||||
requestMap["idm"] = msg.slice(0x0020, 0x0028 - 0x0020)
|
|
||||||
requestMap["pmm"] = msg.slice(0x0028, 0x0030 - 0x0028)
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap))
|
|
||||||
|
|
||||||
|
|
||||||
// Get the decimal represent of the hex value, same from minime
|
|
||||||
val accessCode = (requestMap["idm"] as ByteBuf).getLong(0).toString()
|
|
||||||
.replace("-", "") // Prevent negative overflow
|
|
||||||
.padStart(20, '0')
|
|
||||||
|
|
||||||
logger.info("Response: $accessCode")
|
|
||||||
|
|
||||||
val respSrc = Unpooled.copiedBuffer(ByteArray(0x0030))
|
|
||||||
respSrc.setShortLE(0x0004, 0x0003)
|
|
||||||
respSrc.setShortLE(0x0008, 1)
|
|
||||||
respSrc.setBytes(0x0024, ByteBufUtil.decodeHexDump(accessCode))
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class GoodbyeHandler implements BaseHandler {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(GoodbyeHandler.class);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ChannelHandlerContext ctx, ByteBuf msg) throws JsonProcessingException {
|
|
||||||
Map<String, String> requestMap = new HashMap<>();
|
|
||||||
requestMap.put("type", "goodbye");
|
|
||||||
|
|
||||||
|
|
||||||
logger.info("Request: " + new ObjectMapper().writeValueAsString(requestMap));
|
|
||||||
ctx.flush();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class HelloHandler implements BaseHandler {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(HelloHandler.class);
|
|
||||||
|
|
||||||
private final LogMapper logMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public HelloHandler(LogMapper logMapper) {
|
|
||||||
this.logMapper = logMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ChannelHandlerContext ctx, ByteBuf msg) throws JsonProcessingException {
|
|
||||||
Map<String, Object> requestMap = AimeDbUtil.getBaseInfo(msg);
|
|
||||||
requestMap.put("type", "hello");
|
|
||||||
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap));
|
|
||||||
|
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
|
||||||
resultMap.put("type", "hello");
|
|
||||||
resultMap.put("status", 1);
|
|
||||||
|
|
||||||
logger.info("Response: " + logMapper.write(resultMap));
|
|
||||||
|
|
||||||
ByteBuf respSrc = Unpooled.copiedBuffer(new byte[0x0020]);
|
|
||||||
respSrc.setShortLE(0x0004, 0x0065);
|
|
||||||
respSrc.setShortLE(0x0008, (int) resultMap.get("status"));
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class LogHandler implements BaseHandler {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LogHandler.class);
|
|
||||||
|
|
||||||
private final LogMapper logMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public LogHandler(LogMapper logMapper) {
|
|
||||||
this.logMapper = logMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ChannelHandlerContext ctx, ByteBuf msg) throws JsonProcessingException {
|
|
||||||
Map<String, Object> requestMap = AimeDbUtil.getBaseInfo(msg);
|
|
||||||
requestMap.put("type", "log");
|
|
||||||
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap));
|
|
||||||
|
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
|
||||||
resultMap.put("type", "log");
|
|
||||||
resultMap.put("status", 1);
|
|
||||||
|
|
||||||
logger.info("Response: " + logMapper.write(resultMap));
|
|
||||||
|
|
||||||
ByteBuf respSrc = Unpooled.copiedBuffer(new byte[0x0020]);
|
|
||||||
respSrc.setShortLE(0x0004, 0x000a);
|
|
||||||
respSrc.setShortLE(0x0008, (int) resultMap.get("status"));
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl
|
|
||||||
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil.getBaseInfo
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper
|
|
||||||
import icu.samnyan.aqua.sega.general.dao.CardRepository
|
|
||||||
import io.netty.buffer.ByteBuf
|
|
||||||
import io.netty.buffer.ByteBufUtil
|
|
||||||
import io.netty.buffer.Unpooled
|
|
||||||
import io.netty.channel.ChannelHandlerContext
|
|
||||||
import org.slf4j.Logger
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
class Lookup2Handler(
|
|
||||||
val logMapper: LogMapper,
|
|
||||||
val cardRepository: CardRepository
|
|
||||||
) : BaseHandler {
|
|
||||||
val logger: Logger = LoggerFactory.getLogger(Lookup2Handler::class.java)
|
|
||||||
|
|
||||||
override fun handle(ctx: ChannelHandlerContext, msg: ByteBuf) {
|
|
||||||
val requestMap = getBaseInfo(msg)
|
|
||||||
requestMap["type"] = "lookup2"
|
|
||||||
requestMap["luid"] = ByteBufUtil.hexDump(msg.slice(0x0020, 0x002a - 0x0020))
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap))
|
|
||||||
|
|
||||||
var aimeId: Long = -1
|
|
||||||
val card = cardRepository.findByLuid(requestMap["luid"] as String?)
|
|
||||||
if (card.isPresent) {
|
|
||||||
aimeId = card.get().extId
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("Response: $aimeId")
|
|
||||||
|
|
||||||
val respSrc = Unpooled.copiedBuffer(ByteArray(0x0130))
|
|
||||||
respSrc.setShortLE(0x0004, 0x0010)
|
|
||||||
respSrc.setShortLE(0x0008, 1)
|
|
||||||
respSrc.setLongLE(0x0020, aimeId)
|
|
||||||
respSrc.setByte(0x0024, 0)
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl
|
|
||||||
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil.getBaseInfo
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper
|
|
||||||
import icu.samnyan.aqua.sega.general.dao.CardRepository
|
|
||||||
import io.netty.buffer.ByteBuf
|
|
||||||
import io.netty.buffer.ByteBufUtil
|
|
||||||
import io.netty.buffer.Unpooled
|
|
||||||
import io.netty.channel.ChannelHandlerContext
|
|
||||||
import org.slf4j.Logger
|
|
||||||
import org.slf4j.LoggerFactory
|
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mifare Card lookup? idk
|
|
||||||
*
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
class LookupHandler(
|
|
||||||
val logMapper: LogMapper,
|
|
||||||
val cardRepository: CardRepository
|
|
||||||
) : BaseHandler {
|
|
||||||
val logger: Logger = LoggerFactory.getLogger(LookupHandler::class.java)
|
|
||||||
|
|
||||||
override fun handle(ctx: ChannelHandlerContext, msg: ByteBuf) {
|
|
||||||
val requestMap = getBaseInfo(msg)
|
|
||||||
requestMap["type"] = "lookup"
|
|
||||||
requestMap["luid"] = ByteBufUtil.hexDump(msg.slice(0x0020, 0x002a - 0x0020))
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap))
|
|
||||||
|
|
||||||
var aimeId: Long = -1
|
|
||||||
val card = cardRepository.findByLuid(requestMap["luid"] as String?)
|
|
||||||
if (card.isPresent) {
|
|
||||||
aimeId = card.get().extId
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("Response: $aimeId")
|
|
||||||
|
|
||||||
val respSrc = Unpooled.copiedBuffer(ByteArray(0x0130))
|
|
||||||
respSrc.setShortLE(0x0004, 0x0006)
|
|
||||||
respSrc.setShortLE(0x0008, 1)
|
|
||||||
respSrc.setLongLE(0x0020, aimeId)
|
|
||||||
respSrc.setByte(0x0024, 0)
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper;
|
|
||||||
import icu.samnyan.aqua.sega.general.model.Card;
|
|
||||||
import icu.samnyan.aqua.sega.general.service.CardService;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.ByteBufUtil;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class RegisterHandler implements BaseHandler {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RegisterHandler.class);
|
|
||||||
|
|
||||||
private final LogMapper logMapper;
|
|
||||||
|
|
||||||
private final CardService cardService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public RegisterHandler(LogMapper logMapper, CardService cardService) {
|
|
||||||
this.logMapper = logMapper;
|
|
||||||
this.cardService = cardService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ChannelHandlerContext ctx, ByteBuf msg) throws JsonProcessingException {
|
|
||||||
Map<String, Object> requestMap = AimeDbUtil.getBaseInfo(msg);
|
|
||||||
requestMap.put("type", "register");
|
|
||||||
requestMap.put("luid", ByteBufUtil.hexDump(msg.slice(0x0020, 0x002a - 0x0020)));
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap));
|
|
||||||
|
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
|
||||||
resultMap.put("type", "register");
|
|
||||||
|
|
||||||
if (cardService.getCardByAccessCode((String) requestMap.get("luid")).isEmpty()) {
|
|
||||||
Card card = cardService.registerByAccessCode((String) requestMap.get("luid"));
|
|
||||||
|
|
||||||
resultMap.put("status", 1);
|
|
||||||
resultMap.put("aimeId", card.getExtId());
|
|
||||||
} else {
|
|
||||||
logger.warn("Duplicated Aime Card Register detected, access code: {}", requestMap.get("luid"));
|
|
||||||
resultMap.put("status", 0);
|
|
||||||
resultMap.put("aimeId", 0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("Response: " + logMapper.write(resultMap));
|
|
||||||
|
|
||||||
ByteBuf respSrc = Unpooled.copiedBuffer(new byte[0x0030]);
|
|
||||||
respSrc.setShortLE(0x0004, 0x0006);
|
|
||||||
respSrc.setShortLE(0x0008, (int) resultMap.get("status"));
|
|
||||||
respSrc.setLongLE(0x0020, (long) resultMap.get("aimeId"));
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class TouchHandler implements BaseHandler {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(TouchHandler.class);
|
|
||||||
|
|
||||||
private final LogMapper logMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public TouchHandler(LogMapper logMapper) {
|
|
||||||
this.logMapper = logMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ChannelHandlerContext ctx, ByteBuf msg) throws JsonProcessingException {
|
|
||||||
Map<String, Object> requestMap = AimeDbUtil.getBaseInfo(msg);
|
|
||||||
requestMap.put("type", "touch");
|
|
||||||
requestMap.put("aimeId", msg.getUnsignedIntLE(0x0020));
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap));
|
|
||||||
|
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
|
||||||
resultMap.put("type", "touch");
|
|
||||||
resultMap.put("status", 1);
|
|
||||||
|
|
||||||
logger.info("Response: " + logMapper.write(resultMap));
|
|
||||||
|
|
||||||
ByteBuf respSrc = Unpooled.copiedBuffer(new byte[0x0050]);
|
|
||||||
respSrc.setShortLE(0x0004, 0x000e);
|
|
||||||
respSrc.setShortLE(0x0008, (int) resultMap.get("status"));
|
|
||||||
respSrc.setShortLE(0x0020, 0x006f);
|
|
||||||
respSrc.setShortLE(0x0024, 0x0001);
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.handler.impl;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.handler.BaseHandler;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.AimeDbUtil;
|
|
||||||
import icu.samnyan.aqua.sega.aimedb.util.LogMapper;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class Unknown19Handler implements BaseHandler {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Unknown19Handler.class);
|
|
||||||
|
|
||||||
private final LogMapper logMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public Unknown19Handler(LogMapper logMapper) {
|
|
||||||
this.logMapper = logMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(ChannelHandlerContext ctx, ByteBuf msg) throws JsonProcessingException {
|
|
||||||
Map<String, Object> requestMap = AimeDbUtil.getBaseInfo(msg);
|
|
||||||
requestMap.put("type", "unknown19");
|
|
||||||
|
|
||||||
logger.info("Request: " + logMapper.write(requestMap));
|
|
||||||
|
|
||||||
Map<String, Object> resultMap = new HashMap<>();
|
|
||||||
resultMap.put("type", "unknown19");
|
|
||||||
resultMap.put("status", 1);
|
|
||||||
|
|
||||||
logger.info("Response: " + logMapper.write(resultMap));
|
|
||||||
|
|
||||||
ByteBuf respSrc = Unpooled.copiedBuffer(new byte[0x0040]);
|
|
||||||
respSrc.setShortLE(0x0004, 0x0014);
|
|
||||||
respSrc.setShortLE(0x0008, (int) resultMap.get("status"));
|
|
||||||
|
|
||||||
ctx.writeAndFlush(respSrc);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.util
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf
|
|
||||||
import java.nio.charset.StandardCharsets
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
object AimeDbUtil {
|
|
||||||
@JvmStatic
|
|
||||||
fun getBaseInfo(input: ByteBuf) = mutableMapOf<String, Any>(
|
|
||||||
"gameId" to input.toString(0x000a, 0x000e - 0x000a, StandardCharsets.US_ASCII),
|
|
||||||
"keychipId" to input.toString(0x0014, 0x001f - 0x0014, StandardCharsets.US_ASCII)
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package icu.samnyan.aqua.sega.aimedb.util;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
|
||||||
import icu.samnyan.aqua.sega.util.jackson.ByteBufSerializer;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author samnyan (privateamusement@protonmail.com)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class LogMapper {
|
|
||||||
|
|
||||||
private final ObjectMapper mapper;
|
|
||||||
|
|
||||||
public LogMapper() {
|
|
||||||
mapper = new ObjectMapper();
|
|
||||||
SimpleModule module = new SimpleModule();
|
|
||||||
module.addSerializer(ByteBuf.class, new ByteBufSerializer());
|
|
||||||
mapper.registerModule(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String write(Object o) throws JsonProcessingException {
|
|
||||||
return mapper.writeValueAsString(o);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue