From 30a7fa7ead74c8c57cf3ffd5a97dfb2f4f469638 Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Thu, 22 Feb 2024 19:47:35 -0500 Subject: [PATCH] [O] Convert more stuff to kotlin --- .../aqua/sega/aimedb/AimeDbDecoder.java | 90 ------------------- .../samnyan/aqua/sega/aimedb/AimeDbDecoder.kt | 69 ++++++++++++++ .../aqua/sega/aimedb/AimeDbEncoder.java | 32 ------- .../samnyan/aqua/sega/aimedb/AimeDbEncoder.kt | 28 ++++++ .../sega/aimedb/AimeDbRequestHandler.java | 28 ++---- .../aqua/sega/aimedb/AimeDbServer.java | 45 +++++----- .../sega/aimedb/AimeDbServerInitializer.java | 55 ------------ .../sega/aimedb/AimeDbServerInitializer.kt | 24 +++++ .../sega/aimedb/handler/impl/LookupHandler.kt | 1 - .../aqua/sega/aimedb/util/Encryption.java | 5 +- 10 files changed, 154 insertions(+), 223 deletions(-) delete mode 100644 src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.java create mode 100644 src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.kt delete mode 100644 src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.java create mode 100644 src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.kt delete mode 100644 src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServerInitializer.java create mode 100644 src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServerInitializer.kt diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.java b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.java deleted file mode 100644 index b1210694..00000000 --- a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.java +++ /dev/null @@ -1,90 +0,0 @@ -package icu.samnyan.aqua.sega.aimedb; - -import icu.samnyan.aqua.sega.aimedb.exception.InvalidRequestException; -import icu.samnyan.aqua.sega.aimedb.util.Encryption; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author samnyan (privateamusement@protonmail.com) - */ -@Component -@Scope(BeanDefinition.SCOPE_PROTOTYPE) -public class AimeDbDecoder extends ByteToMessageDecoder { - - private static final Logger logger = LoggerFactory.getLogger(AimeDbDecoder.class); - - private int length = 0; - - /** - * Decrypt the incoming request including frame management - * @param ctx ChannelHandlerContext - * @param in ByteBuf in - * @param out List - * @throws Exception - */ - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - if (in.readableBytes() < 16) { - return; - } - if (length == 0) { - length = getLength(in); - } - - if (in.readableBytes() < length) { - return; - } - - // Create a byte array to store the encrypted data - ByteBuf result = Encryption.decrypt(in.readBytes(length)); - - Map resultMap = new HashMap<>(); - resultMap.put("type", ((Short) result.getShortLE(0x04)).intValue()); - resultMap.put("data", result); - - logger.debug("Aime Server Request Type: " + resultMap.get("type")); - - out.add(resultMap); - } - - /** - * Get the length from request - * - * @param in the request - * @return int the length of this request - * @throws InvalidRequestException - * @throws IllegalBlockSizeException - * @throws InvalidKeyException - * @throws BadPaddingException - * @throws NoSuchAlgorithmException - * @throws NoSuchPaddingException - */ - private int getLength(ByteBuf in) throws InvalidRequestException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { - int currentPos = in.readerIndex(); - ByteBuf result = Encryption.decrypt(in); - // Check the header - if (result.getByte(0) != 0x3e) { - throw new InvalidRequestException(); - } - - // Read the length from offset 6 - - return result.getShortLE(currentPos + 6); - } -} diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.kt b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.kt new file mode 100644 index 00000000..f423815c --- /dev/null +++ b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.kt @@ -0,0 +1,69 @@ +package icu.samnyan.aqua.sega.aimedb + +import icu.samnyan.aqua.sega.aimedb.exception.InvalidRequestException +import icu.samnyan.aqua.sega.aimedb.util.Encryption +import io.netty.buffer.ByteBuf +import io.netty.channel.ChannelHandlerContext +import io.netty.handler.codec.ByteToMessageDecoder +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.config.BeanDefinition +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +/** + * @author samnyan (privateamusement@protonmail.com) + */ +@Component +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +class AimeDbDecoder : ByteToMessageDecoder() { + var length = 0 + val logger: Logger = LoggerFactory.getLogger(AimeDbDecoder::class.java) + + /** + * Decrypt the incoming request including frame management + * @param ctx ChannelHandlerContext + * @param input ByteBuf in + * @param out List + */ + @Throws(Exception::class) + override fun decode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList) { + if (input.readableBytes() < 16) return + if (length == 0) { + length = getLength(input) + logger.info("Aime Server Request Length: $length") + } + + if (input.readableBytes() < length) return + + // Create a byte array to store the encrypted data + val result = Encryption.decrypt(input.readBytes(length)) + + val resultMap: MutableMap = HashMap() + resultMap["type"] = result.getShortLE(0x04).toInt() + resultMap["data"] = result + + logger.debug("Aime Server 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 { + val currentPos = input.readerIndex() + val result = Encryption.decrypt(input) + + // Check the header + if (result.getByte(0).toInt() != 0x3e) { + throw InvalidRequestException() + } + + // Read the length from offset 6 + return result.getShortLE(currentPos + 6).toInt() + } +} diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.java b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.java deleted file mode 100644 index 80aaf224..00000000 --- a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.java +++ /dev/null @@ -1,32 +0,0 @@ -package icu.samnyan.aqua.sega.aimedb; - -import icu.samnyan.aqua.sega.aimedb.util.Encryption; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -/** - * @author samnyan (privateamusement@protonmail.com) - */ -@Component -@Scope(BeanDefinition.SCOPE_PROTOTYPE) -public class AimeDbEncoder extends MessageToByteEncoder { - @Override - protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception { - - if (msg instanceof ByteBuf) { - ByteBuf resp = ((ByteBuf) msg); - resp.writerIndex(0); - resp.writeShortLE(0xa13e); - resp.writeShortLE(0x3087); - resp.setShortLE(0x0006, resp.capacity()); - ByteBuf encryptedResp = Encryption.encrypt(resp); - ctx.writeAndFlush(encryptedResp); - } - - } -} - diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.kt b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.kt new file mode 100644 index 00000000..5ac94fbd --- /dev/null +++ b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.kt @@ -0,0 +1,28 @@ +package icu.samnyan.aqua.sega.aimedb + +import icu.samnyan.aqua.sega.aimedb.util.Encryption +import io.netty.buffer.ByteBuf +import io.netty.channel.ChannelHandlerContext +import io.netty.handler.codec.MessageToByteEncoder +import org.springframework.beans.factory.config.BeanDefinition +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +/** + * @author samnyan (privateamusement@protonmail.com) + */ +@Component +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +class AimeDbEncoder : MessageToByteEncoder() { + override fun encode(ctx: ChannelHandlerContext, msg: Any, out: ByteBuf) { + if (msg is ByteBuf) { + msg.writerIndex(0) + msg.writeShortLE(0xa13e) + msg.writeShortLE(0x3087) + msg.setShortLE(0x0006, msg.capacity()) + val encryptedResp = Encryption.encrypt(msg) + ctx.writeAndFlush(encryptedResp) + } + } +} + diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbRequestHandler.java b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbRequestHandler.java index 89cb6ba4..26610765 100644 --- a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbRequestHandler.java +++ b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbRequestHandler.java @@ -4,6 +4,8 @@ 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; @@ -18,6 +20,7 @@ import java.util.Map; @Component @Scope("prototype") +@AllArgsConstructor public class AimeDbRequestHandler extends ChannelInboundHandlerAdapter { private static final Logger logger = LoggerFactory.getLogger(AimeDbRequestHandler.class); @@ -34,27 +37,12 @@ public class AimeDbRequestHandler extends ChannelInboundHandlerAdapter { private final Unknown19Handler unknown19Handler; private final TouchHandler touchHandler; - @Autowired - public AimeDbRequestHandler(CampaignHandler campaignHandler, FeliCaLookupHandler feliCaLookupHandler, FeliCaLookup2Handler feliCaLookup2Handler, GoodbyeHandler goodbyeHandler, HelloHandler helloHandler, LogHandler logHandler, LookupHandler lookupHandler, Lookup2Handler lookup2Handler, RegisterHandler registerHandler, Unknown19Handler unknown19Handler, TouchHandler touchHandler) { - this.campaignHandler = campaignHandler; - this.feliCaLookupHandler = feliCaLookupHandler; - this.feliCaLookup2Handler = feliCaLookup2Handler; - this.goodbyeHandler = goodbyeHandler; - this.helloHandler = helloHandler; - this.logHandler = logHandler; - this.lookupHandler = lookupHandler; - this.lookup2Handler = lookup2Handler; - this.registerHandler = registerHandler; - this.unknown19Handler = unknown19Handler; - this.touchHandler = touchHandler; - } - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + 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"); + int type = ((int) ((Map) msg).get("type")); + ByteBuf data = (ByteBuf) ((Map) msg).get("data"); switch (type) { case 0x0001: feliCaLookupHandler.handle(ctx, data); @@ -96,12 +84,12 @@ public class AimeDbRequestHandler extends ChannelInboundHandlerAdapter { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - cause.printStackTrace(); + logger.error("Error in AimeDB", cause); ctx.close(); } @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { + public void channelInactive(@NotNull ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); logger.debug("Connection closed"); } diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServer.java b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServer.java index ef0456fd..65706fa7 100644 --- a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServer.java +++ b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServer.java @@ -41,31 +41,34 @@ public class AimeDbServer { } public void start() throws Exception { - if (enableAimeDb) { - ServerBootstrap bootstrap = new ServerBootstrap(); - EventLoopGroup boss = new NioEventLoopGroup(); - EventLoopGroup work = new NioEventLoopGroup(); + if (!enableAimeDb) { + logger.info("Aime DB is disabled."); + return; + } - bootstrap.group(boss, work) - .handler(new LoggingHandler(LogLevel.DEBUG)) - .channel(NioServerSocketChannel.class) - .childHandler(aimeDbServerInitializer) - .option(ChannelOption.SO_BACKLOG, 128); + ServerBootstrap bootstrap = new ServerBootstrap(); + EventLoopGroup boss = new NioEventLoopGroup(); + EventLoopGroup work = new NioEventLoopGroup(); - InetSocketAddress socket; - if(StringUtils.isNotBlank(this.address)) { - try { - socket = new InetSocketAddress(InetAddress.getByName(this.address), this.port); - } catch (UnknownHostException e) { - logger.error("UnknownHostException, please check you have set a correct aimedb.server.address."); - socket = new InetSocketAddress(this.port); - } - } else { + bootstrap.group(boss, work) + .handler(new LoggingHandler(LogLevel.DEBUG)) + .channel(NioServerSocketChannel.class) + .childHandler(aimeDbServerInitializer) + .option(ChannelOption.SO_BACKLOG, 128); + + InetSocketAddress socket; + if(StringUtils.isNotBlank(this.address)) { + try { + socket = new InetSocketAddress(InetAddress.getByName(this.address), this.port); + } catch (UnknownHostException e) { + logger.error("UnknownHostException, please check you have set a correct aimedb.server.address."); socket = new InetSocketAddress(this.port); } - ChannelFuture f = bootstrap.bind(socket).sync(); - logger.info("Aime DB start up on " + socket.toString()); - f.channel().closeFuture(); + } else { + socket = new InetSocketAddress(this.port); } + ChannelFuture f = bootstrap.bind(socket).sync(); + logger.info("Aime DB start up on " + socket); + f.channel().closeFuture(); } } diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServerInitializer.java b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServerInitializer.java deleted file mode 100644 index 726f5255..00000000 --- a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServerInitializer.java +++ /dev/null @@ -1,55 +0,0 @@ -package icu.samnyan.aqua.sega.aimedb; - -import icu.samnyan.aqua.sega.aimedb.handler.impl.*; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelPipeline; -import io.netty.channel.socket.SocketChannel; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -/** - * @author samnyan (privateamusement@protonmail.com) - */ -@Component -@Scope(BeanDefinition.SCOPE_PROTOTYPE) -public class AimeDbServerInitializer extends ChannelInitializer { - - 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; - - @Autowired - public AimeDbServerInitializer(CampaignHandler campaignHandler, FeliCaLookupHandler feliCaLookupHandler, FeliCaLookup2Handler feliCaLookup2Handler, GoodbyeHandler goodbyeHandler, HelloHandler helloHandler, LogHandler logHandler, LookupHandler lookupHandler, Lookup2Handler lookup2Handler, RegisterHandler registerHandler, Unknown19Handler unknown19Handler, TouchHandler touchHandler) { - this.campaignHandler = campaignHandler; - this.feliCaLookup2Handler = feliCaLookup2Handler; - this.feliCaLookupHandler = feliCaLookupHandler; - this.goodbyeHandler = goodbyeHandler; - this.helloHandler = helloHandler; - this.logHandler = logHandler; - this.lookupHandler = lookupHandler; - this.lookup2Handler = lookup2Handler; - this.registerHandler = registerHandler; - this.unknown19Handler = unknown19Handler; - this.touchHandler = touchHandler; - } - - - @Override - protected void initChannel(SocketChannel ch) { - ChannelPipeline pipeline = ch.pipeline(); - pipeline.addLast("encoder", new AimeDbEncoder()); - pipeline.addLast("decoder", new AimeDbDecoder()); - pipeline.addLast("handler", new AimeDbRequestHandler(campaignHandler, feliCaLookupHandler, feliCaLookup2Handler, goodbyeHandler, helloHandler, logHandler, lookupHandler, lookup2Handler, registerHandler, unknown19Handler, touchHandler)); - - } -} diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServerInitializer.kt b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServerInitializer.kt new file mode 100644 index 00000000..7a89b11a --- /dev/null +++ b/src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbServerInitializer.kt @@ -0,0 +1,24 @@ +package icu.samnyan.aqua.sega.aimedb + +import io.netty.channel.ChannelInitializer +import io.netty.channel.socket.SocketChannel +import org.springframework.beans.factory.config.BeanDefinition +import org.springframework.context.annotation.Scope +import org.springframework.stereotype.Component + +/** + * @author samnyan (privateamusement@protonmail.com) + */ +@Component +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +class AimeDbServerInitializer( + val aimeDbRequestHandler: AimeDbRequestHandler +) : ChannelInitializer() { + override fun initChannel(ch: SocketChannel) { + ch.pipeline().apply { + addLast("encoder", AimeDbEncoder()) + addLast("decoder", AimeDbDecoder()) + addLast("handler", aimeDbRequestHandler) + } + } +} diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/handler/impl/LookupHandler.kt b/src/main/java/icu/samnyan/aqua/sega/aimedb/handler/impl/LookupHandler.kt index 9c6fbcd8..3bc74b40 100644 --- a/src/main/java/icu/samnyan/aqua/sega/aimedb/handler/impl/LookupHandler.kt +++ b/src/main/java/icu/samnyan/aqua/sega/aimedb/handler/impl/LookupHandler.kt @@ -10,7 +10,6 @@ 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 /** diff --git a/src/main/java/icu/samnyan/aqua/sega/aimedb/util/Encryption.java b/src/main/java/icu/samnyan/aqua/sega/aimedb/util/Encryption.java index 44f94be5..61776dc7 100644 --- a/src/main/java/icu/samnyan/aqua/sega/aimedb/util/Encryption.java +++ b/src/main/java/icu/samnyan/aqua/sega/aimedb/util/Encryption.java @@ -20,9 +20,7 @@ import java.security.NoSuchAlgorithmException; */ public class Encryption { - private static final Logger logger = LoggerFactory.getLogger(Encryption.class); - - private static SecretKeySpec KEY = new SecretKeySpec("Copyright(C)SEGA".getBytes(StandardCharsets.UTF_8), "AES"); + private static final SecretKeySpec KEY = new SecretKeySpec("Copyright(C)SEGA".getBytes(StandardCharsets.UTF_8), "AES"); public static ByteBuf decrypt(ByteBuf src) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding"); @@ -37,5 +35,4 @@ public class Encryption { byte[] bytes = cipher.doFinal(ByteBufUtil.toAllBytes(src)); return Unpooled.copiedBuffer(bytes); } - }