Group.kt 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright 2019-2021 Mamoe Technologies and contributors.
  3. *
  4. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  5. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
  6. *
  7. * https://github.com/mamoe/mirai/blob/master/LICENSE
  8. */
  9. @file:Suppress("EXPERIMENTAL_API_USAGE", "unused", "UnusedImport", "NOTHING_TO_INLINE")
  10. package net.mamoe.mirai.contact
  11. import kotlinx.coroutines.CoroutineScope
  12. import net.mamoe.kjbb.JvmBlockingBridge
  13. import net.mamoe.mirai.Bot
  14. import net.mamoe.mirai.event.events.*
  15. import net.mamoe.mirai.message.MessageReceipt
  16. import net.mamoe.mirai.message.data.*
  17. import net.mamoe.mirai.utils.ExternalResource
  18. import net.mamoe.mirai.utils.ExternalResource.Companion.uploadAsVoice
  19. import net.mamoe.mirai.utils.MiraiExperimentalApi
  20. import net.mamoe.mirai.utils.OverFileSizeMaxException
  21. /**
  22. * 群.
  23. */
  24. @JvmBlockingBridge
  25. public interface Group : Contact, CoroutineScope {
  26. /**
  27. * 群名称.
  28. *
  29. * 在修改时将会异步上传至服务器, 也会广播事件 [GroupNameChangeEvent].
  30. * 频繁修改可能会被服务器拒绝.
  31. *
  32. * @see GroupNameChangeEvent 群名片修改事件
  33. * @throws PermissionDeniedException 无权限修改时将会抛出异常
  34. */
  35. public var name: String
  36. /**
  37. * 群设置
  38. */
  39. public val settings: GroupSettings
  40. /**
  41. * 同为 groupCode, 用户看到的群号码.
  42. */
  43. public override val id: Long
  44. /**
  45. * 群主.
  46. *
  47. * @return 若机器人是群主, 返回 [botAsMember]. 否则返回相应的成员
  48. */
  49. public val owner: NormalMember
  50. /**
  51. * [Bot] 在群内的 [Member] 实例
  52. */
  53. public val botAsMember: NormalMember
  54. /**
  55. * 机器人被禁言还剩余多少秒
  56. *
  57. * @see BotMuteEvent 机器人被禁言事件
  58. * @see isBotMuted 判断机器人是否正在被禁言
  59. */
  60. public val botMuteRemaining: Int get() = botAsMember.muteTimeRemaining
  61. /**
  62. * 机器人在这个群里的权限
  63. *
  64. * @see Group.checkBotPermission 检查 [Bot] 在这个群里的权限
  65. *
  66. * @see BotGroupPermissionChangeEvent 机器人群员修改
  67. */
  68. public val botPermission: MemberPermission get() = botAsMember.permission
  69. /**
  70. * 群头像下载链接.
  71. */
  72. public override val avatarUrl: String
  73. get() = "https://p.qlogo.cn/gh/$id/${id}/640"
  74. /**
  75. * 群成员列表, 不含机器人自己, 含群主.
  76. *
  77. * 在 [Group] 实例创建的时候查询一次. 并与事件同步事件更新.
  78. */
  79. public val members: ContactList<NormalMember>
  80. /**
  81. * 获取群成员实例. 不存在时返回 `null`.
  82. *
  83. * 当 [id] 为 [Bot.id] 时返回 [botAsMember].
  84. */
  85. public operator fun get(id: Long): NormalMember?
  86. /**
  87. * 获取群成员实例. 不存在时抛出 [kotlin.NoSuchElementException].
  88. *
  89. * 当 [id] 为 [Bot.id] 时返回 [botAsMember].
  90. */
  91. public fun getOrFail(id: Long): NormalMember =
  92. get(id) ?: throw NoSuchElementException("member $id not found in group ${this.id}")
  93. /**
  94. * 当本群存在 [Member.id] 为 [id] 的群员时返回 `true`.
  95. *
  96. * 当 [id] 为 [Bot.id] 时返回 `true`
  97. */
  98. public operator fun contains(id: Long): Boolean
  99. /**
  100. * 当 [member] 是本群成员时返回 `true`. 将同时成员 [所属群][Member.group]. 同一个用户在不同群内的 [Member] 对象不相等.
  101. */
  102. public operator fun contains(member: NormalMember): Boolean = member in members
  103. /**
  104. * 让机器人退出这个群.
  105. * @throws IllegalStateException 当机器人为群主时
  106. * @return 退出成功时 true; 已经退出时 false
  107. */
  108. public suspend fun quit(): Boolean
  109. /**
  110. * 向这个对象发送消息.
  111. *
  112. * 单条消息最大可发送 4500 字符或 50 张图片.
  113. *
  114. * @see GroupMessagePreSendEvent 发送消息前事件
  115. * @see GroupMessagePostSendEvent 发送消息后事件
  116. *
  117. * @throws EventCancelledException 当发送消息事件被取消时抛出
  118. * @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
  119. * @throws MessageTooLargeException 当消息过长时抛出
  120. * @throws IllegalArgumentException 当消息内容为空时抛出 (详见 [Message.isContentEmpty])
  121. *
  122. * @return 消息回执. 可进行撤回 ([MessageReceipt.recall])
  123. */
  124. public override suspend fun sendMessage(message: Message): MessageReceipt<Group>
  125. /**
  126. * 发送纯文本消息
  127. * @see sendMessage
  128. */
  129. public override suspend fun sendMessage(message: String): MessageReceipt<Group> =
  130. this.sendMessage(message.toPlainText())
  131. /**
  132. * 上传一个语音消息以备发送.
  133. *
  134. * - **请手动关闭 [resource]**
  135. * - 请使用 amr 或 silk 格式
  136. *
  137. * @see ExternalResource.uploadAsVoice
  138. *
  139. * @throws EventCancelledException 当发送消息事件被取消
  140. * @throws OverFileSizeMaxException 当语音文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
  141. */
  142. public suspend fun uploadVoice(resource: ExternalResource): Voice
  143. /**
  144. * 将一条消息设置为群精华消息, 需要管理员或群主权限.
  145. * 操作成功返回 `true`.
  146. *
  147. * @throws PermissionDeniedException 没有权限时抛出
  148. *
  149. * @since 2.2
  150. */
  151. public suspend fun setEssenceMessage(source: MessageSource): Boolean
  152. public companion object {
  153. /**
  154. * 将一条消息设置为群精华消息, 需要管理员或群主权限.
  155. * 操作成功返回 `true`.
  156. *
  157. * @throws PermissionDeniedException 没有权限时抛出
  158. *
  159. * @see Group.setEssenceMessage
  160. * @since 2.2
  161. */
  162. @JvmBlockingBridge
  163. public suspend fun Group.setEssenceMessage(chain: MessageChain): Boolean = setEssenceMessage(chain.source)
  164. }
  165. }
  166. /**
  167. * 群设置
  168. *
  169. * @see Group.settings 获取群设置
  170. */
  171. public interface GroupSettings {
  172. /**
  173. * 入群公告, 没有时为空字符串.
  174. *
  175. * 在修改时将会异步上传至服务器.
  176. *
  177. * @see GroupEntranceAnnouncementChangeEvent
  178. * @throws PermissionDeniedException 无权限修改时将会抛出异常
  179. */
  180. public var entranceAnnouncement: String
  181. /**
  182. * 全体禁言状态. `true` 为开启.
  183. *
  184. * 当前仅能修改状态.
  185. *
  186. * @see GroupMuteAllEvent
  187. * @throws PermissionDeniedException 无权限修改时将会抛出异常
  188. */
  189. public var isMuteAll: Boolean
  190. /**
  191. * 允许群员邀请好友入群的状态. `true` 为允许
  192. *
  193. * 在修改时将会异步上传至服务器.
  194. *
  195. * @see GroupAllowMemberInviteEvent
  196. * @throws PermissionDeniedException 无权限修改时将会抛出异常
  197. */
  198. public var isAllowMemberInvite: Boolean
  199. /**
  200. * 自动加群审批
  201. */
  202. @MiraiExperimentalApi
  203. public val isAutoApproveEnabled: Boolean
  204. /**
  205. * 匿名聊天
  206. */
  207. public val isAnonymousChatEnabled: Boolean
  208. }
  209. /**
  210. * 同 [get]. 在一些不适合使用 [get] 的情境下使用 [getMember].
  211. */
  212. @JvmSynthetic
  213. public inline fun Group.getMember(id: Long): NormalMember? = get(id)
  214. /**
  215. * 同 [getMemberOrFail]. 在一些不适合使用 [getOrFail] 的情境下使用 [getMemberOrFail].
  216. */
  217. @JvmSynthetic
  218. public inline fun Group.getMemberOrFail(id: Long): NormalMember = getOrFail(id)
  219. /**
  220. * 返回机器人是否正在被禁言
  221. *
  222. * @see Group.botMuteRemaining 剩余禁言时间
  223. */
  224. public inline val Group.isBotMuted: Boolean get() = this.botMuteRemaining != 0