diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt index e5f29721d..baefa2f31 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidClient.kt @@ -8,6 +8,7 @@ import net.mamoe.mirai.BotAccount import net.mamoe.mirai.RawAccountIdUse import net.mamoe.mirai.data.OnlineStatus import net.mamoe.mirai.qqandroid.QQAndroidBot +import net.mamoe.mirai.qqandroid.network.protocol.packet.EMPTY_BYTE_ARRAY import net.mamoe.mirai.qqandroid.network.protocol.packet.PacketLogger import net.mamoe.mirai.qqandroid.network.protocol.packet.Tlv import net.mamoe.mirai.qqandroid.utils.* @@ -107,6 +108,15 @@ internal open class QQAndroidClient( */ val protocolVersion: Short = 8001 + class C2cMessageSyncData { + var syncCookie = EMPTY_BYTE_ARRAY + var pubAccountCookie = EMPTY_BYTE_ARRAY + var syncFlag: Int = 2 + var msgCtrlBuf: ByteArray = EMPTY_BYTE_ARRAY + } + + val c2cMessageSync = C2cMessageSyncData() + /* * 以下登录使用 */ diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/data/MsgSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/data/MsgSvc.kt index 6840ab328..885530d04 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/data/MsgSvc.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/data/MsgSvc.kt @@ -21,7 +21,7 @@ class MsgSvc : ProtoBuf { @SerialId(5) val uinPairMsgs: List? = null, @SerialId(6) val bindUin: Long = 0L, @SerialId(7) val msgRspType: Int = 0, - @SerialId(8) val pubaccountCookie: ByteArray = EMPTY_BYTE_ARRAY, + @SerialId(8) val pubAccountCookie: ByteArray = EMPTY_BYTE_ARRAY, @SerialId(9) val isPartialSync: Boolean = false, @SerialId(10) val msgCtrlBuf: ByteArray = EMPTY_BYTE_ARRAY ) : ProtoBuf 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 aab5a6a3f..054ec73b3 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 @@ -19,6 +19,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.data.RequestPushNo import net.mamoe.mirai.qqandroid.network.protocol.packet.login.data.RequestDataVersion2 import net.mamoe.mirai.qqandroid.network.protocol.packet.login.data.RequestPacket import net.mamoe.mirai.qqandroid.utils.toMessageChain +import net.mamoe.mirai.utils.cryptor.contentToString import net.mamoe.mirai.utils.firstValue import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.toReadPacket @@ -58,7 +59,11 @@ class MessageSvc { latestRambleNumber = 20, otherRambleNumber = 3, onlineSyncFlag = 1, - serverBuf = from.serverBuf ?: EMPTY_BYTE_ARRAY + serverBuf = from.serverBuf ?: EMPTY_BYTE_ARRAY, + syncCookie = client.c2cMessageSync.syncCookie, + syncFlag = client.c2cMessageSync.syncFlag, + msgCtrlBuf = client.c2cMessageSync.msgCtrlBuf, + pubaccountCookie = client.c2cMessageSync.pubAccountCookie ) ) } @@ -67,7 +72,12 @@ class MessageSvc { // 00 00 01 0F 08 00 12 00 1A 34 08 FF C1 C4 F1 05 10 FF C1 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 8A CA 91 D1 0C 48 9B A5 BD 9B 0A 58 DE 9D 99 F8 08 60 1D 68 FF C1 C4 F1 05 70 00 20 02 2A 9D 01 08 F3 C1 C4 F1 05 10 A2 FF 8C F0 03 18 01 22 8A 01 0A 2A 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 18 A6 01 20 0B 28 AE F9 01 30 F4 C1 C4 F1 05 38 A7 E3 D8 D4 84 80 80 80 01 B8 01 CD B5 01 12 08 08 01 10 00 18 00 20 00 1A 52 0A 50 0A 27 08 00 10 F4 C1 C4 F1 05 18 A7 E3 D8 D4 04 20 00 28 0C 30 00 38 86 01 40 22 4A 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 12 08 0A 06 0A 04 4E 4D 53 4C 12 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00 12 04 4A 02 08 00 30 01 2A 15 08 97 A2 C1 F1 05 10 95 A6 F5 E5 0C 18 01 30 01 40 01 48 81 01 2A 10 08 D3 F7 B5 F1 05 10 DD F1 92 B7 07 18 01 30 01 38 00 42 00 48 00 discardExact(4) val resp = readRemainingAsProtoBuf(MsgSvc.PbGetMsgResp.serializer()) - //println(resp.contentToString()) + + bot.client.c2cMessageSync.syncCookie = resp.syncCookie + bot.client.c2cMessageSync.pubAccountCookie = resp.pubAccountCookie + bot.client.c2cMessageSync.syncFlag = resp.syncFlag + bot.client.c2cMessageSync.msgCtrlBuf = resp.msgCtrlBuf + println(resp.contentToString()) if (resp.uinPairMsgs == null) { return MultiPacket(emptyList()) diff --git a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt index 33a951938..b4fdd1340 100644 --- a/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt +++ b/mirai-core/src/androidMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt @@ -1,10 +1,14 @@ package net.mamoe.mirai.utils.io +import io.ktor.network.selector.ActorSelectorManager import io.ktor.network.sockets.Socket import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openWriteChannel import io.ktor.util.KtorExperimentalAPI +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.io.ByteReadChannel +import kotlinx.coroutines.io.ByteWriteChannel import kotlinx.coroutines.io.readAvailable import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.Closeable @@ -17,24 +21,28 @@ import net.mamoe.mirai.utils.MiraiInternalAPI @MiraiInternalAPI actual class PlatformSocket : Closeable { @UseExperimental(KtorExperimentalAPI::class) - lateinit var channel: Socket + lateinit var socket: Socket @UseExperimental(KtorExperimentalAPI::class) actual val isOpen: Boolean - get() = channel.socketContext.isActive + get() = socket.socketContext.isActive - override fun close() = channel.dispose() + override fun close() = socket.dispose() @PublishedApi - internal val writeChannel = channel.openWriteChannel(true) + internal lateinit var writeChannel: ByteWriteChannel @PublishedApi - internal val readChannel = channel.openReadChannel() + internal lateinit var readChannel: ByteReadChannel /** * @throws SendPacketInternalException */ actual suspend inline fun send(packet: ByteReadPacket) { - writeChannel.writePacket(packet) + try { + writeChannel.writePacket(packet) + } catch (e: Exception) { + throw SendPacketInternalException(e) + } } /** @@ -43,13 +51,19 @@ actual class PlatformSocket : Closeable { actual suspend inline fun read(): ByteReadPacket { // do not use readChannel.readRemaining() !!! this function never returns ByteArrayPool.useInstance { buffer -> - val count = readChannel.readAvailable(buffer) + val count = try { + readChannel.readAvailable(buffer) + } catch (e: Exception) { + throw ReadPacketInternalException(e) + } return buffer.toReadPacket(0, count) } } @UseExperimental(KtorExperimentalAPI::class) actual suspend fun connect(serverHost: String, serverPort: Int) { - channel = aSocket(io.ktor.network.selector.ActorSelectorManager(kotlinx.coroutines.Dispatchers.IO)).tcp().connect(serverHost, serverPort) + socket = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().connect(serverHost, serverPort) + writeChannel = socket.openWriteChannel(true) + readChannel = socket.openReadChannel() } } \ No newline at end of file diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt index bfa804929..b4fdd1340 100644 --- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/io/PlatformSocket.kt @@ -1,10 +1,12 @@ package net.mamoe.mirai.utils.io +import io.ktor.network.selector.ActorSelectorManager import io.ktor.network.sockets.Socket import io.ktor.network.sockets.aSocket import io.ktor.network.sockets.openReadChannel import io.ktor.network.sockets.openWriteChannel import io.ktor.util.KtorExperimentalAPI +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.io.ByteReadChannel import kotlinx.coroutines.io.ByteWriteChannel import kotlinx.coroutines.io.readAvailable @@ -60,7 +62,7 @@ actual class PlatformSocket : Closeable { @UseExperimental(KtorExperimentalAPI::class) actual suspend fun connect(serverHost: String, serverPort: Int) { - socket = aSocket(io.ktor.network.selector.ActorSelectorManager(kotlinx.coroutines.Dispatchers.IO)).tcp().connect(serverHost, serverPort) + socket = aSocket(ActorSelectorManager(Dispatchers.IO)).tcp().connect(serverHost, serverPort) writeChannel = socket.openWriteChannel(true) readChannel = socket.openReadChannel() }