From 37fa8055b58966ea40e86738593852cd0342026a Mon Sep 17 00:00:00 2001 From: Him188moe Date: Fri, 13 Sep 2019 12:51:14 +0800 Subject: [PATCH] Updated network --- .../mirai/network/BotNetworkHandlerImpl.kt | 2 +- .../java/net/mamoe/mirai/network/Protocol.kt | 6 +- .../network/handler/ActionPacketHandler.kt | 16 +- .../mirai/network/handler/DataPacketSocket.kt | 2 +- .../network/handler/MessagePacketHandler.kt | 2 +- .../mirai/network/packet/ClientPacket.kt | 40 +- .../mamoe/mirai/network/packet/GradeInfo.kt | 2 +- .../mamoe/mirai/network/packet/Heartbeat.kt | 2 +- .../net/mamoe/mirai/network/packet/SKey.kt | 4 +- .../mamoe/mirai/network/packet/ServerEvent.kt | 17 +- .../net/mamoe/mirai/network/packet/Session.kt | 9 +- .../net/mamoe/mirai/network/packet/Touch.kt | 22 +- .../mirai/network/packet/VerificationCode.kt | 16 +- .../mirai/network/packet/action/AddContact.kt | 8 +- .../action/ClientSendFriendMessagePacket.kt | 2 +- .../action/ClientSendGroupMessagePacket.kt | 2 +- .../network/packet/image/UploadGroupImage.kt | 6 +- .../login/ClientChangeOnlineStatusPacket.kt | 2 +- .../mirai/network/packet/login/ClientLogin.kt | 20 +- .../ServerLoginResponseKeyExchangePacket.kt | 8 +- ...rverLoginResponsePasswordVerifiedPacket.kt | 10 +- ...LoginResponseVerificationCodeInitPacket.kt | 10 +- .../main/java/net/mamoe/mirai/utils/TEA.kt | 456 +++++++++--------- .../main/java/net/mamoe/mirai/utils/Tested.kt | 2 +- .../main/java/net/mamoe/mirai/utils/Utils.kt | 24 +- .../main/java/net/mamoe/mirai/utils/Varint.kt | 13 +- mirai-core/src/test/java/PacketTest.kt | 47 -- 27 files changed, 349 insertions(+), 401 deletions(-) delete mode 100644 mirai-core/src/test/java/PacketTest.kt diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandlerImpl.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandlerImpl.kt index be6ebc345..adb26bfdd 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandlerImpl.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/BotNetworkHandlerImpl.kt @@ -185,7 +185,7 @@ internal class BotNetworkHandlerImpl(private val bot: Bot) : BotNetworkHandler { * Not async */ @Synchronized - @ExperimentalUnsignedTypes + override fun sendPacket(packet: ClientPacket) { checkNotNull(socket) { "network closed" } if (socket!!.isClosed) { diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt index 06e558b35..187d7327c 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/Protocol.kt @@ -1,3 +1,5 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE") + package net.mamoe.mirai.network import java.net.InetAddress @@ -72,7 +74,7 @@ object Protocol { private val hexToByteArrayCacheMap: MutableMap = mutableMapOf() - @ExperimentalUnsignedTypes + fun hexToBytes(hex: String): ByteArray { hex.hashCode().let { id -> if (hexToByteArrayCacheMap.containsKey(id)) { @@ -86,7 +88,7 @@ object Protocol { } } - @ExperimentalUnsignedTypes + fun hexToUBytes(hex: String): UByteArray = Arrays .stream(hex.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) .map { value -> value.trim { it <= ' ' } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/handler/ActionPacketHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/handler/ActionPacketHandler.kt index f28a562ba..bd68f3323 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/handler/ActionPacketHandler.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/handler/ActionPacketHandler.kt @@ -31,7 +31,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) { private var sKeyRefresherFuture: ScheduledFuture<*>? = null - @ExperimentalUnsignedTypes + override fun onPacketReceived(packet: ServerPacket) { when (packet) { is ServerCanAddFriendResponsePacket -> { @@ -74,12 +74,12 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) { } } - @ExperimentalUnsignedTypes + fun addFriend(qqNumber: Long, message: Supplier) { addFriend(qqNumber, lazy { message.get() }) } - @ExperimentalUnsignedTypes + @JvmSynthetic fun addFriend(qqNumber: Long, message: Lazy = lazyOf("")): CompletableFuture { val future = CompletableFuture() @@ -89,12 +89,12 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) { return future } - @ExperimentalUnsignedTypes + fun requestSKey() { session.socket.sendPacket(ClientSKeyRequestPacket(session.bot.account.qqNumber, session.sessionKey)) } - @ExperimentalUnsignedTypes + fun requestAccountInfo() { session.socket.sendPacket(ClientAccountInfoRequestPacket(session.bot.account.qqNumber, session.sessionKey)) } @@ -111,7 +111,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) { ) : Closeable { lateinit var id: ByteArray - @ExperimentalUnsignedTypes + fun onPacketReceived(packet: ServerPacket) { if (!::id.isInitialized) { return @@ -164,7 +164,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) { ) : Closeable { lateinit var id: ByteArray - @ExperimentalUnsignedTypes + fun onPacketReceived(packet: ServerPacket) { if (!::id.isInitialized) { return @@ -201,7 +201,7 @@ class ActionPacketHandler(session: LoginSession) : PacketHandler(session) { } } - @ExperimentalUnsignedTypes + fun sendAddRequest() { session.socket.sendPacket(ClientCanAddFriendPacket(session.bot.account.qqNumber, qq, session.sessionKey).also { this.id = it.packetIdLast }) } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/handler/DataPacketSocket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/handler/DataPacketSocket.kt index 3384c314d..ee31c5245 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/handler/DataPacketSocket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/handler/DataPacketSocket.kt @@ -16,7 +16,7 @@ interface DataPacketSocket : Closeable { fun distributePacket(packet: ServerPacket) - @ExperimentalUnsignedTypes + fun sendPacket(packet: ClientPacket) fun isClosed(): Boolean diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/handler/MessagePacketHandler.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/handler/MessagePacketHandler.kt index e71e0d932..3cfede045 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/handler/MessagePacketHandler.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/handler/MessagePacketHandler.kt @@ -74,7 +74,7 @@ class MessagePacketHandler(session: LoginSession) : PacketHandler(session) { session.socket.sendPacket(ClientSendFriendMessagePacket(session.bot.account.qqNumber, qq.number, session.sessionKey, message)) } - fun sendGroupMessage(group: Group, message: Message): Unit { + fun sendGroupMessage(group: Group, message: Message) { TODO() //sendPacket(ClientSendGroupMessagePacket(group.groupId, bot.account.qqNumber, sessionKey, message)) } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt index 3b48fd917..eccd56299 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt @@ -1,3 +1,5 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") + package net.mamoe.mirai.network.packet import lombok.Getter @@ -12,12 +14,12 @@ import java.security.MessageDigest /** * @author Him188moe */ -@ExperimentalUnsignedTypes + abstract class ClientPacket : ByteArrayDataOutputStream(), Packet { @Getter val idHex: String - var encoded: Boolean = false + private var encoded: Boolean = false init { val annotation = this.javaClass.getAnnotation(PacketId::class.java) @@ -84,7 +86,6 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet { } -@ExperimentalUnsignedTypes @Throws(IOException::class) fun DataOutputStream.writeIP(ip: String) { for (s in ip.trim().split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) { @@ -97,10 +98,9 @@ fun DataOutputStream.writeTime() { this.writeInt(System.currentTimeMillis().toInt()) } -@ExperimentalUnsignedTypes @Throws(IOException::class) -fun DataOutputStream.writeHex(hex: String) { - for (s in hex.trim().split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) { +fun DataOutputStream.writeHex(uHex: String) { + for (s in uHex.trim().split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) { if (s.isEmpty()) { continue } @@ -116,12 +116,10 @@ fun DataOutputStream.encryptAndWrite(key: ByteArray, encoder: (ByteArrayDataOutp this.write(TEA.encrypt(ByteArrayDataOutputStream().also(encoder).toByteArray(), key)) } -@ExperimentalUnsignedTypes fun DataOutputStream.encryptAndWrite(keyHex: String, encoder: (ByteArrayDataOutputStream) -> Unit) { this.encryptAndWrite(keyHex.hexToBytes(), encoder) } -@ExperimentalUnsignedTypes @Throws(IOException::class) fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray) { ByteArrayDataOutputStream().let { @@ -146,12 +144,10 @@ fun DataOutputStream.writeTLV0006(qq: Long, password: String, loginTime: Int, lo } } -@ExperimentalUnsignedTypes -@TestedSuccessfully +@Tested fun DataOutputStream.writeCRC32() = writeCRC32(getRandomByteArray(16)) -@ExperimentalUnsignedTypes fun DataOutputStream.writeCRC32(key: ByteArray) { key.let { write(it)//key @@ -159,8 +155,8 @@ fun DataOutputStream.writeCRC32(key: ByteArray) { } } -@ExperimentalUnsignedTypes -@TestedSuccessfully + +@Tested fun DataOutputStream.writeDeviceName(random: Boolean = false) { val deviceName: String = if (random) { String(getRandomByteArray(10)) @@ -185,7 +181,7 @@ fun Int.toByteArray(): ByteArray = byteArrayOf( /** * 255u -> 00 00 00 FF */ -@ExperimentalUnsignedTypes + fun UInt.toByteArray(): ByteArray = byteArrayOf( (this.shr(24) and 255u).toByte(), (this.shr(16) and 255u).toByte(), @@ -193,24 +189,14 @@ fun UInt.toByteArray(): ByteArray = byteArrayOf( (this.shr(0) and 255u).toByte() ) -/** - * 255 -> FF 00 00 00 - */ -fun Int.toLByteArray(): ByteArray = byteArrayOf( - (this.ushr(0) and 0xFF).toByte(), - (this.ushr(8) and 0xFF).toByte(), - (this.ushr(16) and 0xFF).toByte(), - (this.ushr(24) and 0xFF).toByte() -) -@ExperimentalUnsignedTypes fun Int.toUHexString(separator: String = " "): String = this.toByteArray().toUHexString(separator) internal fun md5(str: String): ByteArray = MessageDigest.getInstance("MD5").digest(str.toByteArray()) internal fun md5(byteArray: ByteArray): ByteArray = MessageDigest.getInstance("MD5").digest(byteArray) -@ExperimentalUnsignedTypes + @Throws(IOException::class) fun DataOutputStream.writeZero(count: Int) { repeat(count) { @@ -225,13 +211,13 @@ fun DataOutputStream.writeRandom(length: Int) { } } -@ExperimentalUnsignedTypes + @Throws(IOException::class) fun DataOutputStream.writeQQ(qq: Long) { this.write(qq.toUInt().toByteArray()) } -@ExperimentalUnsignedTypes + @Throws(IOException::class) fun DataOutputStream.writeGroup(groupIdOrGroupNumber: Long) { this.write(groupIdOrGroupNumber.toUInt().toByteArray()) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt index c208c07f0..d431672f9 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt @@ -9,7 +9,7 @@ import java.io.DataInputStream * * @author Him188moe */ -@ExperimentalUnsignedTypes + @PacketId("00 5C") class ClientAccountInfoRequestPacket( private val qq: Long, diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Heartbeat.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Heartbeat.kt index 9fcd36304..8a1192842 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Heartbeat.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Heartbeat.kt @@ -7,7 +7,7 @@ import java.io.IOException /** * @author Him188moe */ -@ExperimentalUnsignedTypes + @PacketId("00 58") class ClientHeartbeatPacket( private val qq: Long, diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt index 1e4d515ab..a9e61c8ab 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt @@ -10,7 +10,7 @@ import java.io.DataInputStream * * @author Him188moe */ -@ExperimentalUnsignedTypes + @PacketId("00 1D") class ClientSKeyRequestPacket( private val qq: Long, @@ -31,7 +31,7 @@ class ClientSKeyRequestPacket( * @author Him188moe */ @PacketId("00 1D") -@ExperimentalUnsignedTypes + class ClientSKeyRefreshmentRequestPacket( private val qq: Long, private val sessionKey: ByteArray diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt index 48f64a1d1..a5b605bdf 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerEvent.kt @@ -1,3 +1,5 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE") + package net.mamoe.mirai.network.packet import net.mamoe.mirai.message.FaceID @@ -22,7 +24,7 @@ import java.util.zip.GZIPInputStream abstract class ServerEventPacket(input: DataInputStream, val packetId: ByteArray, val eventIdentity: ByteArray) : ServerPacket(input) { @PacketId("00 17") class Raw(input: DataInputStream, private val packetId: ByteArray) : ServerPacket(input) { - @ExperimentalUnsignedTypes + fun distribute(): ServerEventPacket { val eventIdentity = this.input.readNBytes(16) val type = this.input.goto(18).readNBytes(2) @@ -80,6 +82,7 @@ class ServerGroupUploadFileEventPacket(input: DataInputStream, packetId: ByteArr }//todo test } +@Suppress("EXPERIMENTAL_API_USAGE") class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray, eventIdentity: ByteArray) : ServerEventPacket(input, packetId, eventIdentity) { var groupNumber: Long = 0 var qq: Long = 0 @@ -100,16 +103,16 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray, OTHER, } - @ExperimentalUnsignedTypes + override fun decode() { groupNumber = this.input.goto(51).readInt().toLong() - qq = this.input.goto(56).readLong().toUInt().toLong() + qq = this.input.goto(56).readLong() val fontLength = this.input.goto(108).readShort() //println(this.input.goto(110 + fontLength).readNBytesAt(2).toUHexString())//always 00 00 messageType = when (val id = this.input.goto(110 + fontLength + 2).readByte().toInt()) { 0x13 -> MessageType.NORMAL - 0xE -> MessageType.XML + 0x0E -> MessageType.XML 0x06 -> MessageType.AT @@ -188,7 +191,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray var qq: Long = 0 lateinit var message: MessageChain - @ExperimentalUnsignedTypes + override fun decode() { input.goto(0) println() @@ -291,7 +294,7 @@ B1 89 BE 09 8F 00 1A E5 00 0B 03 A2 09 90 BB 7A 1F 40 00 A6 00 00 00 20 00 05 00 * 告知服务器已经收到数据 */ @PacketId("")//随后写入 -@ExperimentalUnsignedTypes + class ClientMessageResponsePacket( private val qq: Long, private val packetIdFromServer: ByteArray,//4bytes @@ -329,7 +332,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray lateinit var message: String - @ExperimentalUnsignedTypes + override fun decode() { //start at Sep1.0:27 qq = input.readIntAt(0) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Session.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Session.kt index 4fcd289f4..f51c2d824 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Session.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Session.kt @@ -2,7 +2,6 @@ package net.mamoe.mirai.network.packet import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.utils.TEA -import net.mamoe.mirai.utils.getRandomByteArray import net.mamoe.mirai.utils.lazyEncode import java.io.DataInputStream import java.net.InetAddress @@ -10,7 +9,7 @@ import java.net.InetAddress /** * @author Him188moe */ -@ExperimentalUnsignedTypes + @PacketId("08 28 04 34") class ClientSessionRequestPacket( private val qq: Long, @@ -48,12 +47,12 @@ class ClientSessionRequestPacket( it.writeHex("01 0B 00 85 00 02") it.writeHex("B9 ED EF D7 CD E5 47 96 7A B5 28 34 CA 93 6B 5C")//fix2 - it.write(getRandomByteArray(1)) + it.writeRandom(1) it.writeHex("10 00 00 00 00 00 00 00 02") //fix3 it.writeHex("00 63 3E 00 63 02 04 03 06 02 00 04 00 52 D9 00 00 00 00 A9 58 3E 6D 6D 49 AA F6 A6 D9 33 0A E7 7E 36 84 03 01 00 00 68 20 15 8B 00 00 01 02 00 00 03 00 07 DF 00 0A 00 0C 00 01 00 04 00 03 00 04 20 5C 00") - it.write(getRandomByteArray(32))//md5 32 + it.writeRandom(32)//md5 32 it.writeHex("68") it.writeHex("00 00 00 00 00 2D 00 06 00 01") @@ -70,7 +69,7 @@ class ServerSessionKeyResponsePacket(inputStream: DataInputStream, private val d lateinit var sessionKey: ByteArray lateinit var tlv0105: ByteArray - @ExperimentalUnsignedTypes + override fun decode() { when (dataLength) { 407 -> { diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt index c201eac7b..71d542aad 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/Touch.kt @@ -1,6 +1,7 @@ package net.mamoe.mirai.network.packet import net.mamoe.mirai.network.Protocol +import net.mamoe.mirai.network.packet.login.ClientPasswordSubmissionPacket import net.mamoe.mirai.utils.ByteArrayDataOutputStream import net.mamoe.mirai.utils.TEA import net.mamoe.mirai.utils.hexToBytes @@ -11,11 +12,12 @@ import java.io.IOException /** * A packet received when logging in, used to redirect server address * - * @see net.mamoe.mirai.network.packet.client.login.ClientServerRedirectionPacket - * @see net.mamoe.mirai.network.packet.client.login.ClientPasswordSubmissionPacket + * @see ClientServerRedirectionPacket + * @see ClientPasswordSubmissionPacket * * @author Him188moe */ +@Suppress("EXPERIMENTAL_API_USAGE") @PacketId("08 25 31 01") class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inputStream) { var serverIP: String? = null @@ -29,9 +31,9 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp TYPE_08_25_31_02, } - @ExperimentalUnsignedTypes + override fun decode() { - when (val id = input.readByte().toUByte().toInt()) { + when (val id = input.readByte().toInt()) { 0xFE -> { input.skip(94) serverIP = input.readIP() @@ -52,7 +54,7 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp } class Encrypted(private val type: Type, inputStream: DataInputStream) : ServerPacket(inputStream) { - @ExperimentalUnsignedTypes + fun decrypt(): ServerTouchResponsePacket = ServerTouchResponsePacket(decryptBy(when (type) { Type.TYPE_08_25_31_02 -> Protocol.redirectionKey.hexToBytes() Type.TYPE_08_25_31_01 -> Protocol.key0825.hexToBytes() @@ -65,10 +67,10 @@ class ServerTouchResponsePacket(inputStream: DataInputStream) : ServerPacket(inp * * @author Him188moe */ -@ExperimentalUnsignedTypes + @PacketId("08 25 31 01") class ClientTouchPacket(private val qq: Long, private val serverIp: String) : ClientPacket() { - @ExperimentalUnsignedTypes + @Throws(IOException::class) override fun encode() { this.writeQQ(qq) @@ -80,7 +82,7 @@ class ClientTouchPacket(private val qq: Long, private val serverIp: String) : Cl it.writeHex(Protocol.constantData2) it.writeQQ(qq) it.writeHex("00 00 00 00 03 09 00 08 00 01") - it.writeIP(serverIp); + it.writeIP(serverIp) it.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") it.writeHex(Protocol.publicKey) } @@ -92,10 +94,10 @@ class ClientTouchPacket(private val qq: Long, private val serverIp: String) : Cl * * @author Him188moe */ -@ExperimentalUnsignedTypes + @PacketId("08 25 31 02") class ClientServerRedirectionPacket(private val serverIP: String, private val qq: Long) : ClientPacket() { - @ExperimentalUnsignedTypes + override fun encode() { this.writeQQ(qq) this.writeHex(Protocol.fixVer) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt index 09720cc70..484a19e42 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/VerificationCode.kt @@ -2,14 +2,14 @@ package net.mamoe.mirai.network.packet import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.utils.TEA -import net.mamoe.mirai.utils.TestedSuccessfully +import net.mamoe.mirai.utils.Tested import net.mamoe.mirai.utils.hexToBytes import java.io.DataInputStream /** * 客户端请求验证码图片数据的第几部分 */ -@ExperimentalUnsignedTypes + @PacketId("00 BA 31") class ClientVerificationCodeTransmissionRequestPacket( private val packetId: Int, @@ -18,7 +18,7 @@ class ClientVerificationCodeTransmissionRequestPacket( private val verificationSequence: Int, private val token00BA: ByteArray ) : ClientPacket() { - @TestedSuccessfully + @Tested override fun encode() { this.writeByte(packetId)//part of packet id @@ -46,7 +46,7 @@ class ClientVerificationCodeTransmissionRequestPacket( * 提交验证码 */ @PacketId("00 BA 32") -@ExperimentalUnsignedTypes + class ClientVerificationCodeSubmitPacket( private val packetIdLast: Int, private val qq: Long, @@ -93,7 +93,7 @@ class ClientVerificationCodeSubmitPacket( * 刷新验证码 */ @PacketId("00 BA 31") -@ExperimentalUnsignedTypes + class ClientVerificationCodeRefreshPacket( private val packetIdLast: Int, private val qq: Long, @@ -142,7 +142,7 @@ open class ServerVerificationCodeTransmissionPacket(input: DataInputStream, priv lateinit var token00BA: ByteArray//40 bytes var packetIdLast: Int = 0 - @ExperimentalUnsignedTypes + override fun decode() { this.verificationToken = this.input.readNBytesAt(10, 56) @@ -181,7 +181,7 @@ class ServerVerificationCodeCorrectPacket(input: DataInputStream) : ServerVerifi lateinit var token00BA: ByteArray//56 bytes - @ExperimentalUnsignedTypes + override fun decode() { token00BA = this.input.readNBytesAt(10, 56) } @@ -191,7 +191,7 @@ abstract class ServerVerificationCodePacket(input: DataInputStream) : ServerPack @PacketId("00 BA") class Encrypted(input: DataInputStream, private val id: String) : ServerPacket(input) { - @ExperimentalUnsignedTypes + fun decrypt(): ServerVerificationCodePacket { this.input goto 14 val data = TEA.decrypt(this.input.readAllBytes().cutTail(1), Protocol.key00BA.hexToBytes()) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/AddContact.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/AddContact.kt index 0505ffd29..c19724dba 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/AddContact.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/AddContact.kt @@ -1,3 +1,5 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") + package net.mamoe.mirai.network.packet.action import net.mamoe.mirai.network.Protocol @@ -13,7 +15,7 @@ import java.util.* * @author Him188moe */ @PacketId("00 A7") -@ExperimentalUnsignedTypes + class ClientCanAddFriendPacket( val bot: Long, val qq: Long, @@ -47,7 +49,7 @@ class ServerCanAddFriendResponsePacket(input: DataInputStream) : ServerPacket(in FAILED, } - @ExperimentalUnsignedTypes + override fun decode() { val data = input.goto(0).readAllBytes() if (data.size == 99) { @@ -78,7 +80,7 @@ class ServerCanAddFriendResponsePacket(input: DataInputStream) : ServerPacket(in * 请求添加好友 */ @PacketId("00 AE") -@ExperimentalUnsignedTypes + class ClientAddFriendPacket( val bot: Long, val qq: Long, diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendFriendMessagePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendFriendMessagePacket.kt index 509726ffd..2e12fb3a8 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendFriendMessagePacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendFriendMessagePacket.kt @@ -10,7 +10,7 @@ import java.io.DataInputStream * @author Him188moe */ @PacketId("00 CD") -@ExperimentalUnsignedTypes + class ClientSendFriendMessagePacket( private val botQQ: Long, private val targetQQ: Long, diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendGroupMessagePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendGroupMessagePacket.kt index 17f84f988..44d3b890d 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendGroupMessagePacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/ClientSendGroupMessagePacket.kt @@ -9,7 +9,7 @@ import java.io.DataInputStream * @author Him188moe */ @PacketId("00 02") -@ExperimentalUnsignedTypes + class ClientSendGroupMessagePacket( private val groupId: Long,//不是 number private val botQQ: Long, diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/image/UploadGroupImage.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/image/UploadGroupImage.kt index 306b83e70..c0f98f653 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/image/UploadGroupImage.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/image/UploadGroupImage.kt @@ -1,3 +1,5 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") + package net.mamoe.mirai.network.packet.image import net.mamoe.mirai.network.packet.* @@ -15,7 +17,7 @@ import java.io.DataInputStream * @author Him188moe */ @PacketId("03 88") -@ExperimentalUnsignedTypes + class ClientTryGetGroupImageIDPacket( private val bot: Long, private val sessionKey: ByteArray, @@ -108,7 +110,7 @@ abstract class ServerTryUploadGroupImageResponsePacket(input: DataInputStream) : class ServerTryUploadGroupImageSuccessPacket(input: DataInputStream) : ServerTryUploadGroupImageResponsePacket(input) { lateinit var uKey: ByteArray - @ExperimentalUnsignedTypes + override fun decode() { uKey = this.input.gotoWhere(ubyteArrayOf(0x42u, 0x80u, 0x01u)).readNBytes(128) } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientChangeOnlineStatusPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientChangeOnlineStatusPacket.kt index bd0b477e0..3d48d48e6 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientChangeOnlineStatusPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientChangeOnlineStatusPacket.kt @@ -9,7 +9,7 @@ import net.mamoe.mirai.utils.ClientLoginStatus * * @author Him188moe */ -@ExperimentalUnsignedTypes + @PacketId("00 EC") class ClientChangeOnlineStatusPacket( private val qq: Long, diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt index ccd4edbe1..cb6807a56 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientLogin.kt @@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.utils.ByteArrayDataOutputStream import net.mamoe.mirai.utils.TEA -import net.mamoe.mirai.utils.TestedSuccessfully +import net.mamoe.mirai.utils.Tested import net.mamoe.mirai.utils.hexToBytes import java.io.DataOutputStream @@ -14,8 +14,8 @@ import java.io.DataOutputStream * @author Him188moe */ @PacketId("08 36 31 03") -@ExperimentalUnsignedTypes -@TestedSuccessfully + +@Tested class ClientPasswordSubmissionPacket( private val qq: Long, private val password: String, @@ -24,7 +24,7 @@ class ClientPasswordSubmissionPacket( private val tgtgtKey: ByteArray, private val token0825: ByteArray ) : ClientPacket() { - @ExperimentalUnsignedTypes + override fun encode() { this.writeQQ(qq) this.writeHex(Protocol.passwordSubmissionKey1) @@ -40,21 +40,21 @@ class ClientPasswordSubmissionPacket( } @PacketId("08 36 31 04") -@ExperimentalUnsignedTypes + class ClientLoginResendPacket3104(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray, tlv0006: ByteArray? = null) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, tlv0006) @PacketId("08 36 31 05") -@ExperimentalUnsignedTypes + class ClientLoginResendPacket3105(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, null) @PacketId("08 36 31 06") -@ExperimentalUnsignedTypes + class ClientLoginResendPacket3106(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, token00BA: ByteArray, tlv0006: ByteArray? = null) : ClientLoginResendPacket(qq, password, loginTime, loginIP, tgtgtKey, token0825, token00BA, tlv0006) -@ExperimentalUnsignedTypes + open class ClientLoginResendPacket internal constructor( val qq: Long, val password: String, @@ -93,7 +93,7 @@ open class ClientLoginResendPacket internal constructor( /** * @author Him188moe */ -@ExperimentalUnsignedTypes + private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: Int, loginIP: String, tgtgtKey: ByteArray, token0825: ByteArray, tlv0006: ByteArray? = null) { //this.writeInt(System.currentTimeMillis().toInt()) @@ -130,7 +130,7 @@ private fun DataOutputStream.writePart1(qq: Long, password: String, loginTime: I this.writeHex("60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6")//key } -@ExperimentalUnsignedTypes + private fun DataOutputStream.writePart2() { this.writeHex("03 12")//tag diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseKeyExchangePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseKeyExchangePacket.kt index 9470bc0b6..e92a3828e 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseKeyExchangePacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseKeyExchangePacket.kt @@ -4,7 +4,7 @@ import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.network.packet.PacketId import net.mamoe.mirai.network.packet.ServerPacket import net.mamoe.mirai.network.packet.goto -import net.mamoe.mirai.utils.TestedSuccessfully +import net.mamoe.mirai.utils.Tested import java.io.DataInputStream /** @@ -23,7 +23,7 @@ class ServerLoginResponseKeyExchangePacket(input: DataInputStream, val flag: Fla var tokenUnknown: ByteArray? = null lateinit var tgtgtKey: ByteArray//16bytes - @TestedSuccessfully + @Tested override fun decode() { this.input.skip(5) tgtgtKey = this.input.readNBytes(16)//22 @@ -46,8 +46,8 @@ class ServerLoginResponseKeyExchangePacket(input: DataInputStream, val flag: Fla } class Encrypted(input: DataInputStream, private val flag: Flag) : ServerPacket(input) { - @ExperimentalUnsignedTypes - @TestedSuccessfully + + @Tested fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseKeyExchangePacket { return ServerLoginResponseKeyExchangePacket(this.decryptBy(Protocol.shareKey, tgtgtKey), flag).setId(this.idHex) } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt index 438b1259d..8bcbe894f 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponsePasswordVerifiedPacket.kt @@ -1,3 +1,5 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE") + package net.mamoe.mirai.network.packet.login import net.mamoe.mirai.network.Protocol @@ -5,7 +7,7 @@ import net.mamoe.mirai.network.packet.ServerPacket import net.mamoe.mirai.network.packet.goto import net.mamoe.mirai.network.packet.readNBytesAt import net.mamoe.mirai.network.packet.readString -import net.mamoe.mirai.utils.TestedSuccessfully +import net.mamoe.mirai.utils.Tested import net.mamoe.mirai.utils.toUHexString import java.io.DataInputStream @@ -21,8 +23,8 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in lateinit var encryptionKey: ByteArray - @TestedSuccessfully - @ExperimentalUnsignedTypes + @Tested + override fun decode() { this.input.skip(7)//8 this.encryptionKey = this.input.readNBytes(16)//24 @@ -52,7 +54,7 @@ class ServerLoginResponseSuccessPacket(input: DataInputStream) : ServerPacket(in class Encrypted(input: DataInputStream) : ServerPacket(input) { - @ExperimentalUnsignedTypes + fun decrypt(tgtgtKey: ByteArray): ServerLoginResponseSuccessPacket { input goto 14 return ServerLoginResponseSuccessPacket(this.decryptBy(Protocol.shareKey, tgtgtKey)).setId(this.idHex) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt index 9625e38b1..314391011 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ServerLoginResponseVerificationCodeInitPacket.kt @@ -1,10 +1,12 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE") + package net.mamoe.mirai.network.packet.login import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.network.packet.ServerPacket import net.mamoe.mirai.network.packet.dataInputStream import net.mamoe.mirai.network.packet.goto -import net.mamoe.mirai.utils.TestedSuccessfully +import net.mamoe.mirai.utils.Tested import net.mamoe.mirai.utils.hexToUBytes import java.io.DataInputStream @@ -20,8 +22,8 @@ class ServerLoginResponseVerificationCodeInitPacket(input: DataInputStream, priv var unknownBoolean: Boolean? = null - @TestedSuccessfully - @ExperimentalUnsignedTypes + @Tested + override fun decode() { val verifyCodeLength = this.input.goto(78).readShort()//2bytes this.verifyCodePart1 = this.input.readNBytes(verifyCodeLength.toInt()) @@ -39,7 +41,7 @@ class ServerLoginResponseVerificationCodeInitPacket(input: DataInputStream, priv } - @ExperimentalUnsignedTypes + fun decrypt(): ServerLoginResponseVerificationCodeInitPacket { this.input goto 14 val data = this.decryptBy(Protocol.shareKey).goto(0).readAllBytes() diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.kt b/mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.kt index d48de305a..852e96cb0 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/TEA.kt @@ -1,277 +1,269 @@ package net.mamoe.mirai.utils -import net.mamoe.mirai.network.Protocol import java.nio.ByteBuffer import java.util.* import kotlin.experimental.and import kotlin.experimental.xor -/** - * @author Him188moe - */ /** * TEA 加密 * * @author iweiz https://github.com/iweizime/StepChanger/blob/master/app/src/main/java/me/iweizi/stepchanger/qq/Cryptor.java */ -class TEA(private val key: ByteArray) { +object TEA { + private const val UINT32_MASK = 0xffffffffL + private fun doOption(data: ByteArray, key: ByteArray, encrypt: Boolean): ByteArray { + val mRandom = Random() + lateinit var mOutput: ByteArray + lateinit var mInBlock: ByteArray + var mIndexPos: Int + lateinit var mIV: ByteArray + var mOutPos = 0 + var mPreOutPos = 0 + var isFirstBlock = true - companion object { - val CRYPTOR_SHARE_KEY = TEA(Protocol.hexToBytes(Protocol.shareKey)) - val CRYPTOR_0825KEY = TEA(Protocol.hexToBytes(Protocol.key0825)) + val mKey = LongArray(4) - private val UINT32_MASK = 0xffffffffL + for (i in 0..3) { + mKey[i] = pack(key, i * 4, 4) + } - fun doOption(data: ByteArray, key: ByteArray, encrypt: Boolean): ByteArray { - val mRandom = Random() - lateinit var mOutput: ByteArray - lateinit var mInBlock: ByteArray - var mIndexPos: Int - lateinit var mIV: ByteArray - var mOutPos = 0 - var mPreOutPos = 0 - var isFirstBlock: Boolean = true + fun rand(): Int { + return mRandom.nextInt() + } - val mKey = LongArray(4) + fun encode(bytes: ByteArray): ByteArray { + var v0 = pack(bytes, 0, 4) + var v1 = pack(bytes, 4, 4) + var sum: Long = 0 + val delta = 0x9e3779b9L + for (i in 0..15) { + sum = sum + delta and UINT32_MASK + v0 += (v1 shl 4) + mKey[0] xor v1 + sum xor v1.ushr(5) + mKey[1] + v0 = v0 and UINT32_MASK + v1 += (v0 shl 4) + mKey[2] xor v0 + sum xor v0.ushr(5) + mKey[3] + v1 = v1 and UINT32_MASK + } + return ByteBuffer.allocate(8).putInt(v0.toInt()).putInt(v1.toInt()).array() + } - for (i in 0..3) { - mKey[i] = pack(key, i * 4, 4) + fun decode(bytes: ByteArray, offset: Int): ByteArray { + var v0 = pack(bytes, offset, 4) + var v1 = pack(bytes, offset + 4, 4) + val delta = 0x9e3779b9L + var sum = delta shl 4 and UINT32_MASK + for (i in 0..15) { + v1 -= (v0 shl 4) + mKey[2] xor v0 + sum xor v0.ushr(5) + mKey[3] + v1 = v1 and UINT32_MASK + v0 -= (v1 shl 4) + mKey[0] xor v1 + sum xor v1.ushr(5) + mKey[1] + v0 = v0 and UINT32_MASK + sum = sum - delta and UINT32_MASK + } + return ByteBuffer.allocate(8).putInt(v0.toInt()).putInt(v1.toInt()).array() + } + + fun encodeOneBlock() { + mIndexPos = 0 + while (mIndexPos < 8) { + mInBlock[mIndexPos] = if (isFirstBlock) + mInBlock[mIndexPos] + else + (mInBlock[mIndexPos] xor mOutput[mPreOutPos + mIndexPos]) + mIndexPos++ } - fun rand(): Int { - return mRandom.nextInt() + System.arraycopy(encode(mInBlock), 0, mOutput, mOutPos, 8) + mIndexPos = 0 + while (mIndexPos < 8) { + val outPos = mOutPos + mIndexPos + mOutput[outPos] = (mOutput[outPos] xor mIV[mIndexPos]) + mIndexPos++ } + System.arraycopy(mInBlock, 0, mIV, 0, 8) + mPreOutPos = mOutPos + mOutPos += 8 + mIndexPos = 0 + isFirstBlock = false + } - fun encode(bytes: ByteArray): ByteArray { - var v0 = pack(bytes, 0, 4) - var v1 = pack(bytes, 4, 4) - var sum: Long = 0 - val delta = 0x9e3779b9L - for (i in 0..15) { - sum = sum + delta and UINT32_MASK - v0 += (v1 shl 4) + mKey[0] xor v1 + sum xor v1.ushr(5) + mKey[1] - v0 = v0 and UINT32_MASK - v1 += (v0 shl 4) + mKey[2] xor v0 + sum xor v0.ushr(5) + mKey[3] - v1 = v1 and UINT32_MASK - } - return ByteBuffer.allocate(8).putInt(v0.toInt()).putInt(v1.toInt()).array() - } - - fun decode(bytes: ByteArray, offset: Int): ByteArray { - var v0 = pack(bytes, offset, 4) - var v1 = pack(bytes, offset + 4, 4) - val delta = 0x9e3779b9L - var sum = delta shl 4 and UINT32_MASK - for (i in 0..15) { - v1 -= (v0 shl 4) + mKey[2] xor v0 + sum xor v0.ushr(5) + mKey[3] - v1 = v1 and UINT32_MASK - v0 -= (v1 shl 4) + mKey[0] xor v1 + sum xor v1.ushr(5) + mKey[1] - v0 = v0 and UINT32_MASK - sum = sum - delta and UINT32_MASK - } - return ByteBuffer.allocate(8).putInt(v0.toInt()).putInt(v1.toInt()).array() - } - - fun encodeOneBlock() { - mIndexPos = 0 - while (mIndexPos < 8) { - mInBlock[mIndexPos] = if (isFirstBlock) - mInBlock[mIndexPos] - else - (mInBlock[mIndexPos] xor mOutput[mPreOutPos + mIndexPos]) + fun decodeOneBlock(ciphertext: ByteArray, offset: Int, len: Int): Boolean { + mIndexPos = 0 + while (mIndexPos < 8) { + if (mOutPos + mIndexPos < len) { + mIV[mIndexPos] = (mIV[mIndexPos] xor ciphertext[mOutPos + offset + mIndexPos]) mIndexPos++ + continue } - - System.arraycopy(encode(mInBlock), 0, mOutput, mOutPos, 8) - mIndexPos = 0 - while (mIndexPos < 8) { - val out_pos = mOutPos + mIndexPos - mOutput[out_pos] = (mOutput[out_pos] xor mIV[mIndexPos]) - mIndexPos++ - } - System.arraycopy(mInBlock, 0, mIV, 0, 8) - mPreOutPos = mOutPos - mOutPos += 8 - mIndexPos = 0 - isFirstBlock = false - } - - fun decodeOneBlock(ciphertext: ByteArray, offset: Int, len: Int): Boolean { - mIndexPos = 0 - while (mIndexPos < 8) { - if (mOutPos + mIndexPos < len) { - mIV[mIndexPos] = (mIV[mIndexPos] xor ciphertext[mOutPos + offset + mIndexPos]) - mIndexPos++ - continue - } - return true - } - - mIV = decode(mIV, 0) - mOutPos += 8 - mIndexPos = 0 return true - } - fun encrypt(plaintext: ByteArray, offset: Int, len: Int): ByteArray { - var len = len; - var offset = offset; - mInBlock = ByteArray(8) - mIV = ByteArray(8) - mOutPos = 0 - mPreOutPos = 0 - isFirstBlock = true - mIndexPos = (len + 10) % 8 - if (mIndexPos != 0) { - mIndexPos = 8 - mIndexPos - } - mOutput = ByteArray(mIndexPos + len + 10) - mInBlock[0] = (rand() and 0xf8 or mIndexPos).toByte() - for (i in 1..mIndexPos) { - mInBlock[i] = (rand() and 0xff).toByte() - } - ++mIndexPos - for (i in 0..7) { - mIV[i] = 0 - } + mIV = decode(mIV, 0) + mOutPos += 8 + mIndexPos = 0 + return true - var g = 0 - while (g < 2) { - if (mIndexPos < 8) { - mInBlock[mIndexPos++] = (rand() and 0xff).toByte() - ++g - } - if (mIndexPos == 8) { - encodeOneBlock() - } - } + } - while (len > 0) { - if (mIndexPos < 8) { - mInBlock[mIndexPos++] = plaintext[offset++] - } - if (mIndexPos == 8) { - encodeOneBlock() - } - len-- - } - g = 0 - while (g < 7) { - if (mIndexPos < 8) { - mInBlock[mIndexPos++] = 0.toByte() - } - if (mIndexPos == 8) { - encodeOneBlock() - } - g++ - } - return mOutput + @Suppress("NAME_SHADOWING") + fun encrypt(plaintext: ByteArray, offset: Int, len: Int): ByteArray { + var len = len + var offset = offset + mInBlock = ByteArray(8) + mIV = ByteArray(8) + mOutPos = 0 + mPreOutPos = 0 + isFirstBlock = true + mIndexPos = (len + 10) % 8 + if (mIndexPos != 0) { + mIndexPos = 8 - mIndexPos + } + mOutput = ByteArray(mIndexPos + len + 10) + mInBlock[0] = (rand() and 0xf8 or mIndexPos).toByte() + for (i in 1..mIndexPos) { + mInBlock[i] = (rand() and 0xff).toByte() + } + ++mIndexPos + for (i in 0..7) { + mIV[i] = 0 } - fun decrypt(cipherText: ByteArray, offset: Int, len: Int): ByteArray? { - require(!(len % 8 != 0 || len < 16)) { "must len % 8 == 0 && len >= 16" } - mIV = decode(cipherText, offset) - mIndexPos = (mIV[0] and 7).toInt() - var plen = len - mIndexPos - 10 - isFirstBlock = true - if (plen < 0) { - return null + var g = 0 + while (g < 2) { + if (mIndexPos < 8) { + mInBlock[mIndexPos++] = (rand() and 0xff).toByte() + ++g } - mOutput = ByteArray(plen) - mPreOutPos = 0 - mOutPos = 8 - ++mIndexPos - var g = 0 - while (g < 2) { - if (mIndexPos < 8) { - ++mIndexPos - ++g - } - if (mIndexPos == 8) { - isFirstBlock = false - if (!decodeOneBlock(cipherText, offset, len)) { - throw RuntimeException("Unable to decode") - } - } + if (mIndexPos == 8) { + encodeOneBlock() } + } - var outpos = 0 - while (plen != 0) { - if (mIndexPos < 8) { - mOutput[outpos++] = if (isFirstBlock) - mIV[mIndexPos] - else - (cipherText[mPreOutPos + offset + mIndexPos] xor mIV[mIndexPos]) + while (len > 0) { + if (mIndexPos < 8) { + mInBlock[mIndexPos++] = plaintext[offset++] + } + if (mIndexPos == 8) { + encodeOneBlock() + } + len-- + } + g = 0 + while (g < 7) { + if (mIndexPos < 8) { + mInBlock[mIndexPos++] = 0.toByte() + } + if (mIndexPos == 8) { + encodeOneBlock() + } + g++ + } + return mOutput + } + + fun decrypt(cipherText: ByteArray, offset: Int, len: Int): ByteArray? { + require(!(len % 8 != 0 || len < 16)) { "must len % 8 == 0 && len >= 16" } + mIV = decode(cipherText, offset) + mIndexPos = (mIV[0] and 7).toInt() + var plen = len - mIndexPos - 10 + isFirstBlock = true + if (plen < 0) { + return null + } + mOutput = ByteArray(plen) + mPreOutPos = 0 + mOutPos = 8 + ++mIndexPos + var g = 0 + while (g < 2) { + if (mIndexPos < 8) { + ++mIndexPos + ++g + } + if (mIndexPos == 8) { + isFirstBlock = false + if (!decodeOneBlock(cipherText, offset, len)) { + throw RuntimeException("Unable to decode") + } + } + } + + var outpos = 0 + while (plen != 0) { + if (mIndexPos < 8) { + mOutput[outpos++] = if (isFirstBlock) + mIV[mIndexPos] + else + (cipherText[mPreOutPos + offset + mIndexPos] xor mIV[mIndexPos]) + ++mIndexPos + } + if (mIndexPos == 8) { + mPreOutPos = mOutPos - 8 + isFirstBlock = false + if (!decodeOneBlock(cipherText, offset, len)) { + throw RuntimeException("Unable to decode") + } + } + plen-- + } + g = 0 + while (g < 7) { + if (mIndexPos < 8) { + if (cipherText[mPreOutPos + offset + mIndexPos].xor(mIV[mIndexPos]).toInt() != 0) { + throw RuntimeException() + } else { ++mIndexPos } - if (mIndexPos == 8) { - mPreOutPos = mOutPos - 8 - isFirstBlock = false - if (!decodeOneBlock(cipherText, offset, len)) { - throw RuntimeException("Unable to decode") - } - } - plen-- } - g = 0 - while (g < 7) { - if (mIndexPos < 8) { - if (cipherText[mPreOutPos + offset + mIndexPos].xor(mIV[mIndexPos]).toInt() != 0) { - throw RuntimeException() - } else { - ++mIndexPos - } + + if (mIndexPos == 8) { + mPreOutPos = mOutPos + if (!decodeOneBlock(cipherText, offset, len)) { + throw RuntimeException("Unable to decode") } - - if (mIndexPos == 8) { - mPreOutPos = mOutPos - if (!decodeOneBlock(cipherText, offset, len)) { - throw RuntimeException("Unable to decode") - } - } - g++ } - return mOutput + g++ } + return mOutput + } - return if (encrypt) { - encrypt(data, 0, data.size) - } else { - try { - return decrypt(data, 0, data.size)!! - } catch (e: Exception) { - println("Source: " + data.toUHexString(" ")) - println("Key: " + key.toUHexString(" ")) - throw e - } + return if (encrypt) { + encrypt(data, 0, data.size) + } else { + try { + return decrypt(data, 0, data.size)!! + } catch (e: Exception) { + println("Source: " + data.toUHexString(" ")) + println("Key: " + key.toUHexString(" ")) + throw e } } - - fun encrypt(source: ByteArray, key: ByteArray): ByteArray { - return doOption(source, key, true) - } - - fun encrypt(source: ByteArray, keyHex: String): ByteArray { - return encrypt(source, keyHex.hexToBytes()) - } - - fun decrypt(source: ByteArray, key: ByteArray): ByteArray { - return doOption(source, key, false) - } - - fun decrypt(source: ByteArray, keyHex: String): ByteArray { - return decrypt(source, keyHex.hexToBytes()) - } - - private fun pack(bytes: ByteArray, offset: Int, len: Int): Long { - var result: Long = 0 - val max_offset = if (len > 8) offset + 8 else offset + len - for (index in offset until max_offset) { - result = result shl 8 or (bytes[index].toLong() and 0xffL) - } - return result shr 32 or (result and UINT32_MASK) - } + } + + fun encrypt(source: ByteArray, key: ByteArray): ByteArray { + return doOption(source, key, true) + } + + @Suppress("unused") + fun encrypt(source: ByteArray, keyHex: String): ByteArray { + return encrypt(source, keyHex.hexToBytes()) + } + + fun decrypt(source: ByteArray, key: ByteArray): ByteArray { + return doOption(source, key, false) + } + + fun decrypt(source: ByteArray, keyHex: String): ByteArray { + return decrypt(source, keyHex.hexToBytes()) + } + + @Suppress("SameParameterValue") + private fun pack(bytes: ByteArray, offset: Int, len: Int): Long { + var result: Long = 0 + val maxOffset = if (len > 8) offset + 8 else offset + len + for (index in offset until maxOffset) { + result = result shl 8 or (bytes[index].toLong() and 0xffL) + } + return result shr 32 or (result and UINT32_MASK) } } \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/Tested.kt b/mirai-core/src/main/java/net/mamoe/mirai/utils/Tested.kt index 5013309b3..d9bd874b7 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/utils/Tested.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/Tested.kt @@ -5,4 +5,4 @@ package net.mamoe.mirai.utils * * @author Him188moe */ -internal annotation class TestedSuccessfully \ No newline at end of file +internal annotation class Tested \ No newline at end of file diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt b/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt index ceb34397d..788ec66a4 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/Utils.kt @@ -1,3 +1,5 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") + package net.mamoe.mirai.utils import net.mamoe.mirai.network.Protocol @@ -26,14 +28,14 @@ fun ByteArray.toHexString(separator: String = " "): String = this.joinToString(s return@joinToString ret } -@ExperimentalUnsignedTypes + fun ByteArray.toUHexString(separator: String = " "): String = this.toUByteArray().toUHexString(separator) -@ExperimentalUnsignedTypes + @JvmSynthetic fun ByteArray.toUHexString(): String = this.toUByteArray().toUHexString() -@ExperimentalUnsignedTypes + @JvmSynthetic fun UByteArray.toUHexString(separator: String = " "): String { return this.joinToString(separator) { @@ -45,36 +47,36 @@ fun UByteArray.toUHexString(separator: String = " "): String { } } -@ExperimentalUnsignedTypes + @JvmSynthetic fun UByteArray.toUHexString(): String = this.toUHexString(" ") -@ExperimentalUnsignedTypes + fun Byte.toUHexString(): String = this.toUByte().toString(16) -@ExperimentalUnsignedTypes + fun String.hexToBytes(): ByteArray = Protocol.hexToBytes(this) -@ExperimentalUnsignedTypes + fun String.hexToUBytes(): UByteArray = Protocol.hexToUBytes(this) -@ExperimentalUnsignedTypes + fun String.hexToInt(): Int = hexToBytes().toUInt().toInt() -@ExperimentalUnsignedTypes + fun ByteArray.toUInt(): UInt = this[0].toUInt().and(255u).shl(24) + this[1].toUInt().and(255u).shl(16) + this[2].toUInt().and(255u).shl(8) + this[3].toUInt().and(255u).shl(0) open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream()) { open fun toByteArray(): ByteArray = (out as ByteArrayOutputStream).toByteArray() - @ExperimentalUnsignedTypes + open fun toUByteArray(): UByteArray = (out as ByteArrayOutputStream).toByteArray().toUByteArray() } @JvmSynthetic fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDataOutputStream().also(t).toByteArray() -@ExperimentalUnsignedTypes + fun getRandomByteArray(length: Int): ByteArray { val bytes = LinkedList() repeat(length) { bytes.add((Math.random() * 255).toByte()) } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/Varint.kt b/mirai-core/src/main/java/net/mamoe/mirai/utils/Varint.kt index 97a1fdc4b..289749a18 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/utils/Varint.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/Varint.kt @@ -1,4 +1,5 @@ @file:JvmName("Varint") +@file:Suppress("EXPERIMENTAL_API_USAGE") package net.mamoe.mirai.utils @@ -21,7 +22,7 @@ fun encodeZigZag32(signedInt: Int): Long { return (signedInt shl 1 xor (signedInt shr 31)).toLong() } -@ExperimentalUnsignedTypes + @JvmSynthetic fun decodeZigZag32(uint: UInt): Int { return decodeZigZag32(uint.toLong()) @@ -39,25 +40,25 @@ fun decodeZigZag64(signedLong: Long): Long { return signedLong.ushr(1) xor -(signedLong and 1) } -@ExperimentalUnsignedTypes + @Throws(IOException::class) fun DataInputStream.readVarInt(): Int { return decodeZigZag32(this.readUnsignedVarInt()) } -@ExperimentalUnsignedTypes + @Throws(IOException::class) fun DataInputStream.readUnsignedVarInt(): UInt { return read(this, 5).toUInt() } -@ExperimentalUnsignedTypes + @Throws(IOException::class) fun DataInputStream.readVarLong(): Long { return decodeZigZag64(readUnsignedVarLong().toLong()) } -@ExperimentalUnsignedTypes + @Throws(IOException::class) fun DataInputStream.readUnsignedVarLong(): ULong { return read(this, 10).toULong() @@ -68,7 +69,7 @@ fun DataOutputStream.writeVarInt(signedInt: Int) { this.writeUVarInt(encodeZigZag32(signedInt)) } -@ExperimentalUnsignedTypes + @Throws(IOException::class) fun DataOutputStream.writeUVarInt(uint: UInt) { return writeUVarInt(uint.toLong()) diff --git a/mirai-core/src/test/java/PacketTest.kt b/mirai-core/src/test/java/PacketTest.kt deleted file mode 100644 index 4d7b5ffb9..000000000 --- a/mirai-core/src/test/java/PacketTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -import net.mamoe.mirai.network.packet.login.ClientPasswordSubmissionPacket -import net.mamoe.mirai.utils.toUHexString - -@ExperimentalUnsignedTypes -fun main(){ - /* - val data = "00 37 13 08 25 31 01 EB 10 08 30 69 50 1C 84 A9 C2 16 D7 52 B9 1C 79 CA 5A CF FD BC EB 10 08 30 69 50 1C 84 A9 C2 16 D7 52 B9 1C 79 CA 5A CF FD BC AE D8 A6 BB DC 21 6E 79 26 E1 A2 23 11 AA B0 9A AE D8 A6 BB DC 21 6E 79 26 E1 A2 23 11 AA B0 9A 76 E4 B8 DD 03 00 00 00 01 2E 01 00 00 68 52 00 00 00 00 A4 F1 91 88 C9 82 14 99 0C 9E 56 55 91 23 C8 3D C3 47 F0 25 A1 8E 74 EF 1E 0B 32 5B 20 8A FA 3B 0B 52 8F 86 E6 04 F1 D6 F8 63 75 60 8C 0C 7D 06 D1 E0 22 F8 49 EF AF 61 EE 7E 69 72 EB 10 08 30 69 50 1C 84 A9 C2 16 D7 52 B9 1C 79 CA 5A CF FD BC AE D8 A6 BB DC 21 6E 79 26 E1 A2 23 11 AA B0 9A 49 39 72 ED 61 12 B6 88 4D A2 56 23 E9 92 11 92 27 4A 70 00 C9 01 7B 03"; - val s = DataInputStream(data.hexToBytes().inputStream()) - val packet = ServerTouchResponsePacket(ServerTouchResponsePacket.Type.TYPE_08_25_31_01, s) - packet.decode() - System.out.println(packet.token.toUByteArray().toUHexString(" ")) - System.out.println(packet.loginTime.toUHexString(" ")) - System.out.println(packet.loginIP) - */ - - // val packet = ClientPasswordSubmissionPacket(1994701021,"xiaoqqq",) - - /* - val data = "00 01 09 00 70 00 01 5C 71 80 A6 BA 20 62 2E C1 BE BF F2 47 37 40 A1 00 38 91 25 85 58 18 D3 67 77 2C 4D 02 D8 66 A6 F7 3E 57 D8 CE 01 47 7F D0 8F 13 C8 3A E5 19 A2 60 BC 4C 9A 35 4E 92 9F 21 48 6C 67 68 36 6B 94 C1 6F 11 8D 55 6B 04 9A 22 C3 00 20 29 7E D4 A7 16 02 07 14 41 90 3A 65 06 AC CB 28 AB 90 DB 46 33 C9 C0 1D 06 44 7A 92 17 C3 A5 F3 00 00 01 03 00 14 00 01 00 10 60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6 01 07 01 D3 00 01 00 16 00 00 00 01 00 00 00 64 00 00 0D B6 00 09 3A 80 00 00 00 3C 00 02 2E 29 4E 47 5F 68 78 2C 47 25 5F 59 50 65 60 5D 00 88 00 04 5D 59 45 17 B7 5F F8 D4 00 00 00 00 00 78 38 E0 3B 23 4A C5 0E 93 CB C1 66 96 37 8B 46 B2 86 23 3F 2D 09 45 E0 16 1C E9 9C 11 7A FA 2D A8 50 47 42 74 01 06 84 76 0E 5F C6 04 29 1A 4A 65 AA 93 49 DF BD 00 ED 80 B8 26 CA 80 E8 20 6D 15 43 DD D8 E6 48 C2 8A 5A F8 70 6B 51 3A E2 2D 21 95 4B 6A 75 A8 90 CA B1 C0 E5 73 99 D7 59 D8 DD 3D C9 5C E4 49 61 22 11 60 85 48 C4 7D E0 84 62 AD B3 13 84 61 C1 9E 19 35 41 44 44 37 3F 21 33 64 4B 37 5D 77 6D 61 3F 00 78 00 01 5D 59 45 17 00 70 A4 D9 44 9E 95 51 B4 B0 91 CC 1E DB 34 F9 F7 13 8B 30 08 C0 AE 33 22 9C FF 87 CF 9B A2 B0 E5 E1 D0 E0 AD DD 8F E9 F6 1E 01 1F AA 74 46 66 B4 81 54 B9 29 E5 FC 0B 7F C9 13 AE 32 BA D6 55 2E B0 A1 30 24 B6 F2 E7 62 F9 2E 00 E4 51 61 50 7C D1 36 E8 61 96 36 FF B7 32 74 3C 2A F7 74 63 DA 7D 57 84 18 ED 84 E9 D8 87 6D 66 1D D5 84 D4 23 99 00 83 01 63 2A 69 2E 25 79 28 3B 29 33 29 40 28 54 7E 21 00 70 00 01 5D 59 45 17 00 68 6F 1F FB 31 7B D7 B7 D8 91 32 D7 20 8B 8A F6 02 C8 22 E5 24 8C 25 F2 6A C5 B0 ED 35 01 BF AF 42 72 33 4E FB 3F D3 02 BA F4 46 2B 68 20 0B E3 39 81 B1 D3 8A E0 1B 0F 69 D1 70 AE 49 A5 24 4F BB 58 4F F8 31 A0 37 4C CD F1 12 35 80 99 7D 25 CA F9 E9 45 B6 B0 57 56 66 61 C5 7B 90 57 BF E2 2C 94 91 80 1A B0 D7 21 A8 44 2C 33 4A 29 77 5F 71 40 41 38 3D 7A 41 65 33 01 08 00 29 00 01 00 25 00 1D 02 5B 14 28 E0 B9 91 E2 80 A2 CC 80 CF 89 E2 80 A2 CC 81 E0 B9 91 29 02 13 80 02 00 05 00 04 00 00 00 01 01 15 00 10 F9 86 85 81 30 F6 1B E0 E7 97 98 F6 46 C3 4F B2" - val s = DataInputStream(data.hexToBytes().inputStream()) - val packet = ServerLoginResponseSuccessPacket(s,(data.length+1)/3) - packet.decode() - System.out.println("0828key: \n" + packet._0828_rec_decr_key.toUByteArray().toUHexString(" ")) - System.out.println("token88: \n" + packet.token88.toUByteArray().toUHexString(" ")) - System.out.println("token38: \n" + packet.token38.toUByteArray().toUHexString(" ")) - System.out.println("enckey: \n" + packet.encryptionKey.toUByteArray().toUHexString(" ")) - System.out.println("nick: " + packet.nick) - System.out.println("age: " + packet.age) - System.out.println("gender: " + packet.gender) - */ - - /* - val data = "FB 01 04 03 33 00 01 00 BA 02 03 2C 13 00 05 01 00 00 01 23 00 38 F5 C3 CF F4 B4 27 C5 8F 9B D3 ED 18 73 7D E9 CB 43 1F 57 43 BE D3 1B 9A F5 26 2B F4 D9 43 14 9A ED 3B C3 6C E5 7F 4E B0 0C BA 55 57 18 06 78 E1 13 A7 B2 A8 7F 47 E1 1C 02 BC 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 00 82 00 00 00 35 08 03 00 00 00 BA 12 C3 02 00 00 00 04 67 41 4D 41 00 00 B1 8F 0B FC 61 05 00 00 00 01 73 52 47 42 00 AE CE 1C E9 00 00 00 6C 50 4C 54 45 F6 F8 F4 E3 EE FD E5 FD FF EE FD F0 F6 F9 E7 F7 F9 EC F4 FE FF F7 F7 F9 F5 F4 FF EC F7 FF E6 F4 E0 F5 FC F8 49 5B 8F CB DB FA BB C9 F5 2B 40 7C D6 E6 FF FD FB FF ED F1 F0 2A 43 B3 D6 F6 FF FC F1 FC 1C 38 91 A7 BD F6 63 74 BD 70 8B CC 34 4F A5 DE F3 F1 75 88 E7 A4 B7 D3 73 82 A1 8C A3 DC F3 FB D8 4D 68 B9 94 A8 FB 8D 9C B6 CB 42 B0 8E 00 00 0A 6F 49 44 41 54 58 C3 B4 57 89 76 EB 2A 12 14 20 B1 09 10 42 68 DF 2C FB FF FF 71 0A 79 49 E2 E4 CE CC 79 37 8F 13 59 B6 72 EC 2E AA BB AB 9A 2C FB 61 89 8F 95 E5 79 A9 70 CB B2 22 C7 2A 65 DB 5E 72 21 F1 A9 90 B2 28 C4 F9 AF 5F 5F 05 30 9C 28 D2 4B C6 58 F9 8C 92 17 39 13 6D 9B FF EB 10 8A 3B 0F 2F 10 52 64 45 51 64 42 A6 37 79 21 DA FC F2 6F 40 08 9F AE B7 9C A4 C8 27 31 F2 C4 50 A4 D4 9C F9 01 BC A2 90 0F 08 E1 2F AE 1F E3 7E 7D 24 52 F4 67 2C 91 02 E3 CA 13 2F 78 97 00 86 DF 4E C4 23 56 F1 F8 7B 10 90 42 3D D2 93 EE 27 04 F1 80 F0 4B 99 10 4F 62 5E D9 2D EE 57 8A F1 A0 E1 64 20 2B 55 F9 C8 C3 67 08 F8 81 7F F2 F7 BE FD 67 1D 9E 9B 4F EB 89 25 21 28 19 63 09 5D A9 94 2A 59 AA 87 B3 32 4E 84 FF 3C 13 8F AF 06 F1 29 FD E2 C1 02 54 E0 8C 5E 5C 2E A5 72 43 65 F4 E5 72 61 5C 4A 45 81 41 97 79 0A 9E FF 62 22 C2 EB 7E 42 48 45 80 2B 0F 58 B9 66 D6 1C 63 75 D3 97 BC F4 08 0F 08 5C 6B 8D CC 14 1F 10 C4 5F B4 C3 37 66 EE E5 78 CF 42 12 05 CD F5 4D 29 EB 36 AD 19 82 CF 76 35 C6 86 B2 94 A7 36 FC 62 39 BE A8 B8 D7 02 78 08 8F 66 E4 44 45 DF BB AB A3 34 92 14 DF 54 C6 32 1D 00 21 7F 41 08 7F C9 7F F8 28 88 4F B5 90 89 3A 21 90 9E DF E8 DE 34 4D 8C D1 EF C6 AC 6B 7F 74 8E B1 FA 84 90 7F B0 F0 CF 5A E2 27 4C AF 8E 28 EF 24 48 B2 AF B1 9A 96 3E F6 43 75 38 6F 29 5D 1A C7 59 78 87 F0 1B B2 F0 95 05 3C 93 B2 26 B6 9F BA 18 AB AE 59 EC 88 17 17 A9 8F 4B B3 CE 60 A1 CD F2 CB 03 42 10 7F D9 06 1F 76 80 8E 4F 6D 9F 56 99 05 25 A5 DD AA EB 62 7A 6F 87 E6 B8 0E 5D 33 C6 99 C6 C4 02 24 EB 74 8C 87 98 64 F8 5E A9 9E 1E F7 72 FB FF B3 21 8A A4 00 01 00 28 F9 59 C5 E6 34 43 53 95 C8 17 2E 62 78 BF E8 27 BF 20 BA 11 5A 74 D1 7C D0 95 6C F6 A3 41 D2 84 BD 7D F6 64 BC 27 40 50 01 15 00 10 44 98 EB B8 30 3B DE 7D 2B CC 4C 41 B3 1C 92 86" - val s = DataInputStream(data.hexToBytes().inputStream()) - val packet = ServerLoginResponseVerificationCodePacket(s,(data.length+1)/3) - packet.decode() - println(packet.token00BA.toUByteArray().toUHexString(" ")) - println(packet.verifyCode.toUByteArray().toUHexString(" ")) - println(packet.verifyCodeLength) - - File(System.getProperty("user.dir") + "/5.png").createNewFile() - packet.verifyCode.inputStream().transferTo(FileOutputStream(System.getProperty("user.dir") + "/5.png")) - */ - - val packet = ClientPasswordSubmissionPacket(1994701021, "xiaoqqq", 131513, "123.123.123.123", "tgtgtKey".toByteArray(), "".toByteArray()) - packet.encodeToByteArray().toUByteArray().toUHexString(" ") -} \ No newline at end of file