Fix multiplayer turn checker potentially stopping turn checks for everyone that plays that game if a file was not found remotely (#6901)

This commit is contained in:
Timo T 2022-05-22 09:13:48 +02:00 committed by GitHub
parent 244f9477df
commit f34b97a421
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 47 deletions

View File

@ -190,11 +190,9 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
for (gameFile in gameFiles) {
try {
val gamePreview = gameSaver.loadGamePreviewFromFile(gameFile)
if (gamePreview.turnNotification) {
gameIds[count] = gamePreview.gameId
gameNames[count] = gameFile.name()
count++
}
gameIds[count] = gamePreview.gameId
gameNames[count] = gameFile.name()
count++
} catch (ex: Throwable) {
//only loadGamePreviewFromFile can throw an exception
//nothing will be added to the arrays if it fails
@ -207,9 +205,8 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
if (currentGameInfo.currentPlayerCiv.playerId == settings.userId) {
// May be useful to remind a player that he forgot to complete his turn.
val gameIndex = gameIds.indexOf(currentGameInfo.gameId)
// Of the turnNotification is OFF, this will be -1 since we never saved this game in the array
// Or possibly reading the preview file returned an exception
if (gameIndex!=-1) {
// If reading the preview file threw an exception, gameIndex will be -1
if (gameIndex != -1) {
notifyUserAboutTurn(applicationContext, Pair(gameNames[gameIndex], gameIds[gameIndex]))
}
} else {
@ -252,6 +249,12 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
}
}
/**
* Contains gameIds that, if true is set for them, we will not check for updates again. The data here only lives until the user enters Unciv again,
* so if the user changes their remote server, this will be reset and we will check for turns again.
*/
private val notFoundRemotely = mutableMapOf<String, Boolean>()
private val gameSaver = GameSaver
init {
// We can't use Gdx.files since that is only initialized within a com.badlogic.gdx.backends.android.AndroidApplication.
@ -282,6 +285,11 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
if (gameId.isEmpty())
continue
if (notFoundRemotely[gameId] == true) {
// Since the save was not found on the remote server, we do not need to check again, it'll only fail again.
continue
}
try {
Log.d(LOG_TAG, "doWork download ${gameId}")
val gamePreview = OnlineMultiplayerGameSaver(fileStorage).tryDownloadGamePreview(gameId)
@ -313,9 +321,7 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
// FileNotFoundException is thrown by OnlineMultiplayer().tryDownloadGamePreview(gameId)
// and indicates that there is no game preview present for this game
// in the dropbox so we should not check for this game in the future anymore
val currentGamePreview = gameSaver.loadGamePreviewByName(gameNames[arrayIndex])
currentGamePreview.turnNotification = false
gameSaver.saveGame(currentGamePreview, gameNames[arrayIndex])
notFoundRemotely[gameId] = true
}
}

View File

@ -139,7 +139,7 @@ class GameInfo {
civilizations.firstOrNull {
it.isSpectator() && it.playerId == playerId
} ?:
CivilizationInfo(Constants.spectator).also {
CivilizationInfo(Constants.spectator).also {
it.playerType = PlayerType.Human
it.playerId = playerId
civilizations.add(it)
@ -179,14 +179,14 @@ class GameInfo {
}
}
}
fun getYear(turnOffset: Int = 0): Int {
val turn = getEquivalentTurn() + turnOffset
val yearToTurnList = YearsToTurn.getList(gameParameters.gameSpeed)
var year: Float = -4000f
var i = 0
var yearsPerTurn: Float
// if macros are ever added to kotlin, this is one hell of a place for em'
while (i < turn) {
yearsPerTurn = yearToTurnList.firstOrNull { i < it.toTurn }?.yearInterval ?: 0.5f
@ -292,7 +292,7 @@ class GameInfo {
}
)
}
fun getEnabledVictories() = ruleSet.victories.filter { !it.value.hiddenInVictoryScreen && gameParameters.victoryTypes.contains(it.key) }
fun processDiplomaticVictory() {
@ -344,7 +344,7 @@ class GameInfo {
val exploredRevealTiles: Sequence<TileInfo> =
if (ruleSet.tileResources[resourceName]!!.hasUnique(UniqueType.CityStateOnlyResource)) {
// Look for matching mercantile CS centers
// Look for matching mercantile CS centers
getAliveCityStates()
.asSequence()
.filter { it.cityStateResource == resourceName }
@ -423,7 +423,7 @@ class GameInfo {
for (baseUnit in ruleSet.units.values)
baseUnit.ruleset = ruleSet
// This needs to go before tileMap.setTransients, as units need to access
// This needs to go before tileMap.setTransients, as units need to access
// the nation of their civilization when setting transients
for (civInfo in civilizations) civInfo.gameInfo = this
for (civInfo in civilizations) civInfo.setNationTransient()
@ -479,7 +479,7 @@ class GameInfo {
spaceResources.addAll(ruleSet.buildings.values.filter { it.hasUnique(UniqueType.SpaceshipPart) }
.flatMap { it.getResourceRequirements().keys } )
spaceResources.addAll(ruleSet.victories.values.flatMap { it.requiredSpaceshipParts })
barbarians.setTransients(this)
guaranteeUnitPromotions()
@ -502,7 +502,6 @@ class GameInfoPreview() {
var gameId = ""
var currentPlayer = ""
var currentTurnStartTime = 0L
var turnNotification = true //used as setting in the MultiplayerScreen
/**
* Converts a GameInfo object (can be uninitialized) into a GameInfoPreview object.
@ -519,32 +518,4 @@ class GameInfoPreview() {
}
fun getCivilization(civName: String) = civilizations.first { it.civName == civName }
/**
* Updates the current player and turn information in the GameInfoPreview object with the help of a
* GameInfo object (can be uninitialized).
*/
fun updateCurrentTurn(gameInfo: GameInfo) : GameInfoPreview {
currentPlayer = gameInfo.currentPlayer
turns = gameInfo.turns
currentTurnStartTime = gameInfo.currentTurnStartTime
//We update the civilizations in case someone is removed from the game (resign/kick)
civilizations = gameInfo.getCivilizationsAsPreviews()
return this
}
/**
* Updates the current player and turn information in the GameInfoPreview object with the
* help of another GameInfoPreview object.
*/
fun updateCurrentTurn(gameInfo: GameInfoPreview) : GameInfoPreview {
currentPlayer = gameInfo.currentPlayer
turns = gameInfo.turns
currentTurnStartTime = gameInfo.currentTurnStartTime
//We update the civilizations in case someone is removed from the game (resign/kick)
civilizations = gameInfo.civilizations
return this
}
}