New event design

This commit is contained in:
Him188 2020-02-11 20:40:35 +08:00
parent 63b5785b2d
commit 049cf30659
9 changed files with 346 additions and 253 deletions

View File

@ -4,7 +4,8 @@ import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.routing.routing
import kotlinx.serialization.Serializable
import net.mamoe.mirai.api.http.data.*
import net.mamoe.mirai.api.http.data.PermissionDeniedException
import net.mamoe.mirai.api.http.data.StateCode
import net.mamoe.mirai.api.http.data.common.DTO
import net.mamoe.mirai.api.http.data.common.VerifyDTO
import net.mamoe.mirai.contact.Group
@ -84,7 +85,7 @@ fun Application.groupManageModule() {
miraiVerify<MemberInfoDTO>("/memberInfo") { dto ->
val member = dto.session.bot.getGroup(dto.target)[dto.memberId]
with(dto.info) {
name?.let { member.groupCard = it }
name?.let { member.nameCard = it }
specialTitle?.let { member.specialTitle = it }
}
call.respondStateCode(StateCode.Success)
@ -145,5 +146,5 @@ private data class MemberDetailDTO(
val name: String? = null,
val specialTitle: String? = null
) : DTO {
constructor(member: Member) : this(member.groupCard, member.specialTitle)
constructor(member: Member) : this(member.nameCard, member.specialTitle)
}

View File

@ -14,6 +14,8 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.FriendNameRemark
import net.mamoe.mirai.data.PreviousNameList
import net.mamoe.mirai.data.Profile
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.MemberCardChangeEvent
import net.mamoe.mirai.message.data.CustomFaceFromFile
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.MessageChain
@ -149,13 +151,15 @@ internal class MemberImpl(
override val group: GroupImpl by group.unsafeWeakRef()
val qq: QQImpl by qq.unsafeWeakRef()
override var groupCard: String
override var nameCard: String
get() = _groupCard
set(newValue) {
group.checkBotPermissionOperator()
if (_groupCard != newValue) {
val oldValue = _groupCard
_groupCard = newValue
launch {
MemberCardChangeEvent.ByBot(oldValue, newValue, this@MemberImpl).broadcast()
bot.network.run {
TroopManagement.EditGroupNametag(
bot.client,

View File

@ -107,7 +107,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
logger.info("Initializing BotNetworkHandler")
try {
if (::_network.isInitialized) {
BotOfflineEvent(this).broadcast()
BotOfflineEvent.Active(this, cause).broadcast()
_network.closeAndJoin(cause)
}
} catch (e: Exception) {

View File

@ -11,8 +11,9 @@
package net.mamoe.mirai.contact
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.MemberCardChangeEvent
import net.mamoe.mirai.utils.WeakRefProperty
import kotlin.jvm.JvmName
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
@ -32,18 +33,21 @@ interface Member : QQ, Contact {
val permission: MemberPermission
/**
* 群名片. 可能为空.
* 群名片. 可能为空. 修改时将会触发事件
*
* 在修改时将会异步上传至服务器. 无权限修改时将会抛出异常 [PermissionDeniedException]
*
* @see [groupCardOrNick] 获取非空群名片或昵称
* @see MemberCardChangeEvent 群名片被管理员, 自己或 [Bot] 改动事件
*/
var groupCard: String
var nameCard: String
/**
* 群头衔
*
* 在修改时将会异步上传至服务器. 无权限修改时将会抛出异常 [PermissionDeniedException]
*
* @see MemberSpecialTitleChangeEvent 群名片被管理员, 自己或 [Bot] 改动事件
*/
var specialTitle: String
@ -78,9 +82,9 @@ interface Member : QQ, Contact {
/**
* 获取非空群名片或昵称.
*
* [群名片][Member.groupCard] 不为空则返回群名片, 为空则返回 [QQ.nick]
* [群名片][Member.nameCard] 不为空则返回群名片, 为空则返回 [QQ.nick]
*/
val Member.groupCardOrNick: String get() = this.groupCard.takeIf { it.isNotEmpty() } ?: this.nick
val Member.groupCardOrNick: String get() = this.nameCard.takeIf { it.isNotEmpty() } ?: this.nick
@ExperimentalTime
suspend inline fun Member.mute(duration: Duration): Boolean {

View File

@ -1,53 +0,0 @@
/*
* Copyright 2020 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/master/LICENSE
*/
package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.QQ
/**
* [Bot] 登录完成, 好友列表, 群组列表初始化完成
*/
data class BotLoginSucceedEvent(override val bot: Bot) : BotActiveEvent()
/**
* [Bot] 主动离线.
*/
data class BotOfflineEvent(override val bot: Bot) : BotActiveEvent()
// region 好友
/**
* [Bot] 删除一个好友
*/
class BotRemoveFriendEvent(override val friend: QQ) : FriendEvent, BotActiveEvent()
// endregion
// region 群
/**
* 机器人踢出某个群员
*/
class BotKickMemberEvent(override val member: Member) : GroupMemberEvent, BotActiveEvent()
/**
* 机器人禁言某个群成员
*/
class BotMuteMemberEvent(override val member: Member) : GroupMemberEvent, BotActiveEvent()
/**
* 机器人取消禁言某个群成员
*/
class BotUnmuteMemberEvent(override val member: Member) : GroupMemberEvent, BotActiveEvent()
// endregion

View File

@ -0,0 +1,324 @@
/*
* Copyright 2020 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/master/LICENSE
*/
package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
// region Bot 状态
/**
* [Bot] 登录完成, 好友列表, 群组列表初始化完成
*/
data class BotOnlineEvent(override val bot: Bot) : BotActiveEvent
/**
* [Bot] 离线.
*/
sealed class BotOfflineEvent : BotActiveEvent {
/**
* 主动离线
*/
data class Active(override val bot: Bot, val cause: Throwable?) : BotOfflineEvent()
/**
* 被挤下线
*/
data class Force(override val bot: Bot) : BotOfflineEvent()
}
// endregion
// region 群
/**
* Bot 在群里的权限被改变. 操作人一定是群主
*/
data class BotGroupPermissionChangeEvent(
override val group: Group,
val origin: MemberPermission,
val new: MemberPermission
) : BotPassiveEvent, GroupEvent
// region 群设置
/**
* 群设置改变. 此事件广播前修改就已经完成.
*/
interface GroupSettingChangeEvent<T> : GroupEvent, BotPassiveEvent {
val origin: T
val new: T
}
/**
* 群名改变. 此事件广播前修改就已经完成.
*/
sealed class GroupNameChangeEvent(
) : GroupSettingChangeEvent<String>, BotPassiveEvent {
/**
* 由管理员操作
*/
data class ByOperator(
override val origin: String,
override val new: String,
val operator: Member
) : GroupNameChangeEvent() {
override val group: Group
get() = operator.group
}
/**
* 由机器人操作
*/
data class ByBot(
override val origin: String,
override val new: String,
override val group: Group
) : GroupNameChangeEvent()
}
/**
* "全员禁言" 功能状态改变. 此事件广播前修改就已经完成.
*/
sealed class GroupMuteAllEvent : GroupSettingChangeEvent<Boolean>, BotPassiveEvent {
/**
* 由管理员操作
*/
data class ByOperator(
override val origin: Boolean,
override val new: Boolean,
val operator: Member
) : GroupMuteAllEvent() {
override val group: Group
get() = operator.group
}
/**
* 由机器人操作
*/
data class ByBot(
override val origin: Boolean,
override val new: Boolean,
override val group: Group
) : GroupMuteAllEvent()
}
/**
* "坦白说" 功能状态改变. 此事件广播前修改就已经完成.
*/
sealed class GroupConfessTalkEvent : GroupSettingChangeEvent<Boolean>, BotPassiveEvent {
/**
* 由管理员操作
*/
data class ByOperator(
override val origin: Boolean,
override val new: Boolean,
val operator: Member
) : GroupConfessTalkEvent() {
override val group: Group
get() = operator.group
}
/**
* 由机器人操作
*/
data class ByBot(
override val origin: Boolean,
override val new: Boolean,
override val group: Group
) : GroupConfessTalkEvent()
}
// endregion
// region 群成员
// region 成员变更
/**
* 成员加入群的事件
*/
data class MemberJoinEvent(override val member: Member) : GroupMemberEvent, BotPassiveEvent
/**
* 成员离开群的事件
*/
sealed class MemberLeftEvent : GroupMemberEvent {
/**
* 成员被踢出群. 成员不可能是机器人自己.
*/
sealed class Kick : MemberLeftEvent() {
/**
* 被管理员踢出
*/
data class ByOperator(
override val member: Member,
val operator: Member
) : Kick(), BotPassiveEvent
/**
* 被机器人踢出
*/
data class ByBot(
override val member: Member
) : Kick(), BotActiveEvent
}
/**
* 成员主动离开
*/
data class Quit(override val member: Member) : MemberLeftEvent()
}
// endregion
// region 名片和头衔
/**
* 群名片改动. 此事件广播前修改就已经完成.
*/
sealed class MemberCardChangeEvent : GroupMemberEvent {
/**
* 修改前
*/
abstract val origin: String
/**
* 修改后
*/
abstract val new: String
abstract override val member: Member
/**
* 由管理员修改
*/
data class ByOperator(
override val origin: String,
override val new: String,
override val member: Member,
val operator: Member
) : MemberCardChangeEvent(), BotPassiveEvent
/**
* [Bot] 修改. [Member.nameCard]
*/
data class ByBot(
override val origin: String,
override val new: String,
override val member: Member
) : MemberCardChangeEvent(), BotActiveEvent
/**
* 该成员自己修改
*/
data class BySelf(
override val origin: String,
override val new: String,
override val member: Member
) : MemberCardChangeEvent(), BotPassiveEvent
}
/**
* 群头衔改动. 一定为群主操作
*/
data class MemberSpecialTitleChangeEvent(
/**
* 修改前
*/
val origin: String,
/**
* 修改后
*/
val new: String,
override val member: Member
) : GroupMemberEvent
// endregion
// region 成员权限
/**
* 成员权限改变的事件. 成员不可能是机器人自己.
*/
data class MemberPermissionChangeEvent(
override val member: Member,
val origin: MemberPermission,
val new: MemberPermission
) : GroupMemberEvent, BotPassiveEvent
// endregion
// region 禁言
/**
* 群成员被禁言事件. 操作人和被禁言的成员都不可能是机器人本人
*/
sealed class MemberMuteEvent : GroupMemberEvent {
abstract override val member: Member
abstract val durationSeconds: Int
/**
* 管理员禁言成员
*/
data class ByOperator(
override val member: Member,
override val durationSeconds: Int,
val operator: Member
) : MemberMuteEvent(), BotPassiveEvent
/**
* 机器人禁言成员. 通过 [Member.mute] 触发
*/
data class ByBot(
override val member: Member,
override var durationSeconds: Int
) : MemberMuteEvent(), BotActiveEvent
}
/**
* 群成员被取消禁言事件. 操作人和被禁言的成员都不可能是机器人本人
*/
sealed class MemberUnmuteEvent : GroupMemberEvent, BotPassiveEvent {
abstract override val member: Member
/**
* 管理员禁言成员
*/
data class ByOperator(
override val member: Member,
val operator: Member
) : MemberUnmuteEvent(), BotPassiveEvent
/**
* 机器人禁言成员. 通过 [Member.unmute] 触发
*/
data class ByBot(
override val member: Member
) : MemberUnmuteEvent(), BotActiveEvent
}
// endregion
// endregion
// endregion

View File

@ -1,186 +0,0 @@
/*
* Copyright 2020 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/master/LICENSE
*/
package net.mamoe.mirai.event.events
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.data.Packet
// region Bot 在线状态
/**
* 被挤下线
*/
data class BotForceOfflineEvent(
override val bot: Bot,
val title: String,
val tips: String
) : BotPassiveEvent, Packet
// endregion
// region 群
/**
* Bot 在群里的权限被改变. 操作人一定是群主
*/
data class BotGroupPermissionChangeEvent(
override val group: Group,
val origin: MemberPermission,
val new: MemberPermission
) : BotPassiveEvent, GroupEvent
// region 群设置
/**
* 群设置改变
*/
interface GroupSettingChangeEvent<T> : GroupEvent, BotPassiveEvent {
val operator: Member
val origin: T
val new: T
override val group: Group
get() = operator.group
}
/**
* 群名改变
*/
data class GroupNameChangeEvent(
override val operator: Member,
override val origin: String,
override val new: String
) : GroupSettingChangeEvent<String>, BotPassiveEvent
/**
* "全员禁言" 功能状态改变
*/
data class GroupMuteAllEvent(
override val operator: Member,
override val origin: Boolean,
override val new: Boolean
) : GroupSettingChangeEvent<Boolean>, BotPassiveEvent
/**
* "坦白说" 功能状态改变
*/
data class GroupConfessTalkEvent(
override val operator: Member,
override val origin: Boolean,
override val new: Boolean
) : GroupSettingChangeEvent<Boolean>, BotPassiveEvent
// endregion
// region 群成员
// region 成员变更
/**
* 成员加入群的事件
*/
data class MemberJoinEvent(override val member: Member) : GroupMemberEvent, BotPassiveEvent
/**
* 成员离开群的事件
*/
sealed class MemberLeftEvent : GroupMemberEvent, BotPassiveEvent {
/**
* 成员被踢出群. 成员不可能是机器人自己.
*
* @see BotKickMemberEvent 机器人踢出一个人
*/
data class Kick(override val member: Member, val operator: Member) : MemberLeftEvent()
/**
* 成员主动离开
*/
data class Quit(override val member: Member) : MemberLeftEvent()
}
// endregion
// region
/**
* 群名片改动
*/
sealed class MemberCardChangeEvent : GroupMemberEvent, BotPassiveEvent {
/**
* 群名片
*/
abstract val card: String
/**
* 由管理员修改
*/
data class ByOperator(
override val card: String,
override val member: Member,
val operator: Member
) : MemberCardChangeEvent()
/**
* 该成员自己修改
*/
data class BySelf(
override val card: String,
override val member: Member
) : MemberCardChangeEvent()
}
// endregion
// region 成员权限
/**
* 成员权限改变的事件. 成员不可能是机器人自己.
*/
data class MemberPermissionChangeEvent(
override val bot: Bot,
override val member: Member,
val origin: MemberPermission,
val new: MemberPermission
) : GroupMemberEvent, BotPassiveEvent
// endregion
// region 禁言
/**
* 群成员被禁言事件. 操作人和被禁言的成员都不可能是机器人本人
*
* @see BotMuteMemberEvent 机器人禁言一个人
*/
data class MemberMuteEvent(
override val member: Member,
val operator: Member,
val durationSeconds: Int
) : GroupMemberEvent, BotPassiveEvent {
override fun toString(): String = "MemberMuteEvent(member=${member.id}, group=${group.id}, operator=${operator.id}, duration=${durationSeconds}s"
}
/**
* 群成员被取消禁言事件. 操作人和被禁言的成员都不可能是机器人本人
*
* @see BotUnmuteMemberEvent 机器人取消禁言某个人
*/
data class MemberUnmuteEvent(override val member: Member, val operator: Member) : GroupMemberEvent, BotPassiveEvent
// endregion
// endregion
// endregion

View File

@ -13,7 +13,6 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.event.AbstractCancellableEvent
import net.mamoe.mirai.event.Event
/**
@ -31,7 +30,7 @@ interface BotPassiveEvent : BotEvent
/**
* [Bot] 主动发起的动作的事件
*/
abstract class BotActiveEvent : BotEvent, AbstractCancellableEvent()
interface BotActiveEvent : BotEvent
/**

View File

@ -11,7 +11,7 @@ package net.mamoe.mirai.imageplugin
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.GlobalScope
import net.mamoe.mirai.event.events.BotLoginSucceedEvent
import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.plugin.PluginBase
@ -22,7 +22,7 @@ class ImageSenderMain : PluginBase() {
@MiraiExperimentalAPI
override fun onEnable() {
logger.info("Image Sender plugin enabled")
GlobalScope.subscribeAlways<BotLoginSucceedEvent> {
GlobalScope.subscribeAlways<BotOnlineEvent> {
logger.info("${this.bot.uin} login succeed, it will be controlled by Image Sender Plugin")
this.bot.subscribeMessages {