mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 06:16:37 -04:00
Better mod download and error display (#4396)
* Better mod download and error display * Fix Android Studio Insubordinations
This commit is contained in:
parent
3df83b1a75
commit
7875ec4896
@ -982,6 +982,7 @@ Download [modName] = [modName] herunterladen
|
|||||||
Update [modName] = [modName] aktualisieren
|
Update [modName] = [modName] aktualisieren
|
||||||
Could not download mod list = Modliste konnte nicht heruntergeladen werden
|
Could not download mod list = Modliste konnte nicht heruntergeladen werden
|
||||||
Download mod from URL = Modifikation von einer URL herunterladen
|
Download mod from URL = Modifikation von einer URL herunterladen
|
||||||
|
Please enter the mod repository -or- archive zip url: = Geben Sie die URL des Mod Repository oder des zip-Archivs ein:
|
||||||
Download = Herunterladen
|
Download = Herunterladen
|
||||||
Done! = Abgeschlossen!
|
Done! = Abgeschlossen!
|
||||||
Delete [modName] = Lösche [modName]
|
Delete [modName] = Lösche [modName]
|
||||||
@ -1001,6 +1002,7 @@ No description provided = Keine Beschreibung mitgeliefert
|
|||||||
[stargazers]✯ = [stargazers]✯
|
[stargazers]✯ = [stargazers]✯
|
||||||
Author: [author] = Autor: [author]
|
Author: [author] = Autor: [author]
|
||||||
Size: [size] kB = Größe: [size] kB
|
Size: [size] kB = Größe: [size] kB
|
||||||
|
The mod you selected is incompatible with the defined ruleset! = Die gewählte Modifikation ist inkompatibel!
|
||||||
|
|
||||||
# Uniques that are relevant to more than one type of game object
|
# Uniques that are relevant to more than one type of game object
|
||||||
|
|
||||||
|
@ -1000,6 +1000,7 @@ Download [modName] =
|
|||||||
Update [modName] =
|
Update [modName] =
|
||||||
Could not download mod list =
|
Could not download mod list =
|
||||||
Download mod from URL =
|
Download mod from URL =
|
||||||
|
Please enter the mod repository -or- archive zip url: =
|
||||||
Download =
|
Download =
|
||||||
Done! =
|
Done! =
|
||||||
Delete [modName] =
|
Delete [modName] =
|
||||||
@ -1019,6 +1020,7 @@ No description provided =
|
|||||||
[stargazers]✯ =
|
[stargazers]✯ =
|
||||||
Author: [author] =
|
Author: [author] =
|
||||||
Size: [size] kB =
|
Size: [size] kB =
|
||||||
|
The mod you selected is incompatible with the defined ruleset! =
|
||||||
|
|
||||||
# Uniques that are relevant to more than one type of game object
|
# Uniques that are relevant to more than one type of game object
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package com.unciv.ui.newgamescreen
|
|||||||
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox
|
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.Ruleset.CheckModLinksResult
|
import com.unciv.models.ruleset.Ruleset.CheckModLinksResult
|
||||||
import com.unciv.models.ruleset.RulesetCache
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
@ -39,21 +40,19 @@ class ModCheckboxTable(val mods:LinkedHashSet<String>, val screen: CameraStageBa
|
|||||||
mods.remove(oldBaseRuleset)
|
mods.remove(oldBaseRuleset)
|
||||||
mods.add(mod.name)
|
mods.add(mod.name)
|
||||||
|
|
||||||
var isCompatibleWithCurrentRuleset = true
|
|
||||||
var complexModLinkCheck = CheckModLinksResult()
|
var complexModLinkCheck = CheckModLinksResult()
|
||||||
try {
|
try {
|
||||||
val newRuleset = RulesetCache.getComplexRuleset(mods)
|
val newRuleset = RulesetCache.getComplexRuleset(mods)
|
||||||
newRuleset.modOptions.isBaseRuleset = true // This is so the checkModLinks finds all connections
|
newRuleset.modOptions.isBaseRuleset = true // This is so the checkModLinks finds all connections
|
||||||
complexModLinkCheck = newRuleset.checkModLinks()
|
complexModLinkCheck = newRuleset.checkModLinks()
|
||||||
isCompatibleWithCurrentRuleset = !complexModLinkCheck.isError()
|
} catch (ex: Exception) {
|
||||||
} catch (x: Exception) {
|
|
||||||
// This happens if a building is dependent on a tech not in the base ruleset
|
// This happens if a building is dependent on a tech not in the base ruleset
|
||||||
// because newRuleset.updateBuildingCosts() in getComplexRuleset() throws an error
|
// because newRuleset.updateBuildingCosts() in getComplexRuleset() throws an error
|
||||||
isCompatibleWithCurrentRuleset = false
|
complexModLinkCheck = CheckModLinksResult(Ruleset.CheckModLinksStatus.Error, ex.localizedMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCompatibleWithCurrentRuleset) {
|
if (complexModLinkCheck.isError()) {
|
||||||
ToastPopup("The mod you selected is incompatible with the defined ruleset!\n\n$complexModLinkCheck", screen)
|
ToastPopup("{The mod you selected is incompatible with the defined ruleset!}\n\n{$complexModLinkCheck}", screen)
|
||||||
checkBox.isChecked = false
|
checkBox.isChecked = false
|
||||||
mods.clear()
|
mods.clear()
|
||||||
mods.addAll(previousMods)
|
mods.addAll(previousMods)
|
||||||
|
@ -317,13 +317,14 @@ class ModManagementScreen: PickerScreen(disableScroll = true) {
|
|||||||
val downloadButton = "Download mod from URL".toTextButton()
|
val downloadButton = "Download mod from URL".toTextButton()
|
||||||
downloadButton.onClick {
|
downloadButton.onClick {
|
||||||
val popup = Popup(this)
|
val popup = Popup(this)
|
||||||
|
popup.addGoodSizedLabel("Please enter the mod repository -or- archive zip url:").row()
|
||||||
val textArea = TextArea("https://github.com/...", skin)
|
val textArea = TextArea("https://github.com/...", skin)
|
||||||
popup.add(textArea).width(stage.width / 2).row()
|
popup.add(textArea).width(stage.width / 2).row()
|
||||||
val actualDownloadButton = "Download".toTextButton()
|
val actualDownloadButton = "Download".toTextButton()
|
||||||
actualDownloadButton.onClick {
|
actualDownloadButton.onClick {
|
||||||
actualDownloadButton.setText("Downloading...".tr())
|
actualDownloadButton.setText("Downloading...".tr())
|
||||||
actualDownloadButton.disable()
|
actualDownloadButton.disable()
|
||||||
downloadMod(Github.Repo().apply { html_url = textArea.text; default_branch = "master" }) { popup.close() }
|
downloadMod(Github.Repo().parseUrl(textArea.text)) { popup.close() }
|
||||||
}
|
}
|
||||||
popup.add(actualDownloadButton).row()
|
popup.add(actualDownloadButton).row()
|
||||||
popup.addCloseButton()
|
popup.addCloseButton()
|
||||||
@ -354,13 +355,13 @@ class ModManagementScreen: PickerScreen(disableScroll = true) {
|
|||||||
addModInfoToActionTable(repo)
|
addModInfoToActionTable(repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Download and install a mod in the background, called from the right-bottom button */
|
/** Download and install a mod in the background, called both from the right-bottom button and the URL entry popup */
|
||||||
private fun downloadMod(repo: Github.Repo, postAction: () -> Unit = {}) {
|
private fun downloadMod(repo: Github.Repo, postAction: () -> Unit = {}) {
|
||||||
thread(name="DownloadMod") { // to avoid ANRs - we've learnt our lesson from previous download-related actions
|
thread(name="DownloadMod") { // to avoid ANRs - we've learnt our lesson from previous download-related actions
|
||||||
try {
|
try {
|
||||||
val modFolder = Github.downloadAndExtract(repo.html_url, repo.default_branch,
|
val modFolder = Github.downloadAndExtract(repo.html_url, repo.default_branch,
|
||||||
Gdx.files.local("mods"))
|
Gdx.files.local("mods"))
|
||||||
?: return@thread
|
?: throw Exception() // downloadAndExtract returns null for 404 errors and the like -> display something!
|
||||||
rewriteModOptions(repo, modFolder)
|
rewriteModOptions(repo, modFolder)
|
||||||
Gdx.app.postRunnable {
|
Gdx.app.postRunnable {
|
||||||
ToastPopup("Downloaded!", this)
|
ToastPopup("Downloaded!", this)
|
||||||
|
@ -247,6 +247,38 @@ object Github {
|
|||||||
//var stargazers_url = ""
|
//var stargazers_url = ""
|
||||||
//var homepage: String? = null // might use instead of go to repo?
|
//var homepage: String? = null // might use instead of go to repo?
|
||||||
//var has_wiki = false // a wiki could mean proper documentation for the mod?
|
//var has_wiki = false // a wiki could mean proper documentation for the mod?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize `this` with an url, extracting all possible fields from it.
|
||||||
|
*
|
||||||
|
* Allows basic repo url or complete 'zip' url from github's code->download zip menu
|
||||||
|
*
|
||||||
|
* @return `this` to allow chaining
|
||||||
|
*/
|
||||||
|
fun parseUrl(url: String): Repo {
|
||||||
|
// Allow url formats
|
||||||
|
// https://github.com/author/repoName
|
||||||
|
// or
|
||||||
|
// https://github.com/author/repoName/archive/refs/heads/branchName.zip
|
||||||
|
// and extract author, repoName, branchName
|
||||||
|
|
||||||
|
html_url = url
|
||||||
|
default_branch = "master"
|
||||||
|
val matchZip = Regex("""^(.*/(.*)/(.*))/archive/(?:.*/)?([^.]+).zip$""").matchEntire(url)
|
||||||
|
if (matchZip != null && matchZip.groups.size > 3) {
|
||||||
|
html_url = matchZip.groups[1]!!.value
|
||||||
|
owner.login = matchZip.groups[2]!!.value
|
||||||
|
name = matchZip.groups[3]!!.value
|
||||||
|
default_branch = matchZip.groups[4]!!.value
|
||||||
|
} else {
|
||||||
|
val matchRepo = Regex("""^.*/(.*)/(.*)/?$""").matchEntire(url)
|
||||||
|
if (matchRepo != null && matchRepo.groups.size > 2) {
|
||||||
|
owner.login = matchRepo.groups[1]!!.value
|
||||||
|
name = matchRepo.groups[2]!!.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Part of [Repo] in Github API response */
|
/** Part of [Repo] in Github API response */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user