Commit 408accb8 authored by Him188's avatar Him188

Add GroupNotFound, fix #15

parent 5be14fdc
...@@ -11,15 +11,13 @@ import net.mamoe.mirai.contact.internal.Group ...@@ -11,15 +11,13 @@ import net.mamoe.mirai.contact.internal.Group
import net.mamoe.mirai.contact.internal.QQ import net.mamoe.mirai.contact.internal.QQ
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler
import net.mamoe.mirai.network.protocol.tim.packet.action.GroupNotFound
import net.mamoe.mirai.network.protocol.tim.packet.action.GroupPacket import net.mamoe.mirai.network.protocol.tim.packet.action.GroupPacket
import net.mamoe.mirai.network.protocol.tim.packet.action.RawGroupInfo import net.mamoe.mirai.network.protocol.tim.packet.action.RawGroupInfo
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import net.mamoe.mirai.network.protocol.tim.packet.login.isSuccess import net.mamoe.mirai.network.protocol.tim.packet.login.isSuccess
import net.mamoe.mirai.network.qqAccount import net.mamoe.mirai.network.qqAccount
import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.DefaultLogger
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.internal.PositiveNumbers import net.mamoe.mirai.utils.internal.PositiveNumbers
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
import net.mamoe.mirai.utils.io.inline import net.mamoe.mirai.utils.io.inline
...@@ -165,10 +163,10 @@ class Bot(val account: BotAccount, val logger: MiraiLogger, context: CoroutineCo ...@@ -165,10 +163,10 @@ class Bot(val account: BotAccount, val logger: MiraiLogger, context: CoroutineCo
val bot: Bot get() = this@Bot val bot: Bot get() = this@Bot
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
val groups: ContactList<Group> = ContactList(MutableContactList<Group>()) val groups: ContactList<Group> = ContactList(MutableContactList())
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
val qqs: ContactList<QQ> = ContactList(MutableContactList<QQ>()) val qqs: ContactList<QQ> = ContactList(MutableContactList())
/** /**
* 线程安全地获取缓存的 QQ 对象. 若没有对应的缓存, 则会创建一个. * 线程安全地获取缓存的 QQ 对象. 若没有对应的缓存, 则会创建一个.
...@@ -192,10 +190,15 @@ class Bot(val account: BotAccount, val logger: MiraiLogger, context: CoroutineCo ...@@ -192,10 +190,15 @@ class Bot(val account: BotAccount, val logger: MiraiLogger, context: CoroutineCo
/** /**
* 线程安全地获取缓存的群对象. 若没有对应的缓存, 则会创建一个. * 线程安全地获取缓存的群对象. 若没有对应的缓存, 则会创建一个.
*/ */
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class, ExperimentalUnsignedTypes::class)
suspend fun getGroup(id: GroupId): Group = groups.delegate.getOrNull(id.value) ?: inline { suspend fun getGroup(id: GroupId): Group = groups.delegate.getOrNull(id.value) ?: inline {
val info: RawGroupInfo = try { val info: RawGroupInfo = try {
bot.withSession { GroupPacket.QueryGroupInfo(qqAccount, id.toInternalId(), sessionKey).sendAndExpect() } when (val response =
bot.withSession { GroupPacket.QueryGroupInfo(qqAccount, id.toInternalId(), sessionKey).sendAndExpect<GroupPacket.InfoResponse>() }) {
is RawGroupInfo -> response
is GroupNotFound -> throw GroupNotFoundException("id=${id.value.toLong()}")
else -> assertUnreachable()
}
} catch (e: Exception) { } catch (e: Exception) {
throw IllegalStateException("Cannot obtain group info for id ${id.value.toLong()}", e) throw IllegalStateException("Cannot obtain group info for id ${id.value.toLong()}", e)
} }
......
...@@ -36,6 +36,10 @@ class GroupInfo( ...@@ -36,6 +36,10 @@ class GroupInfo(
"GroupInfo(id=${group.id}, owner=$owner, name=$name, announcement=$announcement, members=${members.idContentString}" "GroupInfo(id=${group.id}, owner=$owner, name=$name, announcement=$announcement, members=${members.idContentString}"
} }
internal object GroupNotFound : GroupPacket.InfoResponse {
override fun toString(): String = "GroupPacket.InfoResponse.GroupNotFound"
}
internal data class RawGroupInfo( internal data class RawGroupInfo(
val group: UInt, val group: UInt,
val owner: UInt, val owner: UInt,
...@@ -45,17 +49,21 @@ internal data class RawGroupInfo( ...@@ -45,17 +49,21 @@ internal data class RawGroupInfo(
* 含群主 * 含群主
*/ */
val members: Map<UInt, MemberPermission> val members: Map<UInt, MemberPermission>
) : GroupPacket.GroupPacketResponse { ) : GroupPacket.InfoResponse {
@Suppress("NOTHING_TO_INLINE") // this function it only executed in one place.
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
suspend inline fun parseBy(group: Group): GroupInfo = group.bot.withSession { inline fun parseBy(group: Group): GroupInfo = group.bot.withSession {
val memberList = MutableContactList<Member>()
members.forEach { entry: Map.Entry<UInt, MemberPermission> ->
entry.key.qq().let { group.Member(it, entry.value, it.coroutineContext) }
}
return GroupInfo( return GroupInfo(
group, group,
this@RawGroupInfo.owner.qq().let { Member(it, group, MemberPermission.OWNER, it.coroutineContext) }, this@RawGroupInfo.owner.qq().let { group.Member(it, MemberPermission.OWNER, it.coroutineContext) },
this@RawGroupInfo.name, this@RawGroupInfo.name,
this@RawGroupInfo.announcement, this@RawGroupInfo.announcement,
ContactList(this@RawGroupInfo.members.mapValuesTo(MutableContactList()) { entry: Map.Entry<UInt, MemberPermission> -> ContactList(memberList)
entry.key.qq().let { Member(it,group, entry.value, it.coroutineContext) }
})
) )
} }
} }
...@@ -159,6 +167,8 @@ internal object GroupPacket : SessionPacketFactory<GroupPacket.GroupPacketRespon ...@@ -159,6 +167,8 @@ internal object GroupPacket : SessionPacketFactory<GroupPacket.GroupPacketRespon
override fun toString(): String = "GroupPacket.MuteResponse" override fun toString(): String = "GroupPacket.MuteResponse"
} }
internal interface InfoResponse : Packet, GroupPacketResponse
@PacketVersion(date = "2019.11.27", timVersion = "2.3.2 (21173)") @PacketVersion(date = "2019.11.27", timVersion = "2.3.2 (21173)")
@UseExperimental(ExperimentalStdlibApi::class) @UseExperimental(ExperimentalStdlibApi::class)
override suspend fun ByteReadPacket.decode( override suspend fun ByteReadPacket.decode(
...@@ -166,7 +176,7 @@ internal object GroupPacket : SessionPacketFactory<GroupPacket.GroupPacketRespon ...@@ -166,7 +176,7 @@ internal object GroupPacket : SessionPacketFactory<GroupPacket.GroupPacketRespon
sequenceId: UShort, sequenceId: UShort,
handler: BotNetworkHandler<*> handler: BotNetworkHandler<*>
): GroupPacketResponse { ): GroupPacketResponse {
return when (readUByte().toUInt()) { return when (val packetType = readUByte().toUInt()) {
0x2Au -> MessageResponse 0x2Au -> MessageResponse
0x7Eu -> MuteResponse // 成功: 7E 00 22 96 29 7B; 0x7Eu -> MuteResponse // 成功: 7E 00 22 96 29 7B;
...@@ -179,180 +189,185 @@ internal object GroupPacket : SessionPacketFactory<GroupPacket.GroupPacketRespon ...@@ -179,180 +189,185 @@ internal object GroupPacket : SessionPacketFactory<GroupPacket.GroupPacketRespon
} }
0x72u -> { 0x72u -> {
discardExact(1) // 00 when (val flag = readByte().toInt()) {
discardExact(4) // group internal id 0x02 -> GroupNotFound
val group = readUInt() // group id 0x00 -> {
discardExact(4) // group internal id
discardExact(13) //00 00 00 03 01 01 00 04 01 00 80 01 40 val group = readUInt() // group id
val owner = readUInt()
discardExact(22) discardExact(13) //00 00 00 03 01 01 00 04 01 00 80 01 40
val groupName = readUByteLVString() val owner = readUInt()
discardExact(22)
discardExact(readUByte()) // 00 val groupName = readUByteLVString()
discardExact(readUByte()) // 00
val announcement = readUByteLVString()
discardExact(readUByte()) // 00
discardExact(readUByte()) // 00
discardExact(readUByte()) // 38 ... 未知
discardExact(readUByte()) // 00
discardExact(readUByte()) // 0A ...
discardExact(38)
val stop = readUInt() // 标记读取群成员的结束
discardExact(1) // 00
val members = mutableMapOf<UInt, MemberPermission>()
do {
val qq = readUInt()
val status = readUShort().toInt() // 这个群成员的状态, 最后一 bit 为管理员权限. 这里面还包含其他状态
if (qq == owner) {
continue
}
val permission = when (status.takeLowestOneBit()) { discardExact(readUByte()) // 00
1 -> MemberPermission.ADMINISTRATOR discardExact(readUByte()) // 00
else -> MemberPermission.MEMBER val announcement = readUByteLVString()
discardExact(readUByte()) // 00
discardExact(readUByte()) // 00
discardExact(readUByte()) // 38 ... 未知
discardExact(readUByte()) // 00
discardExact(readUByte()) // 0A ...
discardExact(38)
val stop = readUInt() // 标记读取群成员的结束
discardExact(1) // 00
val members = mutableMapOf<UInt, MemberPermission>()
do {
val qq = readUInt()
val status = readUShort().toInt() // 这个群成员的状态, 最后一 bit 为管理员权限. 这里面还包含其他状态
if (qq == owner) {
continue
}
val permission = when (status.takeLowestOneBit()) {
1 -> MemberPermission.ADMINISTRATOR
else -> MemberPermission.MEMBER
}
members[qq] = permission
} while (qq != stop && remaining != 0L)
members[owner] = MemberPermission.OWNER
return RawGroupInfo(group, owner, groupName, announcement, members)
/*
* 群 Mirai
*
* 00 00 00 03 01 41 00 04 01 40 23 04 40
* B1 89 BE 09 群主
*
* 02 00 00 00 00 00 00 00 00 00 21 00 C8 01
* 00 00 00 01 00 00
* 00 2D
*
* 06 4D 69 72 61 69 20 群名
* 00
* 00
* 00
* 00
* 00
* 38 87 5F D8 E8 D4 E9 79 73 8A A4 21 1C 3E 2C 43 D0 23 55 53 49 D3 1C DB F6 1F 84 59 77 66 DA 9C D7 26 0F E3 BD E1 F2 B9 29 D1 F6 97 1C 42 5E B0 AF 09 51 72 DA 03 37 AB 65
* 00
* 0A 00 00 00 00 06 00 03 00 02 00
* 01 00 04 00 04 00 00 00 01 00 05 00 04 5D 90 A7 25 00 06 00 04 04 08 00 00 00 07 00 04 00 00 05 80 00 09 00 01 01
* B1 89 BE 09 00
* 3E 03 3F A2 00 01
* 48 76 54 DC 00 00
* 76 E4 B8 DD 00 00
* 89 1A 5E AC 00 00
* B1 89 BE 09 00 00
*/
/*
* 群 XkWhXi
*
* 00 00 00 03 01 41 00 04 01 40 21 04 40
* 3E 03 3F A2 群主
*
* 02 00 00 00 01 00 00 00 00 27 1A 00 C8 01
* 00 00 00 01 00 00
* F3 C8
*
* 06 58 6B 57 68 58 69
* 00
* 00
* 3B E6 AC A2 E8 BF 8E E5 BC 80 E8 BD A6 EF BC 8C E5 8E BB 74 6D E7 9A 84 E7 BD 91 E8 AD A6 0A E6 AC A2 E8 BF 8E E5 BC 80 E8 BD A6 EF BC 8C E5 8E BB 74 6D E7 9A 84 E7 BD 91 E8 AD A6
* 00
* 00
* 38 EB 3B A5 90 AC E3 70 1F 42 51 B4 72 81 C8 F5 5A D8 80 69 B6 76 AD A4 AA CC 6A 17 4C 79 81 FF 82 04 BA 13 CE 28 DA 6C 3F 41 77 C0 77 40 B5 87 8E EE 29 20 65 FC 2D FF 63
* 00
* 0A 00 00 00 00 06 00 03 00 02 00
* 01 00 04 00 04 00 00 00 05 00 05 00 04 57 94 6F 41 00 06 00 04 04 08 00 10 00 07 00 04 00 00 04 04 00 09 00 01 00
* B1 89 BE 09 00 2D 5C 53 A6 00 01 2F 9B 1C F2 00 00 35 49 95 D1 00 01 3B FA 06 9F 00 00 3E 03 3F A2 00 00 42 C4 32 63 00 01 59 17 3E 05 00 01 6A 89 3E 3E 00 00 6D D7 4E CA 00 00 76 E4 B8 DD 00 00 7C BB 60 3C 00 01 7C BC D3 C1 00 01 87 73 86 9D 00 00 90 19 72 65 00 00 97 30 9A 6B 00 00 9C B1 E5 55 00 01 B1 89 BE 09 00 01
*/
/*
* 群 20秃顶28火葬30重生异世
*
*
*/
/*
* 群 Big convene' (与上面两个来自不同 bot)
*
* 00 00 00 03 01 01 00 04 01 00 80 01 40
* 6C 18 F5 DA 群主
*
* 02 00 00 27 1B 00 00 00 00 27 1B 01 F4 01
* 00 00 00 01 00 00
* 0F 1F
*
* 0C 42 69 67 20 63 6F 6E 76 65 6E 65 27 00 群名
* 00 96 E6 AF 95 E4 B8 9A E4 BA 86 EF BC 8C E5 B8 8C E6 9C 9B E5 A4 A7 E5 AE B6 E8 83 BD E5 A4 9F E5 83 8F E4 BB A5 E5 89 8D E9 82 A3 E6 A0 B7 E5 BC 80 E5 BF 83 EF BC 8C E5 AD A6 E4 B9 A0 E8 BF 9B E6 AD A5 EF BC 8C E5 A4 A9 E5 A4 A9 E5 BF AB E4 B9 90 E3 80 82 E6 AD A4 E7 BE A4 E7 A6 81 E6 AD A2 E9 AA 82 E4 BA BA EF BC 8C E5 88 B7 E5 B1 8F E6 9A B4 E5 8A 9B EF BC 8C E8 BF 9D E8 A7 84 E8 80 85 E7 A6 81 E8 A8 80 EF BC 8C E4 B8 A5 E9 87 8D E8 80 85 E5 B0 B1
* 76 E8 BF 9B E7 BE A4 E6 97 B6 EF BC 8C E8 AF B7 E4 BF AE E6 94 B9 E6 AD A3 E7 A1 AE E5 A7 93 E5 90 8D E3 80 82 E4 B8 8D E8 83 BD 54 E5 90 8C E5 AD A6 EF BC 8C E5 A4 AA E8 BF 87 E5 88 86 E7 9A 84 54 21 28 E4 BA 92 E8 B5 9E E7 BE A4 EF BC 8C E6 89 8B E6 9C BA E5 9C A8 E7 BA BF E8 81 8A E5 A4 A9 E8 80 85 E5 8F AF E4 BB A5 E4 BA 92 E8 B5 9E E5 AF B9 E6 96 B9
* 00 38 D9 FD F5 21 A6 1F 8D 61 37 A1 7A 92 91 2A 2C 71 46 A9 B9 1C 45 EB 38 74 4A 74 EA 77 7D 14 DB 12 D0 B0 09 C2 AA 22 16 F1 D0 B9 97 21 F0 5A A0 06 59 A7 3B 2F 32 D2 B8 E3
* 00 0F 00 00 00 00 06 00 03 00 02 01 01 00 04 00 04 00 00 00 15 00 05 00 04 52 7C C5 7C 00 06 00 04 00 00 00 20 00 07 00 04 00 00 00 00 00 09 00 01 00
*
* C5 15 BE BE 00 ???为啥这个只有一个呢
* 1C ED 9F 9B 00 00
* 26 D0 E1 3A 00 00
* 2D 5C 53 A6 00 01 自己 管理员
* 2D BD 28 D2 00 00
* 2E 94 76 3E 00 00
* 35 F3 BC F2 00 00
* 37 D6 91 AB 00 00
* 3A 60 1C 3E 00 80 10000000 群员, 好友
* 3A 86 EA A3 00 48 01001000 群员 手机在线
* 3D 7F E7 70 00 00
* 3E 03 3F A2 00 09 00001001 好友, 特别关心, TIM PC 在线, 管理员
* 41 47 0C DD 00 40 01000000 群员, 离线
* 41 B6 32 A8 00 80
* 44 C8 DA 23 00 00
* 45 3E 1B 6A 00 80 10000000 群员 手机在线
* 45 C6 59 E9 00 C0 群员
* 4A BD C6 F9 00 00
* 4C 67 45 E8 00 00
* 4E AD C2 C2 00 80
* 4F A0 F7 EC 00 80
* 50 CB 11 E8 00 00
* 58 22 21 90 00 00
* 59 17 3E 05 00 01 管理员 好友
* 5E 74 48 D9 00 00
* 5E A2 B5 88 00 00
* 66 A1 32 9B 00 40
* 68 07 29 0A 00 00
* 68 0F EF 4F 00 00
* 69 8B 14 F3 00 80
* 6A A5 27 4E 00 00
* 6C 11 A0 89 00 81 10000001 管理员
* 6C 18 F5 DA 00 08 群主
* 6C 21 F8 E2 00 01 管理员
* 71 F8 F5 18 00 00
* 72 0B CC B6 00 00
* 75 53 38 DF 00 00
* 7A A1 8B 82 00 00
* 7C 8C 1D 1B 00 00
* 7C BC D3 C1 00 00
* 84 2D B8 5F 00 00
* 88 4C 33 76 00 00
* 8C C8 0D 43 00 00
* 90 B8 65 22 00 00
* 91 54 89 E9 00 00
* 9C E6 93 A5 00 01 管理员
* 9D 59 6A 36 00 00
* 9D 63 81 5C 00 00
* 9E 31 AF AC 00 00
* 9E 69 86 25 00 80
* A1 FD CA 2D 00 00
* A5 22 5C 48 00 00
* A5 F2 9A B7 00 00
* AF 25 74 9E 00 01
* B1 50 24 00 00 00
* B2 BD 81 A9 00 00
* B5 0E B3 DD 00 00
* B9 BF 0D BC 00 00
* C5 15 BE BE 00 00
*/
} }
members[qq] = permission else -> unsupportedFlag("GroupPacketResponse typed 0x72", flag.toUHexString())
} while (qq != stop && remaining != 0L) }
members[owner] = MemberPermission.OWNER
return RawGroupInfo(group, owner, groupName, announcement, members)
/*
* 群 Mirai
*
* 00 00 00 03 01 41 00 04 01 40 23 04 40
* B1 89 BE 09 群主
*
* 02 00 00 00 00 00 00 00 00 00 21 00 C8 01
* 00 00 00 01 00 00
* 00 2D
*
* 06 4D 69 72 61 69 20 群名
* 00
* 00
* 00
* 00
* 00
* 38 87 5F D8 E8 D4 E9 79 73 8A A4 21 1C 3E 2C 43 D0 23 55 53 49 D3 1C DB F6 1F 84 59 77 66 DA 9C D7 26 0F E3 BD E1 F2 B9 29 D1 F6 97 1C 42 5E B0 AF 09 51 72 DA 03 37 AB 65
* 00
* 0A 00 00 00 00 06 00 03 00 02 00
* 01 00 04 00 04 00 00 00 01 00 05 00 04 5D 90 A7 25 00 06 00 04 04 08 00 00 00 07 00 04 00 00 05 80 00 09 00 01 01
* B1 89 BE 09 00
* 3E 03 3F A2 00 01
* 48 76 54 DC 00 00
* 76 E4 B8 DD 00 00
* 89 1A 5E AC 00 00
* B1 89 BE 09 00 00
*/
/*
* 群 XkWhXi
*
* 00 00 00 03 01 41 00 04 01 40 21 04 40
* 3E 03 3F A2 群主
*
* 02 00 00 00 01 00 00 00 00 27 1A 00 C8 01
* 00 00 00 01 00 00
* F3 C8
*
* 06 58 6B 57 68 58 69
* 00
* 00
* 3B E6 AC A2 E8 BF 8E E5 BC 80 E8 BD A6 EF BC 8C E5 8E BB 74 6D E7 9A 84 E7 BD 91 E8 AD A6 0A E6 AC A2 E8 BF 8E E5 BC 80 E8 BD A6 EF BC 8C E5 8E BB 74 6D E7 9A 84 E7 BD 91 E8 AD A6
* 00
* 00
* 38 EB 3B A5 90 AC E3 70 1F 42 51 B4 72 81 C8 F5 5A D8 80 69 B6 76 AD A4 AA CC 6A 17 4C 79 81 FF 82 04 BA 13 CE 28 DA 6C 3F 41 77 C0 77 40 B5 87 8E EE 29 20 65 FC 2D FF 63
* 00
* 0A 00 00 00 00 06 00 03 00 02 00
* 01 00 04 00 04 00 00 00 05 00 05 00 04 57 94 6F 41 00 06 00 04 04 08 00 10 00 07 00 04 00 00 04 04 00 09 00 01 00
* B1 89 BE 09 00 2D 5C 53 A6 00 01 2F 9B 1C F2 00 00 35 49 95 D1 00 01 3B FA 06 9F 00 00 3E 03 3F A2 00 00 42 C4 32 63 00 01 59 17 3E 05 00 01 6A 89 3E 3E 00 00 6D D7 4E CA 00 00 76 E4 B8 DD 00 00 7C BB 60 3C 00 01 7C BC D3 C1 00 01 87 73 86 9D 00 00 90 19 72 65 00 00 97 30 9A 6B 00 00 9C B1 E5 55 00 01 B1 89 BE 09 00 01
*/
/*
* 群 20秃顶28火葬30重生异世
*
*
*/
/*
* 群 Big convene' (与上面两个来自不同 bot)
*
* 00 00 00 03 01 01 00 04 01 00 80 01 40
* 6C 18 F5 DA 群主
*
* 02 00 00 27 1B 00 00 00 00 27 1B 01 F4 01
* 00 00 00 01 00 00
* 0F 1F
*
* 0C 42 69 67 20 63 6F 6E 76 65 6E 65 27 00 群名
* 00 96 E6 AF 95 E4 B8 9A E4 BA 86 EF BC 8C E5 B8 8C E6 9C 9B E5 A4 A7 E5 AE B6 E8 83 BD E5 A4 9F E5 83 8F E4 BB A5 E5 89 8D E9 82 A3 E6 A0 B7 E5 BC 80 E5 BF 83 EF BC 8C E5 AD A6 E4 B9 A0 E8 BF 9B E6 AD A5 EF BC 8C E5 A4 A9 E5 A4 A9 E5 BF AB E4 B9 90 E3 80 82 E6 AD A4 E7 BE A4 E7 A6 81 E6 AD A2 E9 AA 82 E4 BA BA EF BC 8C E5 88 B7 E5 B1 8F E6 9A B4 E5 8A 9B EF BC 8C E8 BF 9D E8 A7 84 E8 80 85 E7 A6 81 E8 A8 80 EF BC 8C E4 B8 A5 E9 87 8D E8 80 85 E5 B0 B1
* 76 E8 BF 9B E7 BE A4 E6 97 B6 EF BC 8C E8 AF B7 E4 BF AE E6 94 B9 E6 AD A3 E7 A1 AE E5 A7 93 E5 90 8D E3 80 82 E4 B8 8D E8 83 BD 54 E5 90 8C E5 AD A6 EF BC 8C E5 A4 AA E8 BF 87 E5 88 86 E7 9A 84 54 21 28 E4 BA 92 E8 B5 9E E7 BE A4 EF BC 8C E6 89 8B E6 9C BA E5 9C A8 E7 BA BF E8 81 8A E5 A4 A9 E8 80 85 E5 8F AF E4 BB A5 E4 BA 92 E8 B5 9E E5 AF B9 E6 96 B9
* 00 38 D9 FD F5 21 A6 1F 8D 61 37 A1 7A 92 91 2A 2C 71 46 A9 B9 1C 45 EB 38 74 4A 74 EA 77 7D 14 DB 12 D0 B0 09 C2 AA 22 16 F1 D0 B9 97 21 F0 5A A0 06 59 A7 3B 2F 32 D2 B8 E3
* 00 0F 00 00 00 00 06 00 03 00 02 01 01 00 04 00 04 00 00 00 15 00 05 00 04 52 7C C5 7C 00 06 00 04 00 00 00 20 00 07 00 04 00 00 00 00 00 09 00 01 00
*
* C5 15 BE BE 00 ???为啥这个只有一个呢
* 1C ED 9F 9B 00 00
* 26 D0 E1 3A 00 00
* 2D 5C 53 A6 00 01 自己 管理员
* 2D BD 28 D2 00 00
* 2E 94 76 3E 00 00
* 35 F3 BC F2 00 00
* 37 D6 91 AB 00 00
* 3A 60 1C 3E 00 80 10000000 群员, 好友
* 3A 86 EA A3 00 48 01001000 群员 手机在线
* 3D 7F E7 70 00 00
* 3E 03 3F A2 00 09 00001001 好友, 特别关心, TIM PC 在线, 管理员
* 41 47 0C DD 00 40 01000000 群员, 离线
* 41 B6 32 A8 00 80
* 44 C8 DA 23 00 00
* 45 3E 1B 6A 00 80 10000000 群员 手机在线
* 45 C6 59 E9 00 C0 群员
* 4A BD C6 F9 00 00
* 4C 67 45 E8 00 00
* 4E AD C2 C2 00 80
* 4F A0 F7 EC 00 80
* 50 CB 11 E8 00 00
* 58 22 21 90 00 00
* 59 17 3E 05 00 01 管理员 好友
* 5E 74 48 D9 00 00
* 5E A2 B5 88 00 00
* 66 A1 32 9B 00 40
* 68 07 29 0A 00 00
* 68 0F EF 4F 00 00
* 69 8B 14 F3 00 80
* 6A A5 27 4E 00 00
* 6C 11 A0 89 00 81 10000001 管理员
* 6C 18 F5 DA 00 08 群主
* 6C 21 F8 E2 00 01 管理员
* 71 F8 F5 18 00 00
* 72 0B CC B6 00 00
* 75 53 38 DF 00 00
* 7A A1 8B 82 00 00
* 7C 8C 1D 1B 00 00
* 7C BC D3 C1 00 00
* 84 2D B8 5F 00 00
* 88 4C 33 76 00 00
* 8C C8 0D 43 00 00
* 90 B8 65 22 00 00
* 91 54 89 E9 00 00
* 9C E6 93 A5 00 01 管理员
* 9D 59 6A 36 00 00
* 9D 63 81 5C 00 00
* 9E 31 AF AC 00 00
* 9E 69 86 25 00 80
* A1 FD CA 2D 00 00
* A5 22 5C 48 00 00
* A5 F2 9A B7 00 00
* AF 25 74 9E 00 01
* B1 50 24 00 00 00
* B2 BD 81 A9 00 00
* B5 0E B3 DD 00 00
* B9 BF 0D BC 00 00
* C5 15 BE BE 00 00
*/
} }
else -> unsupported() else -> unsupportedType("GroupPacketResponse", packetType.toUHexString())
} }
} }
} }
\ No newline at end of file
...@@ -4,12 +4,14 @@ package net.mamoe.mirai.network.protocol.tim.packet.event ...@@ -4,12 +4,14 @@ package net.mamoe.mirai.network.protocol.tim.packet.event
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readBytes
import kotlinx.io.core.readUInt import kotlinx.io.core.readUInt
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.getGroup import net.mamoe.mirai.getGroup
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.utils.io.toUHexString
// region mute // region mute
/** /**
...@@ -73,15 +75,23 @@ sealed class UnmuteEvent : EventOfMute() { ...@@ -73,15 +75,23 @@ sealed class UnmuteEvent : EventOfMute() {
// endregion // endregion
internal object `Unknown0x02DCPacket_falg=0x0E_MaybeMutePacket` : EventOfMute() {
override val operator: Member get() = error("Getting a field from Unknown0x02DCPacket_MaybeMutePacket")
override val group: Group get() = error("Getting a field from Unknown0x02DCPacket_MaybeMutePacket")
}
sealed class EventOfMute : EventPacket { sealed class EventOfMute : EventPacket {
abstract val operator: Member abstract val operator: Member
abstract val group: Group abstract val group: Group
} }
// TODO: 2019/12/14 这可能不只是禁言的包.
internal object MemberMuteEventPacketParserAndHandler : KnownEventParserAndHandler<EventOfMute>(0x02DCu) { internal object MemberMuteEventPacketParserAndHandler : KnownEventParserAndHandler<EventOfMute>(0x02DCu) {
override suspend fun ByteReadPacket.parse(bot: Bot, identity: EventPacketIdentity): EventOfMute { override suspend fun ByteReadPacket.parse(bot: Bot, identity: EventPacketIdentity): EventOfMute {
//取消 //取消
//00 00 00 11 00 0A 00 04 01 00 00 00 00 0C 00 05 00 01 00 //00 00 00 11 00
// 0A 00 04 01 00 00 00 00 0C 00 05 00 01 00
// 01 01 // 01 01
// 22 96 29 7B // 22 96 29 7B
// 0C 01 // 0C 01
...@@ -92,7 +102,8 @@ internal object MemberMuteEventPacketParserAndHandler : KnownEventParserAndHandl ...@@ -92,7 +102,8 @@ internal object MemberMuteEventPacketParserAndHandler : KnownEventParserAndHandl
// 00 00 00 00 // 00 00 00 00
// 禁言 // 禁言
//00 00 00 11 00 0A 00 04 01 00 00 00 00 0C 00 05 00 01 00 //00 00 00 11 00
// 0A 00 04 01 00 00 00 00 0C 00 05 00 01 00
// 01 // 01
// 01 // 01
// 22 96 29 7B // 22 96 29 7B
...@@ -104,28 +115,43 @@ internal object MemberMuteEventPacketParserAndHandler : KnownEventParserAndHandl ...@@ -104,28 +115,43 @@ internal object MemberMuteEventPacketParserAndHandler : KnownEventParserAndHandl
// 01 // 01
// 76 E4 B8 DD // 76 E4 B8 DD
// 00 27 8D 00 // 00 27 8D 00
discardExact(19)
discardExact(2) discardExact(3)
val group = bot.getGroup(readUInt()) val flag = readByte().toUInt()
discardExact(2) return when (flag) {
val operator = group.getMember(readUInt()) 0x0Eu -> {
discardExact(4) //time //00 00 00 0E 00 08 00 02 00 01 00
discardExact(2) // 0A 00 04 01 00 00 00 35 DB 60 A2 11 00 3E 08 07 20 A2 C1 ED AE 03 5A 34 08 A2 FF 8C F0 03 1A 19 08 F4 0E 10 FE 8C D3 EF 05 18 84 A1 F8 F9 06 20 00 28 00 30 A2 FF 8C F0 03 2A 0D 08 00 12 09 08 F4 0E 10 00 18 01 20 00 30 00 38 00
val memberQQ = readUInt() `Unknown0x02DCPacket_falg=0x0E_MaybeMutePacket`
val durationSeconds = readUInt().toInt()
return if (durationSeconds == 0) {
if (memberQQ == bot.qqAccount) {
BeingUnmutedEvent(operator)
} else {
MemberUnmuteEvent(group.getMember(memberQQ), operator)
} }
} else {
if (memberQQ == bot.qqAccount) { 0x11u -> {
BeingMutedEvent(durationSeconds, operator) discardExact(15)
} else { discardExact(2)
MemberMuteEvent(group.getMember(memberQQ), durationSeconds, operator) val group = bot.getGroup(readUInt())
discardExact(2)
val operator = group.getMember(readUInt())
discardExact(4) //time
discardExact(2)
val memberQQ = readUInt()
val durationSeconds = readUInt().toInt()
if (durationSeconds == 0) {
if (memberQQ == bot.qqAccount) {
BeingUnmutedEvent(operator)
} else {
MemberUnmuteEvent(group.getMember(memberQQ), operator)
}
} else {
if (memberQQ == bot.qqAccount) {
BeingMutedEvent(durationSeconds, operator)
} else {
MemberMuteEvent(group.getMember(memberQQ), durationSeconds, operator)
}
}
} }
else -> error("Unsupported flag in 0x02DC packet. flag=$flag, remainning=${readBytes().toUHexString()}")
} }
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment