mirror of
https://github.com/yairm210/Unciv.git
synced 2025-03-13 19:39:34 +07:00
Extracted File functions from OnlineMultiplayer to separate class, for separation of concerns between *local files* and *online data*
This commit is contained in:
parent
0c4814eae4
commit
cdf6d6169e
89
core/src/com/unciv/logic/multiplayer/MultiplayerFiles.kt
Normal file
89
core/src/com/unciv/logic/multiplayer/MultiplayerFiles.kt
Normal file
@ -0,0 +1,89 @@
|
||||
package com.unciv.logic.multiplayer
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.GameInfoPreview
|
||||
import com.unciv.logic.event.EventBus
|
||||
import com.unciv.utils.debug
|
||||
import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
/** Files that are stored locally */
|
||||
class MultiplayerFiles {
|
||||
internal val files = UncivGame.Current.files
|
||||
internal val savedGames: MutableMap<FileHandle, OnlineMultiplayerGame> = Collections.synchronizedMap(mutableMapOf())
|
||||
|
||||
internal fun updateSavesFromFiles() {
|
||||
val saves = files.getMultiplayerSaves()
|
||||
|
||||
val removedSaves = savedGames.keys - saves.toSet()
|
||||
for (saveFile in removedSaves) {
|
||||
deleteGame(saveFile)
|
||||
}
|
||||
|
||||
val newSaves = saves - savedGames.keys
|
||||
for (saveFile in newSaves) {
|
||||
addGame(saveFile)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the game from disk, does not delete it remotely.
|
||||
*/
|
||||
fun deleteGame(onlineMultiplayerGame: OnlineMultiplayerGame) {
|
||||
deleteGame(onlineMultiplayerGame.fileHandle)
|
||||
}
|
||||
|
||||
private fun deleteGame(fileHandle: FileHandle) {
|
||||
files.deleteSave(fileHandle)
|
||||
|
||||
val game = savedGames[fileHandle] ?: return
|
||||
|
||||
debug("Deleting game %s with id %s", fileHandle.name(), game.preview?.gameId)
|
||||
savedGames.remove(game.fileHandle)
|
||||
}
|
||||
|
||||
internal fun addGame(newGame: GameInfo) {
|
||||
val newGamePreview = newGame.asPreview()
|
||||
addGame(newGamePreview, newGamePreview.gameId)
|
||||
}
|
||||
|
||||
internal fun addGame(preview: GameInfoPreview, saveFileName: String) {
|
||||
val fileHandle = files.saveGame(preview, saveFileName)
|
||||
return addGame(fileHandle, preview)
|
||||
}
|
||||
|
||||
private fun addGame(fileHandle: FileHandle, preview: GameInfoPreview? = null) {
|
||||
debug("Adding game %s", fileHandle.name())
|
||||
val game = OnlineMultiplayerGame(fileHandle, preview, if (preview != null) Instant.now() else null)
|
||||
savedGames[fileHandle] = game
|
||||
}
|
||||
|
||||
fun getGameByName(name: String): OnlineMultiplayerGame? {
|
||||
return savedGames.values.firstOrNull { it.name == name }
|
||||
}
|
||||
|
||||
fun getGameByGameId(gameId: String): OnlineMultiplayerGame? {
|
||||
return savedGames.values.firstOrNull { it.preview?.gameId == gameId }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fires [MultiplayerGameNameChanged]
|
||||
*/
|
||||
fun changeGameName(game: OnlineMultiplayerGame, newName: String, onException: (Exception?)->Unit) {
|
||||
debug("Changing name of game %s to", game.name, newName)
|
||||
val oldPreview = game.preview ?: throw game.error!!
|
||||
val oldLastUpdate = game.getLastUpdate()
|
||||
val oldName = game.name
|
||||
|
||||
val newFileHandle = files.saveGame(oldPreview, newName, onException)
|
||||
val newGame = OnlineMultiplayerGame(newFileHandle, oldPreview, oldLastUpdate)
|
||||
savedGames[newFileHandle] = newGame
|
||||
|
||||
savedGames.remove(game.fileHandle)
|
||||
files.deleteSave(game.fileHandle)
|
||||
EventBus.send(MultiplayerGameNameChanged(oldName, newName))
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package com.unciv.logic.multiplayer
|
||||
|
||||
import com.badlogic.gdx.files.FileHandle
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.GameInfo
|
||||
@ -18,17 +17,11 @@ import com.unciv.utils.Concurrency
|
||||
import com.unciv.utils.Dispatcher
|
||||
import com.unciv.utils.debug
|
||||
import com.unciv.utils.launchOnThreadPool
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.isActive
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.util.Collections
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
|
||||
@ -39,21 +32,24 @@ import java.util.concurrent.atomic.AtomicReference
|
||||
private val FILE_UPDATE_THROTTLE_PERIOD = Duration.ofSeconds(60)
|
||||
|
||||
/**
|
||||
* Provides multiplayer functionality to the rest of the game.
|
||||
* Provides *online* multiplayer functionality to the rest of the game.
|
||||
* Multiplayer data is a mix of local files ([multiplayerFiles]) and server data ([multiplayerServer]).
|
||||
* This class handles functions that require a mix of both.
|
||||
*
|
||||
* See the file of [com.unciv.logic.multiplayer.HasMultiplayerGameName] for all available [EventBus] events.
|
||||
*/
|
||||
class OnlineMultiplayer {
|
||||
private val files = UncivGame.Current.files
|
||||
/** Handles SERVER DATA only */
|
||||
val multiplayerServer = OnlineMultiplayerServer()
|
||||
/** Handles LOCAL FILES only */
|
||||
val multiplayerFiles = MultiplayerFiles()
|
||||
|
||||
private val savedGames: MutableMap<FileHandle, OnlineMultiplayerGame> = Collections.synchronizedMap(mutableMapOf())
|
||||
|
||||
private val lastFileUpdate: AtomicReference<Instant?> = AtomicReference()
|
||||
private val lastAllGamesRefresh: AtomicReference<Instant?> = AtomicReference()
|
||||
private val lastCurGameRefresh: AtomicReference<Instant?> = AtomicReference()
|
||||
|
||||
val games: Set<OnlineMultiplayerGame> get() = savedGames.values.toSet()
|
||||
val games: Set<OnlineMultiplayerGame> get() = multiplayerFiles.savedGames.values.toSet()
|
||||
val multiplayerGameUpdater: Job
|
||||
|
||||
init {
|
||||
@ -86,7 +82,7 @@ class OnlineMultiplayer {
|
||||
private fun getCurrentGame(): OnlineMultiplayerGame? {
|
||||
val gameInfo = UncivGame.Current.gameInfo
|
||||
return if (gameInfo != null && gameInfo.gameParameters.isOnlineMultiplayer) {
|
||||
getGameByGameId(gameInfo.gameId)
|
||||
multiplayerFiles.getGameByGameId(gameInfo.gameId)
|
||||
} else null
|
||||
}
|
||||
|
||||
@ -101,9 +97,9 @@ class OnlineMultiplayer {
|
||||
Concurrency.run("Update all multiplayer games") {
|
||||
val fileThrottleInterval = if (forceUpdate) Duration.ZERO else FILE_UPDATE_THROTTLE_PERIOD
|
||||
// An exception only happens here if the files can't be listed, should basically never happen
|
||||
throttle(lastFileUpdate, fileThrottleInterval, {}, action = ::updateSavesFromFiles)
|
||||
throttle(lastFileUpdate, fileThrottleInterval, {}, action = {multiplayerFiles.updateSavesFromFiles()})
|
||||
|
||||
for (game in savedGames.values) {
|
||||
for (game in multiplayerFiles.savedGames.values) {
|
||||
if (game in doNotUpdate) continue
|
||||
launchOnThreadPool {
|
||||
game.requestUpdate(forceUpdate)
|
||||
@ -112,27 +108,13 @@ class OnlineMultiplayer {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSavesFromFiles() {
|
||||
val saves = files.getMultiplayerSaves()
|
||||
|
||||
val removedSaves = savedGames.keys - saves.toSet()
|
||||
for (saveFile in removedSaves) {
|
||||
deleteGame(saveFile)
|
||||
}
|
||||
|
||||
val newSaves = saves - savedGames.keys
|
||||
for (saveFile in newSaves) {
|
||||
addGame(saveFile)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
|
||||
*/
|
||||
suspend fun createGame(newGame: GameInfo) {
|
||||
multiplayerServer.tryUploadGame(newGame, withPreview = true)
|
||||
addGame(newGame)
|
||||
multiplayerFiles.addGame(newGame)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,32 +131,9 @@ class OnlineMultiplayer {
|
||||
// Game is so old that a preview could not be found on dropbox lets try the real gameInfo instead
|
||||
multiplayerServer.tryDownloadGame(gameId).asPreview()
|
||||
}
|
||||
addGame(gamePreview, saveFileName)
|
||||
multiplayerFiles.addGame(gamePreview, saveFileName)
|
||||
}
|
||||
|
||||
private fun addGame(newGame: GameInfo) {
|
||||
val newGamePreview = newGame.asPreview()
|
||||
addGame(newGamePreview, newGamePreview.gameId)
|
||||
}
|
||||
|
||||
private fun addGame(preview: GameInfoPreview, saveFileName: String) {
|
||||
val fileHandle = files.saveGame(preview, saveFileName)
|
||||
return addGame(fileHandle, preview)
|
||||
}
|
||||
|
||||
private fun addGame(fileHandle: FileHandle, preview: GameInfoPreview? = null) {
|
||||
debug("Adding game %s", fileHandle.name())
|
||||
val game = OnlineMultiplayerGame(fileHandle, preview, if (preview != null) Instant.now() else null)
|
||||
savedGames[fileHandle] = game
|
||||
}
|
||||
|
||||
fun getGameByName(name: String): OnlineMultiplayerGame? {
|
||||
return savedGames.values.firstOrNull { it.name == name }
|
||||
}
|
||||
|
||||
fun getGameByGameId(gameId: String): OnlineMultiplayerGame? {
|
||||
return savedGames.values.firstOrNull { it.preview?.gameId == gameId }
|
||||
}
|
||||
|
||||
/**
|
||||
* Resigns from the given multiplayer [game]. Can only resign if it's currently the user's turn,
|
||||
@ -212,7 +171,7 @@ class OnlineMultiplayer {
|
||||
}
|
||||
|
||||
val newPreview = gameInfo.asPreview()
|
||||
files.saveGame(newPreview, game.fileHandle)
|
||||
multiplayerFiles.files.saveGame(newPreview, game.fileHandle)
|
||||
multiplayerServer.tryUploadGame(gameInfo, withPreview = true)
|
||||
game.doManualUpdate(newPreview)
|
||||
return true
|
||||
@ -227,14 +186,14 @@ class OnlineMultiplayer {
|
||||
loadGame(preview.gameId)
|
||||
}
|
||||
|
||||
/**
|
||||
/** Downloads game, and updates it locally
|
||||
* @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
|
||||
*/
|
||||
suspend fun loadGame(gameId: String) = coroutineScope {
|
||||
val gameInfo = downloadGame(gameId)
|
||||
val gameInfo = multiplayerServer.downloadGame(gameId)
|
||||
val preview = gameInfo.asPreview()
|
||||
val onlineGame = getGameByGameId(gameId)
|
||||
val onlineGame = multiplayerFiles.getGameByGameId(gameId)
|
||||
val onlinePreview = onlineGame?.preview
|
||||
if (onlineGame == null) {
|
||||
createGame(gameInfo)
|
||||
@ -258,49 +217,8 @@ class OnlineMultiplayer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
suspend fun downloadGame(gameId: String): GameInfo {
|
||||
val latestGame = multiplayerServer.tryDownloadGame(gameId)
|
||||
latestGame.isUpToDate = true
|
||||
return latestGame
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the game from disk, does not delete it remotely.
|
||||
*/
|
||||
fun deleteGame(multiplayerGame: OnlineMultiplayerGame) {
|
||||
deleteGame(multiplayerGame.fileHandle)
|
||||
}
|
||||
|
||||
private fun deleteGame(fileHandle: FileHandle) {
|
||||
files.deleteSave(fileHandle)
|
||||
|
||||
val game = savedGames[fileHandle] ?: return
|
||||
|
||||
debug("Deleting game %s with id %s", fileHandle.name(), game.preview?.gameId)
|
||||
savedGames.remove(game.fileHandle)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires [MultiplayerGameNameChanged]
|
||||
*/
|
||||
fun changeGameName(game: OnlineMultiplayerGame, newName: String, onException: (Exception?)->Unit) {
|
||||
debug("Changing name of game %s to", game.name, newName)
|
||||
val oldPreview = game.preview ?: throw game.error!!
|
||||
val oldLastUpdate = game.getLastUpdate()
|
||||
val oldName = game.name
|
||||
|
||||
val newFileHandle = files.saveGame(oldPreview, newName, onException)
|
||||
val newGame = OnlineMultiplayerGame(newFileHandle, oldPreview, oldLastUpdate)
|
||||
savedGames[newFileHandle] = newGame
|
||||
|
||||
savedGames.remove(game.fileHandle)
|
||||
files.deleteSave(game.fileHandle)
|
||||
EventBus.send(MultiplayerGameNameChanged(oldName, newName))
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
|
||||
@ -310,10 +228,10 @@ class OnlineMultiplayer {
|
||||
suspend fun updateGame(gameInfo: GameInfo) {
|
||||
debug("Updating remote game %s", gameInfo.gameId)
|
||||
multiplayerServer.tryUploadGame(gameInfo, withPreview = true)
|
||||
val game = getGameByGameId(gameInfo.gameId)
|
||||
val game = multiplayerFiles.getGameByGameId(gameInfo.gameId)
|
||||
debug("Existing OnlineMultiplayerGame: %s", game)
|
||||
if (game == null) {
|
||||
addGame(gameInfo)
|
||||
multiplayerFiles.addGame(gameInfo)
|
||||
} else {
|
||||
game.doManualUpdate(gameInfo.asPreview())
|
||||
}
|
||||
@ -340,7 +258,6 @@ class OnlineMultiplayer {
|
||||
fun usesCustomServer() = UncivGame.Current.settings.multiplayer.server != Constants.dropboxMultiplayerServer
|
||||
fun usesDropbox() = !usesCustomServer()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@ import com.unciv.logic.multiplayer.ServerFeatureSet
|
||||
*
|
||||
* @param fileStorageIdentifier must be given if UncivGame.Current might not be initialized
|
||||
* @see FileStorage
|
||||
* @see UncivGame.Current.settings.multiplayerServer
|
||||
* @see UncivGame.settings.multiplayer.server
|
||||
*/
|
||||
@Suppress("RedundantSuspendModifier") // Methods can take a long time, so force users to use them in a coroutine to not get ANRs on Android
|
||||
class OnlineMultiplayerServer(
|
||||
@ -142,6 +142,17 @@ class OnlineMultiplayerServer(
|
||||
return gameInfo
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
suspend fun downloadGame(gameId: String): GameInfo {
|
||||
val latestGame = tryDownloadGame(gameId)
|
||||
latestGame.isUpToDate = true
|
||||
return latestGame
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileStorageRateLimitReached if the file storage backend can't handle any additional actions for a time
|
||||
* @throws FileNotFoundException if the file can't be found
|
||||
|
@ -106,12 +106,12 @@ private fun addMultiplayerServerOptions(
|
||||
|
||||
val connectionToServerButton = "Check connection to server".toTextButton()
|
||||
|
||||
val textToShowForMultiplayerAddress = if (OnlineMultiplayer.usesCustomServer()) {
|
||||
val textToShowForOnlineMultiplayerAddress = if (OnlineMultiplayer.usesCustomServer()) {
|
||||
settings.multiplayer.server
|
||||
} else {
|
||||
"https://"
|
||||
}
|
||||
val multiplayerServerTextField = UncivTextField("Server address", textToShowForMultiplayerAddress)
|
||||
val multiplayerServerTextField = UncivTextField("Server address", textToShowForOnlineMultiplayerAddress)
|
||||
multiplayerServerTextField.setTextFieldFilter { _, c -> c !in " \r\n\t\\" }
|
||||
multiplayerServerTextField.programmaticChangeEvents = true
|
||||
val serverIpTable = Table()
|
||||
|
@ -35,16 +35,16 @@ object MultiplayerHelpers {
|
||||
}
|
||||
}
|
||||
|
||||
fun buildDescriptionText(multiplayerGame: OnlineMultiplayerGame): StringBuilder {
|
||||
fun buildDescriptionText(onlineMultiplayerGame: OnlineMultiplayerGame): StringBuilder {
|
||||
val descriptionText = StringBuilder()
|
||||
val ex = multiplayerGame.error
|
||||
val ex = onlineMultiplayerGame.error
|
||||
if (ex != null) {
|
||||
val (message) = LoadGameScreen.getLoadExceptionMessage(ex, "Error while refreshing:")
|
||||
descriptionText.appendLine(message)
|
||||
}
|
||||
val lastUpdate = multiplayerGame.getLastUpdate()
|
||||
val lastUpdate = onlineMultiplayerGame.getLastUpdate()
|
||||
descriptionText.appendLine("Last refresh: [${Duration.between(lastUpdate, Instant.now()).formatShort()}] ago".tr())
|
||||
val preview = multiplayerGame.preview
|
||||
val preview = onlineMultiplayerGame.preview
|
||||
if (preview?.currentPlayer != null) {
|
||||
val currentTurnStartTime = Instant.ofEpochMilli(preview.currentTurnStartTime)
|
||||
descriptionText.appendLine("Current Turn: [${preview.currentPlayer}] since [${Duration.between(currentTurnStartTime, Instant.now()).formatShort()}] ago".tr())
|
||||
|
@ -127,7 +127,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
* Helper function to decrease indentation
|
||||
* Turns the current playerCiv into an AI civ and uploads the game afterwards.
|
||||
*/
|
||||
private fun resign(multiplayerGame: OnlineMultiplayerGame) {
|
||||
private fun resign(onlineMultiplayerGame: OnlineMultiplayerGame) {
|
||||
//Create a popup
|
||||
val popup = Popup(this)
|
||||
popup.addGoodSizedLabel(Constants.working).row()
|
||||
@ -135,7 +135,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
|
||||
Concurrency.runOnNonDaemonThreadPool("Resign") {
|
||||
try {
|
||||
val resignSuccess = game.onlineMultiplayer.resign(multiplayerGame)
|
||||
val resignSuccess = game.onlineMultiplayer.resign(onlineMultiplayerGame)
|
||||
|
||||
launchOnGLThread {
|
||||
if (resignSuccess) {
|
||||
@ -151,7 +151,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
if (ex is MultiplayerAuthException) {
|
||||
launchOnGLThread {
|
||||
AuthPopup(this@MultiplayerScreen) { success ->
|
||||
if (success) resign(multiplayerGame)
|
||||
if (success) resign(onlineMultiplayerGame)
|
||||
}.open(true)
|
||||
}
|
||||
return@runOnNonDaemonThreadPool
|
||||
@ -174,7 +174,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
"Delete save",
|
||||
) {
|
||||
try {
|
||||
game.onlineMultiplayer.deleteGame(selectedGame!!)
|
||||
game.onlineMultiplayer.multiplayerFiles.deleteGame(selectedGame!!)
|
||||
onGameDeleted(selectedGame!!.name)
|
||||
} catch (ex: Exception) {
|
||||
Log.error("Could not delete game!", ex)
|
||||
@ -196,7 +196,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
|
||||
val saveNewNameFunction = {
|
||||
val newName = textField.text.trim()
|
||||
game.onlineMultiplayer.changeGameName(selectedGame!!, newName) {
|
||||
game.onlineMultiplayer.multiplayerFiles.changeGameName(selectedGame!!, newName) {
|
||||
if (it != null) reuseWith("Could not save game!", true)
|
||||
}
|
||||
gameList.update()
|
||||
@ -289,7 +289,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
}
|
||||
|
||||
fun selectGame(name: String) {
|
||||
val multiplayerGame = game.onlineMultiplayer.getGameByName(name)
|
||||
val multiplayerGame = game.onlineMultiplayer.multiplayerFiles.getGameByName(name)
|
||||
if (multiplayerGame == null) {
|
||||
// Should never happen
|
||||
unselectGame()
|
||||
|
@ -329,7 +329,7 @@ class WorldScreen(
|
||||
try {
|
||||
debug("loadLatestMultiplayerState current game: gameId: %s, turn: %s, curCiv: %s",
|
||||
gameInfo.gameId, gameInfo.turns, gameInfo.currentPlayer)
|
||||
val latestGame = game.onlineMultiplayer.downloadGame(gameInfo.gameId)
|
||||
val latestGame = game.onlineMultiplayer.multiplayerServer.downloadGame(gameInfo.gameId)
|
||||
debug("loadLatestMultiplayerState downloaded game: gameId: %s, turn: %s, curCiv: %s",
|
||||
latestGame.gameId, latestGame.turns, latestGame.currentPlayer)
|
||||
if (viewingCiv.civName == latestGame.currentPlayer || viewingCiv.civName == Constants.spectator) {
|
||||
@ -697,7 +697,8 @@ class WorldScreen(
|
||||
private fun updateMultiplayerStatusButton() {
|
||||
if (gameInfo.gameParameters.isOnlineMultiplayer || game.settings.multiplayer.statusButtonInSinglePlayer) {
|
||||
if (statusButtons.multiplayerStatusButton != null) return
|
||||
statusButtons.multiplayerStatusButton = MultiplayerStatusButton(this, game.onlineMultiplayer.getGameByGameId(gameInfo.gameId))
|
||||
statusButtons.multiplayerStatusButton = MultiplayerStatusButton(this,
|
||||
game.onlineMultiplayer.multiplayerFiles.getGameByGameId(gameInfo.gameId))
|
||||
} else {
|
||||
if (statusButtons.multiplayerStatusButton == null) return
|
||||
statusButtons.multiplayerStatusButton = null
|
||||
|
@ -38,7 +38,7 @@ class MultiplayerStatusPopup(
|
||||
}
|
||||
|
||||
private fun gameSelected(gameName: String) {
|
||||
val multiplayerGame = UncivGame.Current.onlineMultiplayer.getGameByName(gameName)!!
|
||||
val multiplayerGame = UncivGame.Current.onlineMultiplayer.multiplayerFiles.getGameByName(gameName)!!
|
||||
selectedGame = multiplayerGame
|
||||
pickerPane.setRightSideButtonEnabled(true)
|
||||
pickerPane.rightSideButton.setText("Load [$gameName]".tr())
|
||||
|
Loading…
Reference in New Issue
Block a user