mirror of
https://github.com/MewoLab/AquaDX.git
synced 2025-10-26 12:32:40 +00:00
[O] Convert more stuff to kotlin
This commit is contained in:
parent
4324d655d2
commit
30a7fa7ead
@ -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<Object>
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> 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<String, Object> 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);
|
||||
}
|
||||
}
|
||||
69
src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.kt
Normal file
69
src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbDecoder.kt
Normal file
@ -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<Object>
|
||||
</Object> */
|
||||
@Throws(Exception::class)
|
||||
override fun decode(ctx: ChannelHandlerContext, input: ByteBuf, out: MutableList<Any>) {
|
||||
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<String, Any> = 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()
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
28
src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.kt
Normal file
28
src/main/java/icu/samnyan/aqua/sega/aimedb/AimeDbEncoder.kt
Normal file
@ -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<Any>() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<SocketChannel> {
|
||||
|
||||
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));
|
||||
|
||||
}
|
||||
}
|
||||
@ -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<SocketChannel>() {
|
||||
override fun initChannel(ch: SocketChannel) {
|
||||
ch.pipeline().apply {
|
||||
addLast("encoder", AimeDbEncoder())
|
||||
addLast("decoder", AimeDbDecoder())
|
||||
addLast("handler", aimeDbRequestHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
/**
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user