Commit 7bb482de authored by jiahua.liu's avatar jiahua.liu

Merge remote-tracking branch 'origin/master'

parents 3eeb640f 75ad1e17
......@@ -9,9 +9,15 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: setup-android
uses: msfjarvis/setup-android@0.2
- name: Setup Java JDK
uses: actions/setup-java@v1.3.0
with:
# Gradle tasks to run - If you want to run ./gradlew assemble, specify assemble here.
gradleTasks: build -x mirai-core:jvmTest
# The Java version to make available on the path. Takes a whole or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x)
java-version: 11
# The package type (jre, jdk, jdk+fx)
java-package: jdk+fx
- name: Gradle Command
uses: eskatos/gradle-command-action@v1
with:
# Gradle command line arguments, see gradle --help
arguments: build -x mirai-core:jvmTest
......@@ -43,7 +43,7 @@ internal abstract class QQAndroidBotBase constructor(
context: Context,
account: BotAccount,
configuration: BotConfiguration
) : BotImpl<QQAndroidBotNetworkHandler>(account, configuration) {
) : BotImpl<QQAndroidBotNetworkHandler>(context, account, configuration) {
val client: QQAndroidClient =
QQAndroidClient(
context,
......@@ -88,10 +88,10 @@ internal abstract class QQAndroidBotBase constructor(
}.groups.asSequence().map { it.groupUin.shl(32) and it.groupCode }
}
override suspend fun queryGroupInfo(id: Long): GroupInfo = network.run {
override suspend fun queryGroupInfo(groupCode: Long): GroupInfo = network.run {
TroopManagement.GetGroupInfo(
client = bot.client,
groupCode = id
groupCode = groupCode
).sendAndExpect<GroupInfoImpl>(retry = 2)
}
......
......@@ -547,5 +547,5 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
super.close(cause)
}
override suspend fun awaitDisconnection() = supervisor.join()
override suspend fun join() = supervisor.join()
}
\ No newline at end of file
......@@ -33,7 +33,7 @@ import kotlin.jvm.JvmStatic
* 机器人对象. 一个机器人实例登录一个 QQ 账号.
* Mirai 为多账号设计, 可同时维护多个机器人.
*
* 注: Bot 为全协程实现, 没有其他任务时若不使用 [awaitDisconnection], 主线程将会退出.
* 注: Bot 为全协程实现, 没有其他任务时若不使用 [join], 主线程将会退出.
*
* @see Contact
*/
......@@ -44,7 +44,8 @@ abstract class Bot : CoroutineScope {
* 复制一份此时的 [Bot] 实例列表.
*/
@JvmStatic
val instances: List<WeakRef<Bot>> get() = BotImpl.instances.toList()
val instances: List<WeakRef<Bot>>
get() = BotImpl.instances.toList()
/**
* 遍历每一个 [Bot] 实例
......@@ -58,6 +59,14 @@ abstract class Bot : CoroutineScope {
fun instanceWhose(qq: Long): Bot = BotImpl.instanceWhose(qq = qq)
}
/**
* [Bot] 运行的 [Context].
*
* 在 JVM 的默认实现为 `class ContextImpl : Context`
* 在 Android 实现为 `android.content.Context`
*/
abstract val context: Context
/**
* 账号信息
*/
......@@ -135,7 +144,9 @@ abstract class Bot : CoroutineScope {
abstract val groups: ContactList<Group>
/**
* 获取一个机器人加入的群. 若没有这个群, 则会抛出异常 [NoSuchElementException]
* 获取一个机器人加入的群.
*
* @throws NoSuchElementException 当不存在这个群时
*/
fun getGroup(id: Long): Group {
return groups.delegate.getOrNull(id)
......@@ -143,21 +154,23 @@ abstract class Bot : CoroutineScope {
}
/**
* 获取群列表. 返回值前 32 bits 为 uin, 后 32 bits 为 groupCode
* 向服务器查询群列表. 返回值前 32 bits 为 uin, 后 32 bits 为 groupCode
*/
abstract suspend fun queryGroupList(): Sequence<Long>
/**
* 查询群资料. 获得的仅为当前时刻的资料.
* 向服务器查询群资料. 获得的仅为当前时刻的资料.
* 请优先使用 [getGroup] 然后查看群资料.
*/
abstract suspend fun queryGroupInfo(id: Long): GroupInfo
abstract suspend fun queryGroupInfo(groupCode: Long): GroupInfo
/**
* 查询群成员列表.
* 向服务器查询群成员列表.
* 请优先使用 [getGroup], [Group.members] 查看群成员.
*
* 这个函数很慢. 请不要频繁使用.
*
* @see Group.calculateGroupUinByGroupCode 使用 groupCode 计算 groupUin
*/
abstract suspend fun queryGroupMemberList(groupUin: Long, groupCode: Long, ownerId: Long): Sequence<MemberInfo>
......@@ -175,7 +188,10 @@ abstract class Bot : CoroutineScope {
/**
* 挂起直到 [Bot] 下线.
*/
suspend inline fun awaitDisconnection() = network.awaitDisconnection()
suspend inline fun join() = network.join()
@Deprecated("使用 join()", ReplaceWith("this.join()"), level = DeprecationLevel.HIDDEN)
suspend inline fun awaitDisconnection() = join()
/**
* 登录, 或重新登录.
......@@ -220,6 +236,8 @@ abstract class Bot : CoroutineScope {
* 注: 不可重新登录. 必须重新实例化一个 [Bot].
*
* @param cause 原因. 为 null 时视为正常关闭, 非 null 时视为异常关闭
*
* @see closeAndJoin
*/
abstract fun close(cause: Throwable? = null)
......@@ -244,6 +262,18 @@ abstract class Bot : CoroutineScope {
// endregion
}
/**
* 关闭这个 [Bot], 停止一切相关活动. 所有引用都会被释放.
*
* 注: 不可重新登录. 必须重新实例化一个 [Bot].
*
* @param cause 原因. 为 null 时视为正常关闭, 非 null 时视为异常关闭
*/
suspend inline fun Bot.closeAndJoin(cause: Throwable? = null) {
close(cause)
coroutineContext[Job]?.join()
}
inline fun Bot.containsFriend(id: Long): Boolean = this.qqs.contains(id)
inline fun Bot.containsGroup(id: Long): Boolean = this.groups.contains(id)
......
......@@ -32,6 +32,7 @@ import kotlin.coroutines.CoroutineContext
@UseExperimental(MiraiExperimentalAPI::class)
@MiraiInternalAPI
abstract class BotImpl<N : BotNetworkHandler> constructor(
context: Context,
account: BotAccount,
val configuration: BotConfiguration
) : Bot(), CoroutineScope {
......@@ -39,6 +40,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
override val coroutineContext: CoroutineContext =
configuration.parentCoroutineContext + botJob + (configuration.parentCoroutineContext[CoroutineExceptionHandler]
?: CoroutineExceptionHandler { _, e -> logger.error("An exception was thrown under a coroutine of Bot", e) })
override val context: Context by context.unsafeWeakRef()
@Suppress("CanBePrimaryConstructorProperty") // for logger
final override val account: BotAccount = account
......
......@@ -80,9 +80,10 @@ abstract class BotNetworkHandler : CoroutineScope {
}
/**
* 等待直到与服务器断开连接. 若未连接则立即返回
* 当 [Bot] 正常运作时, 这个函数将一直挂起协程到 [Bot] 被 [Bot.close]
* 当 [Bot] 离线时, 这个函数立即返回.
*/
abstract suspend fun awaitDisconnection()
abstract suspend fun join()
/**
* 关闭网络接口, 停止所有有关协程和任务
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment