mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-24 06:39:16 +07:00
Auto-download missing mods when joining multiplayer game
This commit is contained in:
@ -6,6 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.unciv.Constants
|
||||
import com.unciv.logic.multiplayer.MultiplayerGame
|
||||
import com.unciv.logic.multiplayer.storage.MultiplayerAuthException
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.components.widgets.UncivTextField
|
||||
import com.unciv.ui.components.extensions.disable
|
||||
@ -64,14 +65,29 @@ class MultiplayerScreen : PickerScreen() {
|
||||
pickerPane.topTable.background = skinStrings.getUiBackground("MultiplayerScreen/TopTable", tintColor = skinStrings.skinConfig.clearColor)
|
||||
}
|
||||
|
||||
fun onGameDeleted(gameName:String){
|
||||
private fun onGameDeleted(gameName:String){
|
||||
if (selectedGame?.name == gameName) unselectGame()
|
||||
gameList.update()
|
||||
}
|
||||
|
||||
private fun setupRightSideButton() {
|
||||
rightSideButton.setText("Join game".tr())
|
||||
rightSideButton.onClick { MultiplayerHelpers.loadMultiplayerGame(this, selectedGame!!) }
|
||||
rightSideButton.onClick {
|
||||
val missingMods = selectedGame!!.preview!!.gameParameters.getModsAndBaseRuleset()
|
||||
.filter { !RulesetCache.containsKey(it) }
|
||||
if (missingMods.isEmpty()) return@onClick MultiplayerHelpers.loadMultiplayerGame(this, selectedGame!!)
|
||||
|
||||
// Download missing mods
|
||||
Concurrency.runOnNonDaemonThreadPool(LoadGameScreen.downloadMissingMods) {
|
||||
LoadGameScreen.loadMissingMods(missingMods, onModDownloaded = {
|
||||
Concurrency.runOnGLThread { ToastPopup("[$it] Downloaded!", this@MultiplayerScreen) }
|
||||
},
|
||||
onCompleted = {
|
||||
RulesetCache.loadRulesets()
|
||||
Concurrency.runOnGLThread { MultiplayerHelpers.loadMultiplayerGame(this@MultiplayerScreen, selectedGame!!) }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createRightSideTable(): Table {
|
||||
@ -98,13 +114,13 @@ class MultiplayerScreen : PickerScreen() {
|
||||
return table
|
||||
}
|
||||
|
||||
fun createRefreshButton(): TextButton {
|
||||
private fun createRefreshButton(): TextButton {
|
||||
val btn = "Refresh list".toTextButton()
|
||||
btn.onClick { game.onlineMultiplayer.requestUpdate() }
|
||||
return btn
|
||||
}
|
||||
|
||||
fun createAddGameButton(): TextButton {
|
||||
private fun createAddGameButton(): TextButton {
|
||||
val btn = "Add multiplayer game".toTextButton()
|
||||
btn.onClick {
|
||||
game.pushScreen(AddMultiplayerGameScreen(this))
|
||||
@ -112,7 +128,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
return btn
|
||||
}
|
||||
|
||||
fun createResignButton(): TextButton {
|
||||
private fun createResignButton(): TextButton {
|
||||
val negativeButtonStyle = skin.get("negative", TextButton.TextButtonStyle::class.java)
|
||||
val resignButton = "Resign".toTextButton(negativeButtonStyle).apply { disable() }
|
||||
resignButton.onClick {
|
||||
@ -128,7 +144,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
return resignButton
|
||||
}
|
||||
|
||||
fun createForceResignButton(): TextButton {
|
||||
private fun createForceResignButton(): TextButton {
|
||||
val negativeButtonStyle = skin.get("negative", TextButton.TextButtonStyle::class.java)
|
||||
val resignButton = "Force current player to resign".toTextButton(negativeButtonStyle).apply { isVisible = false }
|
||||
resignButton.onClick {
|
||||
@ -184,7 +200,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
}
|
||||
}
|
||||
|
||||
fun createDeleteButton(): TextButton {
|
||||
private fun createDeleteButton(): TextButton {
|
||||
val negativeButtonStyle = skin.get("negative", TextButton.TextButtonStyle::class.java)
|
||||
val deleteButton = "Delete save".toTextButton(negativeButtonStyle).apply { disable() }
|
||||
deleteButton.onClick {
|
||||
@ -206,7 +222,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
return deleteButton
|
||||
}
|
||||
|
||||
fun createRenameButton(): TextButton {
|
||||
private fun createRenameButton(): TextButton {
|
||||
val btn = "Rename".toTextButton().apply { disable() }
|
||||
btn.onClick {
|
||||
Popup(this).apply {
|
||||
@ -235,7 +251,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
return btn
|
||||
}
|
||||
|
||||
fun createCopyGameIdButton(): TextButton {
|
||||
private fun createCopyGameIdButton(): TextButton {
|
||||
val btn = "Copy game ID".toTextButton().apply { disable() }
|
||||
btn.onClick {
|
||||
val gameInfo = selectedGame?.preview
|
||||
@ -247,7 +263,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
return btn
|
||||
}
|
||||
|
||||
fun createFriendsListButton(): TextButton {
|
||||
private fun createFriendsListButton(): TextButton {
|
||||
val btn = "Friends list".toTextButton()
|
||||
btn.onClick {
|
||||
game.pushScreen(ViewFriendsListScreen())
|
||||
@ -306,7 +322,7 @@ class MultiplayerScreen : PickerScreen() {
|
||||
descriptionLabel.setText("")
|
||||
}
|
||||
|
||||
fun selectGame(name: String) {
|
||||
private fun selectGame(name: String) {
|
||||
val multiplayerGame = game.onlineMultiplayer.multiplayerFiles.getGameByName(name)
|
||||
if (multiplayerGame == null) {
|
||||
// Should never happen
|
||||
|
@ -45,7 +45,7 @@ class LoadGameScreen : LoadOrSaveScreen() {
|
||||
private const val loadFromCustomLocation = "Load from custom location"
|
||||
private const val loadFromClipboard = "Load copied data"
|
||||
private const val copyExistingSaveToClipboard = "Copy saved game to clipboard"
|
||||
private const val downloadMissingMods = "Download missing mods"
|
||||
internal const val downloadMissingMods = "Download missing mods"
|
||||
|
||||
/** Gets a translated exception message to show to the user.
|
||||
* @return The first returned value is the message, the second is signifying if the user can likely fix this problem. */
|
||||
@ -78,6 +78,25 @@ class LoadGameScreen : LoadOrSaveScreen() {
|
||||
}
|
||||
return Pair(errorText.toString(), isUserFixable)
|
||||
}
|
||||
|
||||
fun loadMissingMods(missingMods: Iterable<String>, onModDownloaded:(String)->Unit, onCompleted:()->Unit){
|
||||
|
||||
for (rawName in missingMods) {
|
||||
val modName = rawName.folderNameToRepoName().lowercase()
|
||||
val repos = Github.tryGetGithubReposWithTopic(10, 1, modName)
|
||||
?: throw UncivShowableException("Could not download mod list.")
|
||||
val repo = repos.items.firstOrNull { it.name.lowercase() == modName }
|
||||
?: throw UncivShowableException("Could not find a mod named \"[$modName]\".")
|
||||
val modFolder = Github.downloadAndExtract(
|
||||
repo,
|
||||
UncivGame.Current.files.getModsFolder()
|
||||
)
|
||||
?: throw Exception("Unexpected 404 error") // downloadAndExtract returns null for 404 errors and the like -> display something!
|
||||
Github.rewriteModOptions(repo, modFolder)
|
||||
onModDownloaded(repo.name)
|
||||
}
|
||||
onCompleted()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
@ -258,31 +277,24 @@ class LoadGameScreen : LoadOrSaveScreen() {
|
||||
descriptionLabel.setText(Constants.loading.tr())
|
||||
Concurrency.runOnNonDaemonThreadPool(downloadMissingMods) {
|
||||
try {
|
||||
for (rawName in missingModsToLoad) {
|
||||
val modName = rawName.folderNameToRepoName().lowercase()
|
||||
val repos = Github.tryGetGithubReposWithTopic(10, 1, modName)
|
||||
?: throw UncivShowableException("Could not download mod list.")
|
||||
val repo = repos.items.firstOrNull { it.name.lowercase() == modName }
|
||||
?: throw UncivShowableException("Could not find a mod named \"[$modName]\".")
|
||||
val modFolder = Github.downloadAndExtract(
|
||||
repo,
|
||||
UncivGame.Current.files.getModsFolder()
|
||||
)
|
||||
?: throw Exception("Unexpected 404 error") // downloadAndExtract returns null for 404 errors and the like -> display something!
|
||||
Github.rewriteModOptions(repo, modFolder)
|
||||
val labelText = descriptionLabel.text // Surprise - a StringBuilder
|
||||
labelText.appendLine()
|
||||
labelText.append("[${repo.name}] Downloaded!".tr())
|
||||
launchOnGLThread { descriptionLabel.setText(labelText) }
|
||||
}
|
||||
launchOnGLThread {
|
||||
RulesetCache.loadRulesets()
|
||||
missingModsToLoad = emptyList()
|
||||
loadMissingModsButton.isVisible = false
|
||||
errorLabel.isVisible = false
|
||||
rightSideTable.pack()
|
||||
ToastPopup("Missing mods are downloaded successfully.", this@LoadGameScreen)
|
||||
}
|
||||
Companion.loadMissingMods(missingModsToLoad,
|
||||
onModDownloaded = {
|
||||
val labelText = descriptionLabel.text // Surprise - a StringBuilder
|
||||
labelText.appendLine()
|
||||
labelText.append("[$it] Downloaded!".tr())
|
||||
launchOnGLThread { descriptionLabel.setText(labelText) }
|
||||
},
|
||||
onCompleted = {
|
||||
launchOnGLThread {
|
||||
RulesetCache.loadRulesets()
|
||||
missingModsToLoad = emptyList()
|
||||
loadMissingModsButton.isVisible = false
|
||||
errorLabel.isVisible = false
|
||||
rightSideTable.pack()
|
||||
ToastPopup("Missing mods are downloaded successfully.", this@LoadGameScreen)
|
||||
}
|
||||
}
|
||||
)
|
||||
} catch (ex: Exception) {
|
||||
handleLoadGameException(ex, "Could not load the missing mods!")
|
||||
} finally {
|
||||
|
Reference in New Issue
Block a user