Bot.kt 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. @file:Suppress("EXPERIMENTAL_API_USAGE", "unused", "FunctionName")
  2. package net.mamoe.mirai
  3. import io.ktor.util.KtorExperimentalAPI
  4. import kotlinx.coroutines.CoroutineScope
  5. import kotlinx.io.OutputStream
  6. import kotlinx.io.core.ByteReadPacket
  7. import kotlinx.io.core.use
  8. import net.mamoe.mirai.contact.*
  9. import net.mamoe.mirai.message.data.Image
  10. import net.mamoe.mirai.network.BotNetworkHandler
  11. import net.mamoe.mirai.network.data.AddFriendResult
  12. import net.mamoe.mirai.network.data.ImageLink
  13. import net.mamoe.mirai.utils.BotConfiguration
  14. import net.mamoe.mirai.utils.GroupNotFoundException
  15. import net.mamoe.mirai.utils.MiraiInternalAPI
  16. import net.mamoe.mirai.utils.MiraiLogger
  17. import net.mamoe.mirai.utils.io.transferTo
  18. import kotlin.coroutines.CoroutineContext
  19. /**
  20. * Mirai 的机器人. 一个机器人实例登录一个 QQ 账号.
  21. * Mirai 为多账号设计, 可同时维护多个机器人.
  22. *
  23. * @see Contact
  24. */
  25. abstract class Bot : CoroutineScope {
  26. @UseExperimental(MiraiInternalAPI::class)
  27. companion object {
  28. inline fun forEachInstance(block: (Bot) -> Unit) = BotImpl.forEachInstance(block)
  29. fun instanceWhose(qq: Long): Bot = BotImpl.instanceWhose(qq = qq)
  30. }
  31. /**
  32. * 账号信息
  33. */
  34. abstract val account: BotAccount
  35. /**
  36. * 日志记录器
  37. */
  38. abstract val logger: MiraiLogger
  39. abstract override val coroutineContext: CoroutineContext
  40. // region contacts
  41. /**
  42. * 与这个机器人相关的 QQ 列表. 机器人与 QQ 不一定是好友
  43. */
  44. abstract val qqs: ContactList<QQ>
  45. /**
  46. * 获取缓存的 QQ 对象. 若没有对应的缓存, 则会线程安全地创建一个.
  47. */
  48. abstract fun getQQ(id: Long): QQ
  49. /**
  50. * 与这个机器人相关的群列表. 机器人不一定是群成员.
  51. */
  52. abstract val groups: ContactList<Group>
  53. /**
  54. * 获取缓存的群对象. 若没有对应的缓存, 则会线程安全地创建一个.
  55. * 若 [id] 无效, 将会抛出 [GroupNotFoundException]
  56. */
  57. abstract suspend fun getGroup(id: GroupId): Group
  58. /**
  59. * 获取缓存的群对象. 若没有对应的缓存, 则会线程安全地创建一个.
  60. * 若 [internalId] 无效, 将会抛出 [GroupNotFoundException]
  61. */
  62. abstract suspend fun getGroup(internalId: GroupInternalId): Group
  63. /**
  64. * 获取缓存的群对象. 若没有对应的缓存, 则会线程安全地创建一个.
  65. * 若 [id] 无效, 将会抛出 [GroupNotFoundException]
  66. */
  67. abstract suspend fun getGroup(id: Long): Group
  68. // endregion
  69. // region network
  70. /**
  71. * 网络模块
  72. */
  73. abstract val network: BotNetworkHandler
  74. /**
  75. * 使用在默认配置基础上修改的配置进行登录
  76. */
  77. suspend inline fun login(configuration: BotConfiguration.() -> Unit) {
  78. return this.login(BotConfiguration().apply(configuration))
  79. }
  80. /**
  81. * 使用特定配置进行登录
  82. */
  83. abstract suspend fun login(configuration: BotConfiguration = BotConfiguration.Default)
  84. // endregion
  85. // region actions
  86. abstract suspend fun Image.getLink(): ImageLink
  87. suspend fun Image.downloadAsByteArray(): ByteArray = getLink().downloadAsByteArray()
  88. suspend fun Image.download(): ByteReadPacket = getLink().download()
  89. /**
  90. * 添加一个好友
  91. *
  92. * @param message 若需要验证请求时的验证消息.
  93. * @param remark 好友备注
  94. */
  95. abstract suspend fun addFriend(id: Long, message: String? = null, remark: String? = null): AddFriendResult
  96. /**
  97. * 同意来自陌生人的加好友请求
  98. */
  99. abstract suspend fun approveFriendAddRequest(id: Long, remark: String?)
  100. // endregion
  101. abstract fun close(throwable: Throwable?)
  102. // region extensions
  103. fun Int.qq(): QQ = getQQ(this.toLong())
  104. fun Long.qq(): QQ = getQQ(this)
  105. suspend inline fun Int.group(): Group = getGroup(this.toLong())
  106. suspend inline fun Long.group(): Group = getGroup(this)
  107. suspend inline fun GroupInternalId.group(): Group = getGroup(this)
  108. suspend inline fun GroupId.group(): Group = getGroup(this)
  109. /**
  110. * 需要调用者自行 close [output]
  111. */
  112. @UseExperimental(KtorExperimentalAPI::class)
  113. suspend inline fun Image.downloadTo(output: OutputStream) =
  114. download().use { input -> input.transferTo(output) }
  115. // endregion
  116. }