diff --git a/core/src/main/kotlin/voodoo/data/nested/NestedEntry.kt b/core/src/main/kotlin/voodoo/data/nested/NestedEntry.kt deleted file mode 100644 index 44944c44..00000000 --- a/core/src/main/kotlin/voodoo/data/nested/NestedEntry.kt +++ /dev/null @@ -1,299 +0,0 @@ -package voodoo.data.nested - -import com.github.ricky12awesome.jss.JsonSchema -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import mu.KotlinLogging -import voodoo.data.DependencyType -import voodoo.data.OptionalData -import voodoo.data.Side -import voodoo.data.components.* -import voodoo.data.curse.PackageType -import voodoo.data.flat.FlatEntry -import kotlin.reflect.KMutableProperty -import kotlin.reflect.full.functions -import kotlin.reflect.full.memberProperties - -private val logger = KotlinLogging.logger {} - -@Serializable -sealed class NestedEntry( - override var name: String? = null, - override var folder: String? = null, - override var description: String? = null, - override var optionalData: OptionalData? = null, - override var side: Side = Side.BOTH, - override var websiteUrl: String = "", - override var dependencies: MutableMap = mutableMapOf(), -// override var replaceDependencies: Map = mapOf(), // TODO: replace with Map - override var packageType: PackageType = PackageType.MOD, - override var transient: Boolean = false, // this entry got added as dependency for something else - override var version: String = "", // TODO: use regex only ? - override var fileName: String? = null, - override var fileNameRegex: String = ".*(? = setOf(), - override var invalidMcVersions: Set = setOf(), - override var enabled: Boolean = true, -) : Common { - abstract var entries: Map - abstract var nodeName: String? - abstract val provider: String - - @Serializable - @SerialName("common") - data class Common( - @Transient override var nodeName: String? = null, - override var entries: Map = emptyMap() - ) : NestedEntry() { - @Transient override val provider = "common" - - } - - @Serializable - @SerialName("curse") - data class Curse( - @Transient override var nodeName: String? = null, - @JsonSchema.StringEnum(["replace_with_curseforge_projects"]) - var projectName: String? = null, - @SerialName("curseProperties") - val curse: CurseComponent = CurseComponent(), - override var entries: Map = emptyMap() - ) : NestedEntry(), CurseMutable by curse { - @Transient override val provider = "curse" - - companion object: NestedEntryProvider { - override fun create() = Curse() - } - } - - @Serializable - @SerialName("direct") - data class Direct( - @Transient override var nodeName: String? = null, - @SerialName("directProperties") - val direct: DirectComponent = DirectComponent(), - override var entries: Map = emptyMap() - ) : NestedEntry(), DirectMutable by direct { - @Transient override val provider = "direct" - - companion object: NestedEntryProvider { - override fun create() = Direct() - } - } - - @Serializable - @SerialName("jenkins") - data class Jenkins( - @Transient override var nodeName: String? = null, - @SerialName("jenkinsProperties") - val jenkins: JenkinsComponent = JenkinsComponent(), - override var entries: Map = emptyMap() - ) : NestedEntry(), JenkinsMutable by jenkins { - @Transient override val provider = "jenkins" - - companion object: NestedEntryProvider { - override fun create() = Jenkins() - } - } - - @Serializable - @SerialName("local") - data class Local( - @Transient override var nodeName: String? = null, - @SerialName("localProperties") - val local: LocalComponent = LocalComponent(), - override var entries: Map = emptyMap() - ) : NestedEntry(), LocalMutable by local { - @Transient override val provider = "local" - companion object: NestedEntryProvider { - override fun create() = Local() - } - } - - @Serializable - @SerialName("noop") - data class Noop( - @Transient override var nodeName: String? = null, - override var entries: Map = emptyMap() - ): NestedEntry() { - @Transient override val provider = "noop" - companion object: NestedEntryProvider { - override fun create() = Noop() - } - } - -// private val debugIdentifier: String -// get() = nodeName ?: toString() - - companion object { - private val logger = KotlinLogging.logger {} - } - - private fun toCommonComponent(id: String) = CommonComponent( - id = id, - name = name, - folder = folder, - description = description, - optionalData = optionalData?.copy(), - side = side, - websiteUrl = websiteUrl, - dependencies = dependencies, - packageType = packageType, - transient = transient, - version = version, - fileName = fileName, - fileNameRegex = fileNameRegex, - validMcVersions = validMcVersions, - invalidMcVersions = invalidMcVersions, - enabled = enabled - ) - - fun flatten(id: String = "root"): List { - flatten("", id) - - // no longer of use because duplicate ids cannot happen -// // remove duplicate entries -// val ids = mutableSetOf() -// -// entries.forEach { entry -> -// if (entry.id in ids) { -// entries -= entry -// } else { -// ids += entry.id -// } -// } - // copy entries - - logger.trace { "flattened entries: ${entries}" } - - val entryList = entries.filterValues { it.enabled }.map { (entryId, entry) -> -// if(!entry.enabled) return null - - logger.trace { "converting to Entry: id=$entryId nestedEntry=$entry" } - with(entry) { - when (this) { - is Common -> FlatEntry.Common( - common = toCommonComponent(entryId) - ) - is Curse -> FlatEntry.Curse( - common = toCommonComponent(entryId), - curse = curse.copy() - ) - is Direct -> FlatEntry.Direct( - common = toCommonComponent(entryId), - direct = direct.copy() - ) - is Jenkins -> FlatEntry.Jenkins( - common = toCommonComponent(entryId), - jenkins = jenkins.copy() - ) - is Local -> FlatEntry.Local( - common = toCommonComponent(entryId), - local = local.copy() - ) - is Noop -> FlatEntry.Noop( - common = toCommonComponent(entryId) - ) - } - } - }.toList() - - logger.trace { "entryList: $entryList"} - - return entryList - } - - private fun flatten(indent: String, parentId: String) { -// val toDelete = mutableListOf() - - entries.forEach { (id, entry) -> - logger.debug { "$indent pre_flatten: ${entry}" } - - // set feature of entry from `this` or DEFAULT - - logger.debug { "$indent copying fields of '${parentId}' -> '${id}'" } - - // TODO: avoid creating and throwing away objects for defaults - mergeProperties(this, entry, Common()) - - when { - entry is Curse && this is Curse -> { - mergeProperties(this, entry, Curse()) - } - entry is Direct && this is Direct -> { - mergeProperties(this, entry, Direct()) - } - entry is Jenkins && this is Jenkins -> { - mergeProperties(this, entry, Jenkins()) - } - entry is Local && this is Local -> { - mergeProperties(this, entry, Local()) - } - } - - logger.trace { "$indent copying to parent: ${entry.entries.keys}" } - this.entries += entry.entries - entry.flatten("$indent| ", id) - } - entries = entries.filter { (id, entry) -> - if (entry.entries.isNotEmpty() || id.isBlank()) { - logger.trace { "dropping group: $id" } - false - } else { - true - } - } -// entries = entries.filterKeys { !toDelete.contains(it) } - entries.forEach { (id, entry) -> - if (id.isBlank()) { - logger.error { entry } - error("entries with blank id must not persist") - } - } - logger.trace { "$indent post_flatten: entries: ${entries.keys}" } - } -} - -private inline fun mergeProperties(a: T, other: T, default: T) { - for (prop in T::class.memberProperties) { - if (prop is KMutableProperty<*>) { - val otherValue = prop.get(other) - val thisValue = prop.get(a) - val defaultValue = prop.get(default) - if (otherValue == defaultValue && thisValue != defaultValue) { - if (prop.name != "entries") { - // clone maps - when (thisValue) { - is MutableMap<*, *> -> { - val map = thisValue.toMutableMap() - // copy lists - map.forEach { (k, v) -> - if (v is List<*>) { - map[k] = v.toList() - } - } - prop.setter.call(other, map) - } - is Set<*> -> prop.setter.call(other, thisValue.toSet()) - else -> { - if (thisValue != null) { - val thisClass = thisValue::class - val copyFuncRef = - thisClass.functions.find { it.name == "copy" && it.parameters.isEmpty() } - if (copyFuncRef != null) { - logger.debug("copy found for $thisClass") - prop.setter.call(other, copyFuncRef.call(thisValue)) - } else { - prop.setter.call(other, thisValue) - } - } else { - prop.setter.call(other, null) - } - } - } - } - } - } - } -} diff --git a/core/src/main/kotlin/voodoo/data/nested/NestedEntryProvider.kt b/core/src/main/kotlin/voodoo/data/nested/NestedEntryProvider.kt deleted file mode 100644 index d3565831..00000000 --- a/core/src/main/kotlin/voodoo/data/nested/NestedEntryProvider.kt +++ /dev/null @@ -1,5 +0,0 @@ -package voodoo.data.nested - -interface NestedEntryProvider { - fun create(): E -} \ No newline at end of file diff --git a/core/src/main/kotlin/voodoo/data/nested/NestedPack.kt b/core/src/main/kotlin/voodoo/data/nested/NestedPack.kt deleted file mode 100644 index 08d0d148..00000000 --- a/core/src/main/kotlin/voodoo/data/nested/NestedPack.kt +++ /dev/null @@ -1,67 +0,0 @@ -package voodoo.data.nested - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import mu.KotlinLogging -import voodoo.data.ModloaderPattern -import voodoo.data.PackOptions -import voodoo.data.flat.FlatModPack -import java.io.File - -/** - * Created by nikky on 28/03/18. - * @author Nikky - */ -@Serializable -data class NestedPack( - @SerialName("\$schema") - val schema: String = "../schema/nested.schema.json", - /** - * Minecraft Version - */ - var mcVersion: String? = null, - /** - * display name - */ - var title: String? = null, - var version: String = "1.0", - var icon: String = "icon.png", - var authors: List = emptyList(), - var modloader: ModloaderPattern = ModloaderPattern.None, - var localDir: String = "local", - var docDir: String? = null, - var packOptions: PackOptions = PackOptions(), - var root: NestedEntry = NestedEntry.Common( - nodeName = "root" - ) -) { - companion object { - private val logger = KotlinLogging.logger {} - fun create(builder: (NestedPack) -> Unit = {}): NestedPack { - val pack = NestedPack() - builder(pack) - return pack - } - } - - // TODO: possibly this flattening step will not be necessary - suspend fun flatten(rootFolder: File, id: String): FlatModPack { - if (!rootFolder.isAbsolute) { - throw IllegalStateException("rootFolder: '$rootFolder' is not absolute") - } - return FlatModPack( - rootFolder = rootFolder, - id = id, - mcVersion = mcVersion ?: throw IllegalStateException("mcVersion must be set for pack '$id'"), - title = title, - version = version, - icon = icon, - authors = authors, - modloader = modloader, - localDir = localDir, - docDir = docDir ?: id, - packOptions = packOptions, - entrySet = root.flatten().toMutableSet() - ) - } -} \ No newline at end of file diff --git a/core/src/main/kotlin/voodoo/provider/Providers.kt b/core/src/main/kotlin/voodoo/provider/Providers.kt index 869c4dc5..a4bfc6e8 100644 --- a/core/src/main/kotlin/voodoo/provider/Providers.kt +++ b/core/src/main/kotlin/voodoo/provider/Providers.kt @@ -2,7 +2,6 @@ package voodoo.provider import mu.KLogging import voodoo.data.flat.FlatEntry -import voodoo.data.nested.NestedEntry object Providers : KLogging() { private val providers = hashMapOf() @@ -27,16 +26,6 @@ object Providers : KLogging() { is FlatEntry.Noop -> NoopProvider } - fun forEntry(entry: NestedEntry) = - when(entry) { - is NestedEntry.Common -> null - is NestedEntry.Curse -> CurseProvider - is NestedEntry.Jenkins -> JenkinsProvider - is NestedEntry.Direct -> DirectProvider - is NestedEntry.Local -> LocalProvider - is NestedEntry.Noop -> NoopProvider - } - fun register(vararg pairs: Pair) { pairs.forEach { (key, provider) -> providers[key.toUpperCase()]?.let { existing -> diff --git a/samples/fabricpack/164Version.voodoo.json5 b/samples/fabricpack/164Version.voodoo.json5 index c0448d12..002b9efa 100644 --- a/samples/fabricpack/164Version.voodoo.json5 +++ b/samples/fabricpack/164Version.voodoo.json5 @@ -11,7 +11,6 @@ "": [ "curse=Fabric/fabric-api", "curse=Fabric/betternether", - "curse=Fabric/betternether", // comment { "type": "curse", diff --git a/voodoo/src/main/kotlin/voodoo/cli/ImportCurseCommand.kt b/voodoo/src/main/kotlin/voodoo/cli/ImportCurseCommand.kt index c8b55877..fbffc777 100644 --- a/voodoo/src/main/kotlin/voodoo/cli/ImportCurseCommand.kt +++ b/voodoo/src/main/kotlin/voodoo/cli/ImportCurseCommand.kt @@ -196,16 +196,11 @@ class ImportCurseCommand() : CliktCommand( // fileNameRegex = "\\Q${addonFile.fileName}\\E" if(!hasCustomProperties) { - val entryString = "curse=${entry.curse_projectName}" - jsonPretty.encodeToJsonElement( - String.serializer(), - entryString + FileEntry.Curse( + curse_projectName = entry.curse_projectName ) } else { - jsonPretty.encodeToJsonElement( - FileEntry.serializer(), - entry - ) + entry } } }.awaitAll() diff --git a/voodoo/src/main/kotlin/voodoo/pack/FileEntry.kt b/voodoo/src/main/kotlin/voodoo/pack/FileEntry.kt index 0df51d8d..07fc5a74 100644 --- a/voodoo/src/main/kotlin/voodoo/pack/FileEntry.kt +++ b/voodoo/src/main/kotlin/voodoo/pack/FileEntry.kt @@ -15,75 +15,77 @@ import voodoo.data.flat.FlatEntry @Serializable sealed class FileEntry { - private val logger = KotlinLogging.logger{} - - interface Common { - val applyOverrides: List - var id: String? - var name: String? - var folder: String? - var description: String? - var optional: Optional? - var side: Side - var websiteUrl: String - var packageType: PackageType - // this entry got added as dependency for something else, only setthis if you know what you are doing - var version: String // TODO: use regex only ? - var transient: Boolean - var fileName: String? - var fileNameRegex: String - var validMcVersions: Set - var invalidMcVersions: Set - - fun id(): String? - fun applyOverride(override: EntryOverride): Common - - fun toCommonComponent(defaultId: String? = null): CommonComponent = CommonComponent( - id = id.takeUnless { it.isNullOrBlank() } ?: defaultId ?: error("id must be set on $this"), - name = name, - folder = folder, - description = description, - optionalData = optional?.toOptionalData(), - side = side, - websiteUrl = websiteUrl, - dependencies = mutableMapOf(), - packageType = packageType, - transient = transient, - version = version, - fileName = fileName, - fileNameRegex = fileNameRegex, - validMcVersions = validMcVersions, - invalidMcVersions = invalidMcVersions - ) + companion object { + private val logger = KotlinLogging.logger {} + } - fun applyCommonOverride(override: EntryOverride) { - override.folder?.let { folder = it } - override.description?.let { description = it } - override.optional?.let { optionalOverride -> - val opt = this.optional ?: Optional() - opt.applyOverride(optionalOverride) - optional = opt - } - override.side?.let { side = it } - override.websiteUrl?.let { websiteUrl = it } - override.packageType?.let { packageType = it } - override.version?.let { version = it } - override.fileName?.let { fileName = it } - override.fileNameRegex?.let { fileNameRegex = it } - override.validMcVersions?.let { validMcVersions += it } - override.invalidMcVersions?.let { invalidMcVersions += it } + abstract val applyOverrides: List + abstract var id: String? + abstract var name: String? + abstract var folder: String? + abstract var description: String? + abstract var optional: Optional? + abstract var side: Side + abstract var websiteUrl: String + abstract var packageType: PackageType + + // this entry got added as dependency for something else, only setthis if you know what you are doing + abstract var version: String // TODO: use regex only ? + abstract var transient: Boolean + abstract var fileName: String? + abstract var fileNameRegex: String + abstract var validMcVersions: Set + abstract var invalidMcVersions: Set + + abstract fun id(): String? + abstract fun applyOverride(override: EntryOverride): FileEntry + abstract fun copyCommon(): FileEntry + + fun toCommonComponent(defaultId: String? = null): CommonComponent = CommonComponent( + id = id.takeUnless { it.isNullOrBlank() } ?: defaultId ?: error("id must be set on $this"), + name = name, + folder = folder, + description = description, + optionalData = optional?.toOptionalData(), + side = side, + websiteUrl = websiteUrl, + dependencies = mutableMapOf(), + packageType = packageType, + transient = transient, + version = version, + fileName = fileName, + fileNameRegex = fileNameRegex, + validMcVersions = validMcVersions, + invalidMcVersions = invalidMcVersions + ) + + fun applyCommonOverride(override: EntryOverride) { + override.folder?.let { folder = it } + override.description?.let { description = it } + override.optional?.let { optionalOverride -> + val opt = this.optional ?: Optional() + opt.applyOverride(optionalOverride) + optional = opt } + override.side?.let { side = it } + override.websiteUrl?.let { websiteUrl = it } + override.packageType?.let { packageType = it } + override.version?.let { version = it } + override.fileName?.let { fileName = it } + override.fileNameRegex?.let { fileNameRegex = it } + override.validMcVersions?.let { validMcVersions += it } + override.invalidMcVersions?.let { invalidMcVersions += it } + } - fun foldOverrides(overrides: Map): E { - val intitalEntry = this as E - val entryId = intitalEntry.id().takeUnless { it.isNullOrBlank() } ?: error("missing entry id for entry: ") - val entry = intitalEntry.applyOverrides.fold(intitalEntry) { acc: E, overrideId -> - val entryOverride = - overrides[overrideId] ?: error("$entryId: override for id $overrideId not found") - return@fold acc.applyOverride(entryOverride) as E - } - return entry as E + fun foldOverrides(overrides: Map): E { + val intitalEntry = this as E + val entryId = intitalEntry.id().takeUnless { it.isNullOrBlank() } ?: error("missing entry id for entry: ") + val entry = intitalEntry.applyOverrides.fold(intitalEntry) { acc: E, overrideId -> + val entryOverride = + overrides[overrideId] ?: error("$entryId: override for id $overrideId not found") + return@fold acc.applyOverride(entryOverride) as E } + return entry as E } fun postParse(overrideKey: String): FileEntry = when (this) { @@ -97,7 +99,7 @@ sealed class FileEntry { // curse_projectName = null, applyOverrides = listOfNotNull(overrideKey.takeUnless { it.isBlank() }) + applyOverrides, curse_projectID = ProjectID(addonid), - id = id.takeUnless { it.isNullOrBlank() } ?: newName, +// id = id.takeUnless { it.isNullOrBlank() } ?: newName, name = name ?: newName ) } else { @@ -151,10 +153,10 @@ sealed class FileEntry { override var transient: Boolean = CommonComponent.DEFAULT.transient, override var version: String = CommonComponent.DEFAULT.version, override var fileName: String? = CommonComponent.DEFAULT.fileName, - override var fileNameRegex: String =CommonComponent.DEFAULT.fileNameRegex, + override var fileNameRegex: String = CommonComponent.DEFAULT.fileNameRegex, override var validMcVersions: Set = CommonComponent.DEFAULT.validMcVersions, override var invalidMcVersions: Set = CommonComponent.DEFAULT.invalidMcVersions, - ) : Common, FileEntry() { + ) : FileEntry() { override fun id() = id.takeUnless { it.isNullOrBlank() } ?: curse_projectName?.substringAfterLast('/') override fun applyOverride(override: EntryOverride): Curse { return when (override) { @@ -171,6 +173,10 @@ sealed class FileEntry { } } + override fun copyCommon(): FileEntry { + return copy() + } + override fun toEntry(overrides: Map): FlatEntry = (foldOverrides(overrides) as Curse).let { FlatEntry.Curse( @@ -213,11 +219,13 @@ sealed class FileEntry { override var transient: Boolean = CommonComponent.DEFAULT.transient, override var version: String = CommonComponent.DEFAULT.version, override var fileName: String? = CommonComponent.DEFAULT.fileName, - override var fileNameRegex: String =CommonComponent.DEFAULT.fileNameRegex, + override var fileNameRegex: String = CommonComponent.DEFAULT.fileNameRegex, override var validMcVersions: Set = CommonComponent.DEFAULT.validMcVersions, override var invalidMcVersions: Set = CommonComponent.DEFAULT.invalidMcVersions, - ) : Common, FileEntry() { - override fun id() = id.takeUnless { it.isNullOrBlank() } ?: direct_url.split(":|&|=".toRegex()).joinToString("_") + ) : FileEntry() { + override fun id() = + id.takeUnless { it.isNullOrBlank() } ?: direct_url.split(":|&|=".toRegex()).joinToString("_") + override fun applyOverride(override: EntryOverride): Direct { return when (override) { is EntryOverride.Direct -> copy( @@ -233,6 +241,10 @@ sealed class FileEntry { } } + override fun copyCommon(): FileEntry { + return copy() + } + override fun toEntry(overrides: Map): FlatEntry = (foldOverrides(overrides) as Direct).let { FlatEntry.Direct( @@ -270,10 +282,10 @@ sealed class FileEntry { override var transient: Boolean = CommonComponent.DEFAULT.transient, override var version: String = CommonComponent.DEFAULT.version, override var fileName: String? = CommonComponent.DEFAULT.fileName, - override var fileNameRegex: String =CommonComponent.DEFAULT.fileNameRegex, + override var fileNameRegex: String = CommonComponent.DEFAULT.fileNameRegex, override var validMcVersions: Set = CommonComponent.DEFAULT.validMcVersions, override var invalidMcVersions: Set = CommonComponent.DEFAULT.invalidMcVersions, - ) : Common, FileEntry() { + ) : FileEntry() { override fun id() = id.takeUnless { it.isNullOrBlank() } ?: jenkins_job override fun applyOverride(override: EntryOverride): Jenkins { return when (override) { @@ -292,6 +304,10 @@ sealed class FileEntry { } } + override fun copyCommon(): FileEntry { + return copy() + } + override fun toEntry(overrides: Map): FlatEntry = (foldOverrides(overrides) as Jenkins).let { FlatEntry.Jenkins( @@ -329,10 +345,10 @@ sealed class FileEntry { override var transient: Boolean = CommonComponent.DEFAULT.transient, override var version: String = CommonComponent.DEFAULT.version, override var fileName: String? = CommonComponent.DEFAULT.fileName, - override var fileNameRegex: String =CommonComponent.DEFAULT.fileNameRegex, + override var fileNameRegex: String = CommonComponent.DEFAULT.fileNameRegex, override var validMcVersions: Set = CommonComponent.DEFAULT.validMcVersions, override var invalidMcVersions: Set = CommonComponent.DEFAULT.invalidMcVersions, - ) : Common, FileEntry() { + ) : FileEntry() { override fun id() = id.takeUnless { it.isNullOrBlank() } ?: local_fileSrc override fun applyOverride(override: EntryOverride): Local { return when (override) { @@ -348,6 +364,10 @@ sealed class FileEntry { } } + override fun copyCommon(): FileEntry { + return copy() + } + override fun toEntry(overrides: Map): FlatEntry = (foldOverrides(overrides) as Local).let { FlatEntry.Local( @@ -380,10 +400,10 @@ sealed class FileEntry { override var transient: Boolean = CommonComponent.DEFAULT.transient, override var version: String = CommonComponent.DEFAULT.version, override var fileName: String? = CommonComponent.DEFAULT.fileName, - override var fileNameRegex: String =CommonComponent.DEFAULT.fileNameRegex, + override var fileNameRegex: String = CommonComponent.DEFAULT.fileNameRegex, override var validMcVersions: Set = CommonComponent.DEFAULT.validMcVersions, override var invalidMcVersions: Set = CommonComponent.DEFAULT.invalidMcVersions, - ) : Common, FileEntry() { + ) : FileEntry() { override fun id() = id override fun applyOverride(override: EntryOverride): Noop { return when (override) { @@ -394,6 +414,10 @@ sealed class FileEntry { } } + override fun copyCommon(): FileEntry { + return copy() + } + override fun toEntry(overrides: Map): FlatEntry = (foldOverrides(overrides) as Noop).let { FlatEntry.Noop( diff --git a/voodoo/src/main/kotlin/voodoo/pack/VersionPack.kt b/voodoo/src/main/kotlin/voodoo/pack/VersionPack.kt index 80c22666..adcf996f 100644 --- a/voodoo/src/main/kotlin/voodoo/pack/VersionPack.kt +++ b/voodoo/src/main/kotlin/voodoo/pack/VersionPack.kt @@ -6,12 +6,11 @@ import kotlinx.serialization.Required import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.builtins.MapSerializer +import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.json.* import mu.KotlinLogging -import voodoo.config.Autocompletions -import voodoo.config.Configuration import voodoo.data.ModloaderPattern import voodoo.data.PackOptions import voodoo.data.flat.FlatModPack @@ -34,16 +33,11 @@ data class VersionPack( val modloader: Modloader, val packageConfiguration: VersionPackageConfig = VersionPackageConfig(), @JsonSchema.Definition("FileEntryList") - val mods: Map>, -// @JsonSchema.Definition("FileEntryList") -// val mods: List, + val mods: Map>, ) { @Transient lateinit var baseDir: File - @Transient - lateinit var modEntries: List - companion object { private val logger = KotlinLogging.logger {} const val extension = "voodoo.json5" @@ -96,9 +90,30 @@ data class VersionPack( jsonObject.toJson(false, true); } - return json.decodeFromString( + val jsonObject = json.decodeFromString( + JsonObject.serializer(), cleanedString + ) + + val mods: Map> = jsonObject["mods"]!!.jsonObject.mapValues { (_, list) -> + list.jsonArray.map { + parseEntry(it) + } + } + + val modsObj = json.encodeToJsonElement( + MapSerializer(String.serializer(), ListSerializer(FileEntry.serializer())), + mods + ) + + val fixedObject = JsonObject( + jsonObject.toMap() + + ("mods" to modsObj) + ) + //TODO: process string entries here + + return json.decodeFromJsonElement( VersionPack.serializer(), - cleanedString + fixedObject ).postParse(packFile.absoluteFile.parentFile) } @@ -118,18 +133,16 @@ data class VersionPack( } fun postParse(baseDir: File): VersionPack { - return this.run { + return run { copy( modloader = modloader.replaceAutoCompletes(), - ).apply { + )/*.apply { modEntries = mods.flatMap { (overrideKey, modsList) -> - modsList.map { element -> - parseEntry(element) - }.map { entry -> + modsList.map { entry -> entry.postParse(overrideKey) } } - } + }*/ }.apply { this.baseDir = baseDir } @@ -163,7 +176,11 @@ data class VersionPack( instanceCfg = packageConfiguration.multimc.instanceCfg ) ), - entrySet = modEntries.map { intitalEntry -> + entrySet = mods.flatMap { (overrideKey, modsList) -> + modsList.map { entry -> + entry.postParse(overrideKey) + } + }.map { intitalEntry -> intitalEntry.toEntry(overrides) }.toMutableSet() ).apply {