diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt index 1d8f6d487..deca61050 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt @@ -2,6 +2,7 @@ package net.mamoe.mirai.qqandroid.network import kotlinx.coroutines.* import kotlinx.io.core.ByteReadPacket +import kotlinx.io.core.readBytes import kotlinx.io.core.use import net.mamoe.mirai.data.Packet import net.mamoe.mirai.event.broadcast @@ -42,24 +43,42 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler SvcReqRegisterPacket(bot.client, RegPushReason.setOnlineStatus).sendAndExpect() } - internal fun launchPacketProcessor(rawInput: ByteReadPacket): Job = launch(CoroutineName("Incoming Packet handler")) { - rawInput.debugPrint("Received").use { input -> - if (input.remaining == 0L) { - bot.logger.error("Empty packet received. Consider if bad packet was sent.") - return@launch - } - KnownPacketFactories.parseIncomingPacket(bot, input) { packet: Packet, packetId: PacketId, sequenceId: Int -> - if (PacketReceivedEvent(packet).broadcast().cancelled) { - return@parseIncomingPacket + + var lastPacket: ByteArray? = null + internal fun launchPacketProcessor(rawInput: ByteReadPacket): Job = + launch(CoroutineName("Incoming Packet handler")) { + rawInput.debugPrint("Received").use { input -> + if (input.remaining == 0L) { + bot.logger.error("Empty packet received. Consider if bad packet was sent.") + return@launch } - packetListeners.forEach { listener -> - if (listener.filter(packetId, sequenceId) && packetListeners.remove(listener)) { - listener.complete(packet) + val fixedInput = if (lastPacket == null) { + input + } else { + ByteReadPacket((lastPacket ?: ByteArray(0)) + input.readBytes(input.remaining.toInt())) + } + while (true) { + val pk1Length = fixedInput.readInt() - 4 + if (pk1Length > fixedInput.remaining) { + lastPacket = pk1Length.toByteArray().plus(fixedInput.readBytes(fixedInput.remaining.toInt())) + break + } + KnownPacketFactories.parseIncomingPacket( + bot, + fixedInput.readBytes(pk1Length).toReadPacket() + ) { packet: Packet, packetId: PacketId, sequenceId: Int -> + if (PacketReceivedEvent(packet).broadcast().cancelled) { + return@parseIncomingPacket + } + packetListeners.forEach { listener -> + if (listener.filter(packetId, sequenceId) && packetListeners.remove(listener)) { + listener.complete(packet) + } + } } } } } - } private suspend fun processReceive() { while (channel.isOpen) { diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt index e6f8553ae..081b271fc 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt @@ -82,7 +82,7 @@ internal object KnownPacketFactories : List> by mutableListOf( else -> error("Illegal flag2. Expected 0x02, got $flag2") } // 00 00 00 60 00 00 00 0B 02 00 00 00 00 0E 31 39 39 34 37 30 31 30 32 31 CE 35 53 19 84 A8 1A B8 5B 48 E3 7C D0 A6 BA 58 6A EB CE 50 B9 A0 98 D5 B9 D0 1C 72 E2 86 24 FC 55 44 6C 6E E3 F9 15 6C EC 6C 6B 94 40 F7 B4 45 CF B4 D0 79 84 FE 30 EA 98 84 44 84 02 32 70 DD D7 07 07 72 DE 87 59 AC - 0x0B -> + 0x0B -> TODO("TO FOX") else -> error("Illegal flag1. Expected 0x0A or 0x0B, got $flag1") } }