From 5bbd8bce532f7431ad68aff5a86ca6dfd7a2c081 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Sun, 14 May 2023 14:36:46 +0300 Subject: [PATCH] Allow mods to contain a "preview.png" file for visual indication --- .../storage/OnlineMultiplayerServer.kt | 15 ++++-------- core/src/com/unciv/models/ruleset/Ruleset.kt | 1 + .../unciv/ui/screens/pickerscreens/GitHub.kt | 12 ++++++++++ .../pickerscreens/ModManagementScreen.kt | 24 +++++++++++++++++-- docs/Modders/Mods.md | 2 ++ 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/core/src/com/unciv/logic/multiplayer/storage/OnlineMultiplayerServer.kt b/core/src/com/unciv/logic/multiplayer/storage/OnlineMultiplayerServer.kt index 36314554ee..05d38938b5 100644 --- a/core/src/com/unciv/logic/multiplayer/storage/OnlineMultiplayerServer.kt +++ b/core/src/com/unciv/logic/multiplayer/storage/OnlineMultiplayerServer.kt @@ -31,17 +31,12 @@ class OnlineMultiplayerServer( val authHeader = if (authenticationHeader == null) { val settings = UncivGame.Current.settings.multiplayer mapOf("Authorization" to settings.getAuthHeader()) - } else { - authenticationHeader - } + } else authenticationHeader - return if (serverUrl == Constants.dropboxMultiplayerServer) { - DropBox - } else { - UncivServerFileStorage.apply { - serverUrl = this@OnlineMultiplayerServer.serverUrl - this.authHeader = authHeader - } + return if (serverUrl == Constants.dropboxMultiplayerServer) DropBox + else UncivServerFileStorage.apply { + serverUrl = this@OnlineMultiplayerServer.serverUrl + this.authHeader = authHeader } } diff --git a/core/src/com/unciv/models/ruleset/Ruleset.kt b/core/src/com/unciv/models/ruleset/Ruleset.kt index a83eb60ebf..603d2bc825 100644 --- a/core/src/com/unciv/models/ruleset/Ruleset.kt +++ b/core/src/com/unciv/models/ruleset/Ruleset.kt @@ -55,6 +55,7 @@ class ModOptions : IHasUniques { var lastUpdated = "" var modUrl = "" + var defaultBranch = "master" var author = "" var modSize = 0 var topics = mutableListOf() diff --git a/core/src/com/unciv/ui/screens/pickerscreens/GitHub.kt b/core/src/com/unciv/ui/screens/pickerscreens/GitHub.kt index f6ad117834..3f9115e72c 100644 --- a/core/src/com/unciv/ui/screens/pickerscreens/GitHub.kt +++ b/core/src/com/unciv/ui/screens/pickerscreens/GitHub.kt @@ -2,6 +2,7 @@ package com.unciv.ui.screens.pickerscreens import com.badlogic.gdx.Files import com.badlogic.gdx.files.FileHandle +import com.badlogic.gdx.graphics.Pixmap import com.unciv.json.fromJsonFile import com.unciv.json.json import com.unciv.logic.BackwardCompatibility.updateDeprecations @@ -20,6 +21,7 @@ import java.io.InputStream import java.io.InputStreamReader import java.net.HttpURLConnection import java.net.URL +import java.nio.ByteBuffer import java.util.zip.ZipEntry import java.util.zip.ZipFile @@ -250,6 +252,15 @@ object Github { return null } + fun tryGetPreviewImage(modUrl:String, defaultBranch: String): Pixmap?{ + val fileLocation = "$modUrl/$defaultBranch/preview.png" + .replace("github.com", "raw.githubusercontent.com") + val file = download(fileLocation) ?: return null + val byteArray = file.readBytes() + val buffer = ByteBuffer.allocateDirect(byteArray.size).put(byteArray).position(0) + return Pixmap(buffer) + } + class Tree { class TreeFile { @@ -385,6 +396,7 @@ object Github { val modOptionsFile = modFolder.child("jsons/ModOptions.json") val modOptions = if (modOptionsFile.exists()) json().fromJsonFile(ModOptions::class.java, modOptionsFile) else ModOptions() modOptions.modUrl = repo.html_url + modOptions.defaultBranch = repo.default_branch modOptions.lastUpdated = repo.pushed_at modOptions.author = repo.owner.login modOptions.modSize = repo.size diff --git a/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt b/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt index 998dcc6265..a58ae15433 100644 --- a/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt +++ b/core/src/com/unciv/ui/screens/pickerscreens/ModManagementScreen.kt @@ -2,9 +2,11 @@ package com.unciv.ui.screens.pickerscreens import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.scenes.scene2d.Actor import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.ui.Button +import com.badlogic.gdx.scenes.scene2d.ui.Image import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane import com.badlogic.gdx.scenes.scene2d.ui.Table @@ -44,8 +46,8 @@ import com.unciv.ui.screens.basescreen.BaseScreen import com.unciv.ui.screens.basescreen.RecreateOnResize import com.unciv.ui.screens.mainmenuscreen.MainMenuScreen import com.unciv.ui.screens.pickerscreens.ModManagementOptions.SortType -import com.unciv.utils.Log import com.unciv.utils.Concurrency +import com.unciv.utils.Log import com.unciv.utils.launchOnGLThread import kotlinx.coroutines.Job import kotlinx.coroutines.isActive @@ -347,7 +349,7 @@ class ModManagementScreen( * @param repo: the repository instance as received from the GitHub api */ private fun addModInfoToActionTable(repo: Github.Repo) { - addModInfoToActionTable(repo.html_url, repo.pushed_at, repo.owner.login, repo.size) + addModInfoToActionTable(repo.html_url, repo.default_branch, repo.pushed_at, repo.owner.login, repo.size) } /** Recreate the information part of the right-hand column * @param modName: The mod name (name from the RuleSet) @@ -358,11 +360,13 @@ class ModManagementScreen( modOptions.modUrl, modOptions.lastUpdated, modOptions.author, + modOptions.defaultBranch, modOptions.modSize ) } private fun addModInfoToActionTable( repoUrl: String, + default_branch: String, updatedAt: String, author: String, modSize: Int @@ -371,6 +375,22 @@ class ModManagementScreen( // Display metadata + val imageHolder = Table() + Concurrency.run { + val imagePixmap = Github.tryGetPreviewImage(repoUrl, default_branch) ?: return@run + Concurrency.runOnGLThread { + val largestImageSize = max(imagePixmap.width, imagePixmap.height) + val cell = imageHolder.add(Image(Texture(imagePixmap))) + + val maxAllowedImageSize = 200f + if (largestImageSize > maxAllowedImageSize) { + val resizeRatio = maxAllowedImageSize / largestImageSize + cell.size(imagePixmap.width * resizeRatio, imagePixmap.height * resizeRatio) + } + } + } + modActionTable.add(imageHolder).row() + if (author.isNotEmpty()) modActionTable.add("Author: [$author]".toLabel()).row() diff --git a/docs/Modders/Mods.md b/docs/Modders/Mods.md index 43859fb069..f843269899 100644 --- a/docs/Modders/Mods.md +++ b/docs/Modders/Mods.md @@ -115,6 +115,8 @@ When loading a mod, it needs to be in its own folder in `/mods` - this is how yo ## Other +You can add an image that will be displayed to users in the mod management by adding a "preview.png" file. + Existing mods can be found [here](https://github.com/topics/unciv-mod)! A list of uniques and how to use them can be found [here](Unique-parameters.md)!