mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-16 19:05:02 -04:00
wip: profiles
This commit is contained in:
parent
334ee2f536
commit
ca26e2711e
@ -1,5 +1,21 @@
|
|||||||
# Config file
|
# Config file
|
||||||
|
|
||||||
There is a config file located in:
|
There is a config file located in:
|
||||||
* Windows: `%AppData%\Minosoft`
|
|
||||||
* MacOS: `"~/Library/Application Support/Minosoft"`
|
* Windows: `%AppData%\Minosoft`
|
||||||
* Linux (and all others): `~\Minosoft`
|
* MacOS: `"~/Library/Application Support/Minosoft"`
|
||||||
|
* Linux (and all others): `~\Minosoft`
|
||||||
|
|
||||||
|
|
||||||
|
- Profiles
|
||||||
|
- Select profile per server
|
||||||
|
- Config reloading
|
||||||
|
- From disk
|
||||||
|
- In eros
|
||||||
|
- Per key combination
|
||||||
|
- Migration
|
||||||
|
- Automatic saving (periodic, per event. maybe use delegates?)
|
||||||
|
- Config editor
|
||||||
|
- Config value checker
|
||||||
|
- Change event, batch those, apply event
|
||||||
|
- Multiple config files (e.g. eros, key combinations, particles, accounts, log, audio, blocks, entities, hit boxes, world, network, assets, physics, hud, other)
|
||||||
|
5
pom.xml
5
pom.xml
@ -429,5 +429,10 @@
|
|||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.12.0</version>
|
<version>3.12.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
|
<artifactId>jackson-module-kotlin</artifactId>
|
||||||
|
<version>2.13.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
package de.bixilon.minosoft
|
package de.bixilon.minosoft
|
||||||
|
|
||||||
import de.bixilon.minosoft.config.Configuration
|
import de.bixilon.minosoft.config.Configuration
|
||||||
|
import de.bixilon.minosoft.config.config2.GlobalProfileManager
|
||||||
import de.bixilon.minosoft.data.accounts.Account
|
import de.bixilon.minosoft.data.accounts.Account
|
||||||
import de.bixilon.minosoft.data.assets.JarAssetsManager
|
import de.bixilon.minosoft.data.assets.JarAssetsManager
|
||||||
import de.bixilon.minosoft.data.assets.Resources
|
import de.bixilon.minosoft.data.assets.Resources
|
||||||
@ -99,6 +100,12 @@ object Minosoft {
|
|||||||
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Config file loaded!" }
|
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Config file loaded!" }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
taskWorker += Task(identifier = StartupTasks.LOAD_CONFIG2, priority = ThreadPool.HIGH, dependencies = arrayOf(StartupTasks.LOAD_VERSIONS), executor = {
|
||||||
|
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Loading config2 file..." }
|
||||||
|
GlobalProfileManager.load()
|
||||||
|
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Config2 file loaded!" }
|
||||||
|
})
|
||||||
|
|
||||||
taskWorker += Task(identifier = StartupTasks.LOAD_LANGUAGE_FILES, dependencies = arrayOf(StartupTasks.LOAD_CONFIG), executor = {
|
taskWorker += Task(identifier = StartupTasks.LOAD_LANGUAGE_FILES, dependencies = arrayOf(StartupTasks.LOAD_CONFIG), executor = {
|
||||||
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Loading language files (${config.config.general.language})" }
|
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Loading language files (${config.config.general.language})" }
|
||||||
LANGUAGE_MANAGER.translators[ProtocolDefinition.MINOSOFT_NAMESPACE] = load(config.config.general.language, null, ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "language/"))
|
LANGUAGE_MANAGER.translators[ProtocolDefinition.MINOSOFT_NAMESPACE] = load(config.config.general.language, null, ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "language/"))
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.config2.config.eros.ErosProfileManager
|
||||||
|
|
||||||
|
object GlobalProfileManager {
|
||||||
|
val DEFAULT_MANAGERS: List<ProfileManager<*>> = listOf(
|
||||||
|
ErosProfileManager,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun load() {
|
||||||
|
for (manager in DEFAULT_MANAGERS) {
|
||||||
|
manager.load(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2
|
||||||
|
|
||||||
|
import com.google.common.collect.HashBiMap
|
||||||
|
import de.bixilon.minosoft.config.config2.config.Profile
|
||||||
|
import de.bixilon.minosoft.config.config2.util.ConfigDelegate
|
||||||
|
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||||
|
import de.bixilon.minosoft.gui.eros.crash.ErosCrashReport.Companion.crash
|
||||||
|
import de.bixilon.minosoft.terminal.RunConfiguration
|
||||||
|
import de.bixilon.minosoft.util.KUtil
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toInt
|
||||||
|
import de.bixilon.minosoft.util.Util
|
||||||
|
import de.bixilon.minosoft.util.json.jackson.Jackson
|
||||||
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
|
import de.bixilon.minosoft.util.logging.LogLevels
|
||||||
|
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||||
|
import de.bixilon.minosoft.util.task.pool.DefaultThreadPool
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.FileWriter
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
|
|
||||||
|
|
||||||
|
interface ProfileManager<T : Profile> {
|
||||||
|
val namespace: ResourceLocation
|
||||||
|
val latestVersion: Int
|
||||||
|
val saveLock: ReentrantLock
|
||||||
|
|
||||||
|
val profiles: HashBiMap<String, T>
|
||||||
|
var selected: T
|
||||||
|
|
||||||
|
val baseDirectory: File
|
||||||
|
get() = File(RunConfiguration.HOME_DIRECTORY + "config/" + namespace.namespace + "/")
|
||||||
|
|
||||||
|
fun getPath(profileName: String, baseDirectory: File = this.baseDirectory): String {
|
||||||
|
return baseDirectory.path + "/" + profileName + "/" + namespace.path + ".json"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates the config from 1 version to the next
|
||||||
|
* Does not convert to the latest version, just 1 version number higher
|
||||||
|
*/
|
||||||
|
fun migrate(from: Int, data: MutableMap<String, Any?>) = Unit
|
||||||
|
fun load(name: String, data: MutableMap<String, Any?>?): T
|
||||||
|
|
||||||
|
|
||||||
|
fun <V> delegate(value: V, checkEquals: Boolean = true): ConfigDelegate<V>
|
||||||
|
|
||||||
|
fun selectDefault()
|
||||||
|
fun createDefaultProfile(): T
|
||||||
|
|
||||||
|
fun initDefaultProfile() {
|
||||||
|
val profile = createDefaultProfile()
|
||||||
|
this.selected = profile
|
||||||
|
save(profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun serialize(profile: T): Map<String, Any?>
|
||||||
|
|
||||||
|
fun save(profile: T) {
|
||||||
|
saveLock.lock()
|
||||||
|
DefaultThreadPool += {
|
||||||
|
try {
|
||||||
|
val data = serialize(profile)
|
||||||
|
val jsonString = Jackson.MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(data)
|
||||||
|
|
||||||
|
val profileFile = File(getPath(getName(profile)))
|
||||||
|
val parent = profileFile.parentFile
|
||||||
|
if (!parent.exists()) {
|
||||||
|
parent.mkdirs()
|
||||||
|
if (!parent.isDirectory) {
|
||||||
|
throw IOException("Could not create profile folder: ${parent.path}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val tempFile = File("${profileFile.path}.tmp")
|
||||||
|
if (tempFile.exists()) {
|
||||||
|
if (!tempFile.delete()) {
|
||||||
|
throw IOException("Could not delete $tempFile!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FileWriter(tempFile).apply {
|
||||||
|
write(jsonString)
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
if (profileFile.exists() && !profileFile.delete()) {
|
||||||
|
throw IOException("Could not delete $profileFile!")
|
||||||
|
}
|
||||||
|
if (!tempFile.renameTo(profileFile)) {
|
||||||
|
throw IOException("Could not move $tempFile to $profileFile!")
|
||||||
|
}
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
exception.crash()
|
||||||
|
} finally {
|
||||||
|
saveLock.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getName(profile: T): String {
|
||||||
|
return profiles.inverse()[profile] ?: "Unknown profile"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load(selected: String?) {
|
||||||
|
val baseDirectory = baseDirectory
|
||||||
|
if (!baseDirectory.exists()) {
|
||||||
|
baseDirectory.mkdirs()
|
||||||
|
// ToDo: Skip further processing
|
||||||
|
}
|
||||||
|
if (!baseDirectory.isDirectory) {
|
||||||
|
throw IOException("${baseDirectory.path} is not an directory!")
|
||||||
|
}
|
||||||
|
val profileNames = baseDirectory.list { current, name -> File(current, name).isDirectory } ?: throw IOException("Can not create a list of profiles in ${baseDirectory.path}")
|
||||||
|
if (selected == null || profileNames.isEmpty()) {
|
||||||
|
initDefaultProfile()
|
||||||
|
}
|
||||||
|
var migrated = false
|
||||||
|
for (profileName in profileNames) {
|
||||||
|
val path = getPath(profileName, baseDirectory)
|
||||||
|
val json: MutableMap<String, Any?>?
|
||||||
|
val jsonString = KUtil.tryCatch(FileNotFoundException::class.java) { Util.readFile(path) }
|
||||||
|
if (jsonString != null) {
|
||||||
|
json = Jackson.MAPPER.readValue(jsonString, Jackson.JSON_MAP_TYPE)!!
|
||||||
|
val version = json["version"]?.toInt() ?: throw IllegalArgumentException("Can not find version attribute in profile: $path")
|
||||||
|
if (version > latestVersion) {
|
||||||
|
throw IllegalStateException("Your profile ($path) was created with a newer version of minosoft. Expected $version <= $latestVersion!")
|
||||||
|
}
|
||||||
|
if (version < latestVersion) {
|
||||||
|
for (toMigrate in version until latestVersion) {
|
||||||
|
migrate(toMigrate, json)
|
||||||
|
}
|
||||||
|
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Migrated profile ($path) from $version to $latestVersion" }
|
||||||
|
json["version"] = latestVersion
|
||||||
|
migrated = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
json = null
|
||||||
|
}
|
||||||
|
|
||||||
|
val profile = load(profileName, json)
|
||||||
|
if (migrated) {
|
||||||
|
save(profile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selected != null) {
|
||||||
|
profiles[selected]?.let { this.selected = it } ?: selectDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.log(LogMessageType.OTHER, LogLevels.INFO) { "Loaded ${profiles.size} $namespace profiles!" }
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val DEFAULT_PROFILE_NAME = "Default"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2.config
|
||||||
|
|
||||||
|
interface Profile {
|
||||||
|
val version: Int
|
||||||
|
val description: String?
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2.config.eros
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.config2.config.Profile
|
||||||
|
import de.bixilon.minosoft.config.config2.config.eros.ErosProfileManager.delegate
|
||||||
|
import de.bixilon.minosoft.config.config2.config.eros.ErosProfileManager.latestVersion
|
||||||
|
import de.bixilon.minosoft.config.config2.config.eros.general.GeneralC2
|
||||||
|
|
||||||
|
class ErosProfile(
|
||||||
|
description: String? = null,
|
||||||
|
) : Profile {
|
||||||
|
override val version: Int = latestVersion
|
||||||
|
override val description by delegate(description ?: "")
|
||||||
|
|
||||||
|
val general: GeneralC2 = GeneralC2()
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return ErosProfileManager.getName(this)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2.config.eros
|
||||||
|
|
||||||
|
import com.google.common.collect.HashBiMap
|
||||||
|
import de.bixilon.minosoft.config.config2.ProfileManager
|
||||||
|
import de.bixilon.minosoft.config.config2.util.ConfigDelegate
|
||||||
|
import de.bixilon.minosoft.modding.event.master.GlobalEventMaster
|
||||||
|
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||||
|
import de.bixilon.minosoft.util.KUtil.unsafeCast
|
||||||
|
import de.bixilon.minosoft.util.json.jackson.Jackson
|
||||||
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
|
|
||||||
|
object ErosProfileManager : ProfileManager<ErosProfile> {
|
||||||
|
override val namespace = "minosoft:eros".toResourceLocation()
|
||||||
|
override val latestVersion = 1
|
||||||
|
override val saveLock = ReentrantLock()
|
||||||
|
|
||||||
|
|
||||||
|
private var currentLoadingPath: String? = null
|
||||||
|
override val profiles: HashBiMap<String, ErosProfile> = HashBiMap.create()
|
||||||
|
|
||||||
|
override var selected: ErosProfile = null.unsafeCast()
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
GlobalEventMaster.fireEvent(ErosProfileSelectEvent(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun selectDefault() {
|
||||||
|
selected = profiles[ProfileManager.DEFAULT_PROFILE_NAME] ?: createDefaultProfile()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createDefaultProfile(): ErosProfile {
|
||||||
|
currentLoadingPath = ProfileManager.DEFAULT_PROFILE_NAME
|
||||||
|
val profile = ErosProfile("Default eros profile")
|
||||||
|
currentLoadingPath = null
|
||||||
|
profiles[ProfileManager.DEFAULT_PROFILE_NAME] = profile
|
||||||
|
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun load(name: String, data: MutableMap<String, Any?>?): ErosProfile {
|
||||||
|
currentLoadingPath = name
|
||||||
|
val profile: ErosProfile = if (data == null) {
|
||||||
|
ErosProfile()
|
||||||
|
} else {
|
||||||
|
Jackson.MAPPER.convertValue(data, ErosProfile::class.java)
|
||||||
|
}
|
||||||
|
profiles[name] = profile
|
||||||
|
currentLoadingPath = null
|
||||||
|
return profile
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(profile: ErosProfile): Map<String, Any?> {
|
||||||
|
return Jackson.MAPPER.convertValue(profile, Jackson.JSON_MAP_TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <V> delegate(value: V, checkEquals: Boolean): ConfigDelegate<V> {
|
||||||
|
return ConfigDelegate(value, checkEquals, this, currentLoadingPath ?: throw IllegalAccessException("Delegate can only be created while loading or creating profiles!"))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2.config.eros
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.modding.event.events.Event
|
||||||
|
|
||||||
|
class ErosProfileSelectEvent(
|
||||||
|
val profile: ErosProfile,
|
||||||
|
) : Event
|
@ -0,0 +1,11 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2.config.eros.general
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.config2.config.eros.ErosProfileManager.delegate
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class GeneralC2 {
|
||||||
|
/**
|
||||||
|
* Language to use for eros (and the fallback for the connection)
|
||||||
|
*/
|
||||||
|
var language: Locale by delegate(Locale.getDefault())
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2.migration
|
||||||
|
|
||||||
|
interface ConfigMigrator {
|
||||||
|
|
||||||
|
fun migrate(data: MutableMap<String, Any>)
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package de.bixilon.minosoft.config.config2.util
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.config.config2.ProfileManager
|
||||||
|
import de.bixilon.minosoft.util.KUtil.realName
|
||||||
|
import de.bixilon.minosoft.util.logging.Log
|
||||||
|
import de.bixilon.minosoft.util.logging.LogLevels
|
||||||
|
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
open class ConfigDelegate<V>(
|
||||||
|
private var value: V,
|
||||||
|
private val checkEquals: Boolean,
|
||||||
|
private val profileManager: ProfileManager<*>,
|
||||||
|
private val profileName: String,
|
||||||
|
) : ReadWriteProperty<Any, V> {
|
||||||
|
|
||||||
|
|
||||||
|
override fun getValue(thisRef: Any, property: KProperty<*>): V {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any, property: KProperty<*>, value: V) {
|
||||||
|
if (checkEquals && this.value == value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Changed option $property in ${thisRef::class.java.realName} in profile $profileName from ${this.value} to $value" }
|
||||||
|
|
||||||
|
// ToDo: Fire event, save config
|
||||||
|
this.value = value
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package de.bixilon.minosoft.data.language
|
||||||
|
|
||||||
|
annotation class Description(
|
||||||
|
val nameKey: String,
|
||||||
|
val translationKey: String,
|
||||||
|
)
|
@ -21,6 +21,7 @@ import java.io.File
|
|||||||
import java.lang.management.ManagementFactory
|
import java.lang.management.ManagementFactory
|
||||||
|
|
||||||
object RunConfiguration {
|
object RunConfiguration {
|
||||||
|
@Deprecated("Use profile manager")
|
||||||
var CONFIG_FILENAME = "minosoft.json" // Filename of minosoft's base configuration (located in AppData/Minosoft/config)
|
var CONFIG_FILENAME = "minosoft.json" // Filename of minosoft's base configuration (located in AppData/Minosoft/config)
|
||||||
|
|
||||||
var LOG_COLOR_MESSAGE = true // The message (after all prefixes) should be colored with ANSI color codes
|
var LOG_COLOR_MESSAGE = true // The message (after all prefixes) should be colored with ANSI color codes
|
||||||
|
@ -137,7 +137,7 @@ object KUtil {
|
|||||||
return synchronizedCopy { Collections.synchronizedSet(this.toMutableSet()) }
|
return synchronizedCopy { Collections.synchronizedSet(this.toMutableSet()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> T.synchronizedDeepCopy(): T? {
|
fun <T> T.synchronizedDeepCopy(): T {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is Map<*, *> -> {
|
is Map<*, *> -> {
|
||||||
val map: MutableMap<Any?, Any?> = synchronizedMapOf()
|
val map: MutableMap<Any?, Any?> = synchronizedMapOf()
|
||||||
@ -170,7 +170,7 @@ object KUtil {
|
|||||||
is String -> this
|
is String -> this
|
||||||
is Number -> this
|
is Number -> this
|
||||||
is Boolean -> this
|
is Boolean -> this
|
||||||
null -> null
|
null -> null.unsafeCast()
|
||||||
else -> TODO("Don't know how to copy ${(this as T)!!::class.java.name}")
|
else -> TODO("Don't know how to copy ${(this as T)!!::class.java.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
|||||||
import de.bixilon.minosoft.config.config.Config
|
import de.bixilon.minosoft.config.config.Config
|
||||||
import de.bixilon.minosoft.gui.rendering.textures.properties.ImageProperties
|
import de.bixilon.minosoft.gui.rendering.textures.properties.ImageProperties
|
||||||
|
|
||||||
|
@Deprecated("Moshi is deprecated, use klaxon or mbf instead")
|
||||||
object JSONSerializer {
|
object JSONSerializer {
|
||||||
val MOSHI = Moshi.Builder()
|
val MOSHI = Moshi.Builder()
|
||||||
.add(RGBColorSerializer)
|
.add(RGBColorSerializer)
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package de.bixilon.minosoft.util.json.jackson
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import com.fasterxml.jackson.databind.PropertyNamingStrategies
|
||||||
|
import com.fasterxml.jackson.databind.type.MapType
|
||||||
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
|
|
||||||
|
object Jackson {
|
||||||
|
val MAPPER = ObjectMapper()
|
||||||
|
.registerModule(KotlinModule())
|
||||||
|
|
||||||
|
|
||||||
|
val JSON_MAP_TYPE: MapType = MAPPER.typeFactory.constructMapType(HashMap::class.java, String::class.java, Any::class.java)
|
||||||
|
|
||||||
|
init {
|
||||||
|
MAPPER.propertyNamingStrategy = PropertyNamingStrategies.SNAKE_CASE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,7 +14,9 @@
|
|||||||
package de.bixilon.minosoft.util.task.worker
|
package de.bixilon.minosoft.util.task.worker
|
||||||
|
|
||||||
enum class StartupTasks {
|
enum class StartupTasks {
|
||||||
|
@Deprecated("Will be replaced with LOAD_CONFIG2")
|
||||||
LOAD_CONFIG,
|
LOAD_CONFIG,
|
||||||
|
LOAD_CONFIG2,
|
||||||
LOAD_LANGUAGE_FILES,
|
LOAD_LANGUAGE_FILES,
|
||||||
LOAD_VERSIONS,
|
LOAD_VERSIONS,
|
||||||
LOAD_DEFAULT_REGISTRIES,
|
LOAD_DEFAULT_REGISTRIES,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user