This commit is contained in:
Him188moe 2019-08-21 00:48:44 +08:00
parent e1f706f76d
commit 9be18408f8
17 changed files with 327 additions and 68 deletions

5
.gitignore vendored
View File

@ -28,4 +28,7 @@ hs_err_pid*
mirai.iml
/.idea/
.idea/*
/.idea/*
/.idea/*
test/
/test

View File

@ -35,7 +35,6 @@ hex | 00 00 00 00 03 09 00 08 00 01
int | g_server
hex | 00 02 00 36 00 12 00 02 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 14 00 1D 01 02 00 19
hex | #publicKey
TEA加密以上, key=MD52
### S -> C

View File

@ -21,6 +21,23 @@
</parent>
<dependencies>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-filter-ssl -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-filter-ssl</artifactId>
<version>1.1.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-filter-compression -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-filter-compression</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>

View File

@ -4,8 +4,8 @@ import lombok.Getter;
import net.mamoe.mirai.event.MiraiEventManager;
import net.mamoe.mirai.event.events.server.ServerDisableEvent;
import net.mamoe.mirai.event.events.server.ServerEnableEvent;
import net.mamoe.mirai.network.Protocol;
import net.mamoe.mirai.network.Robot;
import net.mamoe.mirai.network.packet.client.touch.ClientTouchPacket;
import net.mamoe.mirai.task.MiraiTaskManager;
import net.mamoe.mirai.utils.LoggerTextFormat;
import net.mamoe.mirai.utils.MiraiLogger;
@ -116,11 +116,16 @@ public class MiraiServer {
Robot robot = new Robot(1994701021, "xiaoqqq");
try {
System.out.println(Protocol.Companion.getSERVER_IP().get(3));
//System.out.println(Protocol.Companion.getSERVER_IP().get(3));
//System.out.println(Protocol.Companion.getSERVER_IP().toString());
robot.connect(Protocol.Companion.getSERVER_IP().get(3));
robot.setServerIP("14.116.136.106");
robot.sendPacket(new ClientTouchPacket(1994701021, "14.116.136.106"));
while (true) ;
//robot.connect("14.116.136.106");
//robot.connect(Protocol.Companion.getSERVER_IP().get(2));
//robot.connect("125.39.132.242");
} catch (InterruptedException e) {
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}

View File

@ -4,10 +4,8 @@ import lombok.Getter;
import lombok.Setter;
import net.mamoe.mirai.event.events.Cancellable;
import net.mamoe.mirai.event.events.MiraiEvent;
import net.mamoe.mirai.event.events.server.ServerDisableEvent;
import java.io.Closeable;
import java.io.IOException;
import java.util.function.Consumer;
import java.util.function.Predicate;
@ -79,7 +77,7 @@ public class MiraiEventHook<T extends MiraiEvent> implements Closeable {
if(!(event instanceof Cancellable && event.isCancelled() && this.isIgnoreCancelled())){
this.getHandler().accept((T) event);
}
return this.valid.test((T)event);
return this.valid == null || this.valid.test((T) event);
}
/**

View File

@ -0,0 +1,150 @@
package net.mamoe.mirai.network;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.DatagramSessionConfig;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import java.io.IOException;
import java.net.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class MemoryMonitorTest {
private static final long serialVersionUID = 1L;
public static final int PORT = 8080;
public MemoryMonitorTest() throws IOException {
NioDatagramAcceptor acceptor = new NioDatagramAcceptor();//创建一个UDP的接收器
acceptor.setHandler(new YourHandler());//设置接收器的处理程序
Executor threadPool = Executors.newFixedThreadPool(1500);//建立线程池
acceptor.getFilterChain().addLast("exector", new ExecutorFilter(threadPool));
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
DatagramSessionConfig dcfg = acceptor.getSessionConfig();//建立连接的配置文件
dcfg.setReadBufferSize(4096);//设置接收最大字节默认2048
dcfg.setReceiveBufferSize(1024);//设置输入缓冲区的大小
dcfg.setSendBufferSize(1024);//设置输出缓冲区的大小
dcfg.setReuseAddress(true);//设置每一个非主监听连接的端口可以重用
acceptor.bind(new InetSocketAddress(PORT));//绑定端口
}
public static void main(String[] args) throws IOException {
new MemoryMonitorTest();
}
public class YourHandler extends IoHandlerAdapter {
//messageSent是Server响应给Clinet成功后触发的事件
@Override
public void messageSent(IoSession session, Object message) throws Exception {
if (message instanceof IoBuffer) {
IoBuffer buffer = (IoBuffer) message;
byte[] bb = buffer.array();
for (int i = 0; i < bb.length; i++) {
System.out.print((char) bb[i]);
}
}
}
//抛出异常触发的事件
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
cause.printStackTrace();
session.close(true);
}
//Server接收到UDP请求触发的事件
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
System.out.println("messageReceived");
if (message instanceof IoBuffer) {
IoBuffer buffer = (IoBuffer) message;
// byte[] bb = buffer.array();
// for(int i=0;i<bb.length;i++) {
// System.out.print((char)bb[i]);
// }
IoBuffer buffer1 = IoBuffer.wrap("11".getBytes());//返回信息给Clinet端
session.write(buffer1);
//声明这里message必须为IoBuffer类型
}
}
//连接关闭触发的事件
@Override
public void sessionClosed(IoSession session) throws Exception {
System.out.println("Session closed...");
}
//建立连接触发的事件
@Override
public void sessionCreated(IoSession session) throws Exception {
System.out.println("Session created...");
SocketAddress remoteAddress = session.getRemoteAddress();
System.out.println(remoteAddress);
}
//会话空闲
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
System.out.println("Session idle...");
}
//打开连接触发的事件它与sessionCreated的区别在于一个连接地址A第一次请求Server会建立一个Session默认超时时间为1分钟此时若未达到超时时间这个连接地址A再一次向Server发送请求即是sessionOpened连接地址A第一次向Server发送请求或者连接超时后向Server发送请求时会同时触发sessionCreated和sessionOpened两个事件
@Override
public void sessionOpened(IoSession session) throws Exception {
System.out.println("Session Opened...");
SocketAddress remoteAddress = session.getRemoteAddress();
System.out.println(remoteAddress);
}
public void send(String host, int port) {
try {
InetAddress ia = InetAddress.getByName(host);
DatagramSocket socket = new DatagramSocket(9999);
socket.connect(ia, port);
byte[] buffer = new byte[1024];
buffer = ("22")
.getBytes();
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
System.out.println(dp.getLength());
DatagramPacket dp1 = new DatagramPacket(new byte[22312], 22312);
socket.send(dp);
socket.receive(dp1);
byte[] bb = dp1.getData();
for (int i = 0; i < dp1.getLength(); i++) {
System.out.print((char) bb[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@ -1,22 +1,20 @@
package net.mamoe.mirai.network
import io.netty.bootstrap.Bootstrap
import io.netty.channel.*
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.nio.NioDatagramChannel
import io.netty.handler.codec.bytes.ByteArrayDecoder
import io.netty.channel.Channel
import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.login.*
import net.mamoe.mirai.network.packet.client.touch.ClientTouchPacket
import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.login.*
import net.mamoe.mirai.network.packet.server.security.ServerSessionKeyResponsePacket
import net.mamoe.mirai.network.packet.server.security.ServerSessionKeyResponsePacketEncrypted
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacket
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacketEncrypted
import net.mamoe.mirai.util.getRandomKey
import net.mamoe.mirai.util.toHexString
import net.mamoe.mirai.utils.MiraiLogger
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetSocketAddress
/**
@ -29,7 +27,7 @@ class Robot(val number: Int, private val password: String) {
private var channel: Channel? = null
private var serverIP: String = ""
var serverIP: String = ""
set(value) {
serverAddress = InetSocketAddress(value, 8000)
field = value
@ -64,7 +62,8 @@ class Robot(val number: Int, private val password: String) {
when (packet) {
is ServerTouchResponsePacket -> {
if (packet.serverIP != null) {//redirection
connect(packet.serverIP!!)
serverIP = packet.serverIP!!
//connect(packet.serverIP!!)
sendPacket(ClientServerRedirectionPacket(packet.serverIP!!, number))
} else {//password submission
this.loginIP = packet.loginIP
@ -93,7 +92,7 @@ class Robot(val number: Int, private val password: String) {
is ServerLoginResponseSuccessPacket -> {
this._0828_rec_decr_key = packet._0828_rec_decr_key
sendPacket(ClientLoginSucceedConfirmationPacket(this.number, this.serverIP, this.md5_32, packet.token38, packet.token88, packet.encryptionKey, this.tlv0105))
sendPacket(ClientLoginSucceedConfirmationPacket(this.number, this.serverIP, this.loginIP, this.md5_32, packet.token38, packet.token88, packet.encryptionKey, this.tlv0105))
}
//这个有可能是客户端发送验证码之后收到的回复验证码是否正确?
@ -114,14 +113,15 @@ class Robot(val number: Int, private val password: String) {
is ServerLoginResponseResendPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
is ServerLoginResponseSuccessPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
is ServerSessionKeyResponsePacketEncrypted -> onPacketReceived(packet.decrypt(this._0828_rec_decr_key))
is ServerTouchResponsePacketEncrypted -> onPacketReceived(packet.decrypt())
else -> throw IllegalStateException()
else -> throw IllegalArgumentException(packet.toString())
}
}
@ExperimentalUnsignedTypes
private fun sendPacket(packet: ClientPacket) {
fun sendPacket(packet: ClientPacket) {
try {
MiraiLogger log "Encoding"
packet.encode()
@ -129,19 +129,68 @@ class Robot(val number: Int, private val password: String) {
e.printStackTrace()
}
packet.writeHex(Protocol.tail)
println(packet)
println(packet.toByteArray().toUByteArray().toHexString())
/*val p = DatagramPacket(packet.toByteArray());
p.socketAddress = this.serverAddress*/
channel!!.writeAndFlush(DatagramPacket(packet.toByteArray()))
//ctx.writeAndFlush(packet.toByteArray()).sync()
send(packet.toByteArray())
//println(channel!!.writeAndFlush(packet.toByteArray()).channel().connect(serverAddress).sync().get())
MiraiLogger info "Packet sent: $packet"
}
private fun DatagramPacket(toByteArray: ByteArray): DatagramPacket = DatagramPacket(toByteArray, toByteArray.size, this.serverAddress)
// private val socket = DatagramSocket(15314)
@ExperimentalUnsignedTypes
fun send(data: ByteArray) {
try {
val socket = DatagramSocket((15314 + Math.random() * 5).toInt())
socket.connect(this.serverAddress)
val dp1 = DatagramPacket(ByteArray(22312), 22312)
socket.send(DatagramPacket(data, data.size))
socket.receive(dp1)
val zeroByte: Byte = 0
var i = dp1.data.size - 1;
while (dp1.data[i] == zeroByte) {
--i
}
socket.close()
onPacketReceived(ServerPacket.ofByteArray(dp1.data.copyOfRange(0, i + 1)))
} catch (e: Exception) {
e.printStackTrace()
}
}
/*
private lateinit var ctx: ChannelHandlerContext
@ExperimentalUnsignedTypes
@Throws(InterruptedException::class)
fun connect(ip: String) {
this.serverIP = ip
NioDatagramConnector().let { it.handler = object : IoHandlerAdapter(), IoHandler {
} }
IoConnector connector=udpClient.getConnector();
connector.getFilterChain().addLast("codec",
ProtocolCodecFilter(
TextLineCodecFactory(
Charset.forName("UTF-8"),
LineDelimiter.WINDOWS.getValue(),
LineDelimiter.WINDOWS.getValue())));
ConnectFuture connectFuture=connector.connect(udpClient.getInetSocketAddress());
// 等待是否连接成功,相当于是转异步执行为同步执行。
connectFuture.awaitUninterruptibly();
//连接成功后获取会话对象。如果没有上面的等待由于connect()方法是异步的,
//connectFuture.getSession(),session可能会无法获取。
udpClient.setSession(connectFuture.getSession());
udpClient.getSession().write("HelloUDPServer!");
val group = NioEventLoopGroup()
try {
val b = Bootstrap()
@ -151,14 +200,17 @@ class Robot(val number: Int, private val password: String) {
.channel(NioDatagramChannel::class.java)
.option(ChannelOption.SO_BROADCAST, true)
.handler(object : ChannelInitializer<NioDatagramChannel>() {
override fun channelActive(ctx: ChannelHandlerContext?) {
this@Robot.ctx = ctx!!
super.channelActive(ctx)
}
@Throws(Exception::class)
override fun initChannel(ch: NioDatagramChannel) {
/*ch.pipeline().addLast(object : MessageToMessageEncoder<ByteArray>() {
override fun encode(ctx: ChannelHandlerContext?, msg: ByteArray?, out: MutableList<Any>?) {
out!!.add(DatagramPacket(msg!!))
}
})*/
ch.pipeline().addLast(ByteArrayDecoder())
ch.pipeline().addLast(ByteArrayEncoder())
ch.pipeline().addLast(object : SimpleChannelInboundHandler<ByteArray>() {
override fun channelRead0(ctx: ChannelHandlerContext, bytes: ByteArray) {
try {
@ -172,6 +224,20 @@ class Robot(val number: Int, private val password: String) {
MiraiLogger.catching(cause)
}
})
ch.pipeline().addLast(object : SimpleChannelInboundHandler<DatagramPacket>() {
override fun channelRead0(ctx: ChannelHandlerContext, bytes: DatagramPacket) {
try {
this@Robot.onPacketReceived(ServerPacket.ofByteArray(bytes.data))
} catch (e: Exception) {
MiraiLogger.catching(e)
}
}
override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) {
MiraiLogger.catching(cause)
}
})
}
})
@ -183,5 +249,5 @@ class Robot(val number: Int, private val password: String) {
} finally {
group.shutdownGracefully().sync()
}
}
}*/
}

View File

@ -73,6 +73,7 @@ open class ClientLoginResendPacket internal constructor(val qq: Int, val passwor
class ClientLoginSucceedConfirmationPacket(
private val qq: Int,
private val serverIp: String,
private val loginIP: String,
private val md5_32: ByteArray,
private val token38: ByteArray,
private val token88: ByteArray,
@ -111,7 +112,7 @@ class ClientLoginSucceedConfirmationPacket(
this.writeHex("68")
this.writeHex("00 00 00 00 00 2D 00 06 00 01")
this.writeIP("127.0.0.1")//本地IP地址? todo test that
this.writeIP(loginIP)//本地IP地址? todo test that
return super.toByteArray()
}

View File

@ -6,6 +6,7 @@ import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.client.writeIP
import net.mamoe.mirai.network.packet.client.writeQQ
import net.mamoe.mirai.util.ByteArrayDataOutputStream
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.hexToBytes
import java.io.IOException
@ -25,9 +26,9 @@ class ClientServerRedirectionPacket(private val serverIP: String, private val qq
this.writeHex(Protocol.redirectionKey)
this.write(TEACryptor.encrypt(object : ClientPacket() {
this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
@Throws(IOException::class)
override fun encode() {
override fun toByteArray(): ByteArray {
this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2)
this.writeQQ(qq)
@ -35,7 +36,8 @@ class ClientServerRedirectionPacket(private val serverIP: String, private val qq
this.writeIP(serverIP)
this.writeHex("01 6F A1 58 22 01 00 36 00 12 00 02 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 14 00 1D 01 03 00 19")
this.writeHex(Protocol.publicKey)
return super.toByteArray()
}
}.encodeToByteArray(), Protocol.redirectionKey.hexToBytes()))
}.toByteArray(), Protocol.redirectionKey.hexToBytes()))
}
}

View File

@ -38,10 +38,12 @@ class ClientTouchPacket(val qq: Int, val serverIp: String) : ClientPacket() {
this.writeQQ(qq)
this.writeHex("00 00 00 00 03 09 00 08 00 01")
//this.writeIP("192.168.1.1");
println("serverIp=$serverIp")
this.writeIP(serverIp);
//this.writeIP("123456789")
this.writeHex("00 02 00 36 00 12 00 02 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 14 00 1D 01 02 00 19")
this.writeHex(Protocol.publicKey)
println(super.toUByteArray().toHexString())
return super.toByteArray()
}
}.toByteArray()))

View File

@ -19,7 +19,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
@ExperimentalUnsignedTypes
fun ofByteArray(bytes: ByteArray): ServerPacket {
println("Raw received: $bytes")
println("Raw received: ${bytes.toUByteArray().toHexString()}")
val stream = bytes.dataInputStream()
@ -78,10 +78,9 @@ fun DataInputStream.readUntil(byte: Byte): ByteArray {
fun DataInputStream.readIP(): String {
var buff = ""
for (i in 0..3) {
val byte = readByte()
buff += (byte.toUByte().toString())
val byte = readUnsignedByte()
buff += byte.toString()
if (i != 3) buff += "."
println(byte.toHexString())
}
return buff
}

View File

@ -123,7 +123,7 @@ class ServerLoginResponseSuccessPacketEncrypted(input: DataInputStream, val leng
@ExperimentalUnsignedTypes
fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseSuccessPacket {//todo test
this.input.skip(14)
this.input.skip(7)
return ServerLoginResponseSuccessPacket(TEACryptor.decrypt(TEACryptor.decrypt(this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, Protocol.shareKey.hexToBytes()), tgtgtKey).dataInputStream(), length);
//TeaDecrypt(取文本中间(data, 43, 取文本长度(data) 45), m_0828_rec_decr_key)
}

View File

@ -47,7 +47,7 @@ class ServerSessionKeyResponsePacketEncrypted(inputStream: DataInputStream) : Se
}
fun decrypt(_0828_rec_decr_key: ByteArray): ServerSessionKeyResponsePacket {//todo test
this.input.skip(14)
this.input.skip(7)
return ServerSessionKeyResponsePacket(TEACryptor.decrypt(this.input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, _0828_rec_decr_key).dataInputStream());
//TeaDecrypt(取文本中间(data, 43, 取文本长度(data) 45), m_0828_rec_decr_key)
}

View File

@ -6,6 +6,8 @@ import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.readIP
import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.getRandomKey
import net.mamoe.mirai.util.hexToBytes
import net.mamoe.mirai.util.toHexString
import java.io.DataInputStream
/**
@ -17,7 +19,7 @@ import java.io.DataInputStream
* @author Him188moe
*/
@ToString
class ServerTouchResponsePacket(private val type: Type, inputStream: DataInputStream) : ServerPacket(inputStream) {
class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
var serverIP: String? = null;
var loginTime: Int = 0
@ -32,12 +34,12 @@ class ServerTouchResponsePacket(private val type: Type, inputStream: DataInputSt
@ExperimentalUnsignedTypes
override fun decode() {
when (input.readByte().toInt()) {
when (val id = input.readByte().toUByte().toInt()) {
0xFE -> {
input.skip(94)
serverIP = input.readIP()
}
0X00 -> {
0x00 -> {
input.skip(4)
token = input.readNBytes(56)
input.skip(6)
@ -48,7 +50,7 @@ class ServerTouchResponsePacket(private val type: Type, inputStream: DataInputSt
}
else -> {
throw IllegalStateException()
throw IllegalStateException(arrayOf(id.toUByte()).toUByteArray().toHexString())
}
}
}
@ -59,11 +61,16 @@ class ServerTouchResponsePacketEncrypted(private val type: ServerTouchResponsePa
}
@ExperimentalUnsignedTypes
fun decrypt(): ServerTouchResponsePacket {
input.skip(14)
return ServerTouchResponsePacket(type, DataInputStream(TEACryptor.decrypt(input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, when (type) {
ServerTouchResponsePacket.Type.TYPE_08_25_31_01 -> Protocol.redirectionKey.toByteArray()
ServerTouchResponsePacket.Type.TYPE_08_25_31_02 -> Protocol._0825key.toByteArray()
input.skip(7)
var bytes = input.readAllBytes();
bytes = bytes.copyOfRange(0, bytes.size - 1);
println(bytes.toUByteArray().toHexString())
return ServerTouchResponsePacket(DataInputStream(TEACryptor.decrypt(bytes, when (type) {
ServerTouchResponsePacket.Type.TYPE_08_25_31_02 -> Protocol.redirectionKey.hexToBytes()
ServerTouchResponsePacket.Type.TYPE_08_25_31_01 -> Protocol._0825key.hexToBytes()
}).inputStream()));
}
}

View File

@ -177,7 +177,7 @@ public class TEACryptor {
private byte[] decrypt(byte[] ciphertext, int offset, int len) {
if (len % 8 != 0 || len < 16) {
return null;
throw new IllegalArgumentException("must len % 8 == 0 && len >= 16");
}
mIV = decode(ciphertext, offset);
mIndexPos = mIV[0] & 7;
@ -199,7 +199,7 @@ public class TEACryptor {
if (mIndexPos == 8) {
isFirstBlock = false;
if (!decodeOneBlock(ciphertext, offset, len)) {
return null;
throw new RuntimeException("Unable to decode");
}
}
}
@ -215,14 +215,14 @@ public class TEACryptor {
mPreOutPos = mOutPos - 8;
isFirstBlock = false;
if (!decodeOneBlock(ciphertext, offset, len)) {
return null;
throw new RuntimeException("Unable to decode");
}
}
}
for (g = 0; g < 7; g++) {
if (mIndexPos < 8) {
if ((ciphertext[mPreOutPos + offset + mIndexPos] ^ mIV[mIndexPos]) != 0) {
return null;
throw new RuntimeException();
} else {
++mIndexPos;
}
@ -231,7 +231,7 @@ public class TEACryptor {
if (mIndexPos == 8) {
mPreOutPos = mOutPos;
if (!decodeOneBlock(ciphertext, offset, len)) {
return null;
throw new RuntimeException("Unable to decode");
}
}
}

View File

@ -2,6 +2,7 @@ package net.mamoe.mirai.utils.config;
import net.mamoe.mirai.MiraiServer;
import net.mamoe.mirai.utils.Utils;
import org.jetbrains.annotations.NotNull;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
@ -9,27 +10,34 @@ import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
/**
* YAML-TYPE CONFIG
* Thread SAFE
*
* @author NaturalHG
*/
public class MiraiConfig extends MiraiConfigSection<Object>{
public class MiraiConfig extends MiraiConfigSection<Object> {
private volatile File root;
private final File root;
public MiraiConfig(File file){
public MiraiConfig(@NotNull String configName) {
this(new File(MiraiServer.getInstance().getParentFolder(), Objects.requireNonNull(configName)));
}
public MiraiConfig(@NotNull File file) {
super();
if(!file.toURI().getPath().contains(MiraiServer.getInstance().getParentFolder().getPath())){
file = new File((MiraiServer.getInstance().getParentFolder().getPath() + "/" + file).replace("//","/"));
}
Objects.requireNonNull(file);
/*if (!file.toURI().getPath().contains(MiraiServer.getInstance().getParentFolder().getPath())) {
file = new File(MiraiServer.getInstance().getParentFolder().getPath(), file.getName());
}*/
this.root = file;
if(!file.exists()){
if (!file.exists()) {
try {
if(!file.createNewFile()){
if (!file.createNewFile()) {
return;
}
} catch (IOException e) {
@ -39,31 +47,27 @@ public class MiraiConfig extends MiraiConfigSection<Object>{
this.parse();
}
private MiraiConfig(){
}
public synchronized void save(){
public synchronized void save() {
DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(dumperOptions);
String content = yaml.dump(this);
try {
Utils.writeFile(this.root,content);
Utils.writeFile(this.root, content);
} catch (IOException e) {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
private void parse(){
private void parse() {
DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(dumperOptions);
this.clear();
try {
Map<String,Object> content = yaml.loadAs(Utils.readFile(this.root), LinkedHashMap.class);
if(content != null) {
Map<String, Object> content = yaml.loadAs(Utils.readFile(this.root), LinkedHashMap.class);
if (content != null) {
this.putAll(content);
}
} catch (IOException e) {
@ -72,5 +76,4 @@ public class MiraiConfig extends MiraiConfigSection<Object>{
}
}

View File

@ -94,6 +94,13 @@
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.mina/mina-core -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.1.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency>
<groupId>net.java.dev.jna</groupId>