mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-20 15:24:45 +08:00
Support for approving friend add request
This commit is contained in:
parent
6cd7fb2411
commit
5e56144c61
@ -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 的是啥
|
||||
|
@ -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?
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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),
|
||||
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -94,6 +94,7 @@ abstract class KnownEventParserAndHandler<TPacket : Packet>(override val id: USh
|
||||
GroupFileUploadEventFactory,
|
||||
GroupMemberPermissionChangedEventFactory,
|
||||
GroupMessageEventParserAndHandler,
|
||||
FriendMessageEventParserAndHandler
|
||||
FriendMessageEventParserAndHandler,
|
||||
FriendAddRequestEventPacket
|
||||
)
|
||||
}
|
@ -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
|
||||
|
||||
*/
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
||||
/*
|
||||
|
@ -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 "你好!"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user