Mod manager concurrency (#4750)

* Mod manager concurrency

* Mod manager concurrency - tr
This commit is contained in:
SomeTroglodyte 2021-08-04 12:53:42 +02:00 committed by GitHub
parent a3c9214500
commit c1382477e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 26 deletions

View File

@ -1178,33 +1178,28 @@ Download [modName] = Télécharger [modName]
Update [modName] = Mettre à jour [modName] Update [modName] = Mettre à jour [modName]
Could not download mod list = Impossible de charger la liste des mods Could not download mod list = Impossible de charger la liste des mods
Download mod from URL = Télécharger un mod depuis l'URL Download mod from URL = Télécharger un mod depuis l'URL
# Requires translation! Please enter the mod repository -or- archive zip url: = URL du mod repositoire -ou- du fichier zip:
Please enter the mod repository -or- archive zip url: =
Download = Télécharger Download = Télécharger
Done! = Fini! Done! = Fini!
Delete [modName] = Supprimer [modName] Delete [modName] = Supprimer [modName]
Are you SURE you want to delete this mod? = Êtes vous SÛR de vouloir supprimer ce mod? Are you SURE you want to delete this mod? = Êtes vous SÛR de vouloir supprimer ce mod?
# Requires translation! [mod] was deleted. = Le mod [mod] a été effacé.
[mod] was deleted. =
Updated = Mis à jour Updated = Mis à jour
Current mods = Mods actuels Current mods = Mods actuels
Downloadable mods = Mods téléchargeables Downloadable mods = Mods téléchargeables
Next page = Page suivante Next page = Page suivante
Open Github page = Ouvrir la page GitHub Open Github page = Ouvrir la page GitHub
# Requires translation! Permanent audiovisual mod = Mod audiovisuel permanent
Permanent audiovisual mod =
Installed = Installé Installed = Installé
Downloaded! = Téléchargé! Downloaded! = Téléchargé!
Could not download mod = Échec du téléchargement du mod [modName] Downloaded! = [modName] téléchargé!
Online query result is incomplete = Le résultat de la requête en ligne est incomplêt Could not download mod = Échec du téléchargement du mod [modName]
Online query result is incomplete = Le résultat de la requête en ligne est incomplet
No description provided = Pas de description fournie No description provided = Pas de description fournie
[stargazers]✯ = [stargazers]✯ [stargazers]✯ = [stargazers]✯
# Requires translation! Author: [author] = Auteur: [author]
Author: [author] = Size: [size] kB = Taille: [size] kO
# Requires translation! The mod you selected is incompatible with the defined ruleset! = Le mod choisi es incompatible avec la base de règles actuelle!
Size: [size] kB =
# Requires translation!
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

View File

@ -1097,8 +1097,9 @@ Next page = Nächste Seite
Open Github page = Auf Github öffnen Open Github page = Auf Github öffnen
Permanent audiovisual mod = Permanente audiovisuelle Mod Permanent audiovisual mod = Permanente audiovisuelle Mod
Installed = Installiert Installed = Installiert
Downloaded! = Heruntergeladen! Downloaded! = Heruntergeladen.
Could not download mod = Konnte Modifikation nicht herunterladen [modName] Downloaded! = [modName] heruntergeladen!
Could not download [modName] = Konnte [modName] nicht herunterladen
Online query result is incomplete = Online-Abfrage war unvollständig Online query result is incomplete = Online-Abfrage war unvollständig
No description provided = Keine Beschreibung mitgeliefert No description provided = Keine Beschreibung mitgeliefert
[stargazers]✯ = [stargazers]✯ [stargazers]✯ = [stargazers]✯

View File

@ -1100,7 +1100,8 @@ Open Github page = Abrir Pagina de Github
Permanent audiovisual mod = Mod visual permanente Permanent audiovisual mod = Mod visual permanente
Installed = Instalado Installed = Instalado
Downloaded! = ¡Descargado! Downloaded! = ¡Descargado!
Could not download mod = No se pudo descargar el mod [modName] Downloaded! = ¡[modName] Descargado!
Could not download [modName] = No se pudo descargar el mod [modName]
Online query result is incomplete = La busqueda online está incompleta Online query result is incomplete = La busqueda online está incompleta
No description provided = Sin descripción No description provided = Sin descripción
[stargazers]✯ = [stargazers]✯ [stargazers]✯ = [stargazers]✯

View File

@ -1092,7 +1092,8 @@ Open Github page =
Permanent audiovisual mod = Permanent audiovisual mod =
Installed = Installed =
Downloaded! = Downloaded! =
Could not download mod = [modName] Downloaded! =
Could not download [modName] =
Online query result is incomplete = Online query result is incomplete =
No description provided = No description provided =
[stargazers]✯ = [stargazers]✯ =

View File

@ -364,7 +364,7 @@ class ModManagementScreen: PickerScreen(disableScroll = true) {
?: throw Exception() // downloadAndExtract returns null for 404 errors and the like -> display something! ?: 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("[${repo.name}] Downloaded!", this)
RulesetCache.loadRulesets() RulesetCache.loadRulesets()
refreshInstalledModTable() refreshInstalledModTable()
showModDescription(repo.name) showModDescription(repo.name)
@ -372,7 +372,7 @@ class ModManagementScreen: PickerScreen(disableScroll = true) {
} }
} catch (ex: Exception) { } catch (ex: Exception) {
Gdx.app.postRunnable { Gdx.app.postRunnable {
ToastPopup("Could not download mod", this) ToastPopup("Could not download [${repo.name}]", this)
} }
} finally { } finally {
postAction() postAction()

View File

@ -1,5 +1,6 @@
package com.unciv.ui.worldscreen.mainmenu package com.unciv.ui.worldscreen.mainmenu
import com.badlogic.gdx.Files
import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.files.FileHandle
import com.unciv.logic.GameSaver import com.unciv.logic.GameSaver
import java.io.* import java.io.*
@ -61,12 +62,15 @@ object Github {
val zipUrl = "$gitRepoUrl/archive/$defaultBranch.zip" val zipUrl = "$gitRepoUrl/archive/$defaultBranch.zip"
val inputStream = download(zipUrl) ?: return null val inputStream = download(zipUrl) ?: return null
// Get a mod-specific temp file name
val tempName = "temp-" + gitRepoUrl.hashCode().toString(16)
// Download to temporary zip // Download to temporary zip
val tempZipFileHandle = folderFileHandle.child("tempZip.zip") val tempZipFileHandle = folderFileHandle.child("$tempName.zip")
tempZipFileHandle.write(inputStream, false) tempZipFileHandle.write(inputStream, false)
// prepare temp unpacking folder // prepare temp unpacking folder
val unzipDestination = tempZipFileHandle.sibling("tempZip") // folder, not file val unzipDestination = tempZipFileHandle.sibling(tempName) // folder, not file
// prevent mixing new content with old - hopefully there will never be cadavers of our tempZip stuff // prevent mixing new content with old - hopefully there will never be cadavers of our tempZip stuff
if (unzipDestination.exists()) if (unzipDestination.exists())
if (unzipDestination.isDirectory) unzipDestination.deleteDirectory() else unzipDestination.delete() if (unzipDestination.isDirectory) unzipDestination.deleteDirectory() else unzipDestination.delete()
@ -74,7 +78,7 @@ object Github {
Zip.extractFolder(tempZipFileHandle, unzipDestination) Zip.extractFolder(tempZipFileHandle, unzipDestination)
val innerFolder = unzipDestination.list().first() val innerFolder = unzipDestination.list().first()
// innerFolder should now be "tempZip/$repoName-$defaultBranch/" - use this to get mod name // innerFolder should now be "$tempName/$repoName-$defaultBranch/" - use this to get mod name
val finalDestinationName = innerFolder.name().replace("-$defaultBranch", "").replace('-', ' ') val finalDestinationName = innerFolder.name().replace("-$defaultBranch", "").replace('-', ' ')
// finalDestinationName is now the mod name as we display it. Folder name needs to be identical. // finalDestinationName is now the mod name as we display it. Folder name needs to be identical.
val finalDestination = folderFileHandle.child(finalDestinationName) val finalDestination = folderFileHandle.child(finalDestinationName)
@ -83,7 +87,7 @@ object Github {
var tempBackup: FileHandle? = null var tempBackup: FileHandle? = null
if (finalDestination.exists()) { if (finalDestination.exists()) {
tempBackup = finalDestination.sibling("$finalDestinationName.updating") tempBackup = finalDestination.sibling("$finalDestinationName.updating")
finalDestination.moveTo(tempBackup) finalDestination.renameOrMove(tempBackup)
} }
// Move temp unpacked content to their final place // Move temp unpacked content to their final place
@ -92,7 +96,7 @@ object Github {
// This sort will guarantee the desktop launcher will not re-pack textures and overwrite the atlas as delivered by the mod // This sort will guarantee the desktop launcher will not re-pack textures and overwrite the atlas as delivered by the mod
for (innerFileOrFolder in innerFolder.list() for (innerFileOrFolder in innerFolder.list()
.sortedBy { file -> file.extension() == "atlas" } ) { .sortedBy { file -> file.extension() == "atlas" } ) {
innerFileOrFolder.moveTo(finalDestination) innerFileOrFolder.renameOrMove(finalDestination)
} }
// clean up // clean up
@ -103,6 +107,12 @@ object Github {
return finalDestination return finalDestination
} }
private fun FileHandle.renameOrMove(dest: FileHandle) {
// Gdx tries a java rename for Absolute and External, but NOT for Local - rectify that
if (type() == Files.FileType.Local && file().renameTo(dest.file())) return
moveTo(dest)
}
/** /**
* Implements the ability wo work with GitHub's rate limit, recognize blocks from previous attempts, wait and retry. * Implements the ability wo work with GitHub's rate limit, recognize blocks from previous attempts, wait and retry.