Mod CI - Really autoupdate uniques

This commit is contained in:
yairm210
2024-07-14 13:48:28 +03:00
parent 4a98eff4d1
commit 74f59bd627
3 changed files with 114 additions and 97 deletions

View File

@ -0,0 +1,107 @@
package com.unciv.models.ruleset.validation
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.unique.Unique
import com.unciv.utils.Log
import com.unciv.utils.debug
object UniqueAutoUpdater{
fun autoupdateUniques(
mod: Ruleset,
replaceableUniques: HashMap<String, String> = getDeprecatedReplaceableUniques(mod)
) {
val filesToReplace = listOf(
"Beliefs.json",
"Buildings.json",
"Nations.json",
"Policies.json",
"Techs.json",
"Terrains.json",
"TileImprovements.json",
"UnitPromotions.json",
"UnitTypes.json",
"Units.json",
"Ruins.json"
)
val jsonFolder = mod.folderLocation!!.child("jsons")
for (fileName in filesToReplace) {
val file = jsonFolder.child(fileName)
if (!file.exists() || file.isDirectory) continue
var newFileText = file.readString()
for ((original, replacement) in replaceableUniques) {
newFileText = newFileText.replace("\"$original\"", "\"$replacement\"")
}
file.writeString(newFileText, false)
}
}
fun getDeprecatedReplaceableUniques(mod: Ruleset): HashMap<String, String> {
val objectsToCheck = sequenceOf(
mod.beliefs,
mod.buildings,
mod.nations,
mod.policies,
mod.technologies,
mod.terrains,
mod.tileImprovements,
mod.unitPromotions,
mod.unitTypes,
mod.units,
mod.ruinRewards
)
val allDeprecatedUniques = HashSet<String>()
val deprecatedUniquesToReplacementText = HashMap<String, String>()
val deprecatedUniques = objectsToCheck
.flatMap { it.values }
.flatMap { it.uniqueObjects }
.filter { it.getDeprecationAnnotation() != null }
for (deprecatedUnique in deprecatedUniques) {
if (allDeprecatedUniques.contains(deprecatedUnique.text)) continue
allDeprecatedUniques.add(deprecatedUnique.text)
// note that this replacement does not contain conditionals attached to the original!
var uniqueReplacementText = deprecatedUnique.getReplacementText(mod)
while (Unique(uniqueReplacementText).getDeprecationAnnotation() != null)
uniqueReplacementText = Unique(uniqueReplacementText).getReplacementText(mod)
for (conditional in deprecatedUnique.conditionals)
uniqueReplacementText += " <${conditional.text}>"
val replacementUnique = Unique(uniqueReplacementText)
val modInvariantErrors = UniqueValidator(mod).checkUnique(
replacementUnique,
false,
null,
true
)
for (error in modInvariantErrors)
Log.error("ModInvariantError: %s - %s", error.text, error.errorSeverityToReport)
if (modInvariantErrors.isNotEmpty()) continue // errors means no autoreplace
if (mod.modOptions.isBaseRuleset) {
val modSpecificErrors = UniqueValidator(mod).checkUnique(
replacementUnique,
false,
null,
true
)
for (error in modSpecificErrors)
Log.error("ModSpecificError: %s - %s", error.text, error.errorSeverityToReport)
if (modSpecificErrors.isNotEmpty()) continue
}
deprecatedUniquesToReplacementText[deprecatedUnique.text] = uniqueReplacementText
debug("Replace \"%s\" with \"%s\"", deprecatedUnique.text, uniqueReplacementText)
}
return deprecatedUniquesToReplacementText
}
}

View File

@ -8,9 +8,8 @@ import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.validation.RulesetErrorSeverity
import com.unciv.models.ruleset.validation.UniqueValidator
import com.unciv.models.ruleset.validation.UniqueAutoUpdater
import com.unciv.models.translations.tr
import com.unciv.ui.components.extensions.surroundWithCircle
import com.unciv.ui.components.extensions.toLabel
@ -25,8 +24,6 @@ import com.unciv.ui.popups.ToastPopup
import com.unciv.ui.screens.UniqueBuilderScreen
import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.utils.Concurrency
import com.unciv.utils.Log
import com.unciv.utils.debug
import com.unciv.utils.launchOnGLThread
@ -137,7 +134,7 @@ class ModCheckTab(
it.add(openUniqueBuilderButton).row()
if (!noProblem && mod.folderLocation != null) {
val replaceableUniques = getDeprecatedReplaceableUniques(mod)
val replaceableUniques = UniqueAutoUpdater.getDeprecatedReplaceableUniques(mod)
if (replaceableUniques.isNotEmpty())
it.add("Autoupdate mod uniques".toTextButton()
.onClick { autoUpdateUniques(screen, mod, replaceableUniques) }).row()
@ -172,101 +169,12 @@ class ModCheckTab(
}
private fun getDeprecatedReplaceableUniques(mod: Ruleset): HashMap<String, String> {
val objectsToCheck = sequenceOf(
mod.beliefs,
mod.buildings,
mod.nations,
mod.policies,
mod.technologies,
mod.terrains,
mod.tileImprovements,
mod.unitPromotions,
mod.unitTypes,
mod.units,
mod.ruinRewards
)
val allDeprecatedUniques = HashSet<String>()
val deprecatedUniquesToReplacementText = HashMap<String, String>()
val deprecatedUniques = objectsToCheck
.flatMap { it.values }
.flatMap { it.uniqueObjects }
.filter { it.getDeprecationAnnotation() != null }
for (deprecatedUnique in deprecatedUniques) {
if (allDeprecatedUniques.contains(deprecatedUnique.text)) continue
allDeprecatedUniques.add(deprecatedUnique.text)
// note that this replacement does not contain conditionals attached to the original!
var uniqueReplacementText = deprecatedUnique.getReplacementText(mod)
while (Unique(uniqueReplacementText).getDeprecationAnnotation() != null)
uniqueReplacementText = Unique(uniqueReplacementText).getReplacementText(mod)
for (conditional in deprecatedUnique.conditionals)
uniqueReplacementText += " <${conditional.text}>"
val replacementUnique = Unique(uniqueReplacementText)
val modInvariantErrors = UniqueValidator(mod).checkUnique(
replacementUnique,
false,
null,
true
)
for (error in modInvariantErrors)
Log.error("ModInvariantError: %s - %s", error.text, error.errorSeverityToReport)
if (modInvariantErrors.isNotEmpty()) continue // errors means no autoreplace
if (mod.modOptions.isBaseRuleset) {
val modSpecificErrors = UniqueValidator(mod).checkUnique(
replacementUnique,
false,
null,
true
)
for (error in modSpecificErrors)
Log.error("ModSpecificError: %s - %s", error.text, error.errorSeverityToReport)
if (modSpecificErrors.isNotEmpty()) continue
}
deprecatedUniquesToReplacementText[deprecatedUnique.text] = uniqueReplacementText
debug("Replace \"%s\" with \"%s\"", deprecatedUnique.text, uniqueReplacementText)
}
return deprecatedUniquesToReplacementText
}
private fun autoUpdateUniques(screen: BaseScreen, mod: Ruleset, replaceableUniques: HashMap<String, String>) {
val filesToReplace = listOf(
"Beliefs.json",
"Buildings.json",
"Nations.json",
"Policies.json",
"Techs.json",
"Terrains.json",
"TileImprovements.json",
"UnitPromotions.json",
"UnitTypes.json",
"Units.json",
"Ruins.json"
)
val jsonFolder = mod.folderLocation!!.child("jsons")
for (fileName in filesToReplace) {
val file = jsonFolder.child(fileName)
if (!file.exists() || file.isDirectory) continue
var newFileText = file.readString()
for ((original, replacement) in replaceableUniques) {
newFileText = newFileText.replace("\"$original\"", "\"$replacement\"")
}
file.writeString(newFileText, false)
}
UniqueAutoUpdater.autoupdateUniques(mod, replaceableUniques)
val toastText = "Uniques updated!"
ToastPopup(toastText, screen)
runModChecker()
}
}

View File

@ -13,6 +13,7 @@ import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.ruleset.validation.RulesetErrorSeverity
import com.unciv.models.ruleset.validation.RulesetValidator
import com.unciv.models.ruleset.validation.UniqueAutoUpdater
import com.unciv.ui.components.fonts.Fonts
import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.utils.Display
@ -36,6 +37,7 @@ internal object DesktopLauncher {
// Load the actual ruleset here
ruleset.load(jsonsFolder)
}
UniqueAutoUpdater.autoupdateUniques(ruleset)
val errors = RulesetValidator(ruleset).getErrorList(true)
println(errors.getErrorText(true))
exitProcess(if (errors.any { it.errorSeverityToReport == RulesetErrorSeverity.Error }) 1 else 0)