mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-03 05:09:22 +08:00
Merge remote-tracking branch 'origin'
This commit is contained in:
commit
52b848eb66
15
CHANGELOG.md
15
CHANGELOG.md
@ -2,6 +2,21 @@
|
||||
|
||||
开发版本. 频繁更新, 不保证高稳定性
|
||||
|
||||
## `0.18.0` 2020/2/20
|
||||
|
||||
### mirai-core
|
||||
- 添加 `MessageSource.time`
|
||||
- 添加事件监听时额外的 `coroutineContext`
|
||||
- 为一些带有 `operator` 的事件添加 `.isByBot` 的属性扩展
|
||||
- 优化事件广播逻辑, 修复可能无法触发监听的问题
|
||||
- 为所有 `Contact` 添加 `toString()` (#80)
|
||||
|
||||
### mirai-core-qqandroid
|
||||
- 支持成员禁言状态和时间查询 `Member.muteTimeRemaining`
|
||||
- 修复 `At` 的 `display` (#73), 同时修复 `QuoteReply` 无法显示问题 (#54).
|
||||
- 广播 `BotReloginEvent` (#78)
|
||||
- 支持机器人自身禁言时间的更新和查询 (#82)
|
||||
|
||||
## `0.17.0` 2020/2/20
|
||||
|
||||
### mirai-core
|
||||
|
@ -1,7 +1,7 @@
|
||||
# style guide
|
||||
kotlin.code.style=official
|
||||
# config
|
||||
mirai_version=0.17.0
|
||||
mirai_version=0.18.0
|
||||
mirai_japt_version=1.0.1
|
||||
kotlin.incremental.multiplatform=true
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
|
@ -482,7 +482,9 @@ object MiraiConsoleTerminalUI : MiraiConsoleUI {
|
||||
val width = terminal.terminalSize.columns - 6
|
||||
var x = string
|
||||
while (true) {
|
||||
if (x == "") break
|
||||
if (x == "") {
|
||||
break
|
||||
}
|
||||
val toWrite = if (x.actualLength() > width) {
|
||||
val index = x.getSubStringIndexByActualLength(width)
|
||||
x.substring(0, index).also {
|
||||
|
@ -305,6 +305,7 @@ object MiraiConsole {
|
||||
if (!CommandManager.runCommand(fullCommand)) {
|
||||
logger("未知指令 $fullCommand")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,16 +162,11 @@ internal class QQImpl(
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
return other is QQ && other.id == this.id
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = super.hashCode()
|
||||
override fun toString(): String = "QQ($id)"
|
||||
}
|
||||
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
@Suppress("MemberVisibilityCanBePrivate", "DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
|
||||
internal class MemberImpl(
|
||||
qq: QQImpl,
|
||||
group: GroupImpl,
|
||||
@ -182,9 +177,21 @@ internal class MemberImpl(
|
||||
val qq: QQImpl by qq.unsafeWeakRef()
|
||||
|
||||
override var permission: MemberPermission = memberInfo.permission
|
||||
@Suppress("PropertyName")
|
||||
internal var _nameCard: String = memberInfo.nameCard
|
||||
@Suppress("PropertyName")
|
||||
internal var _specialTitle: String = memberInfo.specialTitle
|
||||
|
||||
@Suppress("PropertyName")
|
||||
var _muteTimestamp: Int = memberInfo.muteTimestamp
|
||||
|
||||
override val muteTimeRemaining: Int =
|
||||
if (_muteTimestamp == 0 || _muteTimestamp == 0xFFFFFFFF.toInt()) {
|
||||
0
|
||||
} else {
|
||||
_muteTimestamp - currentTimeSeconds.toInt() - bot.client.timeDifference.toInt()
|
||||
}
|
||||
|
||||
override var nameCard: String
|
||||
get() = _nameCard
|
||||
set(newValue) {
|
||||
@ -220,7 +227,7 @@ internal class MemberImpl(
|
||||
newValue
|
||||
).sendWithoutExpect()
|
||||
}
|
||||
MemberSpecialTitleChangeEvent(oldValue, newValue, this@MemberImpl).broadcast()
|
||||
MemberSpecialTitleChangeEvent(oldValue, newValue, this@MemberImpl, null).broadcast()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -279,12 +286,9 @@ internal class MemberImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
return other is Member && other.id == this.id
|
||||
override fun toString(): String {
|
||||
return "Member($id)"
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = super.hashCode()
|
||||
}
|
||||
|
||||
internal class MemberInfoImpl(
|
||||
@ -301,6 +305,7 @@ internal class MemberInfoImpl(
|
||||
else -> MemberPermission.MEMBER
|
||||
}
|
||||
override val specialTitle: String get() = jceInfo.sSpecialTitle ?: ""
|
||||
override val muteTimestamp: Int get() = jceInfo.dwShutupTimestap?.toInt() ?: 0
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,13 +328,13 @@ internal class GroupImpl(
|
||||
@UseExperimental(MiraiExperimentalAPI::class)
|
||||
override lateinit var botPermission: MemberPermission
|
||||
|
||||
var _botMuteRemaining: Int = groupInfo.botMuteRemaining
|
||||
var _botMuteTimestamp: Int = groupInfo.botMuteRemaining
|
||||
|
||||
override val botMuteRemaining: Int =
|
||||
if (_botMuteRemaining == 0 || _botMuteRemaining == 0xFFFFFFFF.toInt()) {
|
||||
if (_botMuteTimestamp == 0 || _botMuteTimestamp == 0xFFFFFFFF.toInt()) {
|
||||
0
|
||||
} else {
|
||||
_botMuteRemaining - currentTimeSeconds.toInt() - bot.client.timeDifference.toInt()
|
||||
_botMuteTimestamp - currentTimeSeconds.toInt() - bot.client.timeDifference.toInt()
|
||||
}
|
||||
|
||||
override val members: ContactList<Member> = ContactList(members.mapNotNull {
|
||||
@ -600,10 +605,7 @@ internal class GroupImpl(
|
||||
image.input.close()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
return other is Group && other.id == this.id
|
||||
override fun toString(): String {
|
||||
return "Group($id)"
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = super.hashCode()
|
||||
}
|
@ -194,6 +194,7 @@ internal class MessageSvc {
|
||||
override val nameCard: String get() = ""
|
||||
override val permission: MemberPermission get() = MemberPermission.MEMBER
|
||||
override val specialTitle: String get() = ""
|
||||
override val muteTimestamp: Int get() = 0
|
||||
override val uin: Long get() = msg.msgHead.authUin
|
||||
override val nick: String get() = msg.msgHead.authNick.takeIf { it.isNotEmpty() } ?: msg.msgHead.fromNick
|
||||
}).also { group.members.delegate.addLast(it) })
|
||||
|
@ -142,9 +142,10 @@ internal class OnlinePush {
|
||||
@UseExperimental(ExperimentalStdlibApi::class)
|
||||
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot, sequenceId: Int): Packet {
|
||||
val reqPushMsg = decodeUniPacket(OnlinePushPack.SvcReqPushMsg.serializer(), "req")
|
||||
val packets = reqPushMsg.vMsgInfos.mapNotNull { msgInfo: MsgInfo ->
|
||||
msgInfo.vMsg!!.read {
|
||||
|
||||
@Suppress("USELESS_CAST") // 不要信任 kotlin 类型推断
|
||||
val packets: List<Packet> = reqPushMsg.vMsgInfos.mapNotNull { msgInfo: MsgInfo ->
|
||||
msgInfo.vMsg!!.read {
|
||||
when {
|
||||
msgInfo.shMsgType.toInt() == 732 -> {
|
||||
val group = bot.getGroup(this.readUInt().toLong())
|
||||
@ -162,41 +163,54 @@ internal class OnlinePush {
|
||||
val target = this.readUInt().toLong()
|
||||
val time = this.readInt()
|
||||
|
||||
return@mapNotNull if (target == 0L) {
|
||||
if (target == 0L) {
|
||||
if (time == 0) {
|
||||
GroupMuteAllEvent(
|
||||
return@mapNotNull GroupMuteAllEvent(
|
||||
origin = group.isMuteAll.also { group._muteAll = false },
|
||||
new = false,
|
||||
operator = operator,
|
||||
group = group
|
||||
)
|
||||
) as Packet
|
||||
} else {
|
||||
GroupMuteAllEvent(
|
||||
return@mapNotNull GroupMuteAllEvent(
|
||||
origin = group.isMuteAll.also { group._muteAll = true },
|
||||
new = true,
|
||||
operator = operator,
|
||||
group = group
|
||||
)
|
||||
) as Packet
|
||||
}
|
||||
} else {
|
||||
if (target == bot.uin) {
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY") // false positive
|
||||
return@mapNotNull if (time == 0) {
|
||||
BotUnmuteEvent(operator)
|
||||
} else
|
||||
BotMuteEvent(durationSeconds = time, operator = operator)
|
||||
if (group._botMuteTimestamp != time) {
|
||||
if (time == 0) {
|
||||
group._botMuteTimestamp = 0
|
||||
return@mapNotNull BotUnmuteEvent(operator) as Packet
|
||||
} else {
|
||||
group._botMuteTimestamp = time
|
||||
return@mapNotNull BotMuteEvent(durationSeconds = time, operator = operator) as Packet
|
||||
}
|
||||
} else {
|
||||
return@mapNotNull null
|
||||
}
|
||||
} else {
|
||||
val member = group[target]
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY") // false positive
|
||||
return@mapNotNull if (time == 0) {
|
||||
MemberUnmuteEvent(operator = operator, member = member)
|
||||
member as MemberImpl
|
||||
if (member._muteTimestamp != time) {
|
||||
if (time == 0) {
|
||||
member._muteTimestamp = 0
|
||||
return@mapNotNull MemberUnmuteEvent(member, operator) as Packet
|
||||
} else {
|
||||
member._muteTimestamp = time
|
||||
return@mapNotNull MemberMuteEvent(member, time, operator) as Packet
|
||||
}
|
||||
} else {
|
||||
MemberMuteEvent(operator = operator, member = member, durationSeconds = time)
|
||||
return@mapNotNull null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3585 -> { // 匿名
|
||||
3585 -> {
|
||||
// 匿名
|
||||
val operator = group[this.readUInt().toLong()]
|
||||
val switch = this.readInt() == 0
|
||||
return@mapNotNull GroupAllowAnonymousChatEvent(
|
||||
@ -239,7 +253,7 @@ internal class OnlinePush {
|
||||
}
|
||||
else -> {
|
||||
bot.network.logger.debug { "Unknown server messages $message" }
|
||||
return@mapNotNull NoPacket
|
||||
return@mapNotNull null
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -250,6 +264,7 @@ internal class OnlinePush {
|
||||
// }
|
||||
else -> {
|
||||
bot.network.logger.debug { "unknown group internal type $internalType , data: " + this.readBytes().toUHexString() + " " }
|
||||
return@mapNotNull null
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -257,19 +272,18 @@ internal class OnlinePush {
|
||||
bot.network.logger.debug { "unknown shtype ${msgInfo.shMsgType.toInt()}" }
|
||||
// val content = msgInfo.vMsg.loadAs(OnlinePushPack.MsgType0x210.serializer())
|
||||
// println(content.contentToString())
|
||||
return@mapNotNull null
|
||||
}
|
||||
else -> {
|
||||
bot.network.logger.debug { "unknown shtype ${msgInfo.shMsgType.toInt()}" }
|
||||
return@mapNotNull null
|
||||
}
|
||||
}
|
||||
}
|
||||
return@mapNotNull null
|
||||
}
|
||||
|
||||
return MultiPacket(packets)
|
||||
}
|
||||
|
||||
|
||||
override suspend fun QQAndroidBot.handle(packet: Packet, sequenceId: Int): OutgoingPacket? {
|
||||
return buildResponseUniPacket(client, sequenceId = sequenceId) {
|
||||
|
||||
|
@ -74,6 +74,16 @@ interface Contact : CoroutineScope {
|
||||
* 而 [QQ] 含义为一个独立的人, 可以是好友, 也可以是陌生人.
|
||||
*/
|
||||
override fun equals(other: Any?): Boolean
|
||||
|
||||
/**
|
||||
* @return `bot.hashCode() * 31 + id.hashCode()`
|
||||
*/
|
||||
override fun hashCode(): Int
|
||||
|
||||
/**
|
||||
* @return "QQ($id)" or "Group($id)" or "Member($id)"
|
||||
*/
|
||||
override fun toString(): String
|
||||
}
|
||||
|
||||
suspend inline fun Contact.sendMessage(message: Message) = sendMessage(message.toChain())
|
||||
|
@ -12,6 +12,7 @@
|
||||
package net.mamoe.mirai.contact
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.data.MemberInfo
|
||||
import net.mamoe.mirai.event.events.*
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
@ -89,19 +90,19 @@ interface Group : Contact, CoroutineScope {
|
||||
/**
|
||||
* 机器人被禁言还剩余多少秒
|
||||
*
|
||||
* @see BotMuteEvent
|
||||
* @see isBotMuted
|
||||
* @see BotMuteEvent 机器人被禁言事件
|
||||
* @see isBotMuted 判断机器人是否正在被禁言
|
||||
*/
|
||||
val botMuteRemaining: Int
|
||||
|
||||
/**
|
||||
* 机器人在这个群里的权限
|
||||
*
|
||||
* **MiraiExperimentalAPI**: 在未来可能会被修改
|
||||
* @see Group.checkBotPermission 检查 [Bot] 在这个群里的权限
|
||||
* @see Group.checkBotPermissionOperator 要求 [Bot] 在这个群里的权限为 [管理员或群主][MemberPermission.isOperator]
|
||||
*
|
||||
* @see BotGroupPermissionChangeEvent
|
||||
* @see BotGroupPermissionChangeEvent 机器人群员修改
|
||||
*/
|
||||
@MiraiExperimentalAPI
|
||||
val botPermission: MemberPermission
|
||||
|
||||
|
||||
@ -129,6 +130,7 @@ interface Group : Contact, CoroutineScope {
|
||||
/**
|
||||
* 让机器人退出这个群. 机器人必须为非群主才能退出. 否则将会失败
|
||||
*/
|
||||
@MiraiExperimentalAPI("还未支持")
|
||||
suspend fun quit(): Boolean
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright 2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* 此源代码的使用受 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/master/LICENSE
|
||||
@ -29,33 +29,50 @@ interface Member : QQ, Contact {
|
||||
|
||||
/**
|
||||
* 成员的权限, 动态更新.
|
||||
*
|
||||
* @see MemberPermissionChangeEvent 权限变更事件. 由群主或机器人的操作触发.
|
||||
*/
|
||||
val permission: MemberPermission
|
||||
|
||||
/**
|
||||
* 群名片. 可能为空. 修改时将会触发事件
|
||||
* 群名片. 可能为空.
|
||||
*
|
||||
* 管理员和群主都可修改任何人(包括群主)的群名片.
|
||||
*
|
||||
* 在修改时将会异步上传至服务器.
|
||||
*
|
||||
* @see [nameCardOrNick] 获取非空群名片或昵称
|
||||
*
|
||||
* @see MemberCardChangeEvent 群名片被管理员, 自己或 [Bot] 改动事件
|
||||
* @see MemberCardChangeEvent 群名片被管理员, 自己或 [Bot] 改动事件. 修改时也会触发此事件.
|
||||
* @throws PermissionDeniedException 无权限修改时
|
||||
*/
|
||||
var nameCard: String
|
||||
|
||||
/**
|
||||
* 群头衔
|
||||
* 群头衔.
|
||||
*
|
||||
* 仅群主可以修改群头衔.
|
||||
*
|
||||
* 在修改时将会异步上传至服务器.
|
||||
*
|
||||
* @see MemberSpecialTitleChangeEvent 群名片被管理员, 自己或 [Bot] 改动事件
|
||||
* @see MemberSpecialTitleChangeEvent 群名片被管理员, 自己或 [Bot] 改动事件. 修改时也会触发此事件.
|
||||
* @throws PermissionDeniedException 无权限修改时
|
||||
*/
|
||||
var specialTitle: String
|
||||
|
||||
/**
|
||||
* 禁言
|
||||
* 被禁言剩余时长. 单位为秒.
|
||||
*
|
||||
* @see isMuted 判断改成员是否处于禁言状态
|
||||
* @see mute 设置禁言
|
||||
* @see unmute 取消禁言
|
||||
*/
|
||||
val muteTimeRemaining: Int
|
||||
|
||||
/**
|
||||
* 禁言.
|
||||
*
|
||||
* 管理员可禁言成员, 群主可禁言管理员和群员.
|
||||
*
|
||||
* @param durationSeconds 持续时间. 精确到秒. 范围区间表示为 `(0s, 30days]`. 超过范围则会抛出异常.
|
||||
* @return 机器人无权限时返回 `false`
|
||||
@ -72,6 +89,8 @@ interface Member : QQ, Contact {
|
||||
/**
|
||||
* 解除禁言.
|
||||
*
|
||||
* 管理员可解除成员的禁言, 群主可解除管理员和群员的禁言.
|
||||
*
|
||||
* @see MemberUnmuteEvent 成员被取消禁言事件.
|
||||
* @throws PermissionDeniedException 无权限修改时
|
||||
*/
|
||||
@ -80,6 +99,8 @@ interface Member : QQ, Contact {
|
||||
/**
|
||||
* 踢出该成员.
|
||||
*
|
||||
* 管理员可踢出成员, 群主可踢出管理员和群员.
|
||||
*
|
||||
* @see MemberLeaveEvent.Kick 成员被踢出事件.
|
||||
* @throws PermissionDeniedException 无权限修改时
|
||||
*/
|
||||
@ -98,6 +119,13 @@ interface Member : QQ, Contact {
|
||||
*/
|
||||
val Member.nameCardOrNick: String get() = this.nameCard.takeIf { it.isNotEmpty() } ?: this.nick
|
||||
|
||||
/**
|
||||
* 判断改成员是否处于禁言状态.
|
||||
*/
|
||||
fun Member.isMuted(): Boolean {
|
||||
return muteTimeRemaining != 0 && muteTimeRemaining != 0xFFFFFFFF.toInt()
|
||||
}
|
||||
|
||||
@ExperimentalTime
|
||||
suspend inline fun Member.mute(duration: Duration) {
|
||||
require(duration.inDays <= 30) { "duration must be at most 1 month" }
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
package net.mamoe.mirai.contact
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
|
||||
|
||||
@ -68,7 +69,6 @@ inline fun Member.isAdministrator(): Boolean = this.permission.isAdministrator()
|
||||
inline fun Member.isOperator(): Boolean = this.permission.isOperator()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 权限不足
|
||||
*/
|
||||
@ -77,6 +77,11 @@ expect class PermissionDeniedException : IllegalStateException {
|
||||
constructor(message: String?)
|
||||
}
|
||||
|
||||
/**
|
||||
* 要求 [Bot] 在这个群里的权限为 [required], 否则抛出异常 [PermissionDeniedException]
|
||||
*
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
@UseExperimental(MiraiExperimentalAPI::class)
|
||||
inline fun Group.checkBotPermission(
|
||||
required: MemberPermission,
|
||||
@ -89,6 +94,11 @@ inline fun Group.checkBotPermission(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 要求 [Bot] 在这个群里的权限为 [管理员或群主][MemberPermission.isOperator], 否则抛出异常 [PermissionDeniedException]
|
||||
*
|
||||
* @throws PermissionDeniedException
|
||||
*/
|
||||
@UseExperimental(MiraiExperimentalAPI::class)
|
||||
inline fun Group.checkBotPermissionOperator(
|
||||
lazyMessage: () -> String = {
|
||||
|
@ -17,4 +17,6 @@ interface MemberInfo : FriendInfo {
|
||||
val permission: MemberPermission
|
||||
|
||||
val specialTitle: String
|
||||
|
||||
val muteTimestamp: Int
|
||||
}
|
@ -7,6 +7,8 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package net.mamoe.mirai.event.events
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
@ -194,7 +196,7 @@ data class GroupNameChangeEvent(
|
||||
override val origin: String,
|
||||
override val new: String,
|
||||
override val group: Group,
|
||||
val isByBot: Boolean
|
||||
val isByBot: Boolean // 无法获取 operator
|
||||
) : GroupSettingChangeEvent<String>, Packet
|
||||
|
||||
/**
|
||||
@ -210,6 +212,8 @@ data class GroupEntranceAnnouncementChangeEvent(
|
||||
val operator: Member?
|
||||
) : GroupSettingChangeEvent<String>, Packet
|
||||
|
||||
val GroupEntranceAnnouncementChangeEvent.isByBot: Boolean get() = operator != null
|
||||
|
||||
|
||||
/**
|
||||
* 群 "全员禁言" 功能状态改变. 此事件广播前修改就已经完成.
|
||||
@ -224,6 +228,8 @@ data class GroupMuteAllEvent(
|
||||
val operator: Member?
|
||||
) : GroupSettingChangeEvent<Boolean>, Packet
|
||||
|
||||
val GroupMuteAllEvent.isByBot: Boolean get() = operator != null
|
||||
|
||||
/**
|
||||
* 群 "匿名聊天" 功能状态改变. 此事件广播前修改就已经完成.
|
||||
*/
|
||||
@ -237,6 +243,8 @@ data class GroupAllowAnonymousChatEvent(
|
||||
val operator: Member?
|
||||
) : GroupSettingChangeEvent<Boolean>, Packet
|
||||
|
||||
val GroupAllowAnonymousChatEvent.isByBot: Boolean get() = operator != null
|
||||
|
||||
/**
|
||||
* 群 "坦白说" 功能状态改变. 此事件广播前修改就已经完成.
|
||||
*/
|
||||
@ -260,6 +268,8 @@ data class GroupAllowMemberInviteEvent(
|
||||
val operator: Member?
|
||||
) : GroupSettingChangeEvent<Boolean>, Packet
|
||||
|
||||
val GroupAllowMemberInviteEvent.isByBot: Boolean get() = operator != null
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
@ -293,6 +303,8 @@ sealed class MemberLeaveEvent : GroupMemberEvent {
|
||||
data class Quit(override val member: Member) : MemberLeaveEvent()
|
||||
}
|
||||
|
||||
val MemberLeaveEvent.Kick.isByBot: Boolean get() = operator != null
|
||||
|
||||
// endregion
|
||||
|
||||
// region 名片和头衔
|
||||
@ -319,6 +331,8 @@ data class MemberCardChangeEvent(
|
||||
val operator: Member?
|
||||
) : GroupMemberEvent
|
||||
|
||||
val MemberCardChangeEvent.isByBot: Boolean get() = operator != null
|
||||
|
||||
/**
|
||||
* 群头衔改动. 一定为群主操作
|
||||
*/
|
||||
@ -333,9 +347,18 @@ data class MemberSpecialTitleChangeEvent(
|
||||
*/
|
||||
val new: String,
|
||||
|
||||
override val member: Member
|
||||
override val member: Member,
|
||||
|
||||
/**
|
||||
* 操作人.
|
||||
* 不为 null 时一定为群主. 可能与 [member] 引用相同, 此时为群员自己修改.
|
||||
* 为 null 时则是机器人操作.
|
||||
*/
|
||||
val operator: Member?
|
||||
) : GroupMemberEvent
|
||||
|
||||
val MemberSpecialTitleChangeEvent.isByBot: Boolean get() = operator != null
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
@ -367,6 +390,8 @@ data class MemberMuteEvent(
|
||||
val operator: Member?
|
||||
) : GroupMemberEvent, Packet
|
||||
|
||||
val MemberMuteEvent.isByBot: Boolean get() = operator != null
|
||||
|
||||
/**
|
||||
* 群成员被取消禁言事件. 被禁言的成员都不可能是机器人本人
|
||||
*/
|
||||
@ -378,6 +403,8 @@ data class MemberUnmuteEvent(
|
||||
val operator: Member?
|
||||
) : GroupMemberEvent, Packet
|
||||
|
||||
val MemberUnmuteEvent.isByBot: Boolean get() = operator != null
|
||||
|
||||
// endregion
|
||||
|
||||
// endregion
|
||||
|
Loading…
Reference in New Issue
Block a user