Clarify specialTitle docs and support to detect specialTitle changes (#1531)

This commit is contained in:
sandtechnology 2021-09-27 22:39:11 +08:00 committed by GitHub
parent c09f8ab192
commit 00ecf86094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 59 additions and 19 deletions

View File

@ -2813,7 +2813,7 @@ public final class net/mamoe/mirai/event/events/MemberPermissionChangeEvent : ne
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberSpecialTitleChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent {
public final class net/mamoe/mirai/event/events/MemberSpecialTitleChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent, net/mamoe/mirai/internal/network/Packet {
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Lnet/mamoe/mirai/contact/NormalMember;

View File

@ -2813,7 +2813,7 @@ public final class net/mamoe/mirai/event/events/MemberPermissionChangeEvent : ne
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberSpecialTitleChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent {
public final class net/mamoe/mirai/event/events/MemberSpecialTitleChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent, net/mamoe/mirai/internal/network/Packet {
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Lnet/mamoe/mirai/contact/NormalMember;

View File

@ -85,7 +85,7 @@
##### 名片和头衔
- 成员群名片改动: MemberCardChangeEvent
- 成员群头衔改动: MemberSpecialTitleChangeEvent
- 成员群特殊头衔改动: MemberSpecialTitleChangeEvent
##### 成员权限
- 成员权限改变: MemberPermissionChangeEvent

View File

@ -57,7 +57,7 @@ public interface Member : User {
public val nameCard: String
/**
* 头衔.
* 特殊头衔.
*
* [AnonymousMember] 时一定是 `"匿名"`
*

View File

@ -49,13 +49,13 @@ public interface NormalMember : Member {
public override var nameCard: String
/**
* 头衔.
* 特殊头衔.
*
* 仅群主可以修改群头衔.
* 仅群主可以修改群特殊头衔.
*
* 在修改时将会异步上传至服务器.
*
* @see MemberSpecialTitleChangeEvent 名片被管理员, 自己或 [Bot] 改动事件. 修改时也会触发此事件.
* @see MemberSpecialTitleChangeEvent 特殊头衔被管理员, 自己或 [Bot] 改动事件. 修改时也会触发此事件.
* @throws PermissionDeniedException 无权限修改时
*/
public override var specialTitle: String

View File

@ -73,7 +73,7 @@ public interface GroupInfo {
/*
/**
* 机器人的头衔
* 机器人的特殊头衔
*/
val botSpecialTitle: String

View File

@ -492,7 +492,9 @@ public data class MemberCardChangeEvent @MiraiInternalApi constructor(
) : GroupMemberEvent, Packet, AbstractEvent(), GroupMemberInfoChangeEvent
/**
* 成员群头衔改动. 一定为群主操作
* 成员群特殊头衔改动. 一定为群主操作
*
* 由于服务器并不会告知特殊头衔的重置, 因此此事件在特殊头衔重置后只能由 mirai 在发现变动时才广播
*/
public data class MemberSpecialTitleChangeEvent @MiraiInternalApi constructor(
/**
@ -513,7 +515,7 @@ public data class MemberSpecialTitleChangeEvent @MiraiInternalApi constructor(
* null 时则是机器人操作.
*/
public override val operator: NormalMember?
) : GroupMemberEvent, GroupOperableEvent, AbstractEvent(), GroupMemberInfoChangeEvent
) : GroupMemberEvent, GroupOperableEvent, AbstractEvent(), Packet, GroupMemberInfoChangeEvent
// endregion

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.events.GroupMessageSyncEvent
import net.mamoe.mirai.event.events.MemberCardChangeEvent
import net.mamoe.mirai.event.events.MemberSpecialTitleChangeEvent
import net.mamoe.mirai.internal.contact.GroupImpl
import net.mamoe.mirai.internal.contact.NormalMemberImpl
import net.mamoe.mirai.internal.contact.info
@ -124,6 +125,14 @@ internal class GroupMessageProcessor(
sender.info?.castOrNull<MemberInfoImpl>()?.run {
lastSpeakTimestamp = currentTimeSeconds().toInt()
}
sender.castOrNull<NormalMemberImpl>()?.run {
val specialTitleNow = extraInfo?.senderTitle?.decodeToString().orEmpty()
if (specialTitle != specialTitleNow) {
//群特殊头衔 只有群主才能进行操作
collect(MemberSpecialTitleChangeEvent(specialTitle, specialTitleNow, this, group.owner))
_specialTitle = specialTitleNow
}
}
if (isFromSelfAccount) {
collect(
@ -137,7 +146,6 @@ internal class GroupMessageProcessor(
)
return
} else {
broadcastNameCardChangedEventIfNecessary(sender, nameCard)
collect(

View File

@ -12,6 +12,7 @@ package net.mamoe.mirai.internal.network.notice.group
import kotlinx.io.core.readUInt
import kotlinx.io.core.readUShort
import net.mamoe.mirai.contact.NormalMember
import net.mamoe.mirai.contact.getMember
import net.mamoe.mirai.data.GroupHonorType
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.internal.QQAndroidBot
@ -29,6 +30,7 @@ import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x27
import net.mamoe.mirai.internal.network.protocol.data.proto.TroopTips0x857
import net.mamoe.mirai.internal.utils._miraiContentToString
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.internal.utils.parseToMessageDataList
import net.mamoe.mirai.utils.*
internal class GroupNotificationProcessor(
@ -158,8 +160,8 @@ internal class GroupNotificationProcessor(
when (data.kind) {
0x0C -> processMute(data)
0x0E -> processAllowAnonymousChat(data)
0x10 -> processAllowConfessTask(data)
0x14 -> processGrayTip(data)
0x10 -> processNormalGrayTip(data)
0x14 -> processGeneralGrayTip(data)
}
}
@ -249,8 +251,10 @@ internal class GroupNotificationProcessor(
/**
* @see GroupAllowConfessTalkEvent
* @see MemberSpecialTitleChangeEvent
*/
private fun NoticePipelineContext.processAllowConfessTask(
//gray tip: 聊天中的灰色小框系统提示信息无通用模板为混合xml代码的文本
private fun NoticePipelineContext.processNormalGrayTip(
data: MsgType0x2DC,
) = data.context {
val proto = data.buf.loadAs(TroopTips0x857.NotifyMsgBody.serializer(), offset = 1)
@ -260,10 +264,10 @@ internal class GroupNotificationProcessor(
val tipsInfo = proto.optMsgGraytips ?: return
val message = tipsInfo.optBytesContent.decodeToString()
// 机器人信息
when (tipsInfo.robotGroupOpt) {
// others
// 非机器人信息
0 -> {
//坦白说开关
if (message.endsWith("群聊坦白说")) {
val new = when (message) {
"管理员已关闭群聊坦白说" -> false
@ -274,6 +278,29 @@ internal class GroupNotificationProcessor(
}
}
collect(GroupAllowConfessTalkEvent(new, !new, group, false))
//群特殊头衔授予
} else if (message.endsWith(">头衔")) {
message.parseToMessageDataList().let { seq ->
if (seq.count() == 2) {
val uin = seq.first().data.toLong()
val newTitle = seq.last().text
val member = group.getMember(uin) ?: return@let
member.checkIsMemberImpl()
collect(
MemberSpecialTitleChangeEvent(
member.specialTitle,
newTitle,
member,
group.owner
)
)
member._specialTitle = newTitle
} else {
logger.debug { "Unknown server special title messages $message" }
return
}
}
}
}
}
@ -286,8 +313,9 @@ internal class GroupNotificationProcessor(
* @see NudgeEvent
* @see MemberHonorChangeEvent
* @see GroupTalkativeChangeEvent
*/ // gray tip: 聊天中的灰色小框系统提示信息
private fun NoticePipelineContext.processGrayTip(
*/
// general gray tip: 聊天中的灰色小框系统提示信息(有通用模板)
private fun NoticePipelineContext.processGeneralGrayTip(
data: MsgType0x2DC,
) = data.context {
val grayTip = buf.loadAs(TroopTips0x857.NotifyMsgBody.serializer(), 1).optGeneralGrayTip
@ -323,6 +351,7 @@ internal class GroupNotificationProcessor(
collect(MemberHonorChangeEvent.Achieve(now, GroupHonorType.TALKATIVE))
}
}
//
else -> {
markNotConsumed()
logger.debug {

View File

@ -36,11 +36,12 @@ internal fun MessageData.toMemberInfo() = MemberInfoImpl(
@Suppress("RegExpRedundantEscape")
internal val extraJsonPattern = Regex("<(\\{.*?\\})>")
internal val jsonInstance = Json { ignoreUnknownKeys = true }
@MiraiInternalApi
internal fun String.parseToMessageDataList(): Sequence<MessageData> {
return extraJsonPattern.findAll(this).filter { it.groups.size == 2 }.mapNotNull { result ->
Json.decodeFromString(MessageData.serializer(), result.groups[1]!!.value)
jsonInstance.decodeFromString(MessageData.serializer(), result.groups[1]!!.value)
}
}