diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt index fd55a1722..fe62c0665 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt @@ -245,7 +245,7 @@ suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" } is CanAddFriendResponse.ReadyToAdd, is CanAddFriendResponse.RequireVerification -> { val key = RequestFriendAdditionKeyPacket(bot.qqAccount, id, sessionKey).sendAndExpect().key - AddFriendPacket(bot.qqAccount, id, sessionKey, lazyMessage(), lazyRemark(), key).sendAndExpect() + AddFriendPacket.RequestAdd(bot.qqAccount, id, sessionKey, lazyMessage(), lazyRemark(), key).sendAndExpect() return AddFriendResult.WAITING_FOR_APPROVE } //这个做的是需要验证消息的情况, 不确定 ReadyToAdd 的是啥 diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt index b95591ab1..7496fcf69 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/internal/MessageDataInternal.kt @@ -11,6 +11,7 @@ internal fun IoBuffer.parseMessageFace(): Face { //00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D discardExact(1) + // FIXME: 2019/11/20 EMOJI 表情会解析失败 val id1 = FaceId(readLVNumber().toInt().toUByte())//可能这个是id, 也可能下面那个 discardExact(readByte().toLong()) // -1 readLVNumber()//某id? diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt index d694629ae..f1946d016 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt @@ -7,7 +7,6 @@ import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.protocol.tim.TIMProtocol -import net.mamoe.mirai.utils.io.debugPrint import net.mamoe.mirai.utils.io.encryptAndWrite import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.writeQQ @@ -141,7 +140,7 @@ fun PacketFactory<*, *>.buildSessionProtoPacket( writeInt(head.size) writeInt(proto.size) writeFully(head) - writeFully(proto.debugPrint("proto data")) + writeFully(proto) } is String -> buildSessionProtoPacket(bot, sessionKey, name, id, sequenceId, headerSizeHint, version, head.hexToBytes(), serializer, protoObj) } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketFactory.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketFactory.kt index 5a1eee4ef..42d4b6e21 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketFactory.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketFactory.kt @@ -4,10 +4,17 @@ package net.mamoe.mirai.network.protocol.tim.packet import kotlinx.atomicfu.atomic import kotlinx.io.core.ByteReadPacket +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.network.BotNetworkHandler import net.mamoe.mirai.utils.io.ByteArrayPool +import net.mamoe.mirai.utils.io.debugPrint +import net.mamoe.mirai.utils.io.read import net.mamoe.mirai.utils.io.toUHexString +import net.mamoe.mirai.utils.readProtoMap object PacketFactoryList : MutableList> by mutableListOf() @@ -43,6 +50,25 @@ abstract class PacketFactory(val d */ abstract suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): TPacket + @Suppress("DEPRECATION") + fun ByteReadPacket.decodeProtoPacket(deserializer: DeserializationStrategy, debuggingTag: String? = null): T { + val headLength = readInt() + val protoLength = readInt() + if (debuggingTag != null) { + readBytes(headLength).debugPrint("$debuggingTag head") + } else { + discardExact(headLength) + } + val bytes = readBytes(protoLength) + // println(ByteReadPacket(bytes).readProtoMap()) + + if (debuggingTag != null) { + bytes.read { readProtoMap() }.toString().debugPrint("$debuggingTag proto") + } + + return ProtoBuf.load(deserializer, bytes) + } + companion object { private val sequenceIdInternal = atomic(1) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt index 78a4ab33d..35ee68515 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt @@ -81,6 +81,10 @@ enum class KnownPacketId(override inline val value: UShort, override inline val inline REQUEST_PROFILE_DETAILS(0x003Cu, RequestProfileDetailsPacket), inline QUERY_PREVIOUS_NAME(0x01BCu, QueryPreviousNamePacket), + + // 031F 查询 "新朋友" 记录 + + // @Suppress("DEPRECATION") // inline SUBMIT_IMAGE_FILE_NAME(0x01BDu, SubmitImageFilenamePacket), diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/AddContact.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/AddContact.kt index adc174aa3..27708d2b3 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/AddContact.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/AddContact.kt @@ -5,6 +5,7 @@ package net.mamoe.mirai.network.protocol.tim.packet.action import kotlinx.io.core.* import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.network.BotNetworkHandler +import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.packet.* import net.mamoe.mirai.network.protocol.tim.packet.event.EventPacket import net.mamoe.mirai.utils.io.* @@ -40,13 +41,17 @@ object QueryPreviousNamePacket : SessionPacketFactory() { // [00 00 00 10] 68 69 6D 31 38 38 E7 9A 84 E5 B0 8F 64 69 63 6B // [00 00 00 0F] E4 B8 B6 E6 9A 97 E8 A3 94 E5 89 91 E9 AD 94 - override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): PreviousNameList = - PreviousNameList(ArrayList(readUInt().toInt()).apply { - repeat(size) { + override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): PreviousNameList { + // 00 00 00 01 00 00 00 0F E8 87 AA E5 8A A8 E9 A9 BE E9 A9 B6 31 2E 33 + + val count = readUInt().toInt() + return PreviousNameList(ArrayList(count).apply { + repeat(count) { discardExact(2) add(readUShortLVString()) } }) + } } class PreviousNameList( @@ -192,9 +197,9 @@ object RequestFriendAdditionKeyPacket : SessionPacketFactory() { - operator fun invoke( + @PacketVersion(date = "2019.11.11", timVersion = "2.3.2 (21173)") + fun RequestAdd( bot: UInt, qq: UInt, sessionKey: SessionKey, @@ -243,6 +248,53 @@ object AddFriendPacket : SessionPacketFactory() { // write } + // 03 76 E4 B8 DD + // 00 00 09 //分组 + // 00 29 //有备注 + // 00 09 00 02 00 00 00 00 + // [00 18] E8 87 AA E5 8A A8 E9 A9 BE E9 A9 B6 31 2E 33 E5 93 88 E5 93 88 E5 93 88 + // [00 05] 00 00 00 00 01 + + // 03 76 E4 B8 DD + // 00 00 09 00 11 00 09 00 02 00 00 00 00 //没有备注, 选择分组和上面那个一样 + // 00 00 00 05 00 00 00 00 01 + + // 03 76 E4 B8 DD + // 00 00 00 + // 00 11 //没有备注 + // 00 09 00 02 00 00 00 00 + // 00 00 00 05 00 00 00 00 01 + @PacketVersion(date = "2019.11.20", timVersion = "2.3.2 (21173)") + fun Approve( + bot: UInt, + sessionKey: SessionKey, + /** + * 好友列表分组的组的 ID. "我的好友" 为 0 + */ + friendListId: Short, + qq: UInt, + /** + * 备注. 不设置则需要为 `null` TODO 需要确认是否还需发送一个设置备注包. 因为测试时若有备注则会多发一个包并且包里面有所设置的备注 + */ + remark: String? + ) = buildSessionPacket(bot, sessionKey, version = TIMProtocol.version0x02) { + writeByte(0x03) + writeQQ(qq) + writeZero(1) + writeUShort(friendListId.toUShort()) + writeZero(1) + when (remark) { + null -> writeUByte(0x11u) + else -> writeUByte(0x29u) + } + writeHex("00 09 00 02 00 00 00 00") + when (remark) { + null -> writeZero(2) + else -> writeShortLVString(remark) + } + writeHex("00 05 00 00 00 00 01") + } + object Response : Packet { override fun toString(): String = "AddFriendPacket.Response" } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt index 6a8c56bc3..107f538df 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt @@ -33,9 +33,7 @@ object RequestAccountInfoPacket : SessionPacketFactory): Response = Response diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt index 996058985..0fa128f50 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupImage.kt @@ -4,11 +4,8 @@ package net.mamoe.mirai.network.protocol.tim.packet.action import kotlinx.coroutines.withContext import kotlinx.io.core.ByteReadPacket -import kotlinx.io.core.discardExact -import kotlinx.io.core.readBytes import kotlinx.serialization.SerialId import kotlinx.serialization.Serializable -import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.GroupId import net.mamoe.mirai.contact.GroupInternalId @@ -23,7 +20,6 @@ import net.mamoe.mirai.qqAccount import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.Http import net.mamoe.mirai.utils.assertUnreachable -import net.mamoe.mirai.utils.io.debugPrintln import net.mamoe.mirai.utils.io.toUHexString import kotlin.coroutines.coroutineContext @@ -85,7 +81,7 @@ class ImageDownloadInfo( val thumbnail: String get() = host + ":" + port.first() + _thumbnail!! override val original: String get() = host + ":" + port.first() + _original!! val compressed: String get() = host + ":" + port.first() + _compressed!! - override fun toString(): String = "ImageDownloadInfo(${_original?.let { original } ?: errorMessage ?: "unknown"}" + override fun toString(): String = "ImageDownloadInfo(${_original?.let { original } ?: errorMessage ?: "unknown"})" } fun ImageDownloadInfo.requireSuccess(): ImageDownloadInfo { @@ -224,11 +220,6 @@ object GroupImagePacket : SessionPacketFactory() { } override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): GroupImageResponse { - val headLength = readInt() - val protoLength = readInt() - discardExact(headLength) - val bytes = readBytes(protoLength) - // println(ByteReadPacket(bytes).readProtoMap()) @Serializable data class GroupImageResponseProto( @@ -236,8 +227,7 @@ object GroupImagePacket : SessionPacketFactory() { @SerialId(4) val imageDownloadInfo: ImageDownloadInfo? = null ) - debugPrintln("收到返回=" + bytes.toUHexString()) - val proto = ProtoBuf.load(GroupImageResponseProto.serializer(), bytes) + val proto = decodeProtoPacket(GroupImageResponseProto.serializer()) return when { proto.imageUploadInfoPacket != null -> proto.imageUploadInfoPacket proto.imageDownloadInfo != null -> proto.imageDownloadInfo diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/EventPacketFactory.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/EventPacketFactory.kt index d3bd56e06..11e88e22f 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/EventPacketFactory.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/EventPacketFactory.kt @@ -94,6 +94,7 @@ abstract class KnownEventParserAndHandler(override val id: USh GroupFileUploadEventFactory, GroupMemberPermissionChangedEventFactory, GroupMessageEventParserAndHandler, - FriendMessageEventParserAndHandler + FriendMessageEventParserAndHandler, + FriendAddRequestEventPacket ) } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/FriendAddRequestEventPacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/FriendAddRequestEventPacket.kt new file mode 100644 index 000000000..0f7014e74 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/FriendAddRequestEventPacket.kt @@ -0,0 +1,120 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") + +package net.mamoe.mirai.network.protocol.tim.packet.event + +import kotlinx.io.core.ByteReadPacket +import kotlinx.io.core.discardExact +import kotlinx.io.core.readUInt +import net.mamoe.mirai.Bot +import net.mamoe.mirai.contact.QQ +import net.mamoe.mirai.network.protocol.tim.packet.PacketVersion +import net.mamoe.mirai.network.protocol.tim.packet.action.AddFriendPacket +import net.mamoe.mirai.network.qqAccount +import net.mamoe.mirai.utils.io.readUShortLVString +import net.mamoe.mirai.withSession +import kotlin.jvm.JvmOverloads + + +/** + * 陌生人请求添加机器人账号为好友 + */ +data class ReceiveFriendAddRequestEvent( + val qq: QQ, + /** + * 验证消息 + */ + val message: String +) : EventPacket { + /** + * 同意这个请求 + * + * @param remark 备注名, 不设置则需为 `null` + */ + @JvmOverloads + suspend fun approve(remark: String? = null): Unit = qq.bot.withSession { + AddFriendPacket.Approve(qqAccount, sessionKey, 0, qq.id, remark).sendAndExpect() + } +} + +@PacketVersion(date = "2019.11.20", timVersion = "2.3.2 (21173)") +object FriendAddRequestEventPacket : KnownEventParserAndHandler(0x02DFu) { + override suspend fun ByteReadPacket.parse(bot: Bot, identity: EventPacketIdentity): ReceiveFriendAddRequestEvent = bot.withSession { + // 00 00 00 08 00 0A 00 04 01 00 + // 00 00 00 01 + // 76 E4 B8 DD + // 00 00 00 01 + // 2D 5C 53 A6 + // 76 E4 B8 DD + // 02 00 00 + // 00 0B BC 00 0B 5D D5 2E A3 04 7C 00 02 00 0C E6 88 91 E6 98 AF E6 A2 A8 E5 A4 B4 00 00 + // 有验证消息 + + // 00 00 00 08 00 0A 00 04 01 00 + // 00 00 00 01 + // 76 E4 B8 DD + // 00 00 00 01 + // 2D 5C 53 A6 + // 76 E4 B8 DD + // 02 00 00 + // 09 0B BD 00 02 5D D5 32 50 04 7C 00 02 00 00 00 00 + // 无验证消息 + + // 00 00 00 08 00 0A 00 04 01 00 + // 00 00 00 01 + // 76 E4 B8 DD + // 00 00 00 01 + // 2D 5C 53 A6 + // 76 E4 B8 DD + // 02 00 00 + // 09 0B BD 00 02 5D D5 33 0C 04 7C 00 02 00 0C E6 88 91 E6 98 AF E6 A2 A8 E5 A4 B4 00 00 + // 有验证消息 + + /* + +Mirai 20:35:23 : Packet received: UnknownEventPacket(id=02 10, identity=(761025446->1994701021)) += 00 00 00 08 00 0A 00 04 01 00 00 00 00 00 00 06 00 00 00 4C 08 02 1A 02 08 23 0A 4A 08 DD F1 92 B7 07 10 A6 A7 F1 EA 02 18 02 20 00 28 01 30 09 38 BD 17 40 02 48 8C E6 D4 EE 05 52 0C E6 88 91 E6 98 AF E6 A2 A8 E5 A4 B4 5A 0F E6 9D A5 E8 87 AA E8 AE A8 E8 AE BA E7 BB 84 62 00 6A 06 08 A5 CE 85 8A 06 72 00 +Mirai 20:35:23 : Packet received: UnknownEventPacket(id=02 DF, identity=(761025446->1994701021)) += 00 00 00 08 00 0A 00 04 01 00 00 00 00 01 76 E4 B8 DD 00 00 00 01 2D 5C 53 A6 76 E4 B8 DD 02 00 00 09 0B BD 00 02 5D D5 33 0C 04 7C 00 02 00 0C E6 88 91 E6 98 AF E6 A2 A8 E5 A4 B4 00 00 +Mirai 20:35:23 : Packet received: UnknownEventPacket(id=00 BB, identity=(761025446->1994701021)) += 00 00 00 08 00 0A 00 04 01 00 00 00 01 0C E6 88 91 E6 98 AF E6 A2 A8 E5 A4 B4 01 0B BD 00 02 00 00 00 5E 00 00 00 00 00 00 00 00 01 04 03 EF 00 06 08 A5 CE 85 8A 06 03 F0 00 02 08 01 03 F2 00 14 00 00 00 82 00 00 00 6D 2F AF 0B ED 20 02 EB 94 00 00 00 00 03 ED 00 28 08 01 12 18 68 69 6D 31 38 38 E7 9A 84 E8 80 81 E5 85 AC E7 9A 84 E6 9B BF E8 BA AB 18 00 22 06 E6 A2 A8 E5 A4 B4 28 01 + + */ + //Mirai 20:32:15 : Packet received: UnknownEventPacket(id=02 DF, identity=(761025446->1994701021)) + // = 00 00 00 08 00 0A 00 04 01 00 00 00 00 01 76 E4 B8 DD 00 00 00 01 2D 5C 53 A6 76 E4 B8 DD 02 00 00 09 0B BD 00 02 5D D5 32 50 04 7C 00 02 00 00 00 00 + //Mirai 20:32:15 : Packet received: UnknownEventPacket(id=02 10, identity=(761025446->1994701021)) + // = 00 00 00 08 00 0A 00 04 01 00 00 00 00 00 00 06 00 00 00 40 08 02 1A 02 08 23 0A 3E 08 DD F1 92 B7 07 10 A6 A7 F1 EA 02 18 02 20 00 28 01 30 09 38 BD 17 40 02 48 D0 E4 D4 EE 05 52 00 5A 0F E6 9D A5 E8 87 AA E8 AE A8 E8 AE BA E7 BB 84 62 00 6A 06 08 A5 CE 85 8A 06 72 00 + //Mirai 20:32:15 : Packet received: UnknownEventPacket(id=00 BB, identity=(761025446->1994701021)) + // = 00 00 00 08 00 0A 00 04 01 00 00 00 01 00 01 0B BD 00 02 00 00 00 5E 00 00 00 00 00 00 00 00 01 04 03 EF 00 06 08 A5 CE 85 8A 06 03 F0 00 02 08 01 03 F2 00 14 00 00 00 82 00 00 00 6D 2F AF 0B ED 20 02 EB 94 00 00 00 00 03 ED 00 28 08 01 12 18 68 69 6D 31 38 38 E7 9A 84 E8 80 81 E5 85 AC E7 9A 84 E6 9B BF E8 BA AB 18 00 22 06 E6 A2 A8 E5 A4 B4 28 01 + discardExact(10 + 4) // 00 00 00 08 00 0A 00 04 01 00 00 00 00 01 + discardExact(4) // bot account uint + discardExact(4) // 00 00 00 01 + val qq = readUInt().qq() + discardExact(4) // bot account uint + discardExact(3) // 02 00 00 恒定 + + discardExact(11) // 不确定. 以下为可能的值 + // 00 00 01 00 01 5D D5 3C 57 00 A8 , 1994701021 添加 761025446 + // 09 0B BD 00 02 5D D5 33 0C 04 7C 有验证, 761025446 添加 1994701021 + // 09 0B BD 00 02 5D D5 32 50 04 7C 无验证, 761025446 添加 1994701021 + // 00 0B BC 00 0B 5D D5 2E A3 04 7C 有验证 + + val message = readUShortLVString() + discardExact(2) // 00 01 + + return ReceiveFriendAddRequestEvent(qq, message) + } +} + +/* + +1994701021 向 761025446 发出好友请求, 761025446 收到 0x02DF 事件, body= +00 00 00 08 00 0A 00 04 01 00 +00 00 00 01 +2D 5C 53 A6 +00 00 00 01 +76 E4 B8 DD +2D 5C 53 A6 +02 00 00 +00 00 01 00 01 5D D5 3C 57 00 A8 00 02 00 00 00 00 + + */ diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Proto.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Proto.kt index b2f3d9005..44a43c66a 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Proto.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/Proto.kt @@ -72,7 +72,7 @@ enum class ProtoType(val value: Byte, private val typeName: String) { override fun toString(): String = this.typeName companion object { - fun valueOf(value: Byte): ProtoType = values().firstOrNull { it.value == value } ?: error("Unknown ProtoId $value") + fun valueOf(value: Byte): ProtoType = values().firstOrNull { it.value == value } ?: error("Unknown ProtoType $value") } } @@ -144,7 +144,8 @@ fun ByteReadPacket.readProtoMap(length: Long = this.remaining): ProtoMap { require(this.remaining > expectingRemaining) { "Expecting to read $length bytes, but read ${expectingRemaining + length - this.remaining}" } val id = ProtoFieldId(readUVarInt()) - map[id] = when (id.type) { + + fun readValue(): Any = when (id.type) { ProtoType.VAR_INT -> UVarInt(readUVarInt()) ProtoType.BIT_32 -> readUInt() ProtoType.BIT_64 -> readULong() @@ -153,6 +154,19 @@ fun ByteReadPacket.readProtoMap(length: Long = this.remaining): ProtoMap { ProtoType.START_GROUP -> Unit ProtoType.END_GROUP -> Unit } + + if (map.containsKey(id)) { + if (map[id] is MutableList<*>) { + @Suppress("UNCHECKED_CAST") + (map[id] as MutableList) += readValue() + } else { + map[id] = mutableListOf(map[id]!!) + @Suppress("UNCHECKED_CAST") + (map[id] as MutableList) += readValue() + } + } else { + map[id] = readValue() + } } return map } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/DebugUtil.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/DebugUtil.kt index 027b7b099..105d055b7 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/DebugUtil.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/DebugUtil.kt @@ -12,6 +12,13 @@ internal object DebugLogger : MiraiLogger by DefaultLogger("Packet Debug") internal fun debugPrintln(any: Any?) = DebugLogger.debug(any) +@Deprecated("Low efficiency, only for debug purpose", ReplaceWith("this")) +internal fun String.debugPrint(name: String): String { + DebugLogger.debug("$name=$this") + return this +} + +@Deprecated("Low efficiency, only for debug purpose", ReplaceWith("this")) internal fun ByteArray.debugPrint(name: String): ByteArray { DebugLogger.debug(name + "=" + this.toUHexString()) return this @@ -67,7 +74,6 @@ internal fun BytePacketBuilder.debugColorizedPrintThis(name: String = "", compar @Deprecated("Low efficiency, only for debug purpose", ReplaceWith(" ")) internal fun BytePacketBuilder.debugPrintThis(name: String = "") { val data = this.build().readBytes() - data.debugPrint(name) this.writeFully(data) } diff --git a/mirai-debug/src/main/kotlin/PacketDebuger.kt b/mirai-debug/src/main/kotlin/PacketDebuger.kt index 905af651a..f34106249 100644 --- a/mirai-debug/src/main/kotlin/PacketDebuger.kt +++ b/mirai-debug/src/main/kotlin/PacketDebuger.kt @@ -118,8 +118,8 @@ object PacketDebugger { * 7. 运行完 `mov eax,dword ptr ss:[ebp+10]` * 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey` */ - val sessionKey: SessionKey = SessionKey("FF 75 0E 37 92 1C F3 A2 44 77 8A 61 44 29 EA D8".hexToBytes()) - const val qq: UInt = 1040400290u + val sessionKey: SessionKey = SessionKey("15 95 8D 22 F7 3B C6 6E FE 91 1B 1B 8F A2 9E 1C".hexToBytes()) + const val qq: UInt = 761025446u val IgnoredPacketIdList: List = listOf( KnownPacketId.FRIEND_ONLINE_STATUS_CHANGE, diff --git a/mirai-debug/src/main/kotlin/test/ProtoTest.kt b/mirai-debug/src/main/kotlin/test/ProtoTest.kt index bd23aa103..e61b9b0da 100644 --- a/mirai-debug/src/main/kotlin/test/ProtoTest.kt +++ b/mirai-debug/src/main/kotlin/test/ProtoTest.kt @@ -9,10 +9,12 @@ import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoNumberType import kotlinx.serialization.protobuf.ProtoType import kotlinx.serialization.serializer -import net.mamoe.mirai.utils.* +import net.mamoe.mirai.utils.MiraiInternalAPI +import net.mamoe.mirai.utils.ProtoFieldId import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.read import net.mamoe.mirai.utils.io.toUHexString +import net.mamoe.mirai.utils.readProtoMap import kotlin.reflect.KClass @Serializable @@ -58,17 +60,15 @@ suspend fun main() { } suspend fun deserializeTest() { - println(Http.getURL("http://gchat.qpic.cn/gchatpic_new/1994701021/1994701021-2868483628-39F76532E1AB5CA786D7A51389225385/0?vuin=1994701021&term=255&srvver=26933").remaining) + //println(Http.getURL("http://gchat.qpic.cn/gchatpic_new/1994701021/1994701021-2868483628-39F76532E1AB5CA786D7A51389225385/0?vuin=1994701021&term=255&srvver=26933").remaining) val bytes = """ - - 10 02 22 4E 08 A0 89 F7 B6 03 10 A2 FF 8C F0 03 18 BB 92 94 BF 08 22 10 63 B1 86 6F 41 3E D9 78 CB CF 53 3E 92 28 5C 58 28 04 30 02 38 20 40 FF 01 48 00 50 01 5A 05 32 36 39 33 33 60 00 68 00 70 00 78 00 80 01 97 04 88 01 ED 03 90 01 04 A0 01 01 - - - - """.trimIndent().replace("\n", " ").replace("[", "").replace("]", "") + 08 01 10 00 1A 89 02 10 01 18 03 3A 4D 08 A6 A7 F1 EA 02 10 DD F1 92 B7 07 18 01 20 D3 81 D5 EE 05 2A 00 32 11 E6 9D A5 E8 87 AA 51 51 E5 8F B7 E6 9F A5 E6 89 BE 38 01 40 01 48 00 50 00 58 00 60 01 6A 00 70 00 78 00 80 01 03 A0 01 00 A8 01 00 B0 01 00 C0 01 01 E8 01 00 3A 4A 08 A6 A7 F1 EA 02 10 DD F1 92 B7 07 18 03 20 DC 80 D5 EE 05 2A 00 32 11 E6 9D A5 E8 87 AA 51 51 E5 8F B7 E6 9F A5 E6 89 BE 38 01 40 01 48 00 50 00 58 00 60 01 6A 00 70 00 78 00 80 01 00 A0 01 00 A8 01 00 B0 01 00 C0 01 00 3A 4A 08 A6 A7 F1 EA 02 10 DD F1 92 B7 07 18 03 20 D7 F8 D4 EE 05 2A 00 32 11 E6 9D A5 E8 87 AA 51 51 E5 8F B7 E6 9F A5 E6 89 BE 38 01 40 01 48 00 50 00 58 00 60 01 6A 00 70 00 78 00 80 01 00 A0 01 00 A8 01 00 B0 01 00 C0 01 00 40 D3 81 D5 EE 05 48 01 50 01 58 01 60 DD F1 92 B7 07 72 08 0A 06 08 DD F1 92 B7 07 78 00 + + + """.trimIndent().replace("\n", " ").replace("[", "").replace("]", "") .hexToBytes() /* diff --git a/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt b/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt index 9d79fc140..ae01471da 100644 --- a/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt +++ b/mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt @@ -17,6 +17,7 @@ import net.mamoe.mirai.message.getValue import net.mamoe.mirai.message.sendAsImageTo import net.mamoe.mirai.network.protocol.tim.packet.event.FriendMessage import net.mamoe.mirai.network.protocol.tim.packet.event.GroupMessage +import net.mamoe.mirai.network.protocol.tim.packet.event.ReceiveFriendAddRequestEvent import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess import java.io.File import java.util.* @@ -54,6 +55,10 @@ suspend fun main() { //bot.logger.verbose("收到了一个事件: ${it::class.simpleName}") } + subscribeAlways { + it.approve() + } + bot.subscribeMessages { "你好" reply "你好!"