mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-04 08:59:51 +08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
35f06b3b1d
@ -24,6 +24,10 @@ object MiraiHttpAPIServer {
|
|||||||
SessionManager.authKey = generateSessionKey()//用于验证的key, 使用和SessionKey相同的方法生成, 但意义不同
|
SessionManager.authKey = generateSessionKey()//用于验证的key, 使用和SessionKey相同的方法生成, 但意义不同
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setAuthKey(key: String) {
|
||||||
|
SessionManager.authKey = key
|
||||||
|
}
|
||||||
|
|
||||||
@UseExperimental(KtorExperimentalAPI::class)
|
@UseExperimental(KtorExperimentalAPI::class)
|
||||||
fun start(
|
fun start(
|
||||||
port: Int = 8080,
|
port: Int = 8080,
|
||||||
|
@ -25,6 +25,7 @@ fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(project(":mirai-core"))
|
api(project(":mirai-core"))
|
||||||
api(project(":mirai-core-qqandroid"))
|
api(project(":mirai-core-qqandroid"))
|
||||||
|
api(project(":mirai-api-http"))
|
||||||
runtimeOnly(files("../mirai-core-qqandroid/build/classes/kotlin/jvm/main"))
|
runtimeOnly(files("../mirai-core-qqandroid/build/classes/kotlin/jvm/main"))
|
||||||
runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main"))
|
runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main"))
|
||||||
api(kotlin("serialization"))
|
api(kotlin("serialization"))
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package net.mamoe.mirai.plugin
|
import net.mamoe.mirai.plugin.PluginManager
|
||||||
|
|
||||||
object CommandManager {
|
object CommandManager {
|
||||||
private val registeredCommand: MutableMap<String, Command> = mutableMapOf()
|
private val registeredCommand: MutableMap<String, Command> = mutableMapOf()
|
||||||
@ -25,6 +25,13 @@ object CommandManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun unregister(command: Command) {
|
||||||
|
val allNames = mutableListOf<String>(command.name).also { it.addAll(command.alias) }
|
||||||
|
allNames.forEach {
|
||||||
|
registeredCommand.remove(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun runCommand(fullCommand: String): Boolean {
|
fun runCommand(fullCommand: String): Boolean {
|
||||||
val blocks = fullCommand.split(" ")
|
val blocks = fullCommand.split(" ")
|
||||||
val commandHead = blocks[0].replace("/", "")
|
val commandHead = blocks[0].replace("/", "")
|
||||||
@ -43,12 +50,12 @@ object CommandManager {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class Command(
|
abstract class Command(
|
||||||
val name: String,
|
val name: String,
|
||||||
val alias: List<String> = listOf()
|
val alias: List<String> = listOf(),
|
||||||
|
val description: String = ""
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* 最高优先级监听器
|
* 最高优先级监听器
|
||||||
@ -58,3 +65,4 @@ abstract class Command(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,73 +9,134 @@
|
|||||||
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import net.mamoe.mirai.Bot
|
import net.mamoe.mirai.Bot
|
||||||
import net.mamoe.mirai.plugin.Command
|
import net.mamoe.mirai.alsoLogin
|
||||||
import net.mamoe.mirai.plugin.CommandManager
|
import net.mamoe.mirai.api.http.generateSessionKey
|
||||||
|
import net.mamoe.mirai.plugin.JsonConfig
|
||||||
|
import net.mamoe.mirai.plugin.PluginBase
|
||||||
import net.mamoe.mirai.plugin.PluginManager
|
import net.mamoe.mirai.plugin.PluginManager
|
||||||
|
import java.io.File
|
||||||
import kotlin.concurrent.thread
|
import kotlin.concurrent.thread
|
||||||
|
|
||||||
val bots = mutableMapOf<Long, Bot>()
|
object MiraiConsole {
|
||||||
|
val bots
|
||||||
|
get() = Bot.instances
|
||||||
|
|
||||||
fun main() {
|
val pluginManager: PluginManager
|
||||||
println("loading Mirai in console environments")
|
get() = PluginManager
|
||||||
println("正在控制台环境中启动Mirai ")
|
|
||||||
println()
|
|
||||||
println("Mirai-console is still in testing stage, some feature is not available")
|
|
||||||
println("Mirai-console 还处于测试阶段, 部分功能不可用")
|
|
||||||
println()
|
|
||||||
println("Mirai-console now running on " + System.getProperty("user.dir"))
|
|
||||||
println("Mirai-console 正在 " + System.getProperty("user.dir") + " 运行")
|
|
||||||
println()
|
|
||||||
println("\"/login qqnumber qqpassword \" to login a bot")
|
|
||||||
println("\"/login qq号 qq密码 \" 来登陆一个BOT")
|
|
||||||
|
|
||||||
thread { processNextCommandLine() }
|
var logger: MiraiConsoleLogger = DefaultLogger
|
||||||
|
|
||||||
PluginManager.loadPlugins()
|
var path: String = System.getProperty("user.dir")
|
||||||
defaultCommands()
|
|
||||||
|
|
||||||
Runtime.getRuntime().addShutdownHook(thread(start = false) {
|
val version = " 0.13"
|
||||||
|
val build = "Beta"
|
||||||
|
|
||||||
|
fun start() {
|
||||||
|
logger("Mirai-console v${version} $build is still in testing stage, majority feature is available")
|
||||||
|
logger("Mirai-console v${version} $build 还处于测试阶段, 大部分功能可用")
|
||||||
|
logger()
|
||||||
|
logger("Mirai-console now running under " + System.getProperty("user.dir"))
|
||||||
|
logger("Mirai-console 正在 " + System.getProperty("user.dir") + "下运行")
|
||||||
|
logger()
|
||||||
|
logger("Get news in github: https://github.com/mamoe/mirai")
|
||||||
|
logger("在Github中获取项目最新进展: https://github.com/mamoe/mirai")
|
||||||
|
logger("Mirai为开源项目,请自觉遵守开源项目协议")
|
||||||
|
logger("Powered by Mamoe Technology")
|
||||||
|
logger()
|
||||||
|
logger("\"/login qqnumber qqpassword \" to login a bot")
|
||||||
|
logger("\"/login qq号 qq密码 \" 来登陆一个BOT")
|
||||||
|
|
||||||
|
CommandManager.register(DefaultCommands.DefaultLoginCommand())
|
||||||
|
pluginManager.loadPlugins()
|
||||||
|
CommandListener.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
PluginManager.disableAllPlugins()
|
PluginManager.disableAllPlugins()
|
||||||
})
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
fun defaultCommands() {
|
* Defaults Commands are recommend to be replaced by plugin provided commands
|
||||||
class LoginCommand : Command(
|
*/
|
||||||
"login"
|
object DefaultCommands {
|
||||||
) {
|
class DefaultLoginCommand : Command(
|
||||||
override fun onCommand(args: List<String>): Boolean {
|
"login"
|
||||||
if (args.size < 2) {
|
) {
|
||||||
println("\"/login qqnumber qqpassword \" to login a bot")
|
override fun onCommand(args: List<String>): Boolean {
|
||||||
println("\"/login qq号 qq密码 \" 来登录一个BOT")
|
if (args.size < 2) {
|
||||||
return false
|
println("\"/login qqnumber qqpassword \" to login a bot")
|
||||||
}
|
println("\"/login qq号 qq密码 \" 来登录一个BOT")
|
||||||
val qqNumber = args[0].toLong()
|
return false
|
||||||
val qqPassword = args[1]
|
}
|
||||||
println("login...")
|
val qqNumber = args[0].toLong()
|
||||||
runBlocking {
|
val qqPassword = args[1]
|
||||||
|
println("login...")
|
||||||
try {
|
try {
|
||||||
Bot(qqNumber, qqPassword).also {
|
runBlocking {
|
||||||
it.login()
|
Bot(qqNumber, qqPassword).alsoLogin()
|
||||||
bots[qqNumber] = it
|
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println("$qqNumber login failed")
|
println("$qqNumber login failed")
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CommandManager.register(LoginCommand())
|
|
||||||
|
object CommandListener {
|
||||||
|
fun start() {
|
||||||
|
thread {
|
||||||
|
processNextCommandLine()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tailrec fun processNextCommandLine() {
|
||||||
|
val fullCommand = readLine()
|
||||||
|
if (fullCommand != null && fullCommand.startsWith("/")) {
|
||||||
|
if (!CommandManager.runCommand(fullCommand)) {
|
||||||
|
logger("unknown command $fullCommand")
|
||||||
|
logger("未知指令 $fullCommand")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processNextCommandLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MiraiConsoleLogger {
|
||||||
|
operator fun invoke(any: Any? = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
object DefaultLogger : MiraiConsoleLogger {
|
||||||
|
override fun invoke(any: Any?) {
|
||||||
|
println("[Mirai${version} $build]: " + any?.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MiraiProperties {
|
||||||
|
var HTTP_API_ENABLE: Boolean = true
|
||||||
|
var HTTP_API_PORT: Short = 8080
|
||||||
|
var HTTP_API_AUTH_KEY: String = ""
|
||||||
|
private val file = File(path + "/mirai.json".replace("//", "/"))
|
||||||
|
private lateinit var config: JsonConfig
|
||||||
|
fun load() {
|
||||||
|
if (!file.exists()) {
|
||||||
|
HTTP_API_AUTH_KEY = "INITKEY" + generateSessionKey()
|
||||||
|
save()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config = PluginBase
|
||||||
|
}
|
||||||
|
|
||||||
|
fun save() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tailrec fun processNextCommandLine() {
|
fun main() {
|
||||||
val fullCommand = readLine()
|
MiraiConsole.start()
|
||||||
if (fullCommand != null && fullCommand.startsWith("/")) {
|
Runtime.getRuntime().addShutdownHook(thread(start = false) {
|
||||||
if (!CommandManager.runCommand(fullCommand)) {
|
MiraiConsole.stop()
|
||||||
println("unknown command $fullCommand")
|
})
|
||||||
println("未知指令 $fullCommand")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
processNextCommandLine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,55 +9,205 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.plugin
|
package net.mamoe.mirai.plugin
|
||||||
|
|
||||||
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.Transient
|
||||||
|
import kotlinx.serialization.UnstableDefault
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.io.File
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
import kotlin.reflect.full.isSubclassOf
|
||||||
|
|
||||||
@Serializable
|
/**
|
||||||
class ConfigSection() : ConcurrentHashMap<String, Any>() {
|
* TODO: support all config types
|
||||||
|
*/
|
||||||
|
|
||||||
fun getString(key: String): String {
|
interface Config {
|
||||||
return (get(key) ?: error("ConfigSection does not contain $key ")).toString()
|
fun getConfigSection(key: String): ConfigSection
|
||||||
|
fun getString(key: String): String
|
||||||
|
fun getInt(key: String): Int
|
||||||
|
fun getFloat(key: String): Float
|
||||||
|
fun getDouble(key: String): Double
|
||||||
|
fun getLong(key: String): Long
|
||||||
|
fun getList(key: String): List<*>
|
||||||
|
fun getStringList(key: String): List<String>
|
||||||
|
fun getIntList(key: String): List<Int>
|
||||||
|
fun getFloatList(key: String): List<Float>
|
||||||
|
fun getDoubleList(key: String): List<Double>
|
||||||
|
fun getLongList(key: String): List<Long>
|
||||||
|
operator fun set(key: String, value: Any)
|
||||||
|
operator fun get(key: String): Any?
|
||||||
|
fun exist(key: String): Boolean
|
||||||
|
fun asMap(): Map<String, Any>
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Any> Config.withDefault(crossinline defaultValue: () -> T): ReadWriteProperty<Any, T> {
|
||||||
|
return object : ReadWriteProperty<Any, T> {
|
||||||
|
override fun getValue(thisRef: Any, property: KProperty<*>): T {
|
||||||
|
if (!this@withDefault.exist(property.name)) {
|
||||||
|
return defaultValue.invoke()
|
||||||
|
}
|
||||||
|
return getValue(thisRef, property)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
|
||||||
|
this@withDefault[property.name] = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getInt(key: String): Int {
|
@Suppress("IMPLICIT_CAST_TO_ANY")
|
||||||
return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toInt()
|
inline operator fun <reified T> ConfigSection.getValue(thisRef: Any?, 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)
|
||||||
|
else -> when {
|
||||||
|
T::class.isSubclassOf(ConfigSection::class) -> this.getConfigSection(property.name)
|
||||||
|
T::class == List::class || T::class == MutableList::class -> {
|
||||||
|
val list = this.getList(property.name)
|
||||||
|
return if (list.isEmpty()) {
|
||||||
|
list
|
||||||
|
} else {
|
||||||
|
when (list[0]!!::class) {
|
||||||
|
String::class -> getStringList(property.name)
|
||||||
|
Int::class -> getIntList(property.name)
|
||||||
|
Float::class -> getFloatList(property.name)
|
||||||
|
Double::class -> getDoubleList(property.name)
|
||||||
|
Long::class -> getLongList(property.name)
|
||||||
|
else -> {
|
||||||
|
error("unsupported type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as T
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
error("unsupported type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as T
|
||||||
|
}
|
||||||
|
|
||||||
fun getFloat(key: String): Float {
|
inline operator fun <reified T> ConfigSection.setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||||
return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toFloat()
|
this[property.name] = value!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDouble(key: String): Double {
|
|
||||||
return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toDouble()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLong(key: String): Long {
|
interface ConfigSection : Config {
|
||||||
return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toLong()
|
override fun getConfigSection(key: String): ConfigSection {
|
||||||
}
|
|
||||||
|
|
||||||
fun getConfigSection(key: String): ConfigSection {
|
|
||||||
return (get(key) ?: error("ConfigSection does not contain $key ")) as ConfigSection
|
return (get(key) ?: error("ConfigSection does not contain $key ")) as ConfigSection
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStringList(key: String): List<String> {
|
override fun getString(key: String): String {
|
||||||
|
return (get(key) ?: error("ConfigSection does not contain $key ")).toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInt(key: String): Int {
|
||||||
|
return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFloat(key: String): Float {
|
||||||
|
return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toFloat()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getDouble(key: String): Double {
|
||||||
|
return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLong(key: String): Long {
|
||||||
|
return (get(key) ?: error("ConfigSection does not contain $key ")).toString().toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getList(key: String): List<*> {
|
||||||
|
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringList(key: String): List<String> {
|
||||||
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString() }
|
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIntList(key: String): List<Int> {
|
override fun getIntList(key: String): List<Int> {
|
||||||
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toInt() }
|
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toInt() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFloatList(key: String): List<Float> {
|
override fun getFloatList(key: String): List<Float> {
|
||||||
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toFloat() }
|
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toFloat() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDoubleList(key: String): List<Double> {
|
override fun getDoubleList(key: String): List<Double> {
|
||||||
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toDouble() }
|
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toDouble() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLongList(key: String): List<Long> {
|
override fun getLongList(key: String): List<Long> {
|
||||||
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toLong() }
|
return ((get(key) ?: error("ConfigSection does not contain $key ")) as List<*>).map { it.toString().toLong() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override operator fun set(key: String, value: Any) {
|
||||||
|
this[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
open class ConfigSectionImpl() : ConcurrentHashMap<String, Any>(), ConfigSection {
|
||||||
|
override operator fun get(key: String): Any? {
|
||||||
|
return super.get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun exist(key: String): Boolean {
|
||||||
|
return containsKey(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun asMap(): Map<String, Any> {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface FileConfig {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
abstract class FileConfigImpl internal constructor() : ConfigSectionImpl(), FileConfig {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class JsonConfig internal constructor() : FileConfigImpl() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@UnstableDefault
|
||||||
|
fun load(file: File): Config {
|
||||||
|
require(file.extension.toLowerCase() == "json")
|
||||||
|
val content = file.apply {
|
||||||
|
if (!this.exists()) this.createNewFile()
|
||||||
|
}.readText()
|
||||||
|
|
||||||
|
if (content.isEmpty() || content.isBlank()) {
|
||||||
|
return JsonConfig()
|
||||||
|
}
|
||||||
|
return Json.parse(
|
||||||
|
JsonConfig.serializer(),
|
||||||
|
content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@UnstableDefault
|
||||||
|
fun save(file: File, config: JsonConfig) {
|
||||||
|
require(file.extension.toLowerCase() == "json")
|
||||||
|
val content = Json.stringify(
|
||||||
|
JsonConfig.serializer(),
|
||||||
|
config
|
||||||
|
)
|
||||||
|
file.apply {
|
||||||
|
if (!this.exists()) this.createNewFile()
|
||||||
|
}.writeText(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.plugin
|
package net.mamoe.mirai.plugin
|
||||||
|
|
||||||
|
import Command
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.serialization.UnstableDefault
|
import kotlinx.serialization.UnstableDefault
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
@ -66,32 +67,18 @@ abstract class PluginBase(coroutineContext: CoroutineContext) : CoroutineScope {
|
|||||||
this.onEnable()
|
this.onEnable()
|
||||||
}
|
}
|
||||||
|
|
||||||
@UnstableDefault
|
/**
|
||||||
fun loadConfig(fileName: String = "config.json"): ConfigSection {
|
* TODO: support all config types
|
||||||
var content = File(dataFolder.name + "/" + fileName)
|
*/
|
||||||
.also {
|
|
||||||
if (!it.exists()) it.createNewFile()
|
|
||||||
}.readText()
|
|
||||||
|
|
||||||
if (content == "") {
|
@UnstableDefault
|
||||||
content = "{}"
|
fun loadConfig(fileName: String): Config {
|
||||||
}
|
return JsonConfig.load(File(fileName))
|
||||||
return Json.parse(
|
|
||||||
ConfigSection.serializer(),
|
|
||||||
content
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UnstableDefault
|
@UnstableDefault
|
||||||
fun saveConfig(config: ConfigSection, fileName: String = "config.json") {
|
fun saveConfig(config: Config, fileName: String = "config.json") {
|
||||||
val content = Json.stringify(
|
JsonConfig.save(file = File(fileName), config = config as JsonConfig)
|
||||||
ConfigSection.serializer(),
|
|
||||||
config
|
|
||||||
)
|
|
||||||
File(dataFolder.name + "/" + fileName)
|
|
||||||
.also {
|
|
||||||
if (!it.exists()) it.createNewFile()
|
|
||||||
}.writeText(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user