diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt index 46174e03f..8762e30b5 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt @@ -3,7 +3,7 @@ package net.mamoe.mirai.contact import kotlinx.coroutines.CoroutineScope - +import net.mamoe.mirai.utils.MiraiExperimentalAPI /** * 群. 在 QQ Android 中叫做 "Troop" @@ -12,15 +12,15 @@ interface Group : Contact, CoroutineScope { /** * 群名称. * - * 在修改时将会异步上传至服务器. + * 在修改时将会异步上传至服务器. 无权限修改时将会抛出异常 [PermissionDeniedException] * - * 注: 频繁修改可能会被服务器拒绝 + * 注: 频繁修改可能会被服务器拒绝. */ var name: String /** * 入群公告, 没有时为空字符串. * - * 在修改时将会异步上传至服务器. + * 在修改时将会异步上传至服务器. 无权限修改时将会抛出异常 [PermissionDeniedException] */ var announcement: String /** @@ -32,11 +32,13 @@ interface Group : Contact, CoroutineScope { /** * 坦白说状态. `true` 为允许. * - * 在修改时将会异步上传至服务器. + * 在修改时将会异步上传至服务器. 无权限修改时将会抛出异常 [PermissionDeniedException] */ var confessTalk: Boolean /** * 允许群员邀请好友入群的状态. `true` 为允许 + * + * 在修改时将会异步上传至服务器. 无权限修改时将会抛出异常 [PermissionDeniedException] */ var allowMemberInvite: Boolean /** @@ -45,14 +47,9 @@ interface Group : Contact, CoroutineScope { val autoApprove: Boolean /** * 匿名聊天 - * [可查已完成] */ val anonymousChat: Boolean - /** - * ====以上字段在更新值的时候会自动异步上报服务器更改群信息==== - */ - /** * 同为 groupCode, 用户看到的群号码. */ @@ -64,16 +61,23 @@ interface Group : Contact, CoroutineScope { val owner: Member + /** + * 机器人在这个群里的权限 + * + * **MiraiExperimentalAPI**: 在未来可能会被修改 + */ + @MiraiExperimentalAPI val botPermission: MemberPermission /** + * 群成员列表, 不含机器人自己, 含群主. * 在 [Group] 实例创建的时候查询一次. 并与事件同步事件更新 */ val members: ContactList<Member> /** - * 获取群成员实例. 若此 id 的成员不存在, 则会抛出 [kotlin.NoSuchElementException] + * 获取群成员实例. 不存在时抛出 [kotlin.NoSuchElementException] */ operator fun get(id: Long): Member @@ -93,5 +97,6 @@ interface Group : Contact, CoroutineScope { suspend fun quit(): Boolean + @MiraiExperimentalAPI fun toFullString(): String = "Group(id=${this.id}, name=$name, owner=${owner.id}, members=${members.idContentString})" } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt index 614c93899..684935dfc 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt @@ -21,24 +21,20 @@ interface Member : QQ, Contact { */ val permission: MemberPermission - /** - * ====以下字段会在更新后异步更新到服务器==== - */ - /** * 群名片 + * + * 在修改时将会异步上传至服务器. 无权限修改时将会抛出异常 [PermissionDeniedException] */ var groupCard: String /** * 群头衔 + * + * 在修改时将会异步上传至服务器. 无权限修改时将会抛出异常 [PermissionDeniedException] */ var specialTitle: String - /** - * ====以上字段会在更新后异步更新到服务器==== - */ - /** * 禁言 * @@ -73,59 +69,4 @@ suspend inline fun Member.mute(duration: Duration): Boolean { suspend inline fun Member.mute(durationSeconds: UInt): Boolean { require(durationSeconds.toInt() <= 30 * 24 * 3600) { "duration must be at most 1 month" } return this.mute(durationSeconds.toInt()) // same bin rep. -} - -/** - * 群成员的权限 - */ -enum class MemberPermission { - /** - * 群主 - */ - OWNER, - /** - * 管理员 - */ - ADMINISTRATOR, - /** - * 一般群成员 - */ - MEMBER; -} - -/** - * 是群主 - */ -@Suppress("NOTHING_TO_INLINE") -inline fun MemberPermission.isOwner(): Boolean = this == MemberPermission.OWNER - -/** - * 是管理员 - */ -@Suppress("NOTHING_TO_INLINE") -inline fun MemberPermission.isAdministrator(): Boolean = this == MemberPermission.ADMINISTRATOR - -/** - * 是管理员或群主 - */ -@Suppress("NOTHING_TO_INLINE") -inline fun MemberPermission.isOperator(): Boolean = isAdministrator() || isOwner() - - -/** - * 是群主 - */ -@Suppress("NOTHING_TO_INLINE") -inline fun Member.isOwner(): Boolean = this.permission.isOwner() - -/** - * 是管理员 - */ -@Suppress("NOTHING_TO_INLINE") -inline fun Member.isAdministrator(): Boolean = this.permission.isAdministrator() - -/** - * 时管理员或群主 - */ -@Suppress("NOTHING_TO_INLINE") -inline fun Member.isOperator(): Boolean = this.permission.isOperator() \ No newline at end of file +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Permission.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Permission.kt new file mode 100644 index 000000000..09fc3148d --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Permission.kt @@ -0,0 +1,92 @@ +package net.mamoe.mirai.contact + +import net.mamoe.mirai.utils.MiraiExperimentalAPI + + +/** + * 群成员的权限 + */ +enum class MemberPermission { + /** + * 群主 + */ + OWNER, + /** + * 管理员 + */ + ADMINISTRATOR, + /** + * 一般群成员 + */ + MEMBER; +} + +/** + * 是群主 + */ +@Suppress("NOTHING_TO_INLINE") +inline fun MemberPermission.isOwner(): Boolean = this == MemberPermission.OWNER + +/** + * 是管理员 + */ +@Suppress("NOTHING_TO_INLINE") +inline fun MemberPermission.isAdministrator(): Boolean = this == MemberPermission.ADMINISTRATOR + +/** + * 是管理员或群主 + */ +@Suppress("NOTHING_TO_INLINE") +inline fun MemberPermission.isOperator(): Boolean = isAdministrator() || isOwner() + + +/** + * 是群主 + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Member.isOwner(): Boolean = this.permission.isOwner() + +/** + * 是管理员 + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Member.isAdministrator(): Boolean = this.permission.isAdministrator() + +/** + * 时管理员或群主 + */ +@Suppress("NOTHING_TO_INLINE") +inline fun Member.isOperator(): Boolean = this.permission.isOperator() + + + +/** + * 权限不足 + */ +class PermissionDeniedException : IllegalStateException { + constructor() : super("Permission denied") + constructor(message: String?) : super(message) +} + +@UseExperimental(MiraiExperimentalAPI::class) +inline fun Group.checkBotPermission( + required: MemberPermission, + lazyMessage: () -> String = { + "Permission denied: required $required, got actual $botPermission for $bot in group $id" + } +) { + if (botPermission != required) { + throw PermissionDeniedException(lazyMessage()) + } +} + +@UseExperimental(MiraiExperimentalAPI::class) +inline fun Group.checkBotPermissionOperator( + lazyMessage: () -> String = { + "Permission denied: required ${MemberPermission.ADMINISTRATOR} or ${MemberPermission.OWNER}, got actual $botPermission for $bot in group $id" + } +) { + if (!botPermission.isOperator()) { + throw PermissionDeniedException(lazyMessage()) + } +} \ No newline at end of file