Mod loader resilience (#2211)
* For #2200: Avoid MacOS tripping us * Second hidden test in packImages * Clearer message for a specific mod error, UI message for savegames missing mods * Fixed obsolete imports from rejected experiments * Tiny lint issue * Irrelevant change to test push after rebase
This commit is contained in:
parent
3734f39101
commit
4fb7e11354
6 changed files with 49 additions and 12 deletions
|
@ -366,6 +366,12 @@ Upload map = Karte hochladen
|
|||
Could not upload map! = Kann Karte nicht hochladen!
|
||||
Map uploaded successfully! = Karte hochladen war erfolgreich!
|
||||
Saving... = Speichern...
|
||||
It looks like your saved game can't be loaded! = Dieser Spielstand kann nicht geladen werden!
|
||||
If you could copy your game data ("Copy saved game to clipboard" - = Wenn Sie die Spieldaten kopieren ("Gespeichertes Spiel in die Zwischenablage kopieren"),
|
||||
paste into an email to yairm210@hotmail.com) = und in eine mail an mich (yairm210@hotmail.com) einfügen,
|
||||
I could maybe help you figure out what went wrong, since this isn't supposed to happen! = dann kann ich eventuell helfen den Grund zu finden - das sollte nicht passieren!
|
||||
Missing mods: [mods] = Der Spielstand benötigt das/die mod(s) [mods], diese sind aber nicht verfügbar.
|
||||
|
||||
|
||||
# Options
|
||||
|
||||
|
|
|
@ -366,6 +366,11 @@ Upload map =
|
|||
Could not upload map! =
|
||||
Map uploaded successfully! =
|
||||
Saving... =
|
||||
It looks like your saved game can't be loaded! =
|
||||
If you could copy your game data ("Copy saved game to clipboard" - =
|
||||
paste into an email to yairm210@hotmail.com) =
|
||||
I could maybe help you figure out what went wrong, since this isn't supposed to happen! =
|
||||
Missing mods: [mods] =
|
||||
|
||||
# Options
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ import com.unciv.models.ruleset.RulesetCache
|
|||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class UncivShowableException(missingMods: String) : Exception(missingMods)
|
||||
|
||||
class GameInfo {
|
||||
@Transient lateinit var difficultyObject: Difficulty // Since this is static game-wide, and was taking a large part of nextTurn
|
||||
@Transient lateinit var currentPlayerCiv:CivilizationInfo // this is called thousands of times, no reason to search for it with a find{} every time
|
||||
|
@ -219,6 +221,15 @@ class GameInfo {
|
|||
fun setTransients() {
|
||||
tileMap.gameInfo = this
|
||||
ruleSet = RulesetCache.getComplexRuleset(gameParameters.mods)
|
||||
// any mod the saved game lists that is currently not installed causes null pointer
|
||||
// exceptions in this routine unless it contained no new objects or was very simple.
|
||||
// Player's fault, so better complain early:
|
||||
val missingMods = gameParameters.mods
|
||||
.filterNot { it in ruleSet.mods }
|
||||
.joinToString(limit = 120) { it }
|
||||
if (missingMods.isNotEmpty()) {
|
||||
throw UncivShowableException("Missing mods: [$missingMods]")
|
||||
}
|
||||
|
||||
// Renames as of version 3.1.8, because of translation conflicts with the property "Range" and the difficulty "Immortal"
|
||||
// Needs to be BEFORE tileMap.setTransients, because the units' setTransients is called from there
|
||||
|
@ -370,3 +381,4 @@ class GameInfo {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.unciv.models.ruleset
|
|||
import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.unciv.JsonParser
|
||||
import com.unciv.logic.UncivShowableException
|
||||
import com.unciv.models.ruleset.tech.TechColumn
|
||||
import com.unciv.models.ruleset.tech.Technology
|
||||
import com.unciv.models.ruleset.tile.Terrain
|
||||
|
@ -91,10 +92,11 @@ class Ruleset() {
|
|||
if(buildingsFile.exists()) {
|
||||
buildings += createHashmap(jsonParser.getFromJson(Array<Building>::class.java, buildingsFile))
|
||||
for (building in buildings.values) {
|
||||
if (building.requiredTech == null) continue
|
||||
val column = technologies[building.requiredTech!!]!!.column
|
||||
if (building.cost == 0)
|
||||
building.cost = if (building.isWonder || building.isNationalWonder) column!!.wonderCost else column!!.buildingCost
|
||||
if (building.cost == 0) {
|
||||
val column = technologies[building.requiredTech]?.column
|
||||
?: throw UncivShowableException("Building (${building.name}) must either have an explicit cost or a required tech in the same mod")
|
||||
building.cost = if (building.isWonder || building.isNationalWonder) column.wonderCost else column.buildingCost
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,14 +151,18 @@ object RulesetCache :HashMap<String,Ruleset>(){
|
|||
this[""] = Ruleset().apply { load(Gdx.files.internal("jsons")) }
|
||||
|
||||
for(modFolder in Gdx.files.local("mods").list()){
|
||||
if (modFolder.name().startsWith('.')) continue
|
||||
try{
|
||||
val modRuleset = Ruleset()
|
||||
modRuleset.load(modFolder.child("jsons"))
|
||||
modRuleset.name = modFolder.name()
|
||||
this[modRuleset.name] = modRuleset
|
||||
println ("Mod loaded successfully: " + modRuleset.name)
|
||||
}
|
||||
catch (ex:Exception){
|
||||
println( "Exception loading " + modFolder.name() + ": " + ex.message )
|
||||
println ("Exception loading mod '${modFolder.name()}':")
|
||||
println (" ${ex.localizedMessage}")
|
||||
println (" (Source file ${ex.stackTrace[0].fileName} line ${ex.stackTrace[0].lineNumber})")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
|||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.GameSaver
|
||||
import com.unciv.logic.UncivShowableException
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.utils.disable
|
||||
|
@ -44,11 +45,17 @@ class LoadGameScreen : PickerScreen() {
|
|||
catch (ex:Exception){
|
||||
val cantLoadGamePopup = Popup(this)
|
||||
cantLoadGamePopup.addGoodSizedLabel("It looks like your saved game can't be loaded!").row()
|
||||
cantLoadGamePopup.addGoodSizedLabel("If you could copy your game data (\"Copy saved game to clipboard\" - ").row()
|
||||
cantLoadGamePopup.addGoodSizedLabel(" paste into an email to yairm210@hotmail.com)").row()
|
||||
cantLoadGamePopup.addGoodSizedLabel("I could maybe help you figure out what went wrong, since this isn't supposed to happen!").row()
|
||||
cantLoadGamePopup.open()
|
||||
ex.printStackTrace()
|
||||
if (ex is UncivShowableException && ex.localizedMessage != null) {
|
||||
// thrown exceptions are our own tests and can be shown to the user
|
||||
cantLoadGamePopup.addGoodSizedLabel(ex.localizedMessage).row()
|
||||
cantLoadGamePopup.open()
|
||||
} else {
|
||||
cantLoadGamePopup.addGoodSizedLabel("If you could copy your game data (\"Copy saved game to clipboard\" - ").row()
|
||||
cantLoadGamePopup.addGoodSizedLabel(" paste into an email to yairm210@hotmail.com)").row()
|
||||
cantLoadGamePopup.addGoodSizedLabel("I could maybe help you figure out what went wrong, since this isn't supposed to happen!").row()
|
||||
cantLoadGamePopup.open()
|
||||
ex.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ internal object DesktopLauncher {
|
|||
val modDirectory = File("mods")
|
||||
if(modDirectory.exists()) {
|
||||
for (mod in modDirectory.listFiles()!!){
|
||||
TexturePacker.process(settings, mod.path + "/Images", mod.path, "game")
|
||||
if (!mod.isHidden && File(mod.path + "/Images").exists())
|
||||
TexturePacker.process(settings, mod.path + "/Images", mod.path, "game")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,6 +98,6 @@ internal object DesktopLauncher {
|
|||
presence.details=currentPlayerCiv.nation.getLeaderDisplayName().tr()
|
||||
presence.largeImageKey = "logo" // The actual image is uploaded to the discord app / applications webpage
|
||||
presence.largeImageText ="Turn".tr()+" " + currentPlayerCiv.gameInfo.turns
|
||||
DiscordRPC.INSTANCE.Discord_UpdatePresence(presence);
|
||||
DiscordRPC.INSTANCE.Discord_UpdatePresence(presence)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue