SnowyGUI/common/src/main/kotlin/fr/username404/snowygui/config/Configuration.kt

111 lines
4.1 KiB
Kotlin

package fr.username404.snowygui.config
import com.typesafe.config.*
import com.typesafe.config.ConfigFactory.*
import fr.username404.snowygui.ClickGui
import fr.username404.snowygui.Snowy
import fr.username404.snowygui.gui.elements.ClickBox
import fr.username404.snowygui.gui.feature.Category
import fr.username404.snowygui.gui.feature.Macro
import fr.username404.snowygui.gui.feature.riskyCheatsEnabled
import io.github.config4k.extract
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import net.minecraft.client.Minecraft
import java.io.File
import java.util.function.Supplier
object Configuration {
val ModifiableValues = mutableMapOf<String, Supplier<ConfigValue>>(
"enabledFeatures" to Supplier { ConfigValueFactory.fromMap(enabledFeatures) },
"riskyCheats" to Supplier { ConfigValueFactory.fromAnyRef(riskyCheatsEnabled) },
"macros" to Supplier { ConfigValueFactory.fromIterable((ClickGui.components.find { it is ClickBox && it.isCategory(Category.MACROS) } as ClickBox).buttons.map {
Json.encodeToString(it as Macro)
}) }
); inline fun setConfigValue(s: String, crossinline value: () -> Any) = ModifiableValues.put(s, Supplier { ConfigValueFactory.fromAnyRef(value.invoke()) })
private fun Config.withFullModifiableValues() = ModifiableValues.entries.fold(this) { previous, entry ->
previous.withValue(entry.key, entry.value.get())
}
private val configDirectory: String = (Minecraft.getInstance().gameDirectory.absolutePath + File.separator + "config").also { File(it).mkdir() }
private val file: File = File(configDirectory + File.separator + "snowy.conf")
private suspend fun writeConfig(c: Config) = coroutineScope {
launch {
file.writeText(
"""
|Snowy {
|${
c.root().render(
ConfigRenderOptions.defaults()
.setFormatted(true)
.setJson(false)
.setOriginComments(false)
).prependIndent(" ").trimEnd()
}
|}
""".trimMargin()
)
}
}
val obtained: Config by lazy {
var result: Config = empty()
with(file) {
if (!exists()) {
createNewFile()
setWritable(true)
setReadable(true)
} else try {
result = parseFile(file)
} catch (e: ConfigException) {
Snowy.logs.warn("Could not parse the snowy configuration file, the default configuration will be used instead.")
}
}
load(result).withFallback(
parseString(
"""
|Snowy {
| displayInitMessage = false
| macros = []
| riskyCheats = false
|}
""".trimMargin()
)
).extract<Config>("Snowy")
}.also {
runBlocking {
writeConfig(it.value)
}
}
val enabledFeatures = mutableMapOf<String, Boolean>().apply {
if (obtained.hasPath("enabledFeatures")) {
putAll(obtained.extract("enabledFeatures"))
}
}
val foundMacros: Set<Macro> = run {
obtained.getStringList("macros").map {
Json.decodeFromString<Macro>(it)
}.toSet()
}
init {
Runtime.getRuntime().addShutdownHook(
Thread {
runBlocking {
ClickGui.boxContext {
enabledFeatures.putAll(
buttons.map {
it.run {
title to toggled
}
}
)
}
writeConfig(obtained.withFullModifiableValues()).join()
}
}
)
}
}