1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-03 14:20:10 +08:00

Initialize and register configs in a specific phase, store and retrieve then in DataScope, instead of making them objects.

This commit is contained in:
Him188 2022-02-17 16:54:28 +00:00
parent 835059c44c
commit 062a644474
12 changed files with 113 additions and 66 deletions

View File

@ -38,12 +38,14 @@ import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.NotStableForInheritance
import java.nio.file.Path
import java.util.*
import java.util.concurrent.locks.ReentrantLock
import kotlin.annotation.AnnotationTarget.*
import kotlin.concurrent.thread
import kotlin.coroutines.CoroutineContext
import kotlin.reflect.KClass
/**
@ -227,7 +229,7 @@ public interface MiraiConsoleImplementation : CoroutineScope {
/**
* 前端预先定义的 [LoggerController], 以允许前端使用自己的配置系统
*/
public val loggerController: LoggerController get() = LoggerControllerImpl
public val loggerController: LoggerController get() = LoggerControllerImpl()
///////////////////////////////////////////////////////////////////////////
// ConsoleDataScope
@ -257,17 +259,40 @@ public interface MiraiConsoleImplementation : CoroutineScope {
* @since 2.10.0-RC
*/
@ConsoleFrontEndImplementation
@NotStableForInheritance
public interface ConsoleDataScope {
public val dataHolder: AutoSavePluginDataHolder
public val configHolder: AutoSavePluginDataHolder
public fun addAndReloadConfig(config: PluginConfig)
/**
* @since 2.11.0-RC
*/
public fun <T : PluginData> find(type: KClass<T>): T?
/**
* @since 2.11.0-RC
*/
public fun <T : PluginData> get(type: KClass<T>): T =
find(type) ?: throw NoSuchElementException(type.qualifiedName)
public fun reloadAll()
/**
* @since 2.10.0-RCl
* @since 2.10.0-RC
*/
@ConsoleFrontEndImplementation
public companion object {
/**
* @since 2.11.0-RC
*/
public inline fun <reified T : PluginData> ConsoleDataScope.find(): T? = find(T::class)
/**
* @since 2.11.0-RC
*/
public inline fun <reified T : PluginData> ConsoleDataScope.get(): T = get(T::class)
@JvmStatic
public fun createDefault(
coroutineContext: CoroutineContext,

View File

@ -15,6 +15,7 @@ import kotlinx.coroutines.sync.withLock
import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.MiraiConsoleImplementation
import net.mamoe.mirai.console.MiraiConsoleImplementation.ConsoleDataScope.Companion.get
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.allRegisteredCommands
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
import net.mamoe.mirai.console.command.descriptor.CommandArgumentParserException
@ -28,6 +29,7 @@ import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.*
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.MD5
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.PLAIN
import net.mamoe.mirai.console.internal.data.builtins.DataScope
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
import net.mamoe.mirai.console.internal.pluginManagerImpl
@ -203,7 +205,8 @@ public object BuiltInCommands {
}
suspend fun getPassword(id: Long): Any? {
val acc = AutoLoginConfig.accounts.firstOrNull { it.account == id.toString() }
val config = DataScope.get<AutoLoginConfig>()
val acc = config.accounts.firstOrNull { it.account == id.toString() }
if (acc == null) {
sendMessage("Could not find '$id' in AutoLogin config. Please specify password.")
return null
@ -321,8 +324,9 @@ public object BuiltInCommands {
@Description("查看自动登录账号列表")
@SubCommand
public suspend fun CommandSender.list() {
val config = DataScope.get<AutoLoginConfig>()
sendMessage(buildString {
for (account in AutoLoginConfig.accounts) {
for (account in config.accounts) {
if (account.account == "123456") continue
append("- ")
append("账号: ")
@ -346,27 +350,30 @@ public object BuiltInCommands {
@Description("添加自动登录, passwordKind 可选 PLAIN 或 MD5")
@SubCommand
public suspend fun CommandSender.add(account: Long, password: String, passwordKind: PasswordKind = PLAIN) {
val config = DataScope.get<AutoLoginConfig>()
val accountStr = account.toString()
if (AutoLoginConfig.accounts.any { it.account == accountStr }) {
if (config.accounts.any { it.account == accountStr }) {
sendMessage("已有相同账号在自动登录配置中. 请先删除该账号.")
return
}
AutoLoginConfig.accounts.add(AutoLoginConfig.Account(accountStr, Password(passwordKind, password)))
config.accounts.add(AutoLoginConfig.Account(accountStr, Password(passwordKind, password)))
sendMessage("已成功添加 '$account'.")
}
@Description("清除所有配置")
@SubCommand
public suspend fun CommandSender.clear() {
AutoLoginConfig.accounts.clear()
val config = DataScope.get<AutoLoginConfig>()
config.accounts.clear()
sendMessage("已清除所有自动登录配置.")
}
@Description("删除一个账号")
@SubCommand
public suspend fun CommandSender.remove(account: Long) {
val config = DataScope.get<AutoLoginConfig>()
val accountStr = account.toString()
if (AutoLoginConfig.accounts.removeIf { it.account == accountStr }) {
if (config.accounts.removeIf { it.account == accountStr }) {
sendMessage("已成功删除 '$account'.")
return
}
@ -376,9 +383,10 @@ public object BuiltInCommands {
@Description("设置一个账号的一个配置项")
@SubCommand
public suspend fun CommandSender.setConfig(account: Long, configKey: ConfigurationKey, value: String) {
val config = DataScope.get<AutoLoginConfig>()
val accountStr = account.toString()
val oldAccount = AutoLoginConfig.accounts.find { it.account == accountStr } ?: kotlin.run {
val oldAccount = config.accounts.find { it.account == accountStr } ?: kotlin.run {
sendMessage("未找到账号 $account.")
return
}
@ -389,8 +397,8 @@ public object BuiltInCommands {
put(configKey, value)
})
AutoLoginConfig.accounts.remove(oldAccount)
AutoLoginConfig.accounts.add(newAccount)
config.accounts.remove(oldAccount)
config.accounts.add(newAccount)
sendMessage("成功修改 '$account' 的配置 '$configKey' 为 '$value'")
}
@ -398,9 +406,10 @@ public object BuiltInCommands {
@Description("删除一个账号的一个配置项")
@SubCommand
public suspend fun CommandSender.removeConfig(account: Long, configKey: ConfigurationKey) {
val config = DataScope.get<AutoLoginConfig>()
val accountStr = account.toString()
val oldAccount = AutoLoginConfig.accounts.find { it.account == accountStr } ?: kotlin.run {
val oldAccount = config.accounts.find { it.account == accountStr } ?: kotlin.run {
sendMessage("未找到账号 $account.")
return
}
@ -409,8 +418,8 @@ public object BuiltInCommands {
remove(configKey)
})
AutoLoginConfig.accounts.remove(oldAccount)
AutoLoginConfig.accounts.add(newAccount)
config.accounts.remove(oldAccount)
config.accounts.add(newAccount)
sendMessage("成功删除 '$account' 的配置 '$configKey'.")
}

View File

@ -19,6 +19,7 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.MalformedMiraiConsoleImplementationError
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.MiraiConsoleImplementation
import net.mamoe.mirai.console.MiraiConsoleImplementation.ConsoleDataScope.Companion.get
import net.mamoe.mirai.console.command.BuiltInCommands
import net.mamoe.mirai.console.command.CommandManager
import net.mamoe.mirai.console.command.ConsoleCommandSender
@ -34,7 +35,8 @@ import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.ConfigurationKey
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.MD5
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig.Account.PasswordKind.PLAIN
import net.mamoe.mirai.console.internal.data.builtins.LoggerConfig
import net.mamoe.mirai.console.internal.data.builtins.DataScope
import net.mamoe.mirai.console.internal.data.builtins.PluginDependenciesConfig
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorageImpl
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
@ -115,14 +117,6 @@ internal class MiraiConsoleImplementationBridge(
}
}
phase("setup logger controller") {
if (loggerController === LoggerControllerImpl) {
// Reload LoggerConfig.
consoleDataScope.addAndReloadConfig(LoggerConfig)
LoggerControllerImpl.initialized = true
}
}
phase("greeting") {
val buildDateFormatted =
buildDate.atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
@ -152,7 +146,13 @@ internal class MiraiConsoleImplementationBridge(
phase("load configurations") {
mainLogger.verbose { "Loading configurations..." }
consoleDataScope.addAndReloadConfig(CommandConfig)
consoleDataScope.addAndReloadConfig(AutoLoginConfig())
consoleDataScope.addAndReloadConfig(CommandConfig())
consoleDataScope.addAndReloadConfig(PluginDependenciesConfig())
val loggerController = loggerController
if (loggerController is LoggerControllerImpl) {
consoleDataScope.addAndReloadConfig(loggerController.loggerConfig)
}
consoleDataScope.reloadAll()
}
@ -227,7 +227,8 @@ internal class MiraiConsoleImplementationBridge(
phase("auto-login bots") {
runBlocking {
val accounts = AutoLoginConfig.accounts.toList()
val config = DataScope.get<AutoLoginConfig>()
val accounts = config.accounts.toList()
for (account in accounts.filter {
it.configuration[ConfigurationKey.enable]?.toString()?.equals("true", true) ?: true
}) {

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.console.internal.command
@ -12,6 +12,7 @@ package net.mamoe.mirai.console.internal.command
import kotlinx.atomicfu.locks.withLock
import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.MiraiConsoleImplementation.ConsoleDataScope.Companion.get
import net.mamoe.mirai.console.command.*
import net.mamoe.mirai.console.command.Command.Companion.allNames
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.findDuplicate
@ -21,12 +22,12 @@ import net.mamoe.mirai.console.command.parse.CommandCallParser.Companion.parseCo
import net.mamoe.mirai.console.command.resolve.CommandCallInterceptor.Companion.intercepted
import net.mamoe.mirai.console.command.resolve.CommandCallResolver.Companion.resolve
import net.mamoe.mirai.console.command.resolve.getOrElse
import net.mamoe.mirai.console.internal.data.builtins.DataScope
import net.mamoe.mirai.console.internal.util.ifNull
import net.mamoe.mirai.console.permission.PermissionService.Companion.testPermission
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.toMessageChain
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.castOrNull
import net.mamoe.mirai.utils.childScope
import java.util.concurrent.locks.ReentrantLock
import kotlin.coroutines.CoroutineContext
@ -69,7 +70,7 @@ internal class CommandManagerImpl(
_registeredCommands.filter { it.owner == owner }
override val allRegisteredCommands: List<Command> get() = _registeredCommands.toList() // copy
override val commandPrefix: String get() = CommandConfig.commandPrefix
override val commandPrefix: String get() = DataScope.get<CommandConfig>().commandPrefix
override fun unregisterAllCommands(owner: CommandOwner) {
for (registeredCommand in getRegisteredCommands(owner)) {
unregisterCommand(registeredCommand)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -19,7 +19,7 @@ import net.mamoe.mirai.console.data.value
内置指令系统配置
"""
)
internal object CommandConfig : ReadOnlyPluginConfig("Command") {
internal class CommandConfig : ReadOnlyPluginConfig("Command") {
@ValueDescription(
"""
指令前缀, 默认 "/"

View File

@ -1,10 +1,10 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:Suppress("EXPOSED_SUPER_CLASS")
@ -21,13 +21,12 @@ import net.mamoe.mirai.console.data.ValueDescription
import net.mamoe.mirai.console.data.value
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
import net.mamoe.mirai.utils.SecretsProtection
import net.mamoe.mirai.utils.readString
import net.mamoe.yamlkt.Comment
import net.mamoe.yamlkt.YamlDynamicSerializer
@ConsoleExperimentalApi
@ValueDescription("自动登录配置")
public object AutoLoginConfig : AutoSavePluginConfig("AutoLogin") {
public class AutoLoginConfig : AutoSavePluginConfig("AutoLogin") {
@Serializable
public data class Account(

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -17,28 +17,34 @@ import net.mamoe.mirai.console.data.PluginData
import net.mamoe.mirai.console.data.PluginDataStorage
import net.mamoe.mirai.utils.childScope
import net.mamoe.mirai.utils.minutesToMillis
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.coroutines.CoroutineContext
import kotlin.reflect.KClass
internal val DataScope get() = MiraiConsoleImplementation.getBridge().consoleDataScope
internal class ConsoleDataScopeImpl(
parentCoroutineContext: CoroutineContext,
private val dataStorage: PluginDataStorage,
private val configStorage: PluginDataStorage,
) : CoroutineScope by parentCoroutineContext.childScope("ConsoleDataScope"), MiraiConsoleImplementation.ConsoleDataScope {
) : CoroutineScope by parentCoroutineContext.childScope("ConsoleDataScope"),
MiraiConsoleImplementation.ConsoleDataScope {
override val dataHolder: AutoSavePluginDataHolder = ConsoleBuiltInPluginDataHolder(this.coroutineContext)
override val configHolder: AutoSavePluginDataHolder = ConsoleBuiltInPluginConfigHolder(this.coroutineContext)
private val data: List<PluginData> = mutableListOf()
private val configs: MutableList<PluginConfig> = mutableListOf(
AutoLoginConfig,
PluginDependenciesConfig,
)
private val data: MutableCollection<PluginData> = ConcurrentLinkedQueue() // tentatively make it thread-safe
private val configs: MutableCollection<PluginConfig> = ConcurrentLinkedQueue()
override fun addAndReloadConfig(config: PluginConfig) {
configs.add(config)
configStorage.load(configHolder, config)
}
override fun <T : PluginData> find(type: KClass<T>): T? {
@Suppress("UNCHECKED_CAST")
return (data.find { type.isInstance(it) } ?: configs.find { type.isInstance(it) }) as T?
}
override fun reloadAll() {
data.forEach { dt ->
dataStorage.load(dataHolder, dt)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -9,25 +9,29 @@
package net.mamoe.mirai.console.internal.data.builtins
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.data.ReadOnlyPluginConfig
import net.mamoe.mirai.console.data.ValueDescription
import net.mamoe.mirai.console.data.value
import net.mamoe.mirai.console.logging.AbstractLoggerController
import net.mamoe.mirai.utils.MiraiExperimentalApi
internal object LoggerConfig : ReadOnlyPluginConfig("Logger") {
@ConsoleFrontEndImplementation
@MiraiExperimentalApi
public class LoggerConfig : ReadOnlyPluginConfig("Logger") {
@ValueDescription(
"""
日志输出等级 可选值: ALL, VERBOSE, DEBUG, INFO, WARNING, ERROR, NONE
"""
)
val defaultPriority by value(AbstractLoggerController.LogPriority.INFO)
public val defaultPriority: AbstractLoggerController.LogPriority by value(AbstractLoggerController.LogPriority.INFO)
@ValueDescription(
"""
特定日志记录器输出等级
"""
)
val loggers: Map<String, AbstractLoggerController.LogPriority> by value(
public val loggers: Map<String, AbstractLoggerController.LogPriority> by value(
mapOf(
"example.logger" to AbstractLoggerController.LogPriority.NONE,
"console.debug" to AbstractLoggerController.LogPriority.NONE,

View File

@ -14,7 +14,7 @@ import net.mamoe.mirai.console.data.ValueDescription
import net.mamoe.mirai.console.data.value
@Suppress("RemoveExplicitTypeArguments")
internal object PluginDependenciesConfig : ReadOnlyPluginConfig("PluginDependencies") {
internal class PluginDependenciesConfig : ReadOnlyPluginConfig("PluginDependencies") {
@ValueDescription("远程仓库, 如无必要无需修改")
val repoLoc by value(listOf<String>("https://maven.aliyun.com/repository/public"))
}

View File

@ -9,8 +9,8 @@
package net.mamoe.mirai.console.internal.extension
import net.mamoe.mirai.console.MiraiConsoleImplementation
import net.mamoe.mirai.console.extension.*
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
import net.mamoe.mirai.console.internal.data.kClassQualifiedNameOrTip
import net.mamoe.mirai.console.plugin.Plugin
import net.mamoe.mirai.console.plugin.name
@ -22,7 +22,7 @@ import kotlin.contracts.contract
internal class GlobalComponentStorageImpl : AbstractConcurrentComponentStorage()
// source compatibility for <2.11
internal val GlobalComponentStorage get() = MiraiConsoleImplementationBridge.globalComponentStorage
internal val GlobalComponentStorage get() = MiraiConsoleImplementation.getBridge().globalComponentStorage
/**
* thread-safe.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -9,25 +9,24 @@
package net.mamoe.mirai.console.internal.logging
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.internal.data.builtins.LoggerConfig
import net.mamoe.mirai.console.logging.AbstractLoggerController
import net.mamoe.mirai.console.util.ConsoleInternalApi
@ConsoleFrontEndImplementation
@ConsoleInternalApi
internal object LoggerControllerImpl : AbstractLoggerController.PathBased() {
internal var initialized = false
internal class LoggerControllerImpl : AbstractLoggerController.PathBased() {
// 防止 stack overflow (使用 logger 要加载 LoggerController, LoggerConfig 可能会使用 logger)
// 在 console init 阶段 register
internal val loggerConfig: LoggerConfig by lazy {
LoggerConfig()
}
override fun findPriority(identity: String?): LogPriority? {
if (!initialized) return LogPriority.NONE
return if (identity == null) {
LoggerConfig.defaultPriority
loggerConfig.defaultPriority
} else {
LoggerConfig.loggers[identity]
loggerConfig.loggers[identity]
}
}
override val defaultPriority: LogPriority
get() = if (initialized) LoggerConfig.defaultPriority else LogPriority.NONE
get() = loggerConfig.defaultPriority
}

View File

@ -9,7 +9,9 @@
package net.mamoe.mirai.console.internal.plugin
import net.mamoe.mirai.console.MiraiConsoleImplementation.ConsoleDataScope.Companion.get
import net.mamoe.mirai.console.internal.MiraiConsoleBuildDependencies
import net.mamoe.mirai.console.internal.data.builtins.DataScope
import net.mamoe.mirai.console.internal.data.builtins.PluginDependenciesConfig
import net.mamoe.mirai.console.plugin.PluginManager
import net.mamoe.mirai.utils.MiraiLogger
@ -193,13 +195,14 @@ internal class JvmPluginDependencyDownloader(
}
session.setReadOnly()
val config = DataScope.get<PluginDependenciesConfig>()
repositories = repository.newResolutionRepositories(
session,
PluginDependenciesConfig.repoLoc.map { url ->
config.repoLoc.map { url ->
RemoteRepository.Builder(null, "default", url).build()
}
)
logger.debug { "Remote server: " + PluginDependenciesConfig.repoLoc }
logger.debug { "Remote server: " + config.repoLoc }
}
public fun resolveDependencies(deps: Collection<String>, vararg filters: DependencyFilter): DependencyResult {