smart config

This commit is contained in:
jiahua.liu 2020-02-13 00:10:59 +08:00
parent ab3d524dea
commit 55e70bd3c3
5 changed files with 61 additions and 29 deletions

View File

@ -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
}

View File

@ -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 已随机生成, 请注意修改")
}
}
}
}

View File

@ -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)
}
}

View File

@ -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))
}

View File

@ -74,8 +74,3 @@ actual fun ByteArray.unzip(offset: Int, length: Int): ByteArray {
return output.toByteArray()
}
}
/**
* 时间戳
*/
actual val currentTimeMillis: Long get() = System.currentTimeMillis()