Fix group transfer and retrieve, add tests for notice events:

- GroupRetrieveTest
- GroupTransferTest
- MemberAdminChangeTest
- MemberQuitTest
- MuteTest
This commit is contained in:
Him188 2021-08-25 13:55:43 +08:00
parent 76e2b6c64c
commit f51e721649
9 changed files with 833 additions and 23 deletions

View File

@ -259,3 +259,16 @@ internal fun QQAndroidBot.getGroupByUinOrFail(uin: Long) =
getGroupByUin(uin) ?: throw NoSuchElementException("group.uin=$uin")
internal fun QQAndroidBot.getGroupByUin(uin: Long) = groups.firstOrNull { it.uin == uin }
/**
* uin first
*/
internal fun QQAndroidBot.getGroupByUinOrCode(uinOrCode: Long) =
groups.firstOrNull { it.uin == uinOrCode } ?: groups.firstOrNull { it.id == uinOrCode }
/**
* code first
*/
internal fun QQAndroidBot.getGroupByCodeOrUin(uinOrCode: Long) =
groups.firstOrNull { it.id == uinOrCode } ?: groups.firstOrNull { it.uin == uinOrCode }

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.internal.network.ParseErrorPacket
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.internal.network.component.ComponentStorage
import net.mamoe.mirai.internal.network.notice.BotAware
import net.mamoe.mirai.internal.network.notice.NewContactSupport
import net.mamoe.mirai.internal.network.notice.decoders.DecodedNotifyMsgBody
import net.mamoe.mirai.internal.network.notice.decoders.MsgType0x2DC
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgInfo
@ -78,7 +79,7 @@ internal value class MutableProcessResult(
val data: MutableCollection<Packet>
)
internal interface NoticePipelineContext : BotAware {
internal interface NoticePipelineContext : BotAware, NewContactSupport {
override val bot: QQAndroidBot
val attributes: TypeSafeMap
@ -206,7 +207,7 @@ internal open class NoticeProcessorPipelineImpl private constructor() : NoticePr
}
inner class ContextImpl(
open inner class ContextImpl(
bot: QQAndroidBot, attributes: TypeSafeMap,
) : AbstractNoticePipelineContext(bot, attributes) {
override suspend fun processAlso(data: ProtocolStruct, attributes: TypeSafeMap): ProcessResult {
@ -221,7 +222,7 @@ internal open class NoticeProcessorPipelineImpl private constructor() : NoticePr
override suspend fun process(bot: QQAndroidBot, data: ProtocolStruct, attributes: TypeSafeMap): ProcessResult {
traceLogging.info { "process: data=$data" }
val context = ContextImpl(bot, attributes)
val context = createContext(bot, attributes)
val diff = if (traceLogging.isEnabled) CollectionDiff<Packet>() else null
diff?.save(context.collected.data)
@ -255,6 +256,11 @@ internal open class NoticeProcessorPipelineImpl private constructor() : NoticePr
return context.collected.data
}
protected open fun createContext(
bot: QQAndroidBot,
attributes: TypeSafeMap
): NoticePipelineContext = ContextImpl(bot, attributes)
protected open fun packetToString(data: Any?): String =
data.toDebugString("mirai.network.notice.pipeline.log.full")

View File

@ -21,11 +21,11 @@ import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.internal.contact.addNewNormalMember
import net.mamoe.mirai.internal.contact.info.MemberInfoImpl
import net.mamoe.mirai.internal.getGroupByUin
import net.mamoe.mirai.internal.getGroupByUinOrCode
import net.mamoe.mirai.internal.message.contextualBugReportException
import net.mamoe.mirai.internal.network.components.ContactUpdater
import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
import net.mamoe.mirai.internal.network.components.NoticePipelineContext
import net.mamoe.mirai.internal.network.notice.NewContactSupport
import net.mamoe.mirai.internal.network.notice.decoders.DecodedNotifyMsgBody
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
@ -59,7 +59,7 @@ import net.mamoe.mirai.utils.read
*/
internal class GroupOrMemberListNoticeProcessor(
private val logger: MiraiLogger,
) : MixedNoticeProcessor(), NewContactSupport {
) : MixedNoticeProcessor() {
override suspend fun NoticePipelineContext.processImpl(data: MsgType0x210) {
if (data.uSubMsgType != 0x44L) return
@ -334,7 +334,7 @@ internal class GroupOrMemberListNoticeProcessor(
groupUin: Long,
) {
when (kind) {
2, 0x82 -> bot.getGroupByUin(groupUin)?.let { group ->
2, 0x82 -> bot.getGroupByUinOrCode(groupUin)?.let { group ->
if (target == bot.id) {
collect(BotLeaveEvent.Active(group))
bot.groups.delegate.remove(group)
@ -346,7 +346,7 @@ internal class GroupOrMemberListNoticeProcessor(
member.cancel(CancellationException("Left actively"))
}
}
3, 0x83 -> bot.getGroupByUin(groupUin)?.let { group ->
3, 0x83 -> bot.getGroupByUinOrCode(groupUin)?.let { group ->
if (target == bot.id) {
val member = group.members[operator] ?: return
collect(BotLeaveEvent.Kick(member))
@ -373,7 +373,7 @@ internal class GroupOrMemberListNoticeProcessor(
target: Long,
newPermissionByte: Int,
) {
val group = bot.getGroupByUin(data.fromUin) ?: return
val group = bot.getGroupByUinOrCode(data.fromUin) ?: return
val newPermission = if (newPermissionByte == 1) ADMINISTRATOR else MEMBER
@ -394,13 +394,12 @@ internal class GroupOrMemberListNoticeProcessor(
/**
* Owner of the group [from] transfers ownership to another member [to], or retrieve ownership.
*/
// TODO: 2021/6/26 tests
private suspend fun NoticePipelineContext.handleGroupOwnershipTransfer(
data: OnlinePushTrans.PbMsgInfo,
from: Long,
to: Long,
) {
val group = bot.getGroupByUin(data.fromUin)
val group = bot.getGroupByUinOrCode(data.fromUin)
if (from == bot.id) {
// bot -> member
group ?: return markAsConsumed()
@ -414,17 +413,18 @@ internal class GroupOrMemberListNoticeProcessor(
// member Retrieve or permission changed to OWNER
var newOwner = group[to]
if (newOwner == null) {
newOwner = group.addNewNormalMember(MemberInfoImpl(uin = to, nick = "", permission = OWNER)) ?: return
val nick = Mirai.queryProfile(bot, to).nickname
newOwner = group.addNewNormalMember(MemberInfoImpl(uin = to, nick = nick, permission = OWNER)) ?: return
collect(MemberJoinEvent.Retrieve(newOwner))
} else if (newOwner.permission != OWNER) {
collect(MemberPermissionChangeEvent(newOwner, newOwner.permission, OWNER))
newOwner.permission = OWNER
}
} else {
// member -> bot
// member -> member/bot
// bot Retrieve or permission changed to OWNER
if (group == null) {
if (group == null) { // TODO: 2021/8/25 test this
collect(BotJoinGroupEvent.Retrieve(bot.addNewGroupByUin(data.fromUin) ?: return))
return
}
@ -438,9 +438,20 @@ internal class GroupOrMemberListNoticeProcessor(
// if member is null, he has already quit the group in another event.
}
if (group.botPermission != OWNER) {
collect(BotGroupPermissionChangeEvent(group, group.botPermission, OWNER))
group.botAsMember.permission = OWNER
if (to == bot.id) {
// member -> bot
if (group.botPermission != OWNER) {
collect(BotGroupPermissionChangeEvent(group, group.botPermission, OWNER))
group.botAsMember.permission = OWNER
}
} else {
// member -> member
group[to]?.let { newOwner ->
if (newOwner.permission != OWNER) {
collect(MemberPermissionChangeEvent(newOwner, newOwner.permission, OWNER))
}
newOwner.permission = OWNER
}
}
}
}

View File

@ -30,7 +30,6 @@ import net.mamoe.mirai.utils.TypeSafeMap
import net.mamoe.mirai.utils.cast
import net.mamoe.mirai.utils.currentTimeSeconds
import net.mamoe.mirai.utils.hexToUBytes
import java.util.*
/**
@ -58,11 +57,6 @@ internal abstract class AbstractNoticeProcessorTest : AbstractNettyNHTest(), Gro
}
}
private val properties = Properties().apply {
load(Thread.currentThread().contextClassLoader.getResourceAsStream("recording/data/notice/NoticeProcessorTestData.properties"))
}
fun setBot(id: Long): QQAndroidBot {
bot = createBot(BotAccount(id, "a"))
return bot
@ -146,7 +140,7 @@ internal interface GroupExtensions {
fun Group.addMember(
id: Long,
nick: String,
nick: String = "user$id",
permission: MemberPermission,
remark: String = "",
nameCard: String = "",

View File

@ -0,0 +1,104 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:JvmBlockingBridge
package net.mamoe.mirai.internal.notice.processors
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.events.BotGroupPermissionChangeEvent
import net.mamoe.mirai.event.events.MemberPermissionChangeEvent
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
internal class GroupRetrieveTest : AbstractNoticeProcessorTest() {
@Test
suspend fun `other member retrieves group from another member when they are in the group`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 44,
msgSeq = 27,
msgUid = 14411,
msgTime = 1629,
realMsgTime = 164,
msgData = "00 22 07 BB 01 FF 00 12 C4 B1 00 12 C4 B2".hexToBytes(),
svrIp = -9623,
)
}
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.OWNER)
addMember(1230002, permission = MemberPermission.MEMBER)
}
runTest().toList().run {
assertEquals(2, size, toString())
get(0).run {
assertIs<MemberPermissionChangeEvent>(this)
assertEquals(1230001, member.id)
assertEquals(MemberPermission.OWNER, origin)
assertEquals(MemberPermission.MEMBER, new)
assertEquals(MemberPermission.MEMBER, group.members[1230001]!!.permission)
}
get(1).run {
assertIs<MemberPermissionChangeEvent>(this)
assertEquals(1230002, member.id)
assertEquals(MemberPermission.MEMBER, origin)
assertEquals(MemberPermission.OWNER, new)
assertEquals(MemberPermission.OWNER, group.members[1230002]!!.permission)
}
}
}
@Test
suspend fun `other member retrieves group from bot when they are in the group`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 44,
msgSeq = 459,
msgUid = 14411518,
msgTime = 1629,
realMsgTime = 1629,
msgData = "00 22 07 BB 01 FF 00 12 C4 B3 00 12 C4 B2".hexToBytes(),
svrIp = -164,
)
}
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
addMember(1230002, permission = MemberPermission.MEMBER)
botAsMember.permission = MemberPermission.OWNER
}
runTest().toList().run {
assertEquals(2, size, toString())
get(0).run {
assertIs<BotGroupPermissionChangeEvent>(this)
assertEquals(MemberPermission.OWNER, origin)
assertEquals(MemberPermission.MEMBER, new)
assertEquals(MemberPermission.MEMBER, group.botPermission)
}
get(1).run {
assertIs<MemberPermissionChangeEvent>(this)
assertEquals(1230002, member.id)
assertEquals(MemberPermission.MEMBER, origin)
assertEquals(MemberPermission.OWNER, new)
assertEquals(MemberPermission.OWNER, group.members[1230002]!!.permission)
}
}
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:JvmBlockingBridge
package net.mamoe.mirai.internal.notice.processors
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.events.BotGroupPermissionChangeEvent
import net.mamoe.mirai.event.events.MemberPermissionChangeEvent
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
internal class GroupTransferTest : AbstractNoticeProcessorTest() {
@Test
suspend fun `owner transfers group to other member`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 44,
msgSeq = 439,
msgUid = 14411520,
msgTime = 162974,
realMsgTime = 163874,
msgData = "00 22 07 BB 01 FF 00 12 C4 B2 00 12 C4 B1".hexToBytes(),
svrIp = 194,
)
}
val group = setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
addMember(1230002, permission = MemberPermission.OWNER)
}
runTest().toList().run {
assertEquals(2, size)
get(0).run {
assertIs<MemberPermissionChangeEvent>(this)
assertEquals(1230002, member.id)
assertEquals(MemberPermission.OWNER, origin)
assertEquals(MemberPermission.MEMBER, new)
assertEquals(MemberPermission.MEMBER, group.members[1230002]!!.permission)
}
get(1).run {
assertIs<MemberPermissionChangeEvent>(this)
assertEquals(1230001, member.id)
assertEquals(MemberPermission.MEMBER, origin)
assertEquals(MemberPermission.OWNER, new)
assertEquals(MemberPermission.OWNER, group.members[1230001]!!.permission)
}
}
}
@Test
suspend fun `owner transfers group to bot`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 44,
msgSeq = 291,
msgUid = 144115188,
msgTime = 16298,
realMsgTime = 16298,
msgData = "00 22 07 BB 01 FF 00 12 C4 B2 00 12 C4 B3".hexToBytes(),
svrIp = -14676,
)
}
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
addMember(1230002, permission = MemberPermission.OWNER)
}
runTest().toList().run {
assertEquals(2, size)
get(0).run {
assertIs<MemberPermissionChangeEvent>(this)
assertEquals(1230002, member.id)
assertEquals(MemberPermission.OWNER, origin)
assertEquals(MemberPermission.MEMBER, new)
assertEquals(MemberPermission.MEMBER, group.members[1230002]!!.permission)
}
get(1).run {
assertIs<BotGroupPermissionChangeEvent>(this)
assertEquals(MemberPermission.MEMBER, origin)
assertEquals(MemberPermission.OWNER, new)
assertEquals(MemberPermission.OWNER, group.botPermission)
}
}
}
}

View File

@ -0,0 +1,217 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:JvmBlockingBridge
package net.mamoe.mirai.internal.notice.processors
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.events.BotGroupPermissionChangeEvent
import net.mamoe.mirai.event.events.MemberPermissionChangeEvent
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
/**
* Set/cancel admin permission for bot/member
*/
internal class MemberAdminChangeTest : AbstractNoticeProcessorTest() {
@Test
suspend fun `bot member to admin`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 44,
msgSeq = 4827,
msgUid = 144,
msgTime = 162,
realMsgTime = 1629,
msgData = "00 22 07 BB 01 01 00 12 C4 B3 01".hexToBytes(),
svrIp = 12165,
)
}
// bot was MEMBER
val group = setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
addMember(1230002, permission = MemberPermission.OWNER)
}
runTest().run {
assertEquals(1, size)
val event = single()
assertIs<BotGroupPermissionChangeEvent>(event)
assertEquals(MemberPermission.MEMBER, event.origin)
assertEquals(MemberPermission.ADMINISTRATOR, event.new)
assertEquals(MemberPermission.ADMINISTRATOR, group.botPermission)
}
// bot was ADMINISTRATOR
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
addMember(1230002, permission = MemberPermission.OWNER)
botAsMember.permission = MemberPermission.ADMINISTRATOR
}
runTest().run {
assertEquals(0, size)
}
}
@Test
suspend fun `bot admin to member`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 44,
msgSeq = 483,
msgUid = 14411512,
msgTime = 1629863,
realMsgTime = 1623063,
msgData = "00 22 07 BB 01 00 00 12 C4 B3 00".hexToBytes(),
svrIp = 2039273,
)
}
val group = setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
addMember(1230002, permission = MemberPermission.OWNER)
botAsMember.permission = MemberPermission.ADMINISTRATOR
}
runTest().run {
assertEquals(1, size)
val event = single()
assertIs<BotGroupPermissionChangeEvent>(event)
assertEquals(MemberPermission.ADMINISTRATOR, event.origin)
assertEquals(MemberPermission.MEMBER, event.new)
assertEquals(MemberPermission.MEMBER, group.botPermission)
}
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
addMember(1230002, permission = MemberPermission.OWNER)
botAsMember.permission = MemberPermission.MEMBER // already member
}
runTest().run {
assertEquals(0, size)
}
}
@Test
suspend fun `member member to admin`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 44,
msgSeq = 5639,
msgUid = 1441812,
msgTime = 1623204,
realMsgTime = 1623204,
msgData = "00 22 07 BB 01 01 00 12 C4 B1 01".hexToBytes(),
svrIp = -20900855,
)
}
// member was MEMBER
val group = setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
addMember(1230002, permission = MemberPermission.OWNER)
}
runTest().run {
assertEquals(1, size)
val event = single()
assertIs<MemberPermissionChangeEvent>(event)
assertEquals(1230001, event.member.id)
assertEquals(MemberPermission.MEMBER, event.origin)
assertEquals(MemberPermission.ADMINISTRATOR, event.new)
assertEquals(MemberPermission.ADMINISTRATOR, group.members[1230001]!!.permission)
}
// member was already ADMINISTRATOR
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.ADMINISTRATOR)
addMember(1230002, permission = MemberPermission.OWNER)
}
runTest().run {
assertEquals(0, size)
}
}
@Test
suspend fun `member admin to member`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 44,
msgSeq = 745,
msgUid = 144115576812,
msgTime = 162250,
realMsgTime = 16290,
msgData = "00 22 07 BB 01 00 00 12 C4 B1 00".hexToBytes(),
svrIp = 277969,
)
}
val group = setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
.permission = MemberPermission.ADMINISTRATOR
addMember(1230002, permission = MemberPermission.OWNER)
}
runTest().run {
assertEquals(1, size)
val event = single()
assertIs<MemberPermissionChangeEvent>(event)
assertEquals(1230001, event.member.id)
assertEquals(MemberPermission.ADMINISTRATOR, event.origin)
assertEquals(MemberPermission.MEMBER, event.new)
assertEquals(MemberPermission.MEMBER, group.members[1230001]!!.permission)
}
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, permission = MemberPermission.MEMBER)
.permission = MemberPermission.MEMBER // already member
addMember(1230002, permission = MemberPermission.OWNER)
}
runTest().run {
assertEquals(0, size)
}
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:JvmBlockingBridge
package net.mamoe.mirai.internal.notice.processors
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.events.MemberLeaveEvent
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
internal class MemberQuitTest : AbstractNoticeProcessorTest() {
@Test
suspend fun `member active quit`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230003,
msgType = 34,
msgSeq = 266,
msgUid = 1441151,
msgTime = 16298,
realMsgTime = 1629,
msgData = "00 22 07 BB 01 00 12 C4 B1 02 00 30 39 41 36 36 41 32 31 32 33 35 37 32 43 39 35 38 42 42 36 38 45 32 36 44 34 34 32 38 45 32 32 37 32 36 44 39 44 45 41 31 34 41 44 37 30 31 46 31".hexToBytes(),
svrIp = 618,
extGroupKeyInfo = net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.ExtGroupKeyInfo(
curMaxSeq = 1626,
curTime = 16298,
),
generalFlag = 1,
)
}
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, "user1", MemberPermission.MEMBER)
addMember(1230002, "user2", MemberPermission.OWNER)
}
runTest().run {
assertEquals(1, size)
single().run {
assertIs<MemberLeaveEvent.Quit>(this)
assertEquals(1230001, member.id)
assertEquals(null, group.members[1230001])
}
}
}
@Test
suspend fun `member kick`() {
suspend fun runTest() = use {
net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.PbMsgInfo(
fromUin = 2230203,
toUin = 1230002,
msgType = 34,
msgSeq = 430,
msgUid = 1441,
msgTime = 16298,
realMsgTime = 1629,
msgData = "00 22 07 BB 01 00 12 C4 B1 03 00 12 C4 B3 06 B4 B4 BD A8 D5 DF 00 30 45 31 39 41 35 43 41 37 34 36 44 37 38 31 36 45 34 46 36 37 41 39 35 36 46 32 34 46 46 38 33 41 32 30 34 44 41 33 38 30 35 41 38 34 39 45 44 32".hexToBytes(),
svrIp = 54562,
extGroupKeyInfo = net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans.ExtGroupKeyInfo(
curMaxSeq = 1627,
curTime = 1629,
),
generalFlag = 1,
)
}
setBot(1230003)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230001, "user1", MemberPermission.MEMBER)
addMember(1230002, "user2", MemberPermission.OWNER)
}
runTest().run {
assertEquals(1, size)
single().run {
assertIs<MemberLeaveEvent.Kick>(this)
assertEquals(1230001, member.id)
assertEquals(null, group.members[1230001])
}
}
}
}

View File

@ -0,0 +1,265 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:JvmBlockingBridge
package net.mamoe.mirai.internal.notice.processors
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.events.BotMuteEvent
import net.mamoe.mirai.event.events.BotUnmuteEvent
import net.mamoe.mirai.event.events.MemberMuteEvent
import net.mamoe.mirai.event.events.MemberUnmuteEvent
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgInfo
import net.mamoe.mirai.internal.network.protocol.data.jce.OnlinePushPack
import net.mamoe.mirai.internal.network.protocol.data.jce.ShareData
import net.mamoe.mirai.utils.currentTimeSeconds
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
internal class MuteTest : AbstractNoticeProcessorTest() {
@Test
suspend fun `bot mute`() {
suspend fun MuteTest.runTest() = use {
OnlinePushPack.SvcReqPushMsg(
uin = 1230001,
uMsgTime = 1629868940,
vMsgInfos = mutableListOf(
MsgInfo(
lFromUin = 2230203,
shMsgType = 732,
shMsgSeq = 8352,
strMsg = "",
uRealMsgTime = 16298,
vMsg = "00 22 07 BB 0C 01 00 12 C4 B2 61 25 D3 8D 00 01 00 12 C4 B1 00 00 02 58".hexToBytes(),
uAppShareID = 0,
vMsgCookies = "08 DC 05 10 DC 85 E0 80 80 80 80 80 02 18 03 20 DE 86 03".hexToBytes(),
lMsgUid = 1441151,
lLastChangeTime = 1,
vCPicInfo = mutableListOf(),
stShareData = ShareData(
),
lFromInstId = 0,
vRemarkOfSender = net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY,
strFromMobile = "",
strFromName = "",
vNickName = mutableListOf(),
)
),
svrip = -1467,
vSyncCookie = net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY,
vUinPairMsg = mutableListOf(),
mPreviews = mutableMapOf(
),
)
}
setBot(1230001)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230002, "user2", MemberPermission.OWNER)
}
runTest().run {
assertEquals(1, size)
val event = single()
assertIs<BotMuteEvent>(event)
assertEquals(600, event.durationSeconds)
assertEquals(1230002, event.operator.id)
}
}
@Test
suspend fun `bot unmute`() {
suspend fun MuteTest.runTest() = use {
OnlinePushPack.SvcReqPushMsg(
uin = 1230001,
uMsgTime = 1629869459,
vMsgInfos = mutableListOf(
MsgInfo(
lFromUin = 2230203,
shMsgType = 732,
shMsgSeq = -26716,
strMsg = "",
uRealMsgTime = 1629,
vMsg = "00 22 07 BB 0C 01 00 12 C4 B2 61 25 D5 93 00 01 00 12 C4 B1 00 00 00 00".hexToBytes(),
uAppShareID = 0,
vMsgCookies = "08 DC 05 10 DC 85 E0 80 80 80 80 80 02 18 03 20 DE 86 03".hexToBytes(),
lMsgUid = 1441151,
lLastChangeTime = 1,
vCPicInfo = mutableListOf(),
stShareData = ShareData(
),
lFromInstId = 0,
vRemarkOfSender = net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY,
strFromMobile = "",
strFromName = "",
vNickName = mutableListOf(),
)
),
svrip = 1554,
vSyncCookie = net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY,
vUinPairMsg = mutableListOf(),
mPreviews = mutableMapOf(
),
)
}
setBot(1230001)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230002, "user2", MemberPermission.OWNER)
addMember(1230003, "user3", MemberPermission.MEMBER)
botAsMember.apply {
_muteTimestamp = currentTimeSeconds().toInt() + 600
}
}
runTest().run {
assertEquals(1, size)
val event = single()
assertIs<BotUnmuteEvent>(event)
assertEquals(1230002, event.operator.id)
}
setBot(1230001)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230002, "user2", MemberPermission.OWNER)
addMember(1230003, "user3", MemberPermission.MEMBER)
botAsMember.apply {
_muteTimestamp = 0
}
}
runTest().run {
assertEquals(0, size)
}
}
@Test
suspend fun `member mute`() {
suspend fun MuteTest.runTest() = use {
OnlinePushPack.SvcReqPushMsg(
uin = 1230001,
uMsgTime = 1629870209,
vMsgInfos = mutableListOf(
MsgInfo(
lFromUin = 2230203,
shMsgType = 732,
shMsgSeq = 8159,
strMsg = "",
uRealMsgTime = 16298,
vMsg = "00 22 07 BB 0C 01 00 12 C4 B2 61 25 D8 81 00 01 00 12 C4 B3 00 00 02 58".hexToBytes(),
uAppShareID = 0,
vMsgCookies = "08 DC 05 10 DC 85 E0 80 80 80 80 80 02 18 03 20 DE 86 03".hexToBytes(),
lMsgUid = 1441151,
lLastChangeTime = 1,
vCPicInfo = mutableListOf(),
stShareData = ShareData(
),
lFromInstId = 0,
vRemarkOfSender = net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY,
strFromMobile = "",
strFromName = "",
vNickName = mutableListOf(),
)
),
svrip = -176,
vSyncCookie = net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY,
vUinPairMsg = mutableListOf(),
mPreviews = mutableMapOf(
),
)
}
setBot(1230001)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230002, "user2", MemberPermission.OWNER)
addMember(1230003, "user3", MemberPermission.MEMBER)
}
runTest().run {
assertEquals(1, size)
val event = single()
assertIs<MemberMuteEvent>(event)
assertEquals(600, event.durationSeconds)
assertEquals(1230002, event.operator?.id)
}
}
@Test
suspend fun `member unmute`() {
suspend fun MuteTest.runTest() = use {
OnlinePushPack.SvcReqPushMsg(
uin = 1230001,
uMsgTime = 16298,
vMsgInfos = mutableListOf(
MsgInfo(
lFromUin = 2230203,
shMsgType = 732,
shMsgSeq = 16929,
strMsg = "",
uRealMsgTime = 16298,
vMsg = "00 22 07 BB 0C 01 00 12 C4 B2 61 25 D7 02 00 01 00 12 C4 B3 00 00 00 00".hexToBytes(),
uAppShareID = 0,
vMsgCookies = "08 DC 05 10 DC 85 E0 80 80 80 80 80 02 18 03 20 DE 86 03".hexToBytes(),
lMsgUid = 1441151,
lLastChangeTime = 1,
vCPicInfo = mutableListOf(),
stShareData = ShareData(
),
lFromInstId = 0,
vRemarkOfSender = net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY,
strFromMobile = "",
strFromName = "",
vNickName = mutableListOf(),
)
),
svrip = 20406,
vSyncCookie = net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY,
vUinPairMsg = mutableListOf(),
mPreviews = mutableMapOf(
),
)
}
setBot(1230001)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230002, "user2", MemberPermission.OWNER)
addMember(1230003, "user3", MemberPermission.MEMBER).apply {
_muteTimestamp = currentTimeSeconds().toInt() + 600
}
}
runTest().run {
assertEquals(1, size)
val event = single()
assertIs<MemberUnmuteEvent>(event)
assertEquals(1230002, event.operator?.id)
}
setBot(1230001)
.addGroup(2230203, 1230002, name = "testtest").apply {
addMember(1230002, "user2", MemberPermission.OWNER)
addMember(1230003, "user3", MemberPermission.MEMBER).apply {
_muteTimestamp = 0
}
}
runTest().run {
assertEquals(0, size)
}
}
}