mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-22 05:10:09 +08:00
Change Bot to interface
This commit is contained in:
parent
b0d43eb708
commit
9c71a9c953
@ -20,8 +20,12 @@ import net.mamoe.mirai.contact.*
|
|||||||
import net.mamoe.mirai.message.action.BotNudge
|
import net.mamoe.mirai.message.action.BotNudge
|
||||||
import net.mamoe.mirai.message.action.MemberNudge
|
import net.mamoe.mirai.message.action.MemberNudge
|
||||||
import net.mamoe.mirai.network.LoginFailedException
|
import net.mamoe.mirai.network.LoginFailedException
|
||||||
import net.mamoe.mirai.utils.*
|
import net.mamoe.mirai.utils.BotConfiguration
|
||||||
import kotlin.coroutines.CoroutineContext
|
import net.mamoe.mirai.utils.MiraiExperimentalApi
|
||||||
|
import net.mamoe.mirai.utils.MiraiLogger
|
||||||
|
import net.mamoe.mirai.utils.PlannedRemoval
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.NoSuchElementException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录, 返回 [this]
|
* 登录, 返回 [this]
|
||||||
@ -40,87 +44,31 @@ public suspend inline fun <B : Bot> B.alsoLogin(): B = also { login() }
|
|||||||
*
|
*
|
||||||
* @see BotFactory 构造 [Bot] 的工厂, [Bot] 唯一的构造方式.
|
* @see BotFactory 构造 [Bot] 的工厂, [Bot] 唯一的构造方式.
|
||||||
*/
|
*/
|
||||||
public abstract class Bot internal constructor(
|
public interface Bot : CoroutineScope, ContactOrBot, UserOrBot {
|
||||||
|
/**
|
||||||
|
* Bot 配置
|
||||||
|
*/
|
||||||
public val configuration: BotConfiguration
|
public val configuration: BotConfiguration
|
||||||
) : CoroutineScope, ContactOrBot, UserOrBot {
|
|
||||||
public final override val coroutineContext: CoroutineContext = // for id
|
|
||||||
configuration.parentCoroutineContext
|
|
||||||
.plus(SupervisorJob(configuration.parentCoroutineContext[Job]))
|
|
||||||
.plus(configuration.parentCoroutineContext[CoroutineExceptionHandler]
|
|
||||||
?: CoroutineExceptionHandler { _, e ->
|
|
||||||
logger.error("An exception was thrown under a coroutine of Bot", e)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.plus(CoroutineName("Mirai Bot"))
|
|
||||||
|
|
||||||
|
|
||||||
public companion object {
|
|
||||||
@JvmField
|
|
||||||
@Suppress("ObjectPropertyName")
|
|
||||||
internal val _instances: LockFreeLinkedList<WeakRef<Bot>> = LockFreeLinkedList()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 复制一份此时的 [Bot] 实例列表.
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
public val botInstances: List<Bot>
|
|
||||||
get() = _instances.asSequence().mapNotNull { it.get() }.toList()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 复制一份此时的 [Bot] 实例列表.
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
public val botInstancesSequence: Sequence<Bot>
|
|
||||||
get() = _instances.asSequence().mapNotNull { it.get() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 遍历每一个 [Bot] 实例
|
|
||||||
*/
|
|
||||||
@JvmSynthetic
|
|
||||||
public fun forEachInstance(block: (Bot) -> Unit): Unit = _instances.forEach { it.get()?.let(block) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取一个 [Bot] 实例, 无对应实例时抛出 [NoSuchElementException]
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
@Throws(NoSuchElementException::class)
|
|
||||||
public fun getInstance(qq: Long): Bot =
|
|
||||||
getInstanceOrNull(qq) ?: throw NoSuchElementException(qq.toString())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取一个 [Bot] 实例, 无对应实例时返回 `null`
|
|
||||||
*/
|
|
||||||
@JvmStatic
|
|
||||||
public fun getInstanceOrNull(qq: Long): Bot? =
|
|
||||||
_instances.asSequence().mapNotNull { it.get() }.firstOrNull { it.id == qq }
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
_instances.addLast(this.weakRef())
|
|
||||||
supervisorJob.invokeOnCompletion {
|
|
||||||
_instances.removeIf { it.get()?.id == this.id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QQ 号码. 实际类型为 uint
|
* QQ 号码. 实际类型为 uint
|
||||||
*/
|
*/
|
||||||
public abstract override val id: Long
|
public override val id: Long
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 昵称
|
* 昵称
|
||||||
*/
|
*/
|
||||||
public abstract val nick: String
|
public val nick: String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 日志记录器
|
* 日志记录器
|
||||||
*/
|
*/
|
||||||
public abstract val logger: MiraiLogger
|
public val logger: MiraiLogger
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断 Bot 是否在线 (可正常收发消息)
|
* 当 Bot 在线 (可正常收发消息) 时返回 `true`.
|
||||||
*/
|
*/
|
||||||
public abstract val isOnline: Boolean
|
public val isOnline: Boolean
|
||||||
|
|
||||||
// region contacts
|
// region contacts
|
||||||
|
|
||||||
@ -128,18 +76,18 @@ public abstract class Bot internal constructor(
|
|||||||
* [User.id] 与 [Bot.id] 相同的 [Friend] 实例
|
* [User.id] 与 [Bot.id] 相同的 [Friend] 实例
|
||||||
*/
|
*/
|
||||||
@MiraiExperimentalApi
|
@MiraiExperimentalApi
|
||||||
public abstract val asFriend: Friend
|
public val asFriend: Friend
|
||||||
|
|
||||||
@Deprecated("Use asFriend instead", ReplaceWith("asFriend"))
|
@Deprecated("Use asFriend instead", ReplaceWith("asFriend"))
|
||||||
@PlannedRemoval("2.0-M2")
|
@PlannedRemoval("2.0-M2")
|
||||||
public inline val selfQQ: Friend
|
public val selfQQ: Friend
|
||||||
get() = asFriend
|
get() = asFriend
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 好友列表. 与服务器同步更新.
|
* 好友列表. 与服务器同步更新.
|
||||||
*/
|
*/
|
||||||
public abstract val friends: ContactList<Friend>
|
public val friends: ContactList<Friend>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 以 [对方 QQ 号码][id] 获取一个好友对象, 在获取失败时返回 `null`.
|
* 以 [对方 QQ 号码][id] 获取一个好友对象, 在获取失败时返回 `null`.
|
||||||
@ -155,7 +103,7 @@ public abstract class Bot internal constructor(
|
|||||||
/**
|
/**
|
||||||
* 加入的群列表. 与服务器同步更新.
|
* 加入的群列表. 与服务器同步更新.
|
||||||
*/
|
*/
|
||||||
public abstract val groups: ContactList<Group>
|
public val groups: ContactList<Group>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 以 [群号码][id] 获取一个群对象, 在获取失败时返回 `null`.
|
* 以 [群号码][id] 获取一个群对象, 在获取失败时返回 `null`.
|
||||||
@ -180,7 +128,7 @@ public abstract class Bot internal constructor(
|
|||||||
* @see alsoLogin `.apply { login() }` 捷径
|
* @see alsoLogin `.apply { login() }` 捷径
|
||||||
*/
|
*/
|
||||||
@JvmBlockingBridge
|
@JvmBlockingBridge
|
||||||
public abstract suspend fun login()
|
public suspend fun login()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个 "戳一戳" 消息
|
* 创建一个 "戳一戳" 消息
|
||||||
@ -200,44 +148,149 @@ public abstract class Bot internal constructor(
|
|||||||
*
|
*
|
||||||
* @see closeAndJoin 取消并 [Bot.join], 以确保 [Bot] 相关的活动被完全关闭
|
* @see closeAndJoin 取消并 [Bot.join], 以确保 [Bot] 相关的活动被完全关闭
|
||||||
*/
|
*/
|
||||||
public abstract fun close(cause: Throwable? = null)
|
public fun close(cause: Throwable? = null)
|
||||||
|
|
||||||
public final override fun toString(): String = "Bot($id)"
|
|
||||||
|
public companion object {
|
||||||
|
@Suppress("ObjectPropertyName")
|
||||||
|
internal val _instances: WeakHashMap<Long, Bot> = WeakHashMap()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制一份此时的 [Bot] 实例列表.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
public val instances: List<Bot>
|
||||||
|
get() = _instances.values.filterNotNull()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制一份此时的 [Bot] 实例列表.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
public val instancesSequence: Sequence<Bot>
|
||||||
|
get() = _instances.values.asSequence().filterNotNull()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一个 [Bot] 实例, 无对应实例时抛出 [NoSuchElementException]
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@Throws(NoSuchElementException::class)
|
||||||
|
public fun getInstance(qq: Long): Bot =
|
||||||
|
findInstance(qq) ?: throw NoSuchElementException(qq.toString())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一个 [Bot] 实例, 无对应实例时返回 `null`
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
public inline fun getInstanceOrNull(qq: Long): Bot? = findInstance(qq)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一个 [Bot] 实例, 无对应实例时返回 `null`
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
public fun findInstance(qq: Long): Bot? = _instances[qq]
|
||||||
|
|
||||||
|
|
||||||
|
// deprecated
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 遍历每一个 [Bot] 实例
|
||||||
|
*/
|
||||||
|
@Deprecated(
|
||||||
|
"""
|
||||||
|
In Kotlin, use Sequence.forEach on instancesSequence.
|
||||||
|
In Java, use List.forEach on instances
|
||||||
|
""",
|
||||||
|
ReplaceWith("instancesSequence.forEach(block)", "net.mamoe.mirai.Bot.Companion.instancesSequence"),
|
||||||
|
DeprecationLevel.ERROR
|
||||||
|
)
|
||||||
|
@PlannedRemoval("2.0-M2")
|
||||||
|
public fun forEachInstance(block: (Bot) -> Unit): Unit = instancesSequence.forEach(block)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制一份此时的 [Bot] 实例列表.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@Deprecated(
|
||||||
|
"Use instances for shorter name.",
|
||||||
|
ReplaceWith("instances", "net.mamoe.mirai.Bot.Companion.instances"),
|
||||||
|
DeprecationLevel.ERROR
|
||||||
|
)
|
||||||
|
@PlannedRemoval("2.0-M2")
|
||||||
|
public val botInstances: List<Bot>
|
||||||
|
get() = instances
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制一份此时的 [Bot] 实例列表.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@Deprecated(
|
||||||
|
"Use instancesSequence for shorter name.",
|
||||||
|
ReplaceWith("instancesSequence", "net.mamoe.mirai.Bot.Companion.instancesSequence"),
|
||||||
|
DeprecationLevel.ERROR
|
||||||
|
)
|
||||||
|
@PlannedRemoval("2.0-M2")
|
||||||
|
public val botInstancesSequence: Sequence<Bot>
|
||||||
|
get() = instancesSequence
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 挂起协程直到 [Bot] 协程被关闭 ([Bot.close]).
|
||||||
|
* 即使 [Bot] 离线, 也会等待直到协程关闭.
|
||||||
|
*/
|
||||||
|
@JvmBlockingBridge
|
||||||
|
public suspend fun join(): Unit = supervisorJob.join()
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭这个 [Bot], 停止一切相关活动. 所有引用都会被释放.
|
||||||
|
*
|
||||||
|
* 注: 不可重新登录. 必须重新实例化一个 [Bot].
|
||||||
|
*
|
||||||
|
* @param cause 原因. 为 null 时视为正常关闭, 非 null 时视为异常关闭
|
||||||
|
*/
|
||||||
|
@JvmBlockingBridge
|
||||||
|
public suspend fun closeAndJoin(cause: Throwable? = null) {
|
||||||
|
close(cause)
|
||||||
|
join()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 [Job] 的协程 [Job]. 此 [Job] 为一个 [SupervisorJob]
|
* 获取 [Job] 的协程 [Job]. 此 [Job] 为一个 [SupervisorJob]
|
||||||
*/
|
*/
|
||||||
@get:JvmSynthetic
|
@get:JvmSynthetic
|
||||||
public val Bot.supervisorJob: CompletableJob
|
public inline val Bot.supervisorJob: CompletableJob
|
||||||
get() = this.coroutineContext[Job] as CompletableJob
|
get() = this.coroutineContext[Job] as CompletableJob
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 挂起协程直到 [Bot] 协程被关闭 ([Bot.close]).
|
* 当 [Bot] 拥有 [Friend.id] 为 [id] 的好友时返回 `true`.
|
||||||
* 即使 [Bot] 离线, 也会等待直到协程关闭.
|
|
||||||
*/
|
*/
|
||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
public suspend inline fun Bot.join(): Unit = this.coroutineContext[Job]!!.join()
|
public inline fun Bot.containsFriend(id: Long): Boolean = this.friends.contains(id)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭这个 [Bot], 停止一切相关活动. 所有引用都会被释放.
|
* 当 [Bot] 拥有 [Group.id] 为 [id] 的群时返回 `true`.
|
||||||
*
|
|
||||||
* 注: 不可重新登录. 必须重新实例化一个 [Bot].
|
|
||||||
*
|
|
||||||
* @param cause 原因. 为 null 时视为正常关闭, 非 null 时视为异常关闭
|
|
||||||
*/
|
*/
|
||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
|
public inline fun Bot.containsGroup(id: Long): Boolean = this.groups.contains(id)
|
||||||
|
|
||||||
|
|
||||||
|
// deprecated
|
||||||
|
|
||||||
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER") // source compatibility
|
||||||
|
@PlannedRemoval("2.0-M2")
|
||||||
|
@JvmSynthetic
|
||||||
|
public suspend inline fun Bot.join(): Unit = join()
|
||||||
|
|
||||||
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER") // source compatibility
|
||||||
|
@PlannedRemoval("2.0-M2")
|
||||||
|
@JvmSynthetic
|
||||||
public suspend inline fun Bot.closeAndJoin(cause: Throwable? = null) {
|
public suspend inline fun Bot.closeAndJoin(cause: Throwable? = null) {
|
||||||
close(cause)
|
close(cause)
|
||||||
coroutineContext[Job]?.join()
|
coroutineContext[Job]?.join()
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmSynthetic
|
|
||||||
public inline fun Bot.containsFriend(id: Long): Boolean = this.friends.contains(id)
|
|
||||||
|
|
||||||
@JvmSynthetic
|
|
||||||
public inline fun Bot.containsGroup(id: Long): Boolean = this.groups.contains(id)
|
|
||||||
|
|
||||||
@Deprecated("Use getFriend", ReplaceWith("this.getFriend(id)"))
|
@Deprecated("Use getFriend", ReplaceWith("this.getFriend(id)"))
|
||||||
@PlannedRemoval("2.0-M2")
|
@PlannedRemoval("2.0-M2")
|
||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
|
@ -142,7 +142,7 @@ public interface Image : Message, MessageContent, CodableMessage {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmBlockingBridge
|
@JvmBlockingBridge
|
||||||
public suspend fun Image.queryUrl(): String {
|
public suspend fun Image.queryUrl(): String {
|
||||||
val bot = Bot._instances.peekFirst()?.get() ?: error("No Bot available to query image url")
|
val bot = Bot.instancesSequence.firstOrNull() ?: error("No Bot available to query image url")
|
||||||
return Mirai.queryImageUrl(bot, this)
|
return Mirai.queryImageUrl(bot, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +36,32 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
import kotlin.time.ExperimentalTime
|
import kotlin.time.ExperimentalTime
|
||||||
import kotlin.time.measureTime
|
import kotlin.time.measureTime
|
||||||
|
|
||||||
internal abstract class BotImpl<N : BotNetworkHandler> constructor(
|
internal abstract class AbstractBot<N : BotNetworkHandler> constructor(
|
||||||
configuration: BotConfiguration
|
final override val configuration: BotConfiguration,
|
||||||
) : Bot(configuration), CoroutineScope {
|
final override val id: Long,
|
||||||
|
) : Bot, CoroutineScope {
|
||||||
|
// FASTEST INIT
|
||||||
|
init {
|
||||||
|
Bot._instances[this.id] = this
|
||||||
|
supervisorJob.invokeOnCompletion {
|
||||||
|
Bot._instances.remove(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final override val logger: MiraiLogger by lazy { configuration.botLoggerSupplier(this) }
|
final override val logger: MiraiLogger by lazy { configuration.botLoggerSupplier(this) }
|
||||||
|
|
||||||
|
|
||||||
|
final override val coroutineContext: CoroutineContext = // for id
|
||||||
|
configuration.parentCoroutineContext
|
||||||
|
.plus(SupervisorJob(configuration.parentCoroutineContext[Job]))
|
||||||
|
.plus(configuration.parentCoroutineContext[CoroutineExceptionHandler]
|
||||||
|
?: CoroutineExceptionHandler { _, e ->
|
||||||
|
logger.error("An exception was thrown under a coroutine of Bot", e)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.plus(CoroutineName("Mirai Bot"))
|
||||||
|
|
||||||
|
|
||||||
// region network
|
// region network
|
||||||
|
|
||||||
val network: N get() = _network
|
val network: N get() = _network
|
||||||
@ -60,8 +81,8 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
@OptIn(ExperimentalTime::class)
|
@OptIn(ExperimentalTime::class)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
private val offlineListener: Listener<BotOfflineEvent> =
|
private val offlineListener: Listener<BotOfflineEvent> =
|
||||||
this@BotImpl.subscribeAlways(concurrency = Listener.ConcurrencyKind.LOCKED) { event ->
|
this@AbstractBot.subscribeAlways(concurrency = Listener.ConcurrencyKind.LOCKED) { event ->
|
||||||
if (event.bot != this@BotImpl) {
|
if (event.bot != this@AbstractBot) {
|
||||||
return@subscribeAlways
|
return@subscribeAlways
|
||||||
}
|
}
|
||||||
if (!event.bot.isActive) {
|
if (!event.bot.isActive) {
|
||||||
@ -107,7 +128,7 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
}
|
}
|
||||||
network.withConnectionLock {
|
network.withConnectionLock {
|
||||||
/**
|
/**
|
||||||
* [BotImpl.relogin] only, no [BotNetworkHandler.init]
|
* [AbstractBot.relogin] only, no [BotNetworkHandler.init]
|
||||||
*/
|
*/
|
||||||
@OptIn(ThisApiMustBeUsedInWithConnectionLockBlock::class)
|
@OptIn(ThisApiMustBeUsedInWithConnectionLockBlock::class)
|
||||||
relogin((event as? BotOfflineEvent.Dropped)?.cause)
|
relogin((event as? BotOfflineEvent.Dropped)?.cause)
|
||||||
@ -161,7 +182,7 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* **Exposed public API**
|
* **Exposed public API**
|
||||||
* [BotImpl.relogin] && [BotNetworkHandler.init]
|
* [AbstractBot.relogin] && [BotNetworkHandler.init]
|
||||||
*/
|
*/
|
||||||
final override suspend fun login() {
|
final override suspend fun login() {
|
||||||
@ThisApiMustBeUsedInWithConnectionLockBlock
|
@ThisApiMustBeUsedInWithConnectionLockBlock
|
||||||
@ -266,7 +287,7 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
runCatching { BotOfflineEvent.Active(this@BotImpl, cause).broadcast() }.exceptionOrNull()
|
runCatching { BotOfflineEvent.Active(this@AbstractBot, cause).broadcast() }.exceptionOrNull()
|
||||||
?.let { logger.error(it) }
|
?.let { logger.error(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,6 +299,8 @@ internal abstract class BotImpl<N : BotNetworkHandler> constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final override fun toString(): String = "Bot($id)"
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
@ -42,25 +42,16 @@ internal fun Bot.asQQAndroidBot(): QQAndroidBot {
|
|||||||
internal class QQAndroidBot constructor(
|
internal class QQAndroidBot constructor(
|
||||||
account: BotAccount,
|
account: BotAccount,
|
||||||
configuration: BotConfiguration
|
configuration: BotConfiguration
|
||||||
) : QQAndroidBotBase(account, configuration)
|
) : AbstractBot<QQAndroidBotNetworkHandler>(configuration, account.id) {
|
||||||
|
|
||||||
|
|
||||||
internal abstract class QQAndroidBotBase constructor(
|
|
||||||
private val account: BotAccount,
|
|
||||||
configuration: BotConfiguration
|
|
||||||
) : BotImpl<QQAndroidBotNetworkHandler>(configuration) {
|
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
val client: QQAndroidClient =
|
val client: QQAndroidClient =
|
||||||
QQAndroidClient(
|
QQAndroidClient(
|
||||||
account,
|
account,
|
||||||
bot = this as QQAndroidBot,
|
bot = this,
|
||||||
device = configuration.deviceInfo?.invoke(this) ?: DeviceInfo.random()
|
device = configuration.deviceInfo?.invoke(this) ?: DeviceInfo.random()
|
||||||
)
|
)
|
||||||
internal var firstLoginSucceed: Boolean = false
|
internal var firstLoginSucceed: Boolean = false
|
||||||
|
|
||||||
override val id: Long
|
|
||||||
get() = account.id
|
|
||||||
|
|
||||||
inline val json get() = configuration.json
|
inline val json get() = configuration.json
|
||||||
|
|
||||||
override val friends: ContactList<Friend> = ContactList()
|
override val friends: ContactList<Friend> = ContactList()
|
||||||
@ -78,12 +69,14 @@ internal abstract class QQAndroidBotBase constructor(
|
|||||||
override val asFriend: Friend by lazy {
|
override val asFriend: Friend by lazy {
|
||||||
@OptIn(LowLevelApi::class)
|
@OptIn(LowLevelApi::class)
|
||||||
Mirai._lowLevelNewFriend(this, object : FriendInfo {
|
Mirai._lowLevelNewFriend(this, object : FriendInfo {
|
||||||
override val uin: Long get() = this@QQAndroidBotBase.id
|
override val uin: Long get() = this@QQAndroidBot.id
|
||||||
override val nick: String get() = this@QQAndroidBotBase.nick
|
override val nick: String get() = this@QQAndroidBot.nick
|
||||||
override val remark: String get() = ""
|
override val remark: String get() = ""
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val groups: ContactList<Group> = ContactList()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Final process for 'login'
|
* Final process for 'login'
|
||||||
*/
|
*/
|
||||||
@ -96,11 +89,9 @@ internal abstract class QQAndroidBotBase constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createNetworkHandler(coroutineContext: CoroutineContext): QQAndroidBotNetworkHandler {
|
override fun createNetworkHandler(coroutineContext: CoroutineContext): QQAndroidBotNetworkHandler {
|
||||||
return QQAndroidBotNetworkHandler(coroutineContext, this as QQAndroidBot)
|
return QQAndroidBotNetworkHandler(coroutineContext, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val groups: ContactList<Group> = ContactList()
|
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val groupListModifyLock = Mutex()
|
val groupListModifyLock = Mutex()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user