mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-29 06:51:30 -04:00
Mod management screen takes its list of mods from the Github API!
This commit is contained in:
parent
0074ebfdb5
commit
36f5d22a80
@ -4,19 +4,18 @@ import com.badlogic.gdx.Gdx
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextArea
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener
|
||||
import com.unciv.MainMenuScreen
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.utils.*
|
||||
import com.unciv.ui.worldscreen.mainmenu.Zip
|
||||
import com.unciv.ui.worldscreen.mainmenu.Github
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class ModManagementScreen: PickerScreen() {
|
||||
|
||||
val modTable = Table().apply { defaults().pad(10f) }
|
||||
val downloadTable = Table()
|
||||
val downloadTable = Table().apply { defaults().pad(10f) }
|
||||
|
||||
init {
|
||||
setDefaultCloseAction(MainMenuScreen())
|
||||
@ -24,8 +23,32 @@ class ModManagementScreen: PickerScreen() {
|
||||
|
||||
topTable.add(modTable).pad(10f)
|
||||
|
||||
downloadTable.add(getDownloadButton()).row()
|
||||
|
||||
thread {
|
||||
val repoList: ArrayList<Github.Repo>
|
||||
try {
|
||||
repoList = Github.tryGetGithubReposWithTopic()
|
||||
|
||||
} catch (ex: Exception) {
|
||||
ResponsePopup("Could not download mod list", this)
|
||||
return@thread
|
||||
}
|
||||
|
||||
for (repo in repoList) {
|
||||
repo.name = repo.name.replace('-',' ')
|
||||
val downloadButton = repo.name.toTextButton()
|
||||
downloadButton.onClick {
|
||||
descriptionLabel.setText(repo.description + "\n" + "[${repo.stargazers_count}] Stars".tr())
|
||||
removeRightSideClickListeners()
|
||||
rightSideButton.enable()
|
||||
rightSideButton.setText("Download [${repo.name}]".tr())
|
||||
rightSideButton.onClick { downloadMod(repo.svn_url) }
|
||||
}
|
||||
downloadTable.add(downloadButton).row()
|
||||
}
|
||||
}
|
||||
|
||||
downloadTable.add(getDownloadButton())
|
||||
topTable.add(downloadTable)
|
||||
}
|
||||
|
||||
@ -37,24 +60,9 @@ class ModManagementScreen: PickerScreen() {
|
||||
popup.add(textArea).width(stage.width/2).row()
|
||||
val downloadButton = "Download".toTextButton()
|
||||
downloadButton.onClick {
|
||||
thread { // to avoid ANRs - we've learnt our lesson from previous download-related actions
|
||||
try {
|
||||
downloadButton.setText("Downloading...")
|
||||
downloadButton.disable()
|
||||
Zip.downloadAndExtract(textArea.text+"/archive/master.zip",
|
||||
Gdx.files.local("mods"))
|
||||
Gdx.app.postRunnable {
|
||||
RulesetCache.loadRulesets()
|
||||
refresh()
|
||||
popup.close()
|
||||
}
|
||||
} catch (ex:Exception){
|
||||
Gdx.app.postRunnable {
|
||||
ResponsePopup("Could not download mod", this)
|
||||
popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
downloadButton.setText("Downloading...")
|
||||
downloadButton.disable()
|
||||
downloadMod(textArea.text) { popup.close() }
|
||||
}
|
||||
popup.add(downloadButton).row()
|
||||
popup.addCloseButton()
|
||||
@ -63,6 +71,27 @@ class ModManagementScreen: PickerScreen() {
|
||||
return downloadButton
|
||||
}
|
||||
|
||||
fun downloadMod(gitRepoUrl:String, postAction:()->Unit={}){
|
||||
thread { // to avoid ANRs - we've learnt our lesson from previous download-related actions
|
||||
try {
|
||||
Github.downloadAndExtract(gitRepoUrl+"/archive/master.zip",
|
||||
Gdx.files.local("mods"))
|
||||
Gdx.app.postRunnable {
|
||||
ResponsePopup("Downloaded!", this)
|
||||
RulesetCache.loadRulesets()
|
||||
refresh()
|
||||
}
|
||||
} catch (ex:Exception){
|
||||
Gdx.app.postRunnable {
|
||||
ResponsePopup("Could not download mod", this)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
postAction()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun refresh(){
|
||||
modTable.clear()
|
||||
val currentMods = RulesetCache.values.filter { it.name != "" }
|
||||
@ -71,8 +100,7 @@ class ModManagementScreen: PickerScreen() {
|
||||
rightSideButton.setText("Delete [${mod.name}]".tr())
|
||||
rightSideButton.enable()
|
||||
descriptionLabel.setText(mod.getSummary())
|
||||
rightSideButton.listeners.filter { it != rightSideButton.clickListener }
|
||||
.forEach { rightSideButton.removeListener(it) }
|
||||
removeRightSideClickListeners()
|
||||
rightSideButton.onClick {
|
||||
YesNoPopup("Are you SURE you want to delete this mod?",
|
||||
{ deleteMod(mod) }, this).open()
|
||||
|
@ -62,4 +62,9 @@ open class PickerScreen : CameraStageBaseScreen() {
|
||||
if(UncivGame.Current.worldScreen.isPlayersTurn) rightSideButton.enable()
|
||||
rightSideButton.setText(rightButtonText)
|
||||
}
|
||||
|
||||
fun removeRightSideClickListeners(){
|
||||
rightSideButton.listeners.filter { it != rightSideButton.clickListener }
|
||||
.forEach { rightSideButton.removeListener(it) }
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.files.FileHandle
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.GameSaver
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.models.metadata.GameSettings
|
||||
import com.unciv.ui.saves.Gzip
|
||||
import java.io.*
|
||||
import java.net.HttpURLConnection
|
||||
@ -132,11 +133,12 @@ class OnlineMultiplayer {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object Zip {
|
||||
fun downloadUrl(url:String): InputStream? {
|
||||
with(URL(url).openConnection() as HttpURLConnection) {
|
||||
// requestMethod = "POST" // default is GET
|
||||
object Github {
|
||||
// Consider merging this with the Dropbox function
|
||||
fun download(url: String, action: (HttpURLConnection) -> Unit = {}): InputStream? {
|
||||
with(URL(url).openConnection() as HttpURLConnection)
|
||||
{
|
||||
action(this)
|
||||
|
||||
doOutput = true
|
||||
|
||||
@ -153,17 +155,17 @@ object Zip {
|
||||
|
||||
// This took a long time to get just right, so if you're changing this, TEST IT THOROUGHLY on both Desktop and Phone
|
||||
fun downloadAndExtract(url:String, folderFileHandle:FileHandle) {
|
||||
val inputStream = downloadUrl(url)
|
||||
val inputStream = download(url)
|
||||
if (inputStream == null) return
|
||||
//DropBox.downloadFile(dropboxFileLocation)
|
||||
|
||||
val tempZipFileHandle = folderFileHandle.child("tempZip.zip")
|
||||
tempZipFileHandle.write(inputStream, false)
|
||||
val unzipDestination = tempZipFileHandle.sibling("tempZip") // folder, not file
|
||||
extractFolder(tempZipFileHandle, unzipDestination)
|
||||
Zip.extractFolder(tempZipFileHandle, unzipDestination)
|
||||
val innerFolder = unzipDestination.list().first() // tempZip/<repoName>-master/
|
||||
|
||||
val finalDestination = folderFileHandle.child(innerFolder.name().replace("-master",""))
|
||||
val finalDestinationName = innerFolder.name().replace("-master","").replace('-',' ')
|
||||
val finalDestination = folderFileHandle.child(finalDestinationName)
|
||||
finalDestination.mkdirs() // If we don't create this as a directory, it will think this is a file and nothing will work.
|
||||
for(innerFileOrFolder in innerFolder.list()){
|
||||
innerFileOrFolder.moveTo(finalDestination)
|
||||
@ -173,6 +175,27 @@ object Zip {
|
||||
unzipDestination.deleteDirectory()
|
||||
}
|
||||
|
||||
|
||||
fun tryGetGithubReposWithTopic(): ArrayList<Repo> {
|
||||
val inputStream = download("https://api.github.com/search/repositories?q=topic:unciv-mod")
|
||||
if (inputStream == null) return ArrayList()
|
||||
return GameSaver.json().fromJson(RepoSearch::class.java, inputStream!!.bufferedReader().readText()).items
|
||||
}
|
||||
|
||||
class RepoSearch{
|
||||
var items=ArrayList<Repo>()
|
||||
}
|
||||
|
||||
class Repo {
|
||||
var name = ""
|
||||
var description = ""
|
||||
var svn_url = ""
|
||||
var stargazers_count = 0
|
||||
}
|
||||
}
|
||||
|
||||
object Zip {
|
||||
|
||||
// I went through a lot of similar answers that didn't work until I got to this gem by NeilMonday
|
||||
// (with mild changes to fit the FileHandles)
|
||||
// https://stackoverflow.com/questions/981578/how-to-unzip-files-recursively-in-java
|
||||
|
@ -12,6 +12,7 @@ import com.unciv.models.ruleset.unit.BaseUnit
|
||||
import com.unciv.models.stats.Stat
|
||||
import com.unciv.models.stats.Stats
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.worldscreen.mainmenu.Http
|
||||
import com.unciv.ui.worldscreen.mainmenu.Zip
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
@ -89,4 +90,9 @@ class BasicTests {
|
||||
// Zip.downloadAndExtract("/Mods/Reasoures.zip", FileHandle("""C:\Users\LENOVO\Downloads"""))
|
||||
// Zip.downloadAndExtract("https://github.com/yairm210/Unciv-IV-mod/archive/master.zip", FileHandle("""C:\Users\LENOVO\Downloads"""))
|
||||
// }
|
||||
|
||||
@Test // This should NOT run as part of the test suite!
|
||||
fun tryGetGithubTopicInfo(){
|
||||
println(Http.tryGetGithubTopic())
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user