소스 검색

Support for approving friend add request

Him188 6 년 전
부모
커밋
5e56144c61

+ 1 - 1
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<RequestFriendAdditionKeyPacket.Response>().key
-                AddFriendPacket(bot.qqAccount, id, sessionKey, lazyMessage(), lazyRemark(), key).sendAndExpect<AddFriendPacket.Response>()
+                AddFriendPacket.RequestAdd(bot.qqAccount, id, sessionKey, lazyMessage(), lazyRemark(), key).sendAndExpect<AddFriendPacket.Response>()
                 return AddFriendResult.WAITING_FOR_APPROVE
             }
             //这个做的是需要验证消息的情况, 不确定 ReadyToAdd 的是啥

+ 1 - 0
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?

+ 1 - 2
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 <T> 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)
             }

+ 26 - 0
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<PacketFactory<*, *>> by mutableListOf()
 
@@ -43,6 +50,25 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d
      */
     abstract suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): TPacket
 
+    @Suppress("DEPRECATION")
+    fun <T> ByteReadPacket.decodeProtoPacket(deserializer: DeserializationStrategy<T>, 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)
 

+ 4 - 0
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),
 

+ 57 - 5
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<PreviousNameList>() {
     //      [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<String>(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<String>(count).apply {
+            repeat(count) {
                 discardExact(2)
                 add(readUShortLVString())
             }
         })
+    }
 }
 
 class PreviousNameList(
@@ -192,9 +197,9 @@ object RequestFriendAdditionKeyPacket : SessionPacketFactory<RequestFriendAdditi
  * 请求添加好友
  */
 @AnnotatedId(KnownPacketId.ADD_FRIEND)
-@PacketVersion(date = "2019.11.11", timVersion = "2.3.2 (21173)")
 object AddFriendPacket : SessionPacketFactory<AddFriendPacket.Response>() {
-    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<AddFriendPacket.Response>() {
         //  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"
     }

+ 1 - 3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GradeInfo.kt

@@ -33,9 +33,7 @@ object RequestAccountInfoPacket : SessionPacketFactory<RequestAccountInfoPacket.
 
     @NoLog
     object Response : Packet {
-        //等级
-        //升级剩余活跃天数
-        //ignored
+        override fun toString(): String = "RequestAccountInfoPacket.Response"
     }
 
     override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): Response = Response

+ 2 - 12
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<GroupImageResponse>() {
     }
 
     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<GroupImageResponse>() {
             @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

+ 2 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/EventPacketFactory.kt

@@ -94,6 +94,7 @@ abstract class KnownEventParserAndHandler<TPacket : Packet>(override val id: USh
         GroupFileUploadEventFactory,
         GroupMemberPermissionChangedEventFactory,
         GroupMessageEventParserAndHandler,
-        FriendMessageEventParserAndHandler
+        FriendMessageEventParserAndHandler,
+        FriendAddRequestEventPacket
     )
 }

+ 120 - 0
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<AddFriendPacket.Response>()
+    }
+}
+
+@PacketVersion(date = "2019.11.20", timVersion = "2.3.2 (21173)")
+object FriendAddRequestEventPacket : KnownEventParserAndHandler<ReceiveFriendAddRequestEvent>(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
+
+ */

+ 16 - 2
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<Any>) += readValue()
+            } else {
+                map[id] = mutableListOf(map[id]!!)
+                @Suppress("UNCHECKED_CAST")
+                (map[id] as MutableList<Any>) += readValue()
+            }
+        } else {
+            map[id] = readValue()
+        }
     }
     return map
 }

+ 7 - 1
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)
 }
 

+ 2 - 2
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<PacketId> = listOf(
         KnownPacketId.FRIEND_ONLINE_STATUS_CHANGE,

+ 8 - 8
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()
 
     /*

+ 5 - 0
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<ReceiveFriendAddRequestEvent> {
+        it.approve()
+    }
+
     bot.subscribeMessages {
         "你好" reply "你好!"