diff --git a/mirai-console/build.gradle.kts b/mirai-console/build.gradle.kts index 1ce7990b8..1a896636a 100644 --- a/mirai-console/build.gradle.kts +++ b/mirai-console/build.gradle.kts @@ -40,5 +40,7 @@ dependencies { runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main")) api(kotlin("serialization")) api(group = "com.alibaba", name = "fastjson", version = "1.2.62") + api(group = "org.yaml", name = "snakeyaml", version = "1.25") + api(group = "com.moandjiezana.toml", name = "toml4j", version = "0.7.2") // classpath is not set correctly by IDE } \ No newline at end of file diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsole.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsole.kt index f65894d66..5a65dc299 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsole.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/MiraiConsole.kt @@ -267,7 +267,7 @@ object MiraiConsole { } object MiraiProperties { - var config = File("$path/mirai.json").loadAsConfig() + var config = File("$path/mirai.properties").loadAsConfig() var HTTP_API_ENABLE: Boolean by config.withDefaultWrite { true } var HTTP_API_PORT: Int by config.withDefaultWrite { 8080 } diff --git a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugins/ConfigSection.kt b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugins/ConfigSection.kt index 5c6b26c66..41991dfb2 100644 --- a/mirai-console/src/main/kotlin/net/mamoe/mirai/plugins/ConfigSection.kt +++ b/mirai-console/src/main/kotlin/net/mamoe/mirai/plugins/ConfigSection.kt @@ -13,8 +13,12 @@ import com.alibaba.fastjson.JSON import com.alibaba.fastjson.JSONObject import com.alibaba.fastjson.TypeReference import com.alibaba.fastjson.parser.Feature +import com.moandjiezana.toml.Toml +import com.moandjiezana.toml.TomlWriter import kotlinx.serialization.* +import org.yaml.snakeyaml.Yaml import java.io.File +import java.util.* import java.util.concurrent.ConcurrentHashMap import kotlin.properties.ReadWriteProperty import kotlin.reflect.KClass @@ -63,11 +67,11 @@ interface Config { "yml" -> YamlConfig(file) "yaml" -> YamlConfig(file) "mirai" -> YamlConfig(file) - "ini" -> IniConfig(file) - "toml" -> IniConfig(file) - "properties" -> IniConfig(file) - "property" -> IniConfig(file) - "data" -> IniConfig(file) + "ini" -> TomlConfig(file) + "toml" -> TomlConfig(file) + "properties" -> TomlConfig(file) + "property" -> TomlConfig(file) + "data" -> TomlConfig(file) else -> error("Unsupported file config type ${file.extension.toLowerCase()}") } } @@ -191,8 +195,7 @@ fun <T : Any> Config._smartCast(propertyName: String, _class: KClass<T>): T { } - -interface ConfigSection : Config { +interface ConfigSection : Config, MutableMap<String, Any> { override fun getConfigSection(key: String): ConfigSection { return (get(key) ?: error("ConfigSection does not contain $key ")) as ConfigSection } @@ -281,6 +284,22 @@ open class ConfigSectionImpl() : ConcurrentHashMap<String, Any>(), ConfigSection } } +open class ConfigSectionDelegation( + private val delegation: MutableMap<String, Any> +) : ConfigSection, MutableMap<String, Any> by delegation { + override fun set(key: String, value: Any) { + delegation.put(key, value) + } + + override fun asMap(): Map<String, Any> { + return delegation + } + + override fun save() { + + } +} + interface FileConfig : Config { fun deserialize(content: String): ConfigSection @@ -297,6 +316,18 @@ abstract class FileConfigImpl internal constructor( deserialize(file.readText()) } + override val size: Int get() = content.size + override val entries: MutableSet<MutableMap.MutableEntry<String, Any>> get() = content.entries + override val keys: MutableSet<String> get() = content.keys + override val values: MutableCollection<Any> get() = content.values + override fun containsKey(key: String): Boolean = content.containsKey(key) + override fun containsValue(value: Any): Boolean = content.containsValue(value) + override fun put(key: String, value: Any): Any? = content.put(key, value) + override fun isEmpty(): Boolean = content.isEmpty() + override fun putAll(from: Map<out String, Any>) = content.putAll(from) + override fun clear() = content.clear() + override fun remove(key: String): Any? = content.remove(key) + override fun save() { if (!file.exists()) { file.createNewFile() @@ -318,7 +349,9 @@ abstract class FileConfigImpl internal constructor( } -class JsonConfig internal constructor(file: File) : FileConfigImpl(file) { +class JsonConfig internal constructor( + file: File +) : FileConfigImpl(file) { @UnstableDefault override fun deserialize(content: String): ConfigSection { if (content.isEmpty() || content.isBlank() || content == "{}") { @@ -339,22 +372,35 @@ class JsonConfig internal constructor(file: File) : FileConfigImpl(file) { class YamlConfig internal constructor(file: File) : FileConfigImpl(file) { override fun deserialize(content: String): ConfigSection { - TODO("崔崔还没有写") //To change body of created functions use File | Settings | File Templates. + if (content.isEmpty() || content.isBlank()) { + return ConfigSectionImpl() + } + return ConfigSectionDelegation( + Collections.synchronizedMap( + Yaml().load<LinkedHashMap<String, Any>>(content) as LinkedHashMap<String, Any> + ) + ) } override fun serialize(config: ConfigSection): String { - TODO("崔崔还没有写") //To change body of created functions use File | Settings | File Templates. + return Yaml().dumpAsMap(config) } } -class IniConfig internal constructor(file: File) : FileConfigImpl(file) { +class TomlConfig internal constructor(file: File) : FileConfigImpl(file) { override fun deserialize(content: String): ConfigSection { - TODO("崔崔还没有写") //To change body of created functions use File | Settings | File Templates. + if (content.isEmpty() || content.isBlank()) { + return ConfigSectionImpl() + } + return ConfigSectionDelegation( + Collections.synchronizedMap( + Toml().read(content).toMap() + ) + ) } override fun serialize(config: ConfigSection): String { - TODO("崔崔还没有写") //To change body of created functions use File | Settings | File Templates. + return TomlWriter().write(config) } - -} +} \ No newline at end of file