From 55e70bd3c3002850df1388163abd9488e9829049 Mon Sep 17 00:00:00 2001 From: "jiahua.liu" <n@mamoe.net> Date: Thu, 13 Feb 2020 00:10:59 +0800 Subject: [PATCH] smart config --- mirai-console/build.gradle.kts | 1 + mirai-console/src/main/kotlin/MiraiConsole.kt | 21 ++++++-- .../net/mamoe/mirai/plugin/ConfigSection.kt | 52 +++++++++++++++---- .../net/mamoe/mirai/plugin/PluginBase.kt | 11 +--- .../net/mamoe/mirai/utils/PlatformUtilsJvm.kt | 5 -- 5 files changed, 61 insertions(+), 29 deletions(-) diff --git a/mirai-console/build.gradle.kts b/mirai-console/build.gradle.kts index 34c4dc570..9793ad677 100644 --- a/mirai-console/build.gradle.kts +++ b/mirai-console/build.gradle.kts @@ -29,5 +29,6 @@ dependencies { runtimeOnly(files("../mirai-core-qqandroid/build/classes/kotlin/jvm/main")) runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main")) api(kotlin("serialization")) + api(group = "com.alibaba", name = "fastjson", version = "1.2.62") // classpath is not set correctly by IDE } \ No newline at end of file diff --git a/mirai-console/src/main/kotlin/MiraiConsole.kt b/mirai-console/src/main/kotlin/MiraiConsole.kt index 1cd97a72e..20c177d7d 100644 --- a/mirai-console/src/main/kotlin/MiraiConsole.kt +++ b/mirai-console/src/main/kotlin/MiraiConsole.kt @@ -45,9 +45,11 @@ object MiraiConsole { logger("\"/login qqnumber qqpassword \" to login a bot") logger("\"/login qq号 qq密码 \" 来登陆一个BOT") + MiraiProperties() CommandManager.register(DefaultCommands.DefaultLoginCommand()) pluginManager.loadPlugins() CommandListener.start() + println(MiraiProperties.HTTP_API_ENABLE) } fun stop() { @@ -80,6 +82,7 @@ object MiraiConsole { return true } } + } object CommandListener { @@ -107,17 +110,29 @@ object MiraiConsole { object DefaultLogger : MiraiConsoleLogger { override fun invoke(any: Any?) { - println("[Mirai${version} $build]: " + any?.toString()) + if (any != null) { + println("[Mirai${version} $build]: " + any.toString()) + } } } - @UnstableDefault object MiraiProperties { + val init = !File("$path/mirai.json").exists() + var config = Config.load("$path/mirai.json") var HTTP_API_ENABLE: Boolean by config.withDefault { true } var HTTP_API_PORT: Int by config.withDefault { 8080 } - var HTTP_API_AUTH_KEY: String by config.withDefault { "INITKEY" + generateSessionKey() } + var HTTP_API_AUTH_KEY: String by config + + operator fun invoke() { + if (init) { + HTTP_API_AUTH_KEY = "INITKEY" + generateSessionKey() + logger("Mirai HTTPAPI authkey 已随机生成, 请注意修改") + } + } + + } } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/ConfigSection.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/ConfigSection.kt index d29736bc4..f361d7b67 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/ConfigSection.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/ConfigSection.kt @@ -9,15 +9,21 @@ package net.mamoe.mirai.plugin -import kotlinx.serialization.Serializable -import kotlinx.serialization.UnstableDefault +import com.alibaba.fastjson.JSON +import com.alibaba.fastjson.JSONObject +import com.alibaba.fastjson.TypeReference +import com.alibaba.fastjson.parser.Feature +import kotlinx.serialization.* import kotlinx.serialization.json.Json +import net.mamoe.mirai.utils.cryptor.contentToString import java.io.File import java.util.concurrent.ConcurrentHashMap +import java.util.function.BiConsumer import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty import kotlin.reflect.full.isSubclassOf + /** * TODO: support all config types * only JSON is now supported @@ -31,6 +37,7 @@ interface Config { fun getFloat(key: String): Float fun getDouble(key: String): Double fun getLong(key: String): Long + fun getBoolean(key: String): Boolean fun getList(key: String): List<*> fun getStringList(key: String): List<String> fun getIntList(key: String): List<Int> @@ -69,7 +76,7 @@ inline fun <reified T : Any> Config.withDefault( if (!this@withDefault.exist(property.name)) { return defaultValue.invoke() } - return getValue(thisRef, property) + return smartCast(property) } override fun setValue(thisRef: Any, property: KProperty<*>, value: T) { @@ -80,13 +87,14 @@ inline fun <reified T : Any> Config.withDefault( } @Suppress("IMPLICIT_CAST_TO_ANY") -inline operator fun <reified T> Config.getValue(thisRef: Any?, property: KProperty<*>): T { +inline fun <reified T> Config.smartCast(property: KProperty<*>): T { return when (T::class) { String::class -> this.getString(property.name) Int::class -> this.getInt(property.name) Float::class -> this.getFloat(property.name) Double::class -> this.getDouble(property.name) Long::class -> this.getLong(property.name) + Boolean::class -> this.getBoolean(property.name) else -> when { T::class.isSubclassOf(ConfigSection::class) -> this.getConfigSection(property.name) T::class == List::class || T::class == MutableList::class -> { @@ -113,8 +121,13 @@ inline operator fun <reified T> Config.getValue(thisRef: Any?, property: KProper } as T } +inline operator fun <reified T> Config.getValue(thisRef: Any?, property: KProperty<*>): T { + return smartCast(property) +} + inline operator fun <reified T> Config.setValue(thisRef: Any?, property: KProperty<*>, value: T) { this[property.name] = value!! + this.save() } @@ -135,6 +148,10 @@ interface ConfigSection : Config { return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toFloat() } + override fun getBoolean(key: String): Boolean { + return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toBoolean() + } + override fun getDouble(key: String): Double { return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toDouble() } @@ -175,7 +192,7 @@ interface ConfigSection : Config { @Serializable open class ConfigSectionImpl() : ConcurrentHashMap<String, Any>(), ConfigSection { override fun set(key: String, value: Any) { - this[key] = value + this.put(key, value) } override operator fun get(key: String): Any? { @@ -238,17 +255,30 @@ class JsonConfig internal constructor(file: File) : FileConfigImpl(file) { if (content.isEmpty() || content.isBlank() || content == "{}") { return ConfigSectionImpl() } - return Json.parse( - ConfigSectionImpl.serializer(), - content + val section = ConfigSectionImpl() + val map: LinkedHashMap<String, Any> = JSON.parseObject( + content, + object : TypeReference<LinkedHashMap<String, Any>>() {}, + Feature.OrderedField ) + map.forEach { (t, u) -> + section[t] = u + } + return section } @UnstableDefault override fun serialize(config: ConfigSectionImpl): String { - if (config.isEmpty()) { - return "{}" + return JSONObject.toJSONString(config) + } + + internal class AnySerializer(override val descriptor: SerialDescriptor) : KSerializer<Any> { + override fun deserialize(decoder: Decoder): Any { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun serialize(encoder: Encoder, obj: Any) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } - return Json.stringify(ConfigSectionImpl.serializer(), config) } } \ No newline at end of file diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt index 0975192e3..d4cbc60ef 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugin/PluginBase.kt @@ -67,18 +67,9 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope { this.onEnable() } - /** - * TODO: support all config types - */ - @UnstableDefault fun loadConfig(fileName: String): Config { - return JsonConfig.load(File(fileName)) - } - - @UnstableDefault - fun saveConfig(config: Config, fileName: String = "config.json") { - JsonConfig.save(file = File(fileName), config = config as JsonConfig) + return Config.load(File(fileName)) } diff --git a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/PlatformUtilsJvm.kt b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/PlatformUtilsJvm.kt index 840072726..d952acdba 100644 --- a/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/PlatformUtilsJvm.kt +++ b/mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/PlatformUtilsJvm.kt @@ -74,8 +74,3 @@ actual fun ByteArray.unzip(offset: Int, length: Int): ByteArray { return output.toByteArray() } } - -/** - * 时间戳 - */ -actual val currentTimeMillis: Long get() = System.currentTimeMillis() \ No newline at end of file