Multi-server preparations: Save server info in game, save server functionality in specific class (#9379)

* Save server info in game

* Moved server functionality into server class

* Fix Android multiplayer update
This commit is contained in:
Yair Morgenstern
2023-05-13 21:51:44 +03:00
committed by GitHub
parent 97769b89b6
commit 48bd416347
8 changed files with 99 additions and 96 deletions

View File

@ -29,7 +29,7 @@ import com.badlogic.gdx.backends.android.DefaultAndroidFiles
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
import com.unciv.logic.files.UncivFiles import com.unciv.logic.files.UncivFiles
import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached
import com.unciv.logic.multiplayer.storage.OnlineMultiplayerFiles import com.unciv.logic.multiplayer.storage.OnlineMultiplayerServer
import com.unciv.models.metadata.GameSettingsMultiplayer import com.unciv.models.metadata.GameSettingsMultiplayer
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import java.io.FileNotFoundException import java.io.FileNotFoundException
@ -307,7 +307,7 @@ class MultiplayerTurnCheckWorker(appContext: Context, workerParams: WorkerParame
try { try {
Log.d(LOG_TAG, "doWork download $gameId") Log.d(LOG_TAG, "doWork download $gameId")
val gamePreview = OnlineMultiplayerFiles(fileStorage, mapOf("Authorization" to authHeader)).tryDownloadGamePreview(gameId) val gamePreview = OnlineMultiplayerServer(fileStorage, mapOf("Authorization" to authHeader)).tryDownloadGamePreview(gameId)
Log.d(LOG_TAG, "doWork download $gameId done") Log.d(LOG_TAG, "doWork download $gameId done")
val currentTurnPlayer = gamePreview.getCivilization(gamePreview.currentPlayer) val currentTurnPlayer = gamePreview.getCivilization(gamePreview.currentPlayer)

View File

@ -182,7 +182,7 @@ open class UncivGame(val isConsoleMode: Boolean = false) : Game(), PlatformSpeci
Concurrency.run { Concurrency.run {
// Check if the server is available in case the feature set has changed // Check if the server is available in case the feature set has changed
try { try {
onlineMultiplayer.checkServerStatus() onlineMultiplayer.multiplayerServer.checkServerStatus()
} catch (ex: Exception) { } catch (ex: Exception) {
debug("Couldn't connect to server: " + ex.message) debug("Couldn't connect to server: " + ex.message)
} }

View File

@ -3,7 +3,6 @@ package com.unciv.logic.multiplayer
import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.files.FileHandle
import com.unciv.Constants import com.unciv.Constants
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.json.json
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
import com.unciv.logic.GameInfoPreview import com.unciv.logic.GameInfoPreview
import com.unciv.logic.civilization.NotificationCategory import com.unciv.logic.civilization.NotificationCategory
@ -12,15 +11,13 @@ import com.unciv.logic.event.EventBus
import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached
import com.unciv.logic.multiplayer.storage.MultiplayerAuthException import com.unciv.logic.multiplayer.storage.MultiplayerAuthException
import com.unciv.logic.multiplayer.storage.MultiplayerFileNotFoundException import com.unciv.logic.multiplayer.storage.MultiplayerFileNotFoundException
import com.unciv.logic.multiplayer.storage.OnlineMultiplayerFiles import com.unciv.logic.multiplayer.storage.OnlineMultiplayerServer
import com.unciv.ui.components.extensions.isLargerThan import com.unciv.ui.components.extensions.isLargerThan
import com.unciv.logic.multiplayer.storage.SimpleHttp
import com.unciv.utils.Log
import com.unciv.utils.Concurrency import com.unciv.utils.Concurrency
import com.unciv.utils.Dispatcher import com.unciv.utils.Dispatcher
import com.unciv.utils.debug
import com.unciv.utils.launchOnThreadPool import com.unciv.utils.launchOnThreadPool
import com.unciv.utils.withGLContext import com.unciv.utils.withGLContext
import com.unciv.utils.debug
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -45,8 +42,7 @@ private val FILE_UPDATE_THROTTLE_PERIOD = Duration.ofSeconds(60)
*/ */
class OnlineMultiplayer { class OnlineMultiplayer {
private val files = UncivGame.Current.files private val files = UncivGame.Current.files
private val multiplayerFiles = OnlineMultiplayerFiles() val multiplayerServer = OnlineMultiplayerServer()
private var featureSet = ServerFeatureSet()
private val savedGames: MutableMap<FileHandle, OnlineMultiplayerGame> = Collections.synchronizedMap(mutableMapOf()) private val savedGames: MutableMap<FileHandle, OnlineMultiplayerGame> = Collections.synchronizedMap(mutableMapOf())
@ -55,7 +51,6 @@ class OnlineMultiplayer {
private val lastCurGameRefresh: AtomicReference<Instant?> = AtomicReference() private val lastCurGameRefresh: AtomicReference<Instant?> = AtomicReference()
val games: Set<OnlineMultiplayerGame> get() = savedGames.values.toSet() val games: Set<OnlineMultiplayerGame> get() = savedGames.values.toSet()
val serverFeatureSet: ServerFeatureSet get() = featureSet
init { init {
flow<Unit> { flow<Unit> {
@ -125,7 +120,7 @@ class OnlineMultiplayer {
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time * @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
*/ */
suspend fun createGame(newGame: GameInfo) { suspend fun createGame(newGame: GameInfo) {
multiplayerFiles.tryUploadGame(newGame, withPreview = true) multiplayerServer.tryUploadGame(newGame, withPreview = true)
addGame(newGame) addGame(newGame)
} }
@ -139,11 +134,12 @@ class OnlineMultiplayer {
*/ */
suspend fun addGame(gameId: String, gameName: String? = null) { suspend fun addGame(gameId: String, gameName: String? = null) {
val saveFileName = if (gameName.isNullOrBlank()) gameId else gameName val saveFileName = if (gameName.isNullOrBlank()) gameId else gameName
val gamePreview: GameInfoPreview = try { var gamePreview: GameInfoPreview
multiplayerFiles.tryDownloadGamePreview(gameId) try {
gamePreview = multiplayerServer.tryDownloadGamePreview(gameId)
} catch (ex: MultiplayerFileNotFoundException) { } catch (ex: MultiplayerFileNotFoundException) {
// Game is so old that a preview could not be found on dropbox lets try the real gameInfo instead // Game is so old that a preview could not be found on dropbox lets try the real gameInfo instead
multiplayerFiles.tryDownloadGame(gameId).asPreview() gamePreview = multiplayerServer.tryDownloadGame(gameId).asPreview()
} }
addGame(gamePreview, saveFileName) addGame(gamePreview, saveFileName)
} }
@ -189,7 +185,7 @@ class OnlineMultiplayer {
suspend fun resign(game: OnlineMultiplayerGame): Boolean { suspend fun resign(game: OnlineMultiplayerGame): Boolean {
val preview = game.preview ?: throw game.error!! val preview = game.preview ?: throw game.error!!
// download to work with the latest game state // download to work with the latest game state
val gameInfo = multiplayerFiles.tryDownloadGame(preview.gameId) val gameInfo = multiplayerServer.tryDownloadGame(preview.gameId)
val playerCiv = gameInfo.getCurrentPlayerCivilization() val playerCiv = gameInfo.getCurrentPlayerCivilization()
if (!gameInfo.isUsersTurn()) { if (!gameInfo.isUsersTurn()) {
@ -212,7 +208,7 @@ class OnlineMultiplayer {
val newPreview = gameInfo.asPreview() val newPreview = gameInfo.asPreview()
files.saveGame(newPreview, game.fileHandle) files.saveGame(newPreview, game.fileHandle)
multiplayerFiles.tryUploadGame(gameInfo, withPreview = true) multiplayerServer.tryUploadGame(gameInfo, withPreview = true)
game.doManualUpdate(newPreview) game.doManualUpdate(newPreview)
return true return true
} }
@ -248,7 +244,7 @@ class OnlineMultiplayer {
*/ */
suspend fun loadGame(gameInfo: GameInfo) = coroutineScope { suspend fun loadGame(gameInfo: GameInfo) = coroutineScope {
val gameId = gameInfo.gameId val gameId = gameInfo.gameId
val preview = multiplayerFiles.tryDownloadGamePreview(gameId) val preview = multiplayerServer.tryDownloadGamePreview(gameId)
if (hasLatestGameState(gameInfo, preview)) { if (hasLatestGameState(gameInfo, preview)) {
gameInfo.isUpToDate = true gameInfo.isUpToDate = true
UncivGame.Current.loadGame(gameInfo) UncivGame.Current.loadGame(gameInfo)
@ -262,7 +258,7 @@ class OnlineMultiplayer {
* @throws MultiplayerFileNotFoundException if the file can't be found * @throws MultiplayerFileNotFoundException if the file can't be found
*/ */
suspend fun downloadGame(gameId: String): GameInfo { suspend fun downloadGame(gameId: String): GameInfo {
val latestGame = multiplayerFiles.tryDownloadGame(gameId) val latestGame = multiplayerServer.tryDownloadGame(gameId)
latestGame.isUpToDate = true latestGame.isUpToDate = true
return latestGame return latestGame
} }
@ -311,7 +307,7 @@ class OnlineMultiplayer {
*/ */
suspend fun updateGame(gameInfo: GameInfo) { suspend fun updateGame(gameInfo: GameInfo) {
debug("Updating remote game %s", gameInfo.gameId) debug("Updating remote game %s", gameInfo.gameId)
multiplayerFiles.tryUploadGame(gameInfo, withPreview = true) multiplayerServer.tryUploadGame(gameInfo, withPreview = true)
val game = getGameByGameId(gameInfo.gameId) val game = getGameByGameId(gameInfo.gameId)
debug("Existing OnlineMultiplayerGame: %s", game) debug("Existing OnlineMultiplayerGame: %s", game)
if (game == null) { if (game == null) {
@ -330,66 +326,6 @@ class OnlineMultiplayer {
&& gameInfo.turns == preview.turns && gameInfo.turns == preview.turns
} }
/**
* Checks if the server is alive and sets the [serverFeatureSet] accordingly.
* @return true if the server is alive, false otherwise
*/
fun checkServerStatus(): Boolean {
var statusOk = false
SimpleHttp.sendGetRequest("${UncivGame.Current.settings.multiplayer.server}/isalive") { success, result, _ ->
statusOk = success
if (result.isNotEmpty()) {
featureSet = try {
json().fromJson(ServerFeatureSet::class.java, result)
} catch (ex: Exception) {
Log.error("${UncivGame.Current.settings.multiplayer.server} does not support server feature set", ex)
ServerFeatureSet()
}
}
}
return statusOk
}
/**
* @return true if the authentication was successful or the server does not support authentication.
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
* @throws MultiplayerAuthException if the authentication failed
*/
fun authenticate(password: String?): Boolean {
if (featureSet.authVersion == 0) {
return true
}
val settings = UncivGame.Current.settings.multiplayer
val success = multiplayerFiles.fileStorage().authenticate(
userId=settings.userId,
password=password ?: settings.passwords[settings.server] ?: ""
)
if (password != null && success) {
settings.passwords[settings.server] = password
}
return success
}
/**
* @return true if setting the password was successful, false otherwise.
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
* @throws MultiplayerAuthException if the authentication failed
*/
fun setPassword(password: String): Boolean {
if (
featureSet.authVersion > 0 &&
multiplayerFiles.fileStorage().setPassword(newPassword = password)
) {
val settings = UncivGame.Current.settings.multiplayer
settings.passwords[settings.server] = password
return true
}
return false
}
/** /**
* Checks if [preview1] has a more recent game state than [preview2] * Checks if [preview1] has a more recent game state than [preview2]

View File

@ -8,11 +8,11 @@ import com.unciv.logic.multiplayer.GameUpdateResult.Type.CHANGED
import com.unciv.logic.multiplayer.GameUpdateResult.Type.FAILURE import com.unciv.logic.multiplayer.GameUpdateResult.Type.FAILURE
import com.unciv.logic.multiplayer.GameUpdateResult.Type.UNCHANGED import com.unciv.logic.multiplayer.GameUpdateResult.Type.UNCHANGED
import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached import com.unciv.logic.multiplayer.storage.FileStorageRateLimitReached
import com.unciv.logic.multiplayer.storage.OnlineMultiplayerFiles import com.unciv.logic.multiplayer.storage.OnlineMultiplayerServer
import com.unciv.ui.components.extensions.isLargerThan import com.unciv.ui.components.extensions.isLargerThan
import com.unciv.utils.debug
import com.unciv.utils.launchOnGLThread import com.unciv.utils.launchOnGLThread
import com.unciv.utils.withGLContext import com.unciv.utils.withGLContext
import com.unciv.utils.debug
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import java.time.Duration import java.time.Duration
import java.time.Instant import java.time.Instant
@ -65,7 +65,7 @@ class OnlineMultiplayerGame(
* Fires: [MultiplayerGameUpdateStarted], [MultiplayerGameUpdated], [MultiplayerGameUpdateUnchanged], [MultiplayerGameUpdateFailed] * Fires: [MultiplayerGameUpdateStarted], [MultiplayerGameUpdated], [MultiplayerGameUpdateUnchanged], [MultiplayerGameUpdateFailed]
* *
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time * @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
* @throws MultiplayerFileNotFoundException if the file can't be found * @throws MultiplayerFileNotFoundException if the file can't be found
*/ */
suspend fun requestUpdate(forceUpdate: Boolean = false) = coroutineScope { suspend fun requestUpdate(forceUpdate: Boolean = false) = coroutineScope {
val onUnchanged = { GameUpdateResult(UNCHANGED, preview!!) } val onUnchanged = { GameUpdateResult(UNCHANGED, preview!!) }
@ -106,7 +106,8 @@ class OnlineMultiplayerGame(
private suspend fun update(): GameUpdateResult { private suspend fun update(): GameUpdateResult {
val curPreview = if (preview != null) preview!! else loadPreviewFromFile() val curPreview = if (preview != null) preview!! else loadPreviewFromFile()
val newPreview = OnlineMultiplayerFiles().tryDownloadGamePreview(curPreview.gameId) val serverIdentifier = curPreview.gameParameters.multiplayerServerUrl
val newPreview = OnlineMultiplayerServer(serverIdentifier).tryDownloadGamePreview(curPreview.gameId)
if (newPreview.turns == curPreview.turns && newPreview.currentPlayer == curPreview.currentPlayer) return GameUpdateResult(UNCHANGED, newPreview) if (newPreview.turns == curPreview.turns && newPreview.currentPlayer == curPreview.currentPlayer) return GameUpdateResult(UNCHANGED, newPreview)
UncivGame.Current.files.saveGame(newPreview, fileHandle) UncivGame.Current.files.saveGame(newPreview, fileHandle)
preview = newPreview preview = newPreview

View File

@ -2,9 +2,12 @@ package com.unciv.logic.multiplayer.storage
import com.unciv.Constants import com.unciv.Constants
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.json.json
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
import com.unciv.logic.GameInfoPreview import com.unciv.logic.GameInfoPreview
import com.unciv.logic.files.UncivFiles import com.unciv.logic.files.UncivFiles
import com.unciv.logic.multiplayer.ServerFeatureSet
import com.unciv.utils.Log
/** /**
* Allows access to games stored on a server for multiplayer purposes. * Allows access to games stored on a server for multiplayer purposes.
@ -17,12 +20,14 @@ import com.unciv.logic.files.UncivFiles
* @see UncivGame.Current.settings.multiplayerServer * @see UncivGame.Current.settings.multiplayerServer
*/ */
@Suppress("RedundantSuspendModifier") // Methods can take a long time, so force users to use them in a coroutine to not get ANRs on Android @Suppress("RedundantSuspendModifier") // Methods can take a long time, so force users to use them in a coroutine to not get ANRs on Android
class OnlineMultiplayerFiles( class OnlineMultiplayerServer(
private var fileStorageIdentifier: String? = null, fileStorageIdentifier: String? = null,
private var authenticationHeader: Map<String, String>? = null private var authenticationHeader: Map<String, String>? = null
) { ) {
internal var featureSet = ServerFeatureSet()
val serverUrl = fileStorageIdentifier ?: UncivGame.Current.settings.multiplayer.server
fun fileStorage(): FileStorage { fun fileStorage(): FileStorage {
val identifier = if (fileStorageIdentifier == null) UncivGame.Current.settings.multiplayer.server else fileStorageIdentifier
val authHeader = if (authenticationHeader == null) { val authHeader = if (authenticationHeader == null) {
val settings = UncivGame.Current.settings.multiplayer val settings = UncivGame.Current.settings.multiplayer
mapOf("Authorization" to settings.getAuthHeader()) mapOf("Authorization" to settings.getAuthHeader())
@ -30,16 +35,73 @@ class OnlineMultiplayerFiles(
authenticationHeader authenticationHeader
} }
return if (identifier == Constants.dropboxMultiplayerServer) { return if (serverUrl == Constants.dropboxMultiplayerServer) {
DropBox DropBox
} else { } else {
UncivServerFileStorage.apply { UncivServerFileStorage.apply {
serverUrl = identifier!! serverUrl = this@OnlineMultiplayerServer.serverUrl
this.authHeader = authHeader this.authHeader = authHeader
} }
} }
} }
/**
* Checks if the server is alive and sets the [serverFeatureSet] accordingly.
* @return true if the server is alive, false otherwise
*/
fun checkServerStatus(): Boolean {
var statusOk = false
SimpleHttp.sendGetRequest("${serverUrl}/isalive") { success, result, _ ->
statusOk = success
if (result.isNotEmpty()) {
featureSet = try {
json().fromJson(ServerFeatureSet::class.java, result)
} catch (ex: Exception) {
Log.error("${UncivGame.Current.settings.multiplayer.server} does not support server feature set", ex)
ServerFeatureSet()
}
}
}
return statusOk
}
/**
* @return true if the authentication was successful or the server does not support authentication.
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
* @throws MultiplayerAuthException if the authentication failed
*/
fun authenticate(password: String?): Boolean {
if (featureSet.authVersion == 0) return true
val settings = UncivGame.Current.settings.multiplayer
val success = fileStorage().authenticate(
userId=settings.userId,
password=password ?: settings.passwords[settings.server] ?: ""
)
if (password != null && success) {
settings.passwords[settings.server] = password
}
return success
}
/**
* @return true if setting the password was successful, false otherwise.
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
* @throws MultiplayerAuthException if the authentication failed
*/
fun setPassword(password: String): Boolean {
if (featureSet.authVersion > 0 && fileStorage().setPassword(newPassword = password)) {
val settings = UncivGame.Current.settings.multiplayer
settings.passwords[settings.server] = password
return true
}
return false
}
/** /**
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time * @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
* @throws MultiplayerAuthException if the authentication failed * @throws MultiplayerAuthException if the authentication failed
@ -81,7 +143,9 @@ class OnlineMultiplayerFiles(
*/ */
suspend fun tryDownloadGame(gameId: String): GameInfo { suspend fun tryDownloadGame(gameId: String): GameInfo {
val zippedGameInfo = fileStorage().loadFileData(gameId) val zippedGameInfo = fileStorage().loadFileData(gameId)
return UncivFiles.gameInfoFromString(zippedGameInfo) val gameInfo = UncivFiles.gameInfoFromString(zippedGameInfo)
gameInfo.gameParameters.multiplayerServerUrl = UncivGame.Current.settings.multiplayer.server
return gameInfo
} }
/** /**

View File

@ -43,6 +43,7 @@ class GameParameters : IsPartOfGameInfoSerialization { // Default values are the
var startingEra = "Ancient era" var startingEra = "Ancient era"
var isOnlineMultiplayer = false var isOnlineMultiplayer = false
var multiplayerServerUrl: String? = null
var anyoneCanSpectate = true var anyoneCanSpectate = true
var baseRuleset: String = BaseRuleset.Civ_V_GnK.fullName var baseRuleset: String = BaseRuleset.Civ_V_GnK.fullName
var mods = LinkedHashSet<String>() var mods = LinkedHashSet<String>()
@ -74,6 +75,7 @@ class GameParameters : IsPartOfGameInfoSerialization { // Default values are the
parameters.victoryTypes = ArrayList(victoryTypes) parameters.victoryTypes = ArrayList(victoryTypes)
parameters.startingEra = startingEra parameters.startingEra = startingEra
parameters.isOnlineMultiplayer = isOnlineMultiplayer parameters.isOnlineMultiplayer = isOnlineMultiplayer
parameters.multiplayerServerUrl = multiplayerServerUrl
parameters.anyoneCanSpectate = anyoneCanSpectate parameters.anyoneCanSpectate = anyoneCanSpectate
parameters.baseRuleset = baseRuleset parameters.baseRuleset = baseRuleset
parameters.mods = LinkedHashSet(mods) parameters.mods = LinkedHashSet(mods)

View File

@ -20,7 +20,7 @@ class AuthPopup(stage: Stage, authSuccessful: ((Boolean) -> Unit)? = null)
button.onClick { button.onClick {
try { try {
UncivGame.Current.onlineMultiplayer.authenticate(passwordField.text) UncivGame.Current.onlineMultiplayer.multiplayerServer.authenticate(passwordField.text)
authSuccessful?.invoke(true) authSuccessful?.invoke(true)
close() close()
} catch (ex: Exception) { } catch (ex: Exception) {

View File

@ -192,7 +192,7 @@ private fun addMultiplayerServerOptions(
} }
}).row() }).row()
if (UncivGame.Current.onlineMultiplayer.serverFeatureSet.authVersion > 0) { if (UncivGame.Current.onlineMultiplayer.multiplayerServer.featureSet.authVersion > 0) {
val passwordTextField = UncivTextField.create( val passwordTextField = UncivTextField.create(
settings.multiplayer.passwords[settings.multiplayer.server] ?: "Password" settings.multiplayer.passwords[settings.multiplayer.server] ?: "Password"
) )
@ -255,11 +255,11 @@ private fun addTurnCheckerOptions(
private fun successfullyConnectedToServer(action: (Boolean, Boolean) -> Unit) { private fun successfullyConnectedToServer(action: (Boolean, Boolean) -> Unit) {
Concurrency.run("TestIsAlive") { Concurrency.run("TestIsAlive") {
try { try {
val connectionSuccess = UncivGame.Current.onlineMultiplayer.checkServerStatus() val connectionSuccess = UncivGame.Current.onlineMultiplayer.multiplayerServer.checkServerStatus()
var authSuccess = false var authSuccess = false
if (connectionSuccess) { if (connectionSuccess) {
try { try {
authSuccess = UncivGame.Current.onlineMultiplayer.authenticate(null) authSuccess = UncivGame.Current.onlineMultiplayer.multiplayerServer.authenticate(null)
} catch (_: Exception) { } catch (_: Exception) {
// We ignore the exception here, because we handle the failed auth onGLThread // We ignore the exception here, because we handle the failed auth onGLThread
} }
@ -289,7 +289,7 @@ private fun setPassword(password: String, optionsPopup: OptionsPopup) {
return return
} }
if (UncivGame.Current.onlineMultiplayer.serverFeatureSet.authVersion == 0) { if (UncivGame.Current.onlineMultiplayer.multiplayerServer.featureSet.authVersion == 0) {
popup.reuseWith("This server does not support authentication", true) popup.reuseWith("This server does not support authentication", true)
return return
} }
@ -327,7 +327,7 @@ private fun setPassword(password: String, optionsPopup: OptionsPopup) {
private fun successfullySetPassword(password: String, action: (Boolean, Exception?) -> Unit) { private fun successfullySetPassword(password: String, action: (Boolean, Exception?) -> Unit) {
Concurrency.run("SetPassword") { Concurrency.run("SetPassword") {
try { try {
val setSuccess = UncivGame.Current.onlineMultiplayer.setPassword(password) val setSuccess = UncivGame.Current.onlineMultiplayer.multiplayerServer.setPassword(password)
launchOnGLThread { launchOnGLThread {
action(setSuccess, null) action(setSuccess, null)
} }