Merge 555c474fea1a6bdf84ea4e53baa9909e082a2021 into d51ef24c205b6b05330b3c4d7ce79c402db44447

This commit is contained in:
Loof 2025-09-18 15:08:14 +00:00 committed by GitHub
commit 134c27b588
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 40 additions and 20 deletions

View File

@ -8,16 +8,17 @@ import com.unciv.ui.components.input.onClick
import com.unciv.ui.components.extensions.toTextButton
import com.unciv.ui.screens.basescreen.BaseScreen
class AuthPopup(stage: Stage, authSuccessful: ((Boolean) -> Unit)? = null)
class AuthPopup(stage: Stage, private val authSuccessful: ((Boolean) -> Unit)? = null)
: Popup(stage) {
constructor(screen: BaseScreen, authSuccessful: ((Boolean) -> Unit)? = null) : this(screen.stage, authSuccessful)
init {
val passwordField = UncivTextField("Password")
val button = "Authenticate".toTextButton()
val negativeButtonStyle = BaseScreen.skin.get("negative", TextButton.TextButtonStyle::class.java)
private val passwordField: UncivTextField = UncivTextField("Password")
private val button: TextButton = "Authenticate".toTextButton()
private val negativeButtonStyle: TextButton.TextButtonStyle =
BaseScreen.skin.get("negative", TextButton.TextButtonStyle::class.java)
init {
button.onClick {
try {
UncivGame.Current.onlineMultiplayer.multiplayerServer.authenticate(passwordField.text)
@ -25,17 +26,18 @@ class AuthPopup(stage: Stage, authSuccessful: ((Boolean) -> Unit)? = null)
close()
} catch (_: Exception) {
clear()
addGoodSizedLabel("Authentication failed").colspan(2).row()
add(passwordField).colspan(2).growX().pad(16f, 0f, 16f, 0f).row()
addCloseButton(style = negativeButtonStyle) { authSuccessful?.invoke(false) }.growX().padRight(8f)
add(button).growX().padLeft(8f)
return@onClick
addComponents("Authentication failed")
}
}
addComponents("Please enter your server password")
}
addGoodSizedLabel("Please enter your server password").colspan(2).row()
private fun addComponents(headerLabelText: String) {
addGoodSizedLabel(headerLabelText).colspan(2).row()
add(passwordField).colspan(2).growX().pad(16f, 0f, 16f, 0f).row()
addCloseButton(style = negativeButtonStyle) { authSuccessful?.invoke(false) }.growX().padRight(8f)
addCloseButton(style = negativeButtonStyle) {
authSuccessful?.invoke(false)
}.growX().padRight(8f)
add(button).growX().padLeft(8f)
}
}

View File

@ -70,6 +70,7 @@ import com.unciv.utils.debug
import com.unciv.utils.launchOnGLThread
import com.unciv.utils.launchOnThreadPool
import com.unciv.utils.withGLContext
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import yairm210.purity.annotations.Readonly
@ -595,17 +596,34 @@ class WorldScreen(
gameInfoClone.nextTurn(progressBar)
if (originalGameInfo.gameParameters.isOnlineMultiplayer) {
// outer try-catch for non-auth exceptions
try {
game.onlineMultiplayer.updateGame(gameInfoClone)
}catch (ex: Exception) {
when (ex) {
is MultiplayerAuthException -> {
// keep retrying if upload fails AND reauthentication succeeds
var retryUpload: Boolean
do {
try {
game.onlineMultiplayer.updateGame(gameInfoClone)
// upload succeeded
retryUpload = false
} catch (_: MultiplayerAuthException) {
// true only if authentication succeeds (the popup permits retries)
// false only if user closes the auth popup or the popup init crashes
val authResult = CompletableDeferred<Boolean>()
launchOnGLThread {
AuthPopup(this@WorldScreen) {
success -> if (success) nextTurn()
}.open(true)
try {
AuthPopup(this@WorldScreen, authResult::complete).open(true)
} catch (ex: Exception) {
// GL thread crashed during AuthPopup init, let's wrap up
authResult.complete(false)
// ensure exception is passed to crash handler
throw ex
}
}
retryUpload = authResult.await()
}
} while (retryUpload)
} catch (ex: Exception) { // non-auth exceptions
when (ex) {
is FileStorageRateLimitReached -> {
val message = "Server limit reached! Please wait for [${ex.limitRemainingSeconds}] seconds"
launchOnGLThread {