Commit 9be18408 authored by Him188moe's avatar Him188moe

update

parent e1f706f7
...@@ -28,4 +28,7 @@ hs_err_pid* ...@@ -28,4 +28,7 @@ hs_err_pid*
mirai.iml mirai.iml
/.idea/ /.idea/
.idea/* .idea/*
/.idea/* /.idea/*
\ No newline at end of file
test/
/test
\ No newline at end of file
...@@ -35,7 +35,6 @@ hex | 00 00 00 00 03 09 00 08 00 01 ...@@ -35,7 +35,6 @@ hex | 00 00 00 00 03 09 00 08 00 01
int | g_server 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 | 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 hex | #publicKey
TEA加密以上, key=MD52
### S -> C ### S -> C
......
...@@ -21,6 +21,23 @@ ...@@ -21,6 +21,23 @@
</parent> </parent>
<dependencies> <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> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-all</artifactId> <artifactId>netty-all</artifactId>
......
...@@ -4,8 +4,8 @@ import lombok.Getter; ...@@ -4,8 +4,8 @@ import lombok.Getter;
import net.mamoe.mirai.event.MiraiEventManager; import net.mamoe.mirai.event.MiraiEventManager;
import net.mamoe.mirai.event.events.server.ServerDisableEvent; import net.mamoe.mirai.event.events.server.ServerDisableEvent;
import net.mamoe.mirai.event.events.server.ServerEnableEvent; 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.Robot;
import net.mamoe.mirai.network.packet.client.touch.ClientTouchPacket;
import net.mamoe.mirai.task.MiraiTaskManager; import net.mamoe.mirai.task.MiraiTaskManager;
import net.mamoe.mirai.utils.LoggerTextFormat; import net.mamoe.mirai.utils.LoggerTextFormat;
import net.mamoe.mirai.utils.MiraiLogger; import net.mamoe.mirai.utils.MiraiLogger;
...@@ -116,11 +116,16 @@ public class MiraiServer { ...@@ -116,11 +116,16 @@ public class MiraiServer {
Robot robot = new Robot(1994701021, "xiaoqqq"); Robot robot = new Robot(1994701021, "xiaoqqq");
try { 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()); //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"); //robot.connect("125.39.132.242");
} catch (InterruptedException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
System.exit(1); System.exit(1);
} }
......
...@@ -4,10 +4,8 @@ import lombok.Getter; ...@@ -4,10 +4,8 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import net.mamoe.mirai.event.events.Cancellable; import net.mamoe.mirai.event.events.Cancellable;
import net.mamoe.mirai.event.events.MiraiEvent; import net.mamoe.mirai.event.events.MiraiEvent;
import net.mamoe.mirai.event.events.server.ServerDisableEvent;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
...@@ -79,7 +77,7 @@ public class MiraiEventHook<T extends MiraiEvent> implements Closeable { ...@@ -79,7 +77,7 @@ public class MiraiEventHook<T extends MiraiEvent> implements Closeable {
if(!(event instanceof Cancellable && event.isCancelled() && this.isIgnoreCancelled())){ if(!(event instanceof Cancellable && event.isCancelled() && this.isIgnoreCancelled())){
this.getHandler().accept((T) event); this.getHandler().accept((T) event);
} }
return this.valid.test((T)event); return this.valid == null || this.valid.test((T) event);
} }
/** /**
......
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();
}
}
}
}
package net.mamoe.mirai.network package net.mamoe.mirai.network
import io.netty.bootstrap.Bootstrap import io.netty.channel.Channel
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 net.mamoe.mirai.network.packet.client.ClientPacket import net.mamoe.mirai.network.packet.client.ClientPacket
import net.mamoe.mirai.network.packet.client.login.* 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.client.writeHex
import net.mamoe.mirai.network.packet.server.ServerPacket import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.login.* 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.ServerSessionKeyResponsePacket
import net.mamoe.mirai.network.packet.server.security.ServerSessionKeyResponsePacketEncrypted 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.ServerTouchResponsePacket
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacketEncrypted
import net.mamoe.mirai.util.getRandomKey import net.mamoe.mirai.util.getRandomKey
import net.mamoe.mirai.util.toHexString
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import java.net.DatagramPacket import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetSocketAddress import java.net.InetSocketAddress
/** /**
...@@ -29,7 +27,7 @@ class Robot(val number: Int, private val password: String) { ...@@ -29,7 +27,7 @@ class Robot(val number: Int, private val password: String) {
private var channel: Channel? = null private var channel: Channel? = null
private var serverIP: String = "" var serverIP: String = ""
set(value) { set(value) {
serverAddress = InetSocketAddress(value, 8000) serverAddress = InetSocketAddress(value, 8000)
field = value field = value
...@@ -64,7 +62,8 @@ class Robot(val number: Int, private val password: String) { ...@@ -64,7 +62,8 @@ class Robot(val number: Int, private val password: String) {
when (packet) { when (packet) {
is ServerTouchResponsePacket -> { is ServerTouchResponsePacket -> {
if (packet.serverIP != null) {//redirection if (packet.serverIP != null) {//redirection
connect(packet.serverIP!!) serverIP = packet.serverIP!!
//connect(packet.serverIP!!)
sendPacket(ClientServerRedirectionPacket(packet.serverIP!!, number)) sendPacket(ClientServerRedirectionPacket(packet.serverIP!!, number))
} else {//password submission } else {//password submission
this.loginIP = packet.loginIP this.loginIP = packet.loginIP
...@@ -93,7 +92,7 @@ class Robot(val number: Int, private val password: String) { ...@@ -93,7 +92,7 @@ class Robot(val number: Int, private val password: String) {
is ServerLoginResponseSuccessPacket -> { is ServerLoginResponseSuccessPacket -> {
this._0828_rec_decr_key = packet._0828_rec_decr_key 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) { ...@@ -114,14 +113,15 @@ class Robot(val number: Int, private val password: String) {
is ServerLoginResponseResendPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!)) is ServerLoginResponseResendPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
is ServerLoginResponseSuccessPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!)) is ServerLoginResponseSuccessPacketEncrypted -> onPacketReceived(packet.decrypt(this.tgtgtKey!!))
is ServerSessionKeyResponsePacketEncrypted -> onPacketReceived(packet.decrypt(this._0828_rec_decr_key)) is ServerSessionKeyResponsePacketEncrypted -> onPacketReceived(packet.decrypt(this._0828_rec_decr_key))
is ServerTouchResponsePacketEncrypted -> onPacketReceived(packet.decrypt())
else -> throw IllegalStateException() else -> throw IllegalArgumentException(packet.toString())
} }
} }
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
private fun sendPacket(packet: ClientPacket) { fun sendPacket(packet: ClientPacket) {
try { try {
MiraiLogger log "Encoding" MiraiLogger log "Encoding"
packet.encode() packet.encode()
...@@ -129,19 +129,68 @@ class Robot(val number: Int, private val password: String) { ...@@ -129,19 +129,68 @@ class Robot(val number: Int, private val password: String) {
e.printStackTrace() e.printStackTrace()
} }
packet.writeHex(Protocol.tail) packet.writeHex(Protocol.tail)
println(packet)
println(packet.toByteArray().toUByteArray().toHexString())
/*val p = DatagramPacket(packet.toByteArray()); /*val p = DatagramPacket(packet.toByteArray());
p.socketAddress = this.serverAddress*/ 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" MiraiLogger info "Packet sent: $packet"
} }
private fun DatagramPacket(toByteArray: ByteArray): DatagramPacket = DatagramPacket(toByteArray, toByteArray.size, this.serverAddress) 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 @ExperimentalUnsignedTypes
@Throws(InterruptedException::class) @Throws(InterruptedException::class)
fun connect(ip: String) { fun connect(ip: String) {
this.serverIP = ip 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("Hello,UDPServer!");
val group = NioEventLoopGroup() val group = NioEventLoopGroup()
try { try {
val b = Bootstrap() val b = Bootstrap()
...@@ -151,14 +200,17 @@ class Robot(val number: Int, private val password: String) { ...@@ -151,14 +200,17 @@ class Robot(val number: Int, private val password: String) {
.channel(NioDatagramChannel::class.java) .channel(NioDatagramChannel::class.java)
.option(ChannelOption.SO_BROADCAST, true) .option(ChannelOption.SO_BROADCAST, true)
.handler(object : ChannelInitializer<NioDatagramChannel>() { .handler(object : ChannelInitializer<NioDatagramChannel>() {
override fun channelActive(ctx: ChannelHandlerContext?) {
this@Robot.ctx = ctx!!
super.channelActive(ctx)
}
@Throws(Exception::class) @Throws(Exception::class)
override fun initChannel(ch: NioDatagramChannel) { 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(ByteArrayDecoder())
ch.pipeline().addLast(ByteArrayEncoder())
ch.pipeline().addLast(object : SimpleChannelInboundHandler<ByteArray>() { ch.pipeline().addLast(object : SimpleChannelInboundHandler<ByteArray>() {
override fun channelRead0(ctx: ChannelHandlerContext, bytes: ByteArray) { override fun channelRead0(ctx: ChannelHandlerContext, bytes: ByteArray) {
try { try {
...@@ -172,6 +224,20 @@ class Robot(val number: Int, private val password: String) { ...@@ -172,6 +224,20 @@ class Robot(val number: Int, private val password: String) {
MiraiLogger.catching(cause) 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) { ...@@ -183,5 +249,5 @@ class Robot(val number: Int, private val password: String) {
} finally { } finally {
group.shutdownGracefully().sync() group.shutdownGracefully().sync()
} }
} }*/
} }
...@@ -73,6 +73,7 @@ open class ClientLoginResendPacket internal constructor(val qq: Int, val passwor ...@@ -73,6 +73,7 @@ open class ClientLoginResendPacket internal constructor(val qq: Int, val passwor
class ClientLoginSucceedConfirmationPacket( class ClientLoginSucceedConfirmationPacket(
private val qq: Int, private val qq: Int,
private val serverIp: String, private val serverIp: String,
private val loginIP: String,
private val md5_32: ByteArray, private val md5_32: ByteArray,
private val token38: ByteArray, private val token38: ByteArray,
private val token88: ByteArray, private val token88: ByteArray,
...@@ -111,7 +112,7 @@ class ClientLoginSucceedConfirmationPacket( ...@@ -111,7 +112,7 @@ class ClientLoginSucceedConfirmationPacket(
this.writeHex("68") this.writeHex("68")
this.writeHex("00 00 00 00 00 2D 00 06 00 01") 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() return super.toByteArray()
} }
......
...@@ -6,6 +6,7 @@ import net.mamoe.mirai.network.packet.client.ClientPacket ...@@ -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.writeHex
import net.mamoe.mirai.network.packet.client.writeIP import net.mamoe.mirai.network.packet.client.writeIP
import net.mamoe.mirai.network.packet.client.writeQQ 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.TEACryptor
import net.mamoe.mirai.util.hexToBytes import net.mamoe.mirai.util.hexToBytes
import java.io.IOException import java.io.IOException
...@@ -25,9 +26,9 @@ class ClientServerRedirectionPacket(private val serverIP: String, private val qq ...@@ -25,9 +26,9 @@ class ClientServerRedirectionPacket(private val serverIP: String, private val qq
this.writeHex(Protocol.redirectionKey) this.writeHex(Protocol.redirectionKey)
this.write(TEACryptor.encrypt(object : ClientPacket() { this.write(TEACryptor.encrypt(object : ByteArrayDataOutputStream() {
@Throws(IOException::class) @Throws(IOException::class)
override fun encode() { override fun toByteArray(): ByteArray {
this.writeHex(Protocol._0825data0) this.writeHex(Protocol._0825data0)
this.writeHex(Protocol._0825data2) this.writeHex(Protocol._0825data2)
this.writeQQ(qq) this.writeQQ(qq)
...@@ -35,7 +36,8 @@ class ClientServerRedirectionPacket(private val serverIP: String, private val qq ...@@ -35,7 +36,8 @@ class ClientServerRedirectionPacket(private val serverIP: String, private val qq
this.writeIP(serverIP) 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("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) this.writeHex(Protocol.publicKey)
return super.toByteArray()
} }
}.encodeToByteArray(), Protocol.redirectionKey.hexToBytes())) }.toByteArray(), Protocol.redirectionKey.hexToBytes()))
} }
} }
\ No newline at end of file
...@@ -38,10 +38,12 @@ class ClientTouchPacket(val qq: Int, val serverIp: String) : ClientPacket() { ...@@ -38,10 +38,12 @@ class ClientTouchPacket(val qq: Int, val serverIp: String) : ClientPacket() {
this.writeQQ(qq) this.writeQQ(qq)
this.writeHex("00 00 00 00 03 09 00 08 00 01") this.writeHex("00 00 00 00 03 09 00 08 00 01")
//this.writeIP("192.168.1.1"); //this.writeIP("192.168.1.1");
println("serverIp=$serverIp")
this.writeIP(serverIp); this.writeIP(serverIp);
//this.writeIP("123456789") //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("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) this.writeHex(Protocol.publicKey)
println(super.toUByteArray().toHexString())
return super.toByteArray() return super.toByteArray()
} }
}.toByteArray())) }.toByteArray()))
......
...@@ -19,7 +19,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { ...@@ -19,7 +19,7 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun ofByteArray(bytes: ByteArray): ServerPacket { fun ofByteArray(bytes: ByteArray): ServerPacket {
println("Raw received: $bytes") println("Raw received: ${bytes.toUByteArray().toHexString()}")
val stream = bytes.dataInputStream() val stream = bytes.dataInputStream()
...@@ -78,10 +78,9 @@ fun DataInputStream.readUntil(byte: Byte): ByteArray { ...@@ -78,10 +78,9 @@ fun DataInputStream.readUntil(byte: Byte): ByteArray {
fun DataInputStream.readIP(): String { fun DataInputStream.readIP(): String {
var buff = "" var buff = ""
for (i in 0..3) { for (i in 0..3) {
val byte = readByte() val byte = readUnsignedByte()
buff += (byte.toUByte().toString()) buff += byte.toString()
if (i != 3) buff += "." if (i != 3) buff += "."
println(byte.toHexString())
} }
return buff return buff
} }
......
...@@ -123,7 +123,7 @@ class ServerLoginResponseSuccessPacketEncrypted(input: DataInputStream, val leng ...@@ -123,7 +123,7 @@ class ServerLoginResponseSuccessPacketEncrypted(input: DataInputStream, val leng
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseSuccessPacket {//todo test 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); 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) //TeaDecrypt(取文本中间(data, 43, 取文本长度(data) - 45), m_0828_rec_decr_key)
} }
......
...@@ -47,7 +47,7 @@ class ServerSessionKeyResponsePacketEncrypted(inputStream: DataInputStream) : Se ...@@ -47,7 +47,7 @@ class ServerSessionKeyResponsePacketEncrypted(inputStream: DataInputStream) : Se
} }
fun decrypt(_0828_rec_decr_key: ByteArray): ServerSessionKeyResponsePacket {//todo test 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()); 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) //TeaDecrypt(取文本中间(data, 43, 取文本长度(data) - 45), m_0828_rec_decr_key)
} }
......
...@@ -6,6 +6,8 @@ import net.mamoe.mirai.network.packet.server.ServerPacket ...@@ -6,6 +6,8 @@ import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.readIP import net.mamoe.mirai.network.packet.server.readIP
import net.mamoe.mirai.util.TEACryptor import net.mamoe.mirai.util.TEACryptor
import net.mamoe.mirai.util.getRandomKey import net.mamoe.mirai.util.getRandomKey
import net.mamoe.mirai.util.hexToBytes
import net.mamoe.mirai.util.toHexString
import java.io.DataInputStream import java.io.DataInputStream
/** /**
...@@ -17,7 +19,7 @@ import java.io.DataInputStream ...@@ -17,7 +19,7 @@ import java.io.DataInputStream
* @author Him188moe * @author Him188moe
*/ */
@ToString @ToString
class ServerTouchResponsePacket(private val type: Type, inputStream: DataInputStream) : ServerPacket(inputStream) { class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) {
var serverIP: String? = null; var serverIP: String? = null;
var loginTime: Int = 0 var loginTime: Int = 0
...@@ -32,12 +34,12 @@ class ServerTouchResponsePacket(private val type: Type, inputStream: DataInputSt ...@@ -32,12 +34,12 @@ class ServerTouchResponsePacket(private val type: Type, inputStream: DataInputSt
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
override fun decode() { override fun decode() {
when (input.readByte().toInt()) { when (val id = input.readByte().toUByte().toInt()) {
0xFE -> { 0xFE -> {
input.skip(94) input.skip(94)
serverIP = input.readIP() serverIP = input.readIP()
} }
0X00 -> { 0x00 -> {
input.skip(4) input.skip(4)
token = input.readNBytes(56) token = input.readNBytes(56)
input.skip(6) input.skip(6)
...@@ -48,7 +50,7 @@ class ServerTouchResponsePacket(private val type: Type, inputStream: DataInputSt ...@@ -48,7 +50,7 @@ class ServerTouchResponsePacket(private val type: Type, inputStream: DataInputSt
} }
else -> { else -> {
throw IllegalStateException() throw IllegalStateException(arrayOf(id.toUByte()).toUByteArray().toHexString())
} }
} }
} }
...@@ -59,11 +61,16 @@ class ServerTouchResponsePacketEncrypted(private val type: ServerTouchResponsePa ...@@ -59,11 +61,16 @@ class ServerTouchResponsePacketEncrypted(private val type: ServerTouchResponsePa
} }
@ExperimentalUnsignedTypes
fun decrypt(): ServerTouchResponsePacket { fun decrypt(): ServerTouchResponsePacket {
input.skip(14) input.skip(7)
return ServerTouchResponsePacket(type, DataInputStream(TEACryptor.decrypt(input.readAllBytes().let { it.copyOfRange(0, it.size - 1) }, when (type) { var bytes = input.readAllBytes();
ServerTouchResponsePacket.Type.TYPE_08_25_31_01 -> Protocol.redirectionKey.toByteArray() bytes = bytes.copyOfRange(0, bytes.size - 1);
ServerTouchResponsePacket.Type.TYPE_08_25_31_02 -> Protocol._0825key.toByteArray() 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())); }).inputStream()));
} }
} }
\ No newline at end of file
...@@ -177,7 +177,7 @@ public class TEACryptor { ...@@ -177,7 +177,7 @@ public class TEACryptor {
private byte[] decrypt(byte[] ciphertext, int offset, int len) { private byte[] decrypt(byte[] ciphertext, int offset, int len) {
if (len % 8 != 0 || len < 16) { if (len % 8 != 0 || len < 16) {
return null; throw new IllegalArgumentException("must len % 8 == 0 && len >= 16");
} }
mIV = decode(ciphertext, offset); mIV = decode(ciphertext, offset);
mIndexPos = mIV[0] & 7; mIndexPos = mIV[0] & 7;
...@@ -199,7 +199,7 @@ public class TEACryptor { ...@@ -199,7 +199,7 @@ public class TEACryptor {
if (mIndexPos == 8) { if (mIndexPos == 8) {
isFirstBlock = false; isFirstBlock = false;
if (!decodeOneBlock(ciphertext, offset, len)) { if (!decodeOneBlock(ciphertext, offset, len)) {
return null; throw new RuntimeException("Unable to decode");
} }
} }
} }
...@@ -215,14 +215,14 @@ public class TEACryptor { ...@@ -215,14 +215,14 @@ public class TEACryptor {
mPreOutPos = mOutPos - 8; mPreOutPos = mOutPos - 8;
isFirstBlock = false; isFirstBlock = false;
if (!decodeOneBlock(ciphertext, offset, len)) { if (!decodeOneBlock(ciphertext, offset, len)) {
return null; throw new RuntimeException("Unable to decode");
} }
} }
} }
for (g = 0; g < 7; g++) { for (g = 0; g < 7; g++) {
if (mIndexPos < 8) { if (mIndexPos < 8) {
if ((ciphertext[mPreOutPos + offset + mIndexPos] ^ mIV[mIndexPos]) != 0) { if ((ciphertext[mPreOutPos + offset + mIndexPos] ^ mIV[mIndexPos]) != 0) {
return null; throw new RuntimeException();
} else { } else {
++mIndexPos; ++mIndexPos;
} }
...@@ -231,7 +231,7 @@ public class TEACryptor { ...@@ -231,7 +231,7 @@ public class TEACryptor {
if (mIndexPos == 8) { if (mIndexPos == 8) {
mPreOutPos = mOutPos; mPreOutPos = mOutPos;
if (!decodeOneBlock(ciphertext, offset, len)) { if (!decodeOneBlock(ciphertext, offset, len)) {
return null; throw new RuntimeException("Unable to decode");
} }
} }
} }
......
...@@ -2,6 +2,7 @@ package net.mamoe.mirai.utils.config; ...@@ -2,6 +2,7 @@ package net.mamoe.mirai.utils.config;
import net.mamoe.mirai.MiraiServer; import net.mamoe.mirai.MiraiServer;
import net.mamoe.mirai.utils.Utils; import net.mamoe.mirai.utils.Utils;
import org.jetbrains.annotations.NotNull;
import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
...@@ -9,27 +10,34 @@ import java.io.File; ...@@ -9,27 +10,34 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* YAML-TYPE CONFIG * YAML-TYPE CONFIG
* Thread SAFE * Thread SAFE
*
* @author NaturalHG * @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(); super();
if(!file.toURI().getPath().contains(MiraiServer.getInstance().getParentFolder().getPath())){ Objects.requireNonNull(file);
file = new File((MiraiServer.getInstance().getParentFolder().getPath() + "/" + file).replace("//","/")); /*if (!file.toURI().getPath().contains(MiraiServer.getInstance().getParentFolder().getPath())) {
} file = new File(MiraiServer.getInstance().getParentFolder().getPath(), file.getName());
}*/
this.root = file; this.root = file;
if(!file.exists()){ if (!file.exists()) {
try { try {
if(!file.createNewFile()){ if (!file.createNewFile()) {
return; return;
} }
} catch (IOException e) { } catch (IOException e) {
...@@ -39,31 +47,27 @@ public class MiraiConfig extends MiraiConfigSection<Object>{ ...@@ -39,31 +47,27 @@ public class MiraiConfig extends MiraiConfigSection<Object>{
this.parse(); this.parse();
} }
private MiraiConfig(){ public synchronized void save() {
}
public synchronized void save(){
DumperOptions dumperOptions = new DumperOptions(); DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(dumperOptions); Yaml yaml = new Yaml(dumperOptions);
String content = yaml.dump(this); String content = yaml.dump(this);
try { try {
Utils.writeFile(this.root,content); Utils.writeFile(this.root, content);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void parse(){ private void parse() {
DumperOptions dumperOptions = new DumperOptions(); DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(dumperOptions); Yaml yaml = new Yaml(dumperOptions);
this.clear(); this.clear();
try { try {
Map<String,Object> content = yaml.loadAs(Utils.readFile(this.root), LinkedHashMap.class); Map<String, Object> content = yaml.loadAs(Utils.readFile(this.root), LinkedHashMap.class);
if(content != null) { if (content != null) {
this.putAll(content); this.putAll(content);
} }
} catch (IOException e) { } catch (IOException e) {
...@@ -72,5 +76,4 @@ public class MiraiConfig extends MiraiConfigSection<Object>{ ...@@ -72,5 +76,4 @@ public class MiraiConfig extends MiraiConfigSection<Object>{
} }
} }
...@@ -94,6 +94,13 @@ ...@@ -94,6 +94,13 @@
<dependencyManagement> <dependencyManagement>
<dependencies> <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 --> <!-- https://mvnrepository.com/artifact/net.java.dev.jna/jna -->
<dependency> <dependency>
<groupId>net.java.dev.jna</groupId> <groupId>net.java.dev.jna</groupId>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment