From c1382477e0d3be28383633b63171098061d91483 Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Wed, 4 Aug 2021 12:53:42 +0200 Subject: [PATCH] Mod manager concurrency (#4750) * Mod manager concurrency * Mod manager concurrency - tr --- .../jsons/translations/French.properties | 25 ++++++++----------- .../jsons/translations/German.properties | 5 ++-- .../jsons/translations/Spanish.properties | 3 ++- .../jsons/translations/template.properties | 3 ++- .../ui/pickerscreens/ModManagementScreen.kt | 4 +-- .../unciv/ui/worldscreen/mainmenu/GitHub.kt | 20 +++++++++++---- 6 files changed, 34 insertions(+), 26 deletions(-) diff --git a/android/assets/jsons/translations/French.properties b/android/assets/jsons/translations/French.properties index b4a00ca7ae..55398ac693 100644 --- a/android/assets/jsons/translations/French.properties +++ b/android/assets/jsons/translations/French.properties @@ -1178,33 +1178,28 @@ Download [modName] = Télécharger [modName] Update [modName] = Mettre à jour [modName] Could not download mod list = Impossible de charger la liste des mods Download mod from URL = Télécharger un mod depuis l'URL - # Requires translation! -Please enter the mod repository -or- archive zip url: = +Please enter the mod repository -or- archive zip url: = URL du mod repositoire -ou- du fichier zip: Download = Télécharger Done! = Fini! Delete [modName] = Supprimer [modName] Are you SURE you want to delete this mod? = Êtes vous SÛR de vouloir supprimer ce mod? - # Requires translation! -[mod] was deleted. = +[mod] was deleted. = Le mod [mod] a été effacé. Updated = Mis à jour Current mods = Mods actuels Downloadable mods = Mods téléchargeables Next page = Page suivante Open Github page = Ouvrir la page GitHub - # Requires translation! -Permanent audiovisual mod = +Permanent audiovisual mod = Mod audiovisuel permanent Installed = Installé -Downloaded! = Téléchargé ! -Could not download mod = Échec du téléchargement du mod -Online query result is incomplete = Le résultat de la requête en ligne est incomplêt +Downloaded! = Téléchargé! +[modName] Downloaded! = [modName] téléchargé! +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 [stargazers]✯ = [stargazers]✯ - # Requires translation! -Author: [author] = - # Requires translation! -Size: [size] kB = - # Requires translation! -The mod you selected is incompatible with the defined ruleset! = +Author: [author] = Auteur: [author] +Size: [size] kB = Taille: [size] kO +The mod you selected is incompatible with the defined ruleset! = Le mod choisi es incompatible avec la base de règles actuelle! # Uniques that are relevant to more than one type of game object diff --git a/android/assets/jsons/translations/German.properties b/android/assets/jsons/translations/German.properties index af39a81b84..8b83274529 100644 --- a/android/assets/jsons/translations/German.properties +++ b/android/assets/jsons/translations/German.properties @@ -1097,8 +1097,9 @@ Next page = Nächste Seite Open Github page = Auf Github öffnen Permanent audiovisual mod = Permanente audiovisuelle Mod Installed = Installiert -Downloaded! = Heruntergeladen! -Could not download mod = Konnte Modifikation nicht herunterladen +Downloaded! = Heruntergeladen. +[modName] Downloaded! = [modName] heruntergeladen! +Could not download [modName] = Konnte [modName] nicht herunterladen Online query result is incomplete = Online-Abfrage war unvollständig No description provided = Keine Beschreibung mitgeliefert [stargazers]✯ = [stargazers]✯ diff --git a/android/assets/jsons/translations/Spanish.properties b/android/assets/jsons/translations/Spanish.properties index 68a849650c..e18c386009 100644 --- a/android/assets/jsons/translations/Spanish.properties +++ b/android/assets/jsons/translations/Spanish.properties @@ -1100,7 +1100,8 @@ Open Github page = Abrir Pagina de Github Permanent audiovisual mod = Mod visual permanente Installed = Instalado 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 No description provided = Sin descripción [stargazers]✯ = [stargazers]✯ diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index fbeeeb3ddc..0a97da60cc 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -1092,7 +1092,8 @@ Open Github page = Permanent audiovisual mod = Installed = Downloaded! = -Could not download mod = +[modName] Downloaded! = +Could not download [modName] = Online query result is incomplete = No description provided = [stargazers]✯ = diff --git a/core/src/com/unciv/ui/pickerscreens/ModManagementScreen.kt b/core/src/com/unciv/ui/pickerscreens/ModManagementScreen.kt index 90e0509a04..1f0b223364 100644 --- a/core/src/com/unciv/ui/pickerscreens/ModManagementScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/ModManagementScreen.kt @@ -364,7 +364,7 @@ class ModManagementScreen: PickerScreen(disableScroll = true) { ?: throw Exception() // downloadAndExtract returns null for 404 errors and the like -> display something! rewriteModOptions(repo, modFolder) Gdx.app.postRunnable { - ToastPopup("Downloaded!", this) + ToastPopup("[${repo.name}] Downloaded!", this) RulesetCache.loadRulesets() refreshInstalledModTable() showModDescription(repo.name) @@ -372,7 +372,7 @@ class ModManagementScreen: PickerScreen(disableScroll = true) { } } catch (ex: Exception) { Gdx.app.postRunnable { - ToastPopup("Could not download mod", this) + ToastPopup("Could not download [${repo.name}]", this) } } finally { postAction() diff --git a/core/src/com/unciv/ui/worldscreen/mainmenu/GitHub.kt b/core/src/com/unciv/ui/worldscreen/mainmenu/GitHub.kt index ba24f5b7b8..dffd7845e2 100644 --- a/core/src/com/unciv/ui/worldscreen/mainmenu/GitHub.kt +++ b/core/src/com/unciv/ui/worldscreen/mainmenu/GitHub.kt @@ -1,5 +1,6 @@ package com.unciv.ui.worldscreen.mainmenu +import com.badlogic.gdx.Files import com.badlogic.gdx.files.FileHandle import com.unciv.logic.GameSaver import java.io.* @@ -61,12 +62,15 @@ object Github { val zipUrl = "$gitRepoUrl/archive/$defaultBranch.zip" val inputStream = download(zipUrl) ?: return null + // Get a mod-specific temp file name + val tempName = "temp-" + gitRepoUrl.hashCode().toString(16) + // Download to temporary zip - val tempZipFileHandle = folderFileHandle.child("tempZip.zip") + val tempZipFileHandle = folderFileHandle.child("$tempName.zip") tempZipFileHandle.write(inputStream, false) // 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 if (unzipDestination.exists()) if (unzipDestination.isDirectory) unzipDestination.deleteDirectory() else unzipDestination.delete() @@ -74,7 +78,7 @@ object Github { Zip.extractFolder(tempZipFileHandle, unzipDestination) 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('-', ' ') // finalDestinationName is now the mod name as we display it. Folder name needs to be identical. val finalDestination = folderFileHandle.child(finalDestinationName) @@ -83,7 +87,7 @@ object Github { var tempBackup: FileHandle? = null if (finalDestination.exists()) { tempBackup = finalDestination.sibling("$finalDestinationName.updating") - finalDestination.moveTo(tempBackup) + finalDestination.renameOrMove(tempBackup) } // 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 for (innerFileOrFolder in innerFolder.list() .sortedBy { file -> file.extension() == "atlas" } ) { - innerFileOrFolder.moveTo(finalDestination) + innerFileOrFolder.renameOrMove(finalDestination) } // clean up @@ -103,6 +107,12 @@ object Github { 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.