diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/ProtoBuf.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/ProtoBuf.kt index baae9c9c3..70ae9f22f 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/ProtoBuf.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/io/ProtoBuf.kt @@ -7,6 +7,7 @@ import kotlinx.io.core.writeFully import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.SerializationStrategy import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport +import net.mamoe.mirai.utils.io.toUHexString /** * 仅有标示作用 @@ -14,7 +15,10 @@ import net.mamoe.mirai.qqandroid.io.serialization.ProtoBufWithNullableSupport interface ProtoBuf fun BytePacketBuilder.writeProtoBuf(serializer: SerializationStrategy, v: T) { - this.writeFully(v.toByteArray(serializer)) + + this.writeFully(v.toByteArray(serializer).also { + println("发送 protobuf: ${it.toUHexString()}") + }) } /** diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Msg.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Msg.kt index cefbc44b9..78eff1cf7 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Msg.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/data/proto/Msg.kt @@ -469,7 +469,7 @@ class ImMsgBody : ProtoBuf { @SerialId(16) val bubbleSubId: Int = 0, @SerialId(17) val pendantId: Long = 0L, @SerialId(18) val rpIndex: ByteArray = EMPTY_BYTE_ARRAY, - @SerialId(19) val pbReserve: ByteArray = EMPTY_BYTE_ARRAY + @SerialId(19) val pbReserve: ByteArray = EMPTY_BYTE_ARRAY // 78 00 F8 01 00 C8 02 00 ) : ProtoBuf @Serializable @@ -811,12 +811,12 @@ class ImMsgBody : ProtoBuf { @Serializable class RichText( - @SerialId(1) val attr: Attr? = Attr(), + @SerialId(1) val attr: Attr? = null, @SerialId(2) val elems: MutableList = mutableListOf(), - @SerialId(3) val notOnlineFile: NotOnlineFile? = NotOnlineFile(), - @SerialId(4) val ptt: Ptt? = Ptt(), - @SerialId(5) val tmpPtt: TmpPtt? = TmpPtt(), - @SerialId(6) val trans211TmpMsg: Trans211TmpMsg? = Trans211TmpMsg() + @SerialId(3) val notOnlineFile: NotOnlineFile? =null, + @SerialId(4) val ptt: Ptt? =null, + @SerialId(5) val tmpPtt: TmpPtt? = null, + @SerialId(6) val trans211TmpMsg: Trans211TmpMsg? = null ) : ProtoBuf @Serializable diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt index a02d31df8..5d80c0613 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt @@ -2,6 +2,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.discardExact +import kotlinx.io.core.writeFully import net.mamoe.mirai.data.MultiPacket import net.mamoe.mirai.data.Packet import net.mamoe.mirai.message.FriendMessage @@ -21,10 +22,11 @@ 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.buildOutgoingUniPacket import net.mamoe.mirai.qqandroid.utils.toMessageChain -import net.mamoe.mirai.qqandroid.utils.toRichText +import net.mamoe.mirai.qqandroid.utils.toRichTextElems import net.mamoe.mirai.utils.cryptor.contentToString import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.toReadPacket +import kotlin.math.absoluteValue import kotlin.random.Random class MessageSvc { @@ -131,18 +133,22 @@ class MessageSvc { toUin: Long, message: MessageChain ): OutgoingPacket = buildOutgoingUniPacket(client) { + + ///writeFully("0A 08 0A 06 08 89 FC A6 8C 0B 12 06 08 01 10 00 18 00 1A 1F 0A 1D 12 08 0A 06 0A 04 F0 9F 92 A9 12 11 AA 02 0E 88 01 00 9A 01 08 78 00 F8 01 00 C8 02 00 20 9B 7A 28 F4 CA 9B B8 03 32 34 08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00 40 01".hexToBytes()) + + ///return@buildOutgoingUniPacket writeProtoBuf( MsgSvc.PbSendMsgReq.serializer(), MsgSvc.PbSendMsgReq( routingHead = MsgSvc.RoutingHead(c2c = MsgSvc.C2C(toUin = toUin)), contentHead = MsgComm.ContentHead(pkgNum = 1), msgBody = ImMsgBody.MsgBody( - richText = message.toRichText().apply { - elems.add(ImMsgBody.Elem(generalFlags = ImMsgBody.GeneralFlags(pbReserve = "78 00 F8 01 00 C8 02 00".hexToBytes()))) - } + richText = ImMsgBody.RichText( + elems = message.toRichTextElems() + ) ), - msgSeq = 15741, - msgRand = Random.nextInt(), - syncCookie = client.c2cMessageSync.syncCookie, + msgSeq = 17041, + msgRand = Random.nextInt().absoluteValue, + syncCookie = client.c2cMessageSync.syncCookie.takeIf { it.isNotEmpty() } ?: "08 92 C2 C4 F1 05 10 92 C2 C4 F1 05 18 E6 ED B9 C3 02 20 89 FE BE A4 06 28 89 84 F9 A2 06 48 DE 8C EA E5 0E 58 D9 BD BB A0 09 60 1D 68 92 C2 C4 F1 05 70 00".hexToBytes(), msgVia = 1 ) ) diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/MessageQQA.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/MessageQQA.kt index 7da313928..c20ff229c 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/MessageQQA.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/utils/MessageQQA.kt @@ -5,13 +5,13 @@ import net.mamoe.mirai.message.data.* import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody -internal fun MessageChain.toRichText(): ImMsgBody.RichText { - val richText = ImMsgBody.RichText() +internal fun MessageChain.toRichTextElems(): MutableList { + val elems = mutableListOf() this.forEach { when (it) { is PlainText -> { - richText.elems.add(ImMsgBody.Elem(text = ImMsgBody.Text(str = it.stringValue))) + elems.add(ImMsgBody.Elem(text = ImMsgBody.Text(str = it.stringValue))) } is At -> { @@ -19,7 +19,7 @@ internal fun MessageChain.toRichText(): ImMsgBody.RichText { } } - return richText + return elems } diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacket.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacket.kt index 13e4d51df..c31d3dc32 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacket.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/OutgoingPacket.kt @@ -4,9 +4,9 @@ package net.mamoe.mirai.timpc.network.packet import kotlinx.io.core.* import kotlinx.serialization.SerializationStrategy +import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.data.Packet import net.mamoe.mirai.network.BotNetworkHandler -import net.mamoe.mirai.qqandroid.io.serialization.ProtoBuf import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.cryptor.encryptAndWrite import net.mamoe.mirai.utils.io.hexToBytes diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketFactory.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketFactory.kt index 59934b5f4..29cde3a08 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketFactory.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/network/packet/PacketFactory.kt @@ -9,9 +9,9 @@ import kotlinx.io.core.discardExact import kotlinx.io.core.readBytes import kotlinx.io.pool.useInstance import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.data.Packet import net.mamoe.mirai.network.BotNetworkHandler -import net.mamoe.mirai.qqandroid.io.serialization.ProtoBuf import net.mamoe.mirai.utils.cryptor.Decrypter import net.mamoe.mirai.utils.cryptor.DecrypterType import net.mamoe.mirai.utils.cryptor.readProtoMap diff --git a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/utils/writeProto.kt b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/utils/writeProto.kt index 1666dd9f6..fa67ffd0f 100644 --- a/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/utils/writeProto.kt +++ b/mirai-core-timpc/src/commonMain/kotlin/net.mamoe.mirai.timpc/utils/writeProto.kt @@ -3,6 +3,6 @@ package net.mamoe.mirai.timpc.utils import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.writeFully import kotlinx.serialization.SerializationStrategy -import net.mamoe.mirai.qqandroid.io.serialization.ProtoBuf +import kotlinx.serialization.protobuf.ProtoBuf fun BytePacketBuilder.writeProto(serializer: SerializationStrategy, obj: T) = writeFully(ProtoBuf.dump(serializer, obj)) diff --git a/mirai-debug/src/main/kotlin/test/ProfileTest.kt b/mirai-debug/src/main/kotlin/test/ProfileTest.kt deleted file mode 100644 index c3dbad5b1..000000000 --- a/mirai-debug/src/main/kotlin/test/ProfileTest.kt +++ /dev/null @@ -1,23 +0,0 @@ -package test - -import net.mamoe.mirai.utils.io.hexToBytes -import net.mamoe.mirai.utils.io.read -import net.mamoe.mirai.utils.io.readTLVMap -import net.mamoe.mirai.utils.io.toUHexString - - -@ExperimentalStdlibApi -@Suppress("EXPERIMENTAL_API_USAGE") -fun main() { - val newMap = - "4E 22 00 03 E5 AE 89 4E 25 00 06 35 31 31 34 39 35 4E 26 00 01 2D 4E 27 00 01 2D 4E 29 00 01 02 4E 2A 00 06 56 69 76 69 61 6E 4E 2B 00 10 31 35 36 31 34 38 39 31 33 40 71 71 2E 63 6F 6D 4E 2D 00 1D 68 74 74 70 3A 2F 2F 31 35 36 31 34 38 39 31 33 2E 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 4E 2E 00 02 33 00 4E 2F 00 04 33 33 39 00 4E 30 00 01 2D 4E 31 00 01 00 4E 33 00 2D E6 88 91 E7 95 99 E9 95 BF E7 9A 84 E5 A4 B4 E5 8F 91 EF BC 8C E6 98 AF E4 BD A0 E9 94 99 E8 BF 87 E7 9A 84 E5 B9 B4 E5 8D 8E 2E 2E 2E 4E 35 00 18 E5 B9 BF E4 B8 9C E6 8A 80 E6 9C AF E5 B8 88 E8 8C 83 E5 AD A6 E9 99 A2 4E 36 00 01 0A 4E 37 00 01 03 4E 38 00 01 01 4E 3F 00 04 07 C2 0B 02 4E 40 00 0C 00 00 00 31 00 00 34 34 00 00 00 33 4E 41 00 02 00 00 4E 42 00 02 00 00 4E 43 00 02 00 00 4E 45 00 01 21 4E 49 00 04 00 00 00 00 4E 4B 00 04 00 00 00 00 4E 4F 00 01 00 4E 54 00 00 4E 5B 00 00 52 0B 00 04 13 88 02 02 52 0F 00 14 00 00 00 00 00 00 00 00 12 05 10 58 89 10 00 00 00 00 00 00 5D C2 00 0C 00 00 00 31 00 00 34 34 00 00 31 34 5D C8 00 1E E7 B4 A2 E5 B0 BC EF BC 88 E4 B8 AD E5 9B BD EF BC 89 E6 9C 89 E9 99 90 E5 85 AC E5 8F B8 65 97 00 01 11 69 9D 00 04 00 00 00 00 69 A9 00 00 9D A5 00 02 00 00 A4 91 00 02 00 00 A4 93 00 02 00 00 A4 94 00 02 00 00 A4 9C 00 02 00 00 A4 B5 00 02 00 00" - .hexToBytes().read { - readTLVMap(tagSize = 2, expectingEOF = true) - } - newMap.forEach { (key, value) -> - if (!(value.isEmpty() || value.all { it.toInt() == 0 })) { - println(key.toUShort().toUHexString() + "=" + value.decodeToString()) - } - } - return -} \ No newline at end of file diff --git a/mirai-debug/src/main/kotlin/test/ProtoTest.kt b/mirai-debug/src/main/kotlin/test/ProtoTest.kt deleted file mode 100644 index ed7f3f4d5..000000000 --- a/mirai-debug/src/main/kotlin/test/ProtoTest.kt +++ /dev/null @@ -1,55 +0,0 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") - -package test - -import kotlinx.serialization.ImplicitReflectionSerializer -import kotlinx.serialization.SerialId -import kotlinx.serialization.Serializable -import kotlinx.serialization.protobuf.ProtoNumberType -import kotlinx.serialization.protobuf.ProtoType -import kotlinx.serialization.serializer -import net.mamoe.mirai.qqandroid.io.serialization.ProtoBuf -import net.mamoe.mirai.utils.MiraiInternalAPI -import net.mamoe.mirai.utils.cryptor.readProtoMap -import net.mamoe.mirai.utils.io.hexToBytes -import net.mamoe.mirai.utils.io.read -import kotlin.reflect.KClass - -@Serializable -data class ProtoTest( - //@SerialId(1) val string: String, - //@SerialId(1) val int: Int, - //@SerialId(1) val boolean: Boolean, - //@SerialId(1) val short: Short, - //@SerialId(1) val byte: Byte, - @SerialId(1) @ProtoType(ProtoNumberType.FIXED) val fixedByte: Byte -) - -@UseExperimental(MiraiInternalAPI::class) -suspend fun main() { - deserializeTest() -} - -suspend fun deserializeTest() { - val bytes = - """ - 08 02 1A 55 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 1A 25 2F 34 35 35 38 66 39 30 38 2D 37 62 39 61 2D 34 65 32 66 2D 38 63 36 39 2D 34 61 35 32 61 66 62 33 36 35 61 37 20 01 30 04 38 05 40 09 48 01 58 00 60 01 6A 0A 38 2E 32 2E 30 2E 31 32 39 36 70 E0 8C B2 F0 05 78 01 50 03 - """.trimIndent() - .replace("\n", " ") - .replace("UVarInt", "", ignoreCase = true) - .replace("uint", "", ignoreCase = true) - .replace("[", "") - .replace("]", "") - .replace("(", "") - .replace(")", "") - .replace(" ", " ") - .replace(" ", " ") - .replace(" ", " ") - .replace("_", "") - .replace(",", "") - .hexToBytes() - println(bytes.read { readProtoMap() }) -} - -@UseExperimental(ImplicitReflectionSerializer::class) -fun KClass.loadFrom(protoBuf: ByteArray): T = ProtoBuf.load(this.serializer(), protoBuf) \ No newline at end of file