diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.GetMessage.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.GetMessage.kt deleted file mode 100644 index 711b6fb9e..000000000 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.GetMessage.kt +++ /dev/null @@ -1,82 +0,0 @@ -package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive - -import kotlinx.io.core.ByteReadPacket -import kotlinx.serialization.protobuf.ProtoBuf -import net.mamoe.mirai.qqandroid.QQAndroidBot -import net.mamoe.mirai.qqandroid.network.QQAndroidClient -import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY -import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket -import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketFactory -import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgingPacket -import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.data.Cmd0x352Packet -import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.data.MsgSvc -import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.data.RequestPushNotify - -internal object GetMsgRequest : PacketFactory("MessageSvc.PbGetMsg") { - override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): MsgSvc.PbGetMsgResp { - println("received MsgSvc.PbGetMsgResp") - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - /** - @Serializable - class PbGetMsgReq( - @SerialId(1) val syncFlag: Int /* enum */ = 0, - @SerialId(2) val syncCookie: ByteArray = EMPTY_BYTE_ARRAY, - @SerialId(3) val rambleFlag: Int = 1, - @SerialId(4) val latestRambleNumber: Int = 20, - @SerialId(5) val otherRambleNumber: Int = 3, - @SerialId(6) val onlineSyncFlag: Int = 1, - @SerialId(7) val contextFlag: Int = 0, - @SerialId(8) val whisperSessionId: Int = 0, - @SerialId(9) val msgReqType: Int = 0, - @SerialId(10) val pubaccountCookie: ByteArray = EMPTY_BYTE_ARRAY, - @SerialId(11) val msgCtrlBuf: ByteArray = EMPTY_BYTE_ARRAY, - @SerialId(12) val serverBuf: ByteArray = EMPTY_BYTE_ARRAY - ) : ProtoBuf - - - @Serializable - internal class RequestPushNotify( - @SerialId(0) val uin: Long = 0L, - @SerialId(1) val ctype: Byte = 0, - @SerialId(2) val strService: String?, - @SerialId(3) val strCmd: String?, - @SerialId(4) val vNotifyCookie: ByteArray? = EMPTY_BYTE_ARRAY, - @SerialId(5) val usMsgType: Int?, - @SerialId(6) val wUserActive: Int?, - @SerialId(7) val wGeneralFlag: Int?, - @SerialId(8) val bindedUin: Long?, - @SerialId(9) val stMsgInfo: MsgInfo?, - @SerialId(10) val msgCtrlBuf: String?, - @SerialId(11) val serverBuf: ByteArray?, - @SerialId(12) val pingFlag: Long?, - @SerialId(13) val svrip: Int? - ) : JceStruct, Packet - */ - operator fun invoke( - client: QQAndroidClient, - notify: RequestPushNotify - ): OutgoingPacket = buildOutgingPacket(client, key = client.wLoginSigInfo.d2Key) { - val req = MsgSvc.PbGetMsgReq( - serverBuf = notify.serverBuf ?: EMPTY_BYTE_ARRAY, - msgReqType = notify.usMsgType ?: 0, - syncFlag = 0, - rambleFlag = 0, - contextFlag = 1, - latestRambleNumber = 20, - otherRambleNumber = 3, - onlineSyncFlag = 1 - ) - - val data = ProtoBuf.dump( - MsgSvc.PbGetMsgReq.serializer(), - req - ) - - writeInt(data.size) - writeFully(data, 0, data.size) - } - -} - diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PushNotify.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PushNotify.kt index 054ec73b3..bda6e2f5a 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PushNotify.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.PushNotify.kt @@ -25,6 +25,9 @@ import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.toReadPacket class MessageSvc { + /** + * 告知要刷新消息 + */ internal object PushNotify : PacketFactory("MessageSvc.PushNotify") { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): RequestPushNotify { discardExact(8) @@ -42,13 +45,18 @@ class MessageSvc { } } + + /** + * 进行刷新消息 + */ internal object PbGetMsg : PacketFactory>("MessageSvc.PbGetMsg") { + val EXTRA_DATA = "08 00 12 33 6D 6F 64 65 6C 3A 78 69 61 6F 6D 69 20 36 3B 6F 73 3A 32 32 3B 76 65 72 73 69 6F 6E 3A 76 32 6D 61 6E 3A 78 69 61 6F 6D 69 73 79 73 3A 4C 4D 59 34 38 5A 18 E4 E1 A4 FF FE 2D 20 E9 E1 A4 FF FE 2D 28 A8 E1 A4 FF FE 2D 30 99 E1 A4 FF FE 2D".hexToBytes() operator fun invoke( client: QQAndroidClient, from: RequestPushNotify ): OutgoingPacket = buildOutgoingUniPacket( client, - extraData = "08 00 12 33 6D 6F 64 65 6C 3A 78 69 61 6F 6D 69 20 36 3B 6F 73 3A 32 32 3B 76 65 72 73 69 6F 6E 3A 76 32 6D 61 6E 3A 78 69 61 6F 6D 69 73 79 73 3A 4C 4D 59 34 38 5A 18 E4 E1 A4 FF FE 2D 20 E9 E1 A4 FF FE 2D 28 A8 E1 A4 FF FE 2D 30 99 E1 A4 FF FE 2D".hexToBytes().toReadPacket() + extraData = EXTRA_DATA.toReadPacket() ) { writeProtoBuf( MsgSvc.PbGetMsgReq.serializer(), diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt index ee1fc35f9..e8c99edc1 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.PbPushGroupMsg.kt @@ -14,7 +14,11 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.data.ImMsgBody import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.data.MsgOnlinePush import net.mamoe.mirai.qqandroid.utils.toMessageChain + internal class OnlinePush { + /** + * 接受群消息 + */ internal object PbPushGroupMsg : PacketFactory("OnlinePush.PbPushGroupMsg") { @UseExperimental(ExperimentalStdlibApi::class) override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): GroupMessage { diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt index 64b942a05..4e7ef7417 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/login/LoginPacket.kt @@ -274,12 +274,12 @@ internal object LoginPacket : PacketFactory("wt println("type=$type") discardExact(2) - val tlvMap: Map = this.readTLVMap() + val tlvMap: TlvMap = this.readTLVMap() return when (type.toInt()) { 0 -> onLoginSuccess(tlvMap, bot) 1, 15 -> onErrorMessage(tlvMap) 2 -> onSolveLoginCaptcha(tlvMap, bot) - -96 -> onUnsafeDeviceLogin(tlvMap, bot) + -96 -> onUnsafeDeviceLogin(tlvMap) -52 -> onSMSVerifyNeeded(tlvMap, bot) else -> error("unknown login result type: $type") } @@ -287,18 +287,18 @@ internal object LoginPacket : PacketFactory("wt private fun onSMSVerifyNeeded( - tlvMap: Map, + tlvMap: TlvMap, bot: QQAndroidBot ): LoginPacketResponse.SMSVerifyCodeNeeded { - bot.client.t104 = tlvMap[0x104]!! - return LoginPacketResponse.SMSVerifyCodeNeeded(tlvMap[0x174] ?: EMPTY_BYTE_ARRAY, tlvMap[0x402]!!) + bot.client.t104 = tlvMap.getOrFail(0x104) + return LoginPacketResponse.SMSVerifyCodeNeeded(tlvMap[0x174] ?: EMPTY_BYTE_ARRAY, tlvMap.getOrFail(0x402)) } - private fun onUnsafeDeviceLogin(tlvMap: Map, bot: QQAndroidBot): LoginPacketResponse.UnsafeLogin { - return LoginPacketResponse.UnsafeLogin(tlvMap[0x204]!!.toReadPacket().readRemainingBytes().encodeToString()) + private fun onUnsafeDeviceLogin(tlvMap: TlvMap): LoginPacketResponse.UnsafeLogin { + return LoginPacketResponse.UnsafeLogin(tlvMap.getOrFail(0x204).toReadPacket().readRemainingBytes().encodeToString()) } - private fun onErrorMessage(tlvMap: Map): LoginPacketResponse.Error { + private fun onErrorMessage(tlvMap: TlvMap): LoginPacketResponse.Error { return tlvMap[0x146]?.toReadPacket()?.run { readShort() // ver readShort() // code @@ -313,8 +313,7 @@ internal object LoginPacket : PacketFactory("wt @InternalAPI @UseExperimental(MiraiDebugAPI::class) - private fun onSolveLoginCaptcha(tlvMap: Map, bot: QQAndroidBot): LoginPacketResponse. Captcha { - val client = bot.client + private fun onSolveLoginCaptcha(tlvMap: TlvMap, bot: QQAndroidBot): LoginPacketResponse. Captcha { // val ret = tlvMap[0x104]?.let { println(it.toUHexString()) } println() val question = tlvMap[0x165] ?: error("CAPTCHA QUESTION UNKNOWN") @@ -322,8 +321,8 @@ internal object LoginPacket : PacketFactory("wt 0x36 -> { //图片验证 DebugLogger.debug("是一个图片验证码") - bot.client.t104 = tlvMap[0x104]!! - val imageData = tlvMap[0x105]!!.toReadPacket() + bot.client.t104 = tlvMap.getOrFail(0x104) + val imageData = tlvMap.getOrFail(0x105).toReadPacket() val signInfoLength = imageData.readShort() imageData.discardExact(2)//image Length val sign = imageData.readBytes(signInfoLength.toInt()) @@ -332,15 +331,12 @@ internal object LoginPacket : PacketFactory("wt sign = sign ) } - else -> { - error("UNKNOWN CAPTCHA QUESTION: $question") - } + else -> error("UNKNOWN CAPTCHA QUESTION: $question") } - return TODO() } @UseExperimental(MiraiDebugAPI::class) - private fun onLoginSuccess(tlvMap: Map, bot: QQAndroidBot): LoginPacketResponse.Success { + private fun onLoginSuccess(tlvMap: TlvMap, bot: QQAndroidBot): LoginPacketResponse.Success { val client = bot.client println("TLV KEYS: " + tlvMap.keys.joinToString { it.contentToString() }) @@ -544,7 +540,7 @@ internal object LoginPacket : PacketFactory("wt } - private fun Map.getOrEmpty(key: Int): ByteArray { + private fun TlvMap.getOrEmpty(key: Int): ByteArray { return this[key] ?: byteArrayOf() } @@ -623,7 +619,7 @@ internal object LoginPacket : PacketFactory("wt * 设置 [QQAndroidClient.uin] */ private fun QQAndroidClient.analysisTlv113(t113: ByteArray) = t113.read { - val uin = readUInt().toLong() + _uin = readUInt().toLong() /* // nothing to do diff --git a/mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/serverToClient.kt b/mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/serverToClient.kt index 3ef21b1c8..a67e589b0 100644 --- a/mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/serverToClient.kt +++ b/mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/serverToClient.kt @@ -68,38 +68,22 @@ private fun processFullPacketWithoutLength(packet: ByteReadPacket) { val flag3 = readByte().toInt() check(flag3 == 0) { "Illegal flag3. Expected 0, got $flag3" } -<<<<<<< Updated upstream val uinAccount = readString(readInt() - 4)//uin -======= - println("uinAccount=" + readString(readInt() - 4))//uin ->>>>>>> Stashed changes //debugPrint("remaining") (if (flag2 == 2) { -<<<<<<< Updated upstream //PacketLogger.verbose("SSO, 尝试使用 16 zero 解密.") -======= - PacketLogger.verbose("SSO, 尝试使用 16 zero 解密.") ->>>>>>> Stashed changes kotlin.runCatching { decryptBy(DECRYPTER_16_ZERO).also { PacketLogger.verbose("成功使用 16 zero 解密") } } } else { -<<<<<<< Updated upstream //PacketLogger.verbose("Uni, 尝试使用 d2Key 解密.") -======= - PacketLogger.verbose("Uni, 尝试使用 d2Key 解密.") ->>>>>>> Stashed changes kotlin.runCatching { decryptBy(D2Key).also { PacketLogger.verbose("成功使用 d2Key 解密") } } }).getOrElse { -<<<<<<< Updated upstream PacketLogger.verbose("解密失败, 尝试其他各种key") -======= - PacketLogger.verbose("失败, 尝试其他各种key") ->>>>>>> Stashed changes this.readBytes().tryDecryptOrNull()?.toReadPacket() }?.debugPrint("sso/uni body=")?.let { if (flag1 == 0x0A) { @@ -111,11 +95,7 @@ private fun processFullPacketWithoutLength(packet: ByteReadPacket) { val bytes = it.data.readBytes() if (flag2 == 2 && it.packetFactory != null) { PacketLogger.debug("Oicq Reuqest= " + bytes.toUHexString()) -<<<<<<< Updated upstream - try { -======= try{ ->>>>>>> Stashed changes bytes.toReadPacket().parseOicqResponse { if (it.packetFactory.commandName == "wtlogin.login") { DebugLogger.info("服务器发来了 wtlogin.login. 正在解析 key") @@ -149,11 +129,7 @@ private fun processFullPacketWithoutLength(packet: ByteReadPacket) { } } } -<<<<<<< Updated upstream } catch (e: Exception) { -======= - }catch (e: Exception){ ->>>>>>> Stashed changes e.printStackTrace() } } else // always discarded. 00 1C @@ -189,15 +165,9 @@ private fun ByteReadPacket.parseOicqResponse(body: ByteReadPacket.() -> Unit) { val packet = when (encryptionMethod) { 4 -> { // peer public key, ECDH var data = this.decryptBy(shareKeyCalculatedByConstPubKey, 0, this.readRemaining - 1) -<<<<<<< Updated upstream data.read { println("第一层解密: ${data.toUHexString()}") val peerShareKey = ECDH.calculateShareKey(loadPrivateKey(ecdhPrivateKeyS), readUShortLVByteArray().adjustToPublicKey()) -======= - data.read{ - println("第一层解密: ${data.toUHexString()}") - val peerShareKey = ECDH.calculateShareKey(loadPrivateKey(ecdhPrivateKeyS), readUShortLVByteArray().adjustToPublicKey()) ->>>>>>> Stashed changes body(this.decryptBy(peerShareKey)) } }