From 97b90b08c8b86e90009adde70337973aa0ed16d1 Mon Sep 17 00:00:00 2001 From: Him188moe Date: Fri, 16 Aug 2019 00:04:39 +0800 Subject: [PATCH] update --- .../java/net/mamoe/mirai/contact/Contact.kt | 2 +- .../main/java/net/mamoe/mirai/contact/QQ.kt | 4 +- .../net/mamoe/mirai/network/BinaryStream.java | 8 --- .../net/mamoe/mirai/network/ClientHandler.kt | 40 ++++++++++- .../java/net/mamoe/mirai/network/Robot.kt | 13 +++- .../packet/client/Client0825ResponsePacket.kt | 32 +++++++++ .../network/packet/server/Server0825Packet.kt | 38 +++++++++++ .../packet/server/ServerLoginSucceedPacket.kt | 11 +++ .../network/packet/server/ServerPacket.kt | 67 +++++++++++++------ .../net/mamoe/mirai/util/TEAEncryption.java | 4 +- 10 files changed, 184 insertions(+), 35 deletions(-) delete mode 100644 mirai-core/src/main/java/net/mamoe/mirai/network/BinaryStream.java create mode 100644 mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0825ResponsePacket.kt create mode 100644 mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/Server0825Packet.kt create mode 100644 mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerLoginSucceedPacket.kt diff --git a/mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt b/mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt index 108cd7e43..e2ec5509e 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/contact/Contact.kt @@ -5,7 +5,7 @@ package net.mamoe.mirai.contact * * @author Him188moe @ Mirai Project */ -abstract class Contact(number: Long) { +abstract class Contact(val number: Long) { /** * Async diff --git a/mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt b/mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt index e87a6ae70..159d1b4ac 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/contact/QQ.kt @@ -19,7 +19,7 @@ class QQ(number: Long) : Contact(number) { /** * At(@) this account. */ - open fun at(): String { - return "[@" + this.number + "]" + fun at(): String { + return "[@$number]" } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/BinaryStream.java b/mirai-core/src/main/java/net/mamoe/mirai/network/BinaryStream.java deleted file mode 100644 index ed862b37b..000000000 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/BinaryStream.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.mamoe.mirai.network; - -/** - * @author Him188moe @ Mirai Project - */ -public class BinaryStream { - -} diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/ClientHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/ClientHandler.kt index aa99ed1a1..353323594 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/ClientHandler.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/ClientHandler.kt @@ -11,8 +11,46 @@ import net.mamoe.mirai.network.packet.server.ServerPacket */ @Log4j2 class ClientHandler(val robot: Robot) : SimpleChannelInboundHandler() { - override fun channelRead0(ctx: ChannelHandlerContext?, bytes: ByteArray?) { + private object Reader { + private var length: Int? = null + private lateinit var bytes: ByteArray + + fun init(bytes: ByteArray) { + this.length = length + this.bytes = bytes + } + + /** + * Reads bytes, combining them to create a packet, returning remaining bytes. + */ + fun read(bytes: ByteArray): ByteArray? { + checkNotNull(this.length) + val needSize = length!! - this.bytes.size;//How many bytes we need + if (needSize == bytes.size || needSize > bytes.size) { + this.bytes += bytes + return null; + } + + //We got more than we need + this.bytes += bytes.copyOfRange(0, needSize) + return bytes.copyOfRange(needSize, bytes.size - needSize)//We got remaining bytes, that is of another packet + } + + fun isPacketAvailable() = this.length == this.bytes.size + + fun toServerPacket(): ServerPacket { + return ServerPacket.ofByteArray(this.bytes) + } + } + + override fun channelRead0(ctx: ChannelHandlerContext?, bytes: ByteArray) { try { + /*val remaining = Reader.read(bytes); + if (Reader.isPacketAvailable()) { + robot.onPacketReceived(Reader.toServerPacket()) + Reader.init() + remaining + }*/ robot.onPacketReceived(ServerPacket.ofByteArray(bytes)) } catch (e: Exception) { MiraiServer.getLogger().catching(e) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/Robot.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/Robot.kt index 6ee1f968e..7becbac1e 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/Robot.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/Robot.kt @@ -1,12 +1,16 @@ package net.mamoe.mirai.network import net.mamoe.mirai.network.packet.Packet +import net.mamoe.mirai.network.packet.client.Client0825ResponsePacket +import net.mamoe.mirai.network.packet.server.Server0825Packet import net.mamoe.mirai.network.packet.server.ServerPacket /** + * [number] is a QQ number. + * * @author Him188moe @ Mirai Project */ -open class Robot() { +class Robot(val number: Long) { internal fun onPacketReceived(packet: Packet) { if (packet !is ServerPacket) { @@ -14,5 +18,12 @@ open class Robot() { } packet.decode() + if (packet is Server0825Packet) {//todo 检查是否需要修改 UDP 连接??? + sendPacket(Client0825ResponsePacket(packet.serverIP, number)); + } + } + + internal fun sendPacket(packet: Packet) { + TODO() } } \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0825ResponsePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0825ResponsePacket.kt new file mode 100644 index 000000000..536f1e7df --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0825ResponsePacket.kt @@ -0,0 +1,32 @@ +package net.mamoe.mirai.network.packet.client + +import net.mamoe.mirai.network.Protocol +import net.mamoe.mirai.network.packet.PacketId +import net.mamoe.mirai.util.TEAEncryption +import java.io.IOException + +/** + * @author Him188moe @ Mirai Project + */ +@PacketId(0x08_25_31_02) +class Client0825ResponsePacket(private val serverIP: String, private val qq: Long) : ClientPacket() { + override fun encode() { + this.writeQQ(qq) + this.writeHex(Protocol.fixVer) + this.writeHex(Protocol.redirectionKey) + + //TEA 加密 + this.write(TEAEncryption.encrypt(object : ClientPacket() { + @Throws(IOException::class) + override fun encode() { + this.writeHex(Protocol._0825data0) + this.writeHex(Protocol._0825data2) + this.writeQQ(qq) + this.writeHex("00 01 00 00 03 09 00 0C 00 01") + 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) + } + }.encodeToByteArray(), Protocol.hexToBytes(Protocol.redirectionKey))) + } +} \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/Server0825Packet.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/Server0825Packet.kt new file mode 100644 index 000000000..1ba5aabd5 --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/Server0825Packet.kt @@ -0,0 +1,38 @@ +package net.mamoe.mirai.network.packet.server + +import net.mamoe.mirai.network.Protocol +import net.mamoe.mirai.util.TEAEncryption +import java.io.DataInputStream + +/** + * A packet received when logging in, used to redirect server address + * + * @author Him188moe @ Mirai Project + */ +class Server0825Packet(private val type: Type, inputStream: DataInputStream) : ServerPacket(inputStream) { + lateinit var serverIP: String; + + enum class Type { + TYPE_08_25_31_01, + TYPE_08_25_31_02, + } + + override fun decode() { + input.skip(43 - 11)//todo: check + val data = DataInputStream(TEAEncryption.decrypt(input.readAllBytes().let { it.copyOfRange(0, it.size - 45) }, when (type) { + Type.TYPE_08_25_31_01 -> Protocol.redirectionKey.toByteArray() + Type.TYPE_08_25_31_02 -> Protocol._0825key.toByteArray() + }).inputStream()); + + when (data.readByte().toInt()) { + 0xFE -> { + serverIP = data.readIP() + } + 0X00 -> { + + } + else -> { + } + } + } +} \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerLoginSucceedPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerLoginSucceedPacket.kt new file mode 100644 index 000000000..2e5ab2902 --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerLoginSucceedPacket.kt @@ -0,0 +1,11 @@ +package net.mamoe.mirai.network.packet.server + +import java.io.DataInputStream + +/** + * @author Him188moe @ Mirai Project + */ +class ServerLoginSucceedPacket(inputStream: DataInputStream) : ServerPacket(inputStream) { + override fun decode() { + } +} \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt index 62d16a94f..1e89e2e7c 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/server/ServerPacket.kt @@ -1,28 +1,55 @@ -package net.mamoe.mirai.network.packet.server; +package net.mamoe.mirai.network.packet.server -import net.mamoe.mirai.network.packet.Packet; -import org.jetbrains.annotations.NotNull; +import net.mamoe.mirai.network.packet.Packet -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.InputStream; +import java.io.DataInputStream /** * @author Him188moe @ Mirai Project */ -public abstract class ServerPacket extends DataInputStream implements Packet { - public static ServerPacket ofByteArray(byte[] bytes) { - // TODO: 2019/8/15 process bytes +abstract class ServerPacket(val input: DataInputStream) : Packet { + + abstract fun decode() + + companion object { + + fun ofByteArray(bytes: ByteArray): ServerPacket { + + val stream = DataInputStream(bytes.inputStream()) + + stream.skipUntil(10) + val idBytes = stream.readUntil(11) + val id = idBytes.map { it.toString(16) }.joinToString("") + + return when (id) { + "08 25 31 01" -> Server0825Packet(Server0825Packet.Type.TYPE_08_25_31_01, stream); + "08 25 31 02" -> Server0825Packet(Server0825Packet.Type.TYPE_08_25_31_02, stream); + + else -> throw UnsupportedOperationException(); + } + } } - - - public ServerPacket(@NotNull InputStream in) { - super(in); - } - - public ServerPacket(@NotNull byte[] in) { - this(new ByteArrayInputStream(in)); - } - - public abstract void decode(); +} + +fun DataInputStream.skipUntil(byte: Byte) { + while (readByte() != byte); +} + +fun DataInputStream.readUntil(byte: Byte): ByteArray { + var buff = byteArrayOf() + var b: Byte + b = readByte() + while (b != byte) { + buff += b + b = readByte() + } + return buff +} + +fun DataInputStream.readIP(): String { + var buff = ""; + for (i in 0..12) {//todo: check that + buff += readByte().toInt(); + } + return buff; } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/util/TEAEncryption.java b/mirai-core/src/main/java/net/mamoe/mirai/util/TEAEncryption.java index e1e22a018..f359346c1 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/util/TEAEncryption.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/util/TEAEncryption.java @@ -8,11 +8,11 @@ public final class TEAEncryption { return new _TEAEncryption().encrypt(source, key); } - public byte[] decrypt(byte[] source, byte[] key) { + public static byte[] decrypt(byte[] source, byte[] key) { return new _TEAEncryption().decrypt(source, key); } - public byte[] decrypt(byte[] source, int offset, int length, byte[] key) { + public static byte[] decrypt(byte[] source, int offset, int length, byte[] key) { return new _TEAEncryption().decrypt(source, offset, length, key); }