From 7f168ded4385f92ef782127069a80ee2a4fa962f Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 15 Jul 2023 22:15:14 +0200 Subject: [PATCH 01/16] chore: bump javagi --- build.gradle.kts | 2 +- .../jfronny/inceptum/gtk/control/InstanceGridEntryFactory.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 53f536a..ecea4fe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,7 +17,7 @@ val jbAnnotationsVersion by extra("24.0.1") val lwjglVersion by extra("3.3.2") val imguiVersion by extra("1.86.10") // launcher-gtk -val javagiVersion by extra("v0.5.1") +val javagiVersion by extra("0.6.0") val flavorProp: String by extra(prop("flavor", "custom")) if (!setOf("custom", "maven", "fat", "windows", "linux", "macos").contains(flavorProp)) throw IllegalStateException("Unsupported flavor: $flavorProp") diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/InstanceGridEntryFactory.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/InstanceGridEntryFactory.kt index 95493af..799ee0a 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/InstanceGridEntryFactory.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/InstanceGridEntryFactory.kt @@ -3,8 +3,8 @@ package io.gitlab.jfronny.inceptum.gtk.control import io.gitlab.jfronny.inceptum.gtk.util.get import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance import org.gnome.gtk.* -import org.pango.EllipsizeMode -import org.pango.WrapMode +import org.gnome.pango.EllipsizeMode +import org.gnome.pango.WrapMode class InstanceGridEntryFactory( private val instanceList: List From a7a135c5981eb9ea56619cd64bfa01e329c5a85d Mon Sep 17 00:00:00 2001 From: JFronny Date: Mon, 24 Jul 2023 14:29:06 +0200 Subject: [PATCH 02/16] chore: basic mod browsing (untested due to GTK4 issues) --- buildSrc/build.gradle.kts | 2 +- .../src/main/kotlin/inceptum.java.gradle.kts | 2 +- .../gitlab/jfronny/inceptum/common/Net.java | 6 +- launcher-gtk/build.gradle.kts | 7 +- .../gtk/control/InstanceListEntryFactory.kt | 11 +- .../inceptum/gtk/control/LoadingRevealer.kt | 37 +++ .../control/settings/SectionedSettingsTab.kt | 2 +- .../gtk/control/settings/SettingsTab.kt | 4 +- .../gtk/control/settings/SettingsWindow.kt | 2 +- .../inceptum/gtk/util/StringListExt.kt | 1 + .../gtk/window/settings/instance/ExportTab.kt | 3 +- .../window/settings/instance/GeneralTab.kt | 4 +- .../instance/InstanceSettingsWindow.kt | 8 +- .../gtk/window/settings/instance/ModsTab.kt | 252 +++++++++++++++++- .../window/settings/launcher/AccountsTab.kt | 2 +- .../window/settings/launcher/GeneralTab.kt | 2 +- .../src/main/resources/inceptum.properties | 10 +- .../src/main/resources/inceptum_de.properties | 10 +- .../inceptum/imgui/window/AddModWindow.java | 20 +- .../inceptum/launcher/api/CurseforgeApi.java | 4 + .../inceptum/launcher/api/ModrinthApi.java | 17 ++ .../response/GetModDescriptionResponse.java | 8 + .../launcher/model/inceptum/ModMeta.java | 26 ++ .../model/modrinth/ModrinthLatest.java | 20 ++ .../system/source/CurseforgeModSource.java | 25 ++ .../system/source/DirectModSource.java | 25 +- .../launcher/system/source/ModSource.java | 6 + .../system/source/ModrinthModSource.java | 38 +-- 28 files changed, 475 insertions(+), 79 deletions(-) create mode 100644 launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/LoadingRevealer.kt create mode 100644 launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/curseforge/response/GetModDescriptionResponse.java create mode 100644 launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/modrinth/ModrinthLatest.java diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 8e8b9f4..e239ad1 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -10,5 +10,5 @@ repositories { dependencies { implementation("gradle.plugin.com.github.johnrengelman:shadow:7.1.2") implementation("de.undercouch:gradle-download-task:5.1.2") - implementation("io.gitlab.jfronny:convention:1.4-SNAPSHOT") + implementation("io.gitlab.jfronny:convention:1.5-SNAPSHOT") } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/inceptum.java.gradle.kts b/buildSrc/src/main/kotlin/inceptum.java.gradle.kts index c97b26f..af4cac0 100644 --- a/buildSrc/src/main/kotlin/inceptum.java.gradle.kts +++ b/buildSrc/src/main/kotlin/inceptum.java.gradle.kts @@ -1,5 +1,5 @@ plugins { - `java-library` + id("jf.java") `maven-publish` } diff --git a/common/src/main/java/io/gitlab/jfronny/inceptum/common/Net.java b/common/src/main/java/io/gitlab/jfronny/inceptum/common/Net.java index d5e3272..2cda26d 100644 --- a/common/src/main/java/io/gitlab/jfronny/inceptum/common/Net.java +++ b/common/src/main/java/io/gitlab/jfronny/inceptum/common/Net.java @@ -39,7 +39,7 @@ public class Net { } public static T downloadObject(String url, ThrowingFunction func, String apiKey) throws IOException { - return downloadObject(url, () -> HttpUtils.get(url).header("x-api-key", apiKey).sendString(), func, true); + return downloadObject(url, () -> downloadStringAuthenticated(url, apiKey), func, true); } public static T downloadObject(String url, String sha1, ThrowingFunction func) throws IOException { @@ -82,6 +82,10 @@ public class Net { return new String(downloadData(url, sha1), StandardCharsets.UTF_8); } + public static String downloadStringAuthenticated(String url, String apiKey) throws IOException, URISyntaxException { + return HttpUtils.get(url).header("x-api-key", apiKey).sendString(); + } + public static void downloadFile(String url, Path path) throws IOException, URISyntaxException { if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent()); Files.write(path, downloadData(url)); diff --git a/launcher-gtk/build.gradle.kts b/launcher-gtk/build.gradle.kts index e3158ce..5c20bc7 100644 --- a/launcher-gtk/build.gradle.kts +++ b/launcher-gtk/build.gradle.kts @@ -3,13 +3,18 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("inceptum.application") id("com.github.johnrengelman.shadow") - kotlin("jvm") version "1.9.0-RC" + kotlin("jvm") version "1.9.0" + kotlin("plugin.sam.with.receiver") version "1.9.0" } application { mainClass.set("io.gitlab.jfronny.inceptum.gtk.GtkMain") } +samWithReceiver { + annotation("io.gitlab.jfronny.commons.SamWithReceiver") +} + repositories { mavenLocal() maven("https://jitpack.io") { diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/InstanceListEntryFactory.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/InstanceListEntryFactory.kt index 581a07f..612d7b1 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/InstanceListEntryFactory.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/InstanceListEntryFactory.kt @@ -16,6 +16,7 @@ import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceNameTool import io.gitlab.jfronny.inceptum.launcher.system.launch.LaunchType import org.gnome.adw.ActionRow +import org.gnome.gdk.Gdk import org.gnome.gio.Menu import org.gnome.gtk.* import java.io.IOException @@ -32,7 +33,6 @@ class InstanceListEntryFactory( launch.addCssClass("flat") launch.name = "inceptum-launch" launch.tooltipText = I18n["instance.launch"] - launch.hasTooltip = true val menu = MenuButton() menu.addCssClass("flat") @@ -49,7 +49,7 @@ class InstanceListEntryFactory( row.fixSubtitle() val rightClicked = GestureClick() - rightClicked.button = 3 + rightClicked.button = Gdk.BUTTON_SECONDARY rightClicked.onPressed { nPress, _, _ -> if (nPress == 1) menu.emitActivate() } row.addController(rightClicked) @@ -59,11 +59,11 @@ class InstanceListEntryFactory( override fun BindContext.bind(widget: ActionRow, data: Decomposed) { if (data.instance?.isLocked ?: true) { data.item.activatable = false - data.row.subtitle = if (data.instance?.isRunningLocked ?: false) I18n["instance.launch.locked.running"] + widget.subtitle = if (data.instance?.isRunningLocked ?: false) I18n["instance.launch.locked.running"] else I18n["instance.launch.locked.setup"] } - data.row.title = data.instance.toString() + widget.title = data.instance.toString() data.thumbnail.bind(data.instance!!) @@ -137,14 +137,13 @@ class InstanceListEntryFactory( val launch = suffixes.firstChild as Button val menuButton = launch.nextSibling as MenuButton val popoverMenu = menuButton.popover as PopoverMenu - return Decomposed(listItem, id, instance, widget, thumbnail, launch, popoverMenu) + return Decomposed(listItem, id, instance, thumbnail, launch, popoverMenu) } class Decomposed( val item: ListItem, val instanceId: String, val instance: Instance?, - val row: ActionRow, val thumbnail: InstanceThumbnail, val launch: Button, val popoverMenu: PopoverMenu diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/LoadingRevealer.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/LoadingRevealer.kt new file mode 100644 index 0000000..114f4d8 --- /dev/null +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/LoadingRevealer.kt @@ -0,0 +1,37 @@ +package io.gitlab.jfronny.inceptum.gtk.control + +import org.gnome.gtk.Align +import org.gnome.gtk.ProgressBar +import org.gnome.gtk.Revealer +import org.gnome.gtk.RevealerTransitionType + +class LoadingRevealer: Revealer() { + private val progressBar: ProgressBar + + init { + transitionType = RevealerTransitionType.CROSSFADE + revealChild = false + vexpand = false + hexpand = false + valign = Align.CENTER + halign = Align.FILL + progressBar = ProgressBar().apply { + hexpand = true + vexpand = false + addCssClass("osd") + } + child = progressBar + } + + fun setRunning(state: Boolean) { + revealChild = state + } + + fun setProgress(progress: Double) { + progressBar.fraction = progress.coerceIn(0.0, 1.0) + } + + fun pulse() { + progressBar.pulse() + } +} \ No newline at end of file diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SectionedSettingsTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SectionedSettingsTab.kt index 56c14de..f627258 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SectionedSettingsTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SectionedSettingsTab.kt @@ -7,7 +7,7 @@ import org.gnome.gtk.* import org.jetbrains.annotations.PropertyKey import java.util.concurrent.atomic.AtomicInteger -open class SectionedSettingsTab(window: Window?): SettingsTab(window, Box(Orientation.VERTICAL, 8)) { +open class SectionedSettingsTab(window: W?): SettingsTab(window, Box(Orientation.VERTICAL, 8)) { init { content.marginHorizontal = 24 content.marginTop = 12 diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsTab.kt index 1081c6b..581364d 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsTab.kt @@ -5,8 +5,8 @@ import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend import org.gnome.gtk.Widget import org.gnome.gtk.Window -open class SettingsTab( - protected val window: Window?, +open class SettingsTab( + protected val window: W?, val content: T ) { protected fun showError(message: String, t: Throwable) = diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt index 959ae5e..3d048f3 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt @@ -40,7 +40,7 @@ open class SettingsWindow(app: Application?) : Window() { setDefaultSize(720, 360) } - fun addTab(tab: SettingsTab<*>, title: @PropertyKey(resourceBundle = I18n.BUNDLE) String, iconName: String) { + fun addTab(tab: SettingsTab<*, *>, title: @PropertyKey(resourceBundle = I18n.BUNDLE) String, iconName: String) { stack.addTitledWithIcon(tab.content, title, I18n[title], iconName) } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/StringListExt.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/StringListExt.kt index 6d6c618..047137b 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/StringListExt.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/StringListExt.kt @@ -5,5 +5,6 @@ import org.gnome.gtk.StringList fun StringList.clear() = splice(0, size, null) fun StringList.addAll(values: Array) = splice(size, 0, values) +fun StringList.replaceAll(values: Array) = splice(0, size, values) val ListModel.size get() = nItems \ No newline at end of file diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ExportTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ExportTab.kt index 76fe9ce..72865e5 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ExportTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ExportTab.kt @@ -13,7 +13,8 @@ import org.gnome.gio.Cancellable import org.gnome.gtk.* import java.nio.file.Path -class ExportTab(private val instance: Instance, window: InstanceSettingsWindow?) : SectionedSettingsTab(window) { +class ExportTab(window: InstanceSettingsWindow) : SectionedSettingsTab(window) { + private val instance: Instance = window.instance init { section(null) { row("instance.settings.export.version", "instance.settings.export.version.subtitle") { diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt index 7d55e22..75ee020 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt @@ -14,7 +14,6 @@ import io.gitlab.jfronny.inceptum.gtk.util.markup import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi import io.gitlab.jfronny.inceptum.launcher.api.McApi -import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceNameTool import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser @@ -26,12 +25,13 @@ import java.nio.file.Files import java.nio.file.Path import java.util.* -class GeneralTab(instance: Instance, window: InstanceSettingsWindow) : SectionedSettingsTab(window) { +class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab(window) { companion object { private val VERSIONS = McApi.getVersions() } init { + val instance = window.instance section(null) { row("instance.settings.general.name", "instance.settings.general.name.placeholder") { val apply = Button.newWithLabel(I18n["instance.settings.apply"]) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/InstanceSettingsWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/InstanceSettingsWindow.kt index b2a00d8..2ca22c6 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/InstanceSettingsWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/InstanceSettingsWindow.kt @@ -4,10 +4,10 @@ import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsWindow import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance import org.gnome.gtk.Application -class InstanceSettingsWindow(app: Application?, instance: Instance) : SettingsWindow(app) { +class InstanceSettingsWindow(val app: Application?, val instance: Instance) : SettingsWindow(app) { init { - addTab(GeneralTab(instance, this), "instance.settings.general", "preferences-other-symbolic") - addTab(ModsTab(instance, this), "instance.settings.mods", "package-x-generic-symbolic") - addTab(ExportTab(instance, this), "instance.settings.export", "send-to-symbolic") + addTab(GeneralTab(this), "instance.settings.general", "preferences-other-symbolic") + addTab(ModsTab(this), "instance.settings.mods", "package-x-generic-symbolic") + addTab(ExportTab(this), "instance.settings.export", "send-to-symbolic") } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt index 7a0a3cb..948365e 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt @@ -1,20 +1,55 @@ package io.gitlab.jfronny.inceptum.gtk.window.settings.instance +import io.gitlab.jfronny.commons.concurrent.AsyncRequest +import io.gitlab.jfronny.commons.concurrent.VoidFuture import io.gitlab.jfronny.inceptum.gtk.control.ILabel import io.gitlab.jfronny.inceptum.gtk.control.KDropDown +import io.gitlab.jfronny.inceptum.gtk.control.KSignalListItemFactory +import io.gitlab.jfronny.inceptum.gtk.control.LoadingRevealer import io.gitlab.jfronny.inceptum.gtk.control.settings.SettingsTab +import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.clear +import io.gitlab.jfronny.inceptum.gtk.util.fixSubtitle +import io.gitlab.jfronny.inceptum.gtk.util.replaceAll +import io.gitlab.jfronny.inceptum.launcher.LauncherEnv +import io.gitlab.jfronny.inceptum.launcher.api.CurseforgeApi +import io.gitlab.jfronny.inceptum.launcher.api.ModrinthApi +import io.gitlab.jfronny.inceptum.launcher.model.modrinth.ModrinthProjectType import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance +import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod +import io.gitlab.jfronny.inceptum.launcher.system.instance.ModManager +import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath +import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner +import io.gitlab.jfronny.inceptum.launcher.system.source.CurseforgeModSource +import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource +import io.gitlab.jfronny.inceptum.launcher.system.source.ModrinthModSource +import org.gnome.adw.ActionRow import org.gnome.adw.Leaflet import org.gnome.adw.LeafletTransitionType -import org.gnome.gtk.Box -import org.gnome.gtk.Orientation -import org.gnome.gtk.SearchBar -import org.gnome.gtk.SearchEntry -import org.gnome.gtk.Separator +import org.gnome.glib.GLib +import org.gnome.gtk.* +import org.jetbrains.annotations.PropertyKey +import java.util.concurrent.ForkJoinPool +import kotlin.jvm.optionals.getOrNull + +class ModsTab(window: InstanceSettingsWindow) : SettingsTab(window, Leaflet()) { + private val instance: Instance + private val mds: ModsDirScanner + private val listModel: StringList + private val loadingRevealer = LoadingRevealer() + private val descriptionLabel: ILabel + + private var page: Page = Page.LOCAL + enum class Page { + LOCAL, MODRINTH, CURSEFORGE + } -class ModsTab(instance: Instance?, window: InstanceSettingsWindow?) : SettingsTab(window, Leaflet()) { init { + instance = window.instance + mds = instance.mds + content.apply { + //TODO consider filter panel via Flap homogeneous = false canNavigateBack = true transitionType = LeafletTransitionType.OVER @@ -23,9 +58,9 @@ class ModsTab(instance: Instance?, window: InstanceSettingsWindow?) : SettingsTa append(KDropDown("instance.settings.mods.local", "instance.settings.mods.modrinth", "instance.settings.mods.curseforge").apply { onChange { newFilter -> when (newFilter) { - 0 -> switchToLocalMods() - 1 -> switchToModrinthMods() - 2 -> switchToCurseforgeMods() + 0 -> switchTo(Page.LOCAL) + 1 -> switchTo(Page.MODRINTH) + 2 -> switchTo(Page.CURSEFORGE) } } }) @@ -39,17 +74,206 @@ class ModsTab(instance: Instance?, window: InstanceSettingsWindow?) : SettingsTa child = entry keyCaptureWidget = entry }) + listModel = StringList(arrayOf()) + append(Overlay().apply { + child = ModsListView(listModel) + addOverlay(loadingRevealer) + }) }) append(Separator(Orientation.VERTICAL)).navigatable = false append(Box(Orientation.VERTICAL, 6).apply { - append(ILabel("instance.settings.mods.unsupported")) + descriptionLabel = ILabel("instance.settings.mods.select") + append(descriptionLabel) //TODO content }) + + addTickCallback { _, _ -> + val toShow = mutableListOf() + if (page == Page.LOCAL) { + loadingRevealer.setRunning(!mds.isComplete) + val mods = window.instance.mods + loadingRevealer.setProgress((mods.filter { mds.hasScanned(it) }.size.toDouble() / mods.size)) + for (mod in mods) { + if (mod.name.contains(currentSearchString)) { + //TODO improve this search + this@ModsTab.mods[mod.name] = ModState.Installed(mod) + toShow.add(mod.name) + } + } + listModel.replaceAll(mods.map { it.name }.toTypedArray()) + } else { + loadingRevealer.setRunning(searchResult == null || !mds.isComplete) + if (searchResult != null) { + for (mod in searchResult.orEmpty()) { + this@ModsTab.mods[mod.name] = mod + toShow.add(mod.name) + } + } + } + listModel.replaceAll(toShow.toTypedArray()) + GLib.SOURCE_CONTINUE + } } } - fun switchToLocalMods(): Unit = TODO("set up") - fun switchToModrinthMods(): Unit = TODO("set up") - fun switchToCurseforgeMods(): Unit = TODO("set up") - fun updateSearch(search: String): Unit = TODO("set up") + private var currentSearchString: String = "" + private var searchResult: List? = null + //TODO search pagination + private val search = AsyncRequest({ + searchResult = null + loadingRevealer.setRunning(true) + loadingRevealer.pulse() + VoidFuture(ForkJoinPool.commonPool().submit { + val sources: List = when (page) { + Page.CURSEFORGE -> { + val cf = CurseforgeApi.search(instance.gameVersion, currentSearchString, 0, "Popularity") //TODO allow user to choose sort mode + cf.mapNotNull { + if (isCancelled) return@submit + val file = it.latestFilesIndexes.firstOrNull { it.gameVersion == instance.gameVersion } //TODO support compatible minor versions + if (file == null) null + else CurseforgeModSource(it.id, file.fileId) + } + } + Page.MODRINTH -> { + val mr = ModrinthApi.search(currentSearchString, 0, instance.gameVersion, ModrinthProjectType.mod).hits + mr.mapNotNull { + if (isCancelled) return@submit + val file = ModrinthApi.getLatestVersions(it.project_id, instance.gameVersion).best + if (file == null) null + else ModrinthModSource(file.id) + } + } + Page.LOCAL -> listOf() + } + searchResult = sources.map { ModState(it) } + }) + }, { + loadingRevealer.setRunning(false) + }) + fun switchTo(page: Page): Unit { + listModel.clear() + mods.clear() + this.page = page + updateSearch(currentSearchString) + } + fun updateSearch(search: String): Unit { + descriptionLabel.text = "Searching is currently unsupported" + currentSearchString = search + this.search.request() + } + fun selectMod(mod: ModState): Unit { + //TODO detailed menu for version selection, ... + descriptionLabel.setMarkup(mod.description) + } + + inner class ModsListView(model: StringList): ListView(ModsListSelectionModel(model), ModsListItemFactory()) { + init { + vscrollPolicy = ScrollablePolicy.NATURAL + addCssClass("navigation-sidebar") + } + } + + class ModsListSelectionModel(model: StringList): SingleSelection(model) { + init { + autoselect = false +// onSelectionChanged { position, nItems -> +// val v = (selectedItem as? StringObject)?.string +// if (v != null) +// } + } + } + + private val mods = LinkedHashMap() + + //TODO https://gitlab.gnome.org/World/gfeeds/-/blob/master/data/ui/sidebar_listbox_row.blp + inner class ModsListItemFactory: KSignalListItemFactory() { + override fun setup(): ActionRow { + val row = ActionRow() + row.activatable = true + + val quickAction = Button.newFromIconName("folder-download-symbolic") + quickAction.addCssClass("flat") + quickAction.tooltipText = I18n["instance.settings.mods.download"] + + row.fixSubtitle() + + return row + } + + override fun BindContext.bind(widget: ActionRow, data: Decomposed) { + widget.title = data.mod!!.name + widget.subtitle = data.mod.summary + registerForUnbind(widget.onActivated { selectMod(data.mod) }) + fun setupQuickAction( + iconName: String, + description: @PropertyKey(resourceBundle = I18n.BUNDLE) String, + handler: Button.Clicked + ) { + data.quickAction.iconName = iconName + data.quickAction.tooltipText = I18n[description] + registerForUnbind(data.quickAction.onClicked(handler)) + } + when (data.mod) { + is ModState.Installed -> if (data.mod.outdated) setupQuickAction("software-update-available-symbolic", "instance.settings.mods.update") { + data.mod.updates[0]() + } + else setupQuickAction("edit-delete-symbolic", "instance.settings.mods.delete") { + data.mod.remove() + } + is ModState.Available -> setupQuickAction("folder-download-symbolic", "instance.settings.mods.download") { + data.mod.install() + } + else -> setupQuickAction("dialog-question-symbolic", "instance.settings.mods.unknown") { + LauncherEnv.showError(I18n["instance.settings.mods.unknown.description"], I18n["instance.settings.mods.unknown"]) + } + } + } + + override fun UnbindContext.unbind(widget: ActionRow, data: Decomposed) { + // Not needed currently + } + + override fun ActionContext.castWidget(widget: Widget): ActionRow = widget as ActionRow + override fun ActionContext.lookup(id: String, widget: ActionRow): Decomposed { + val mod = mods[id] + val suffixes = widget.firstChild!!.lastChild as Box + val quickAction = suffixes.firstChild as Button + return Decomposed(mod, quickAction) + } + } + + data class Decomposed(val mod: ModState?, val quickAction: Button) + + interface ModState { + val name: String + val summary: String + val description: String + + class Installed(private val mod: Mod) : ModState { + private val sources = mod.metadata.sources + val updates: List<() -> Unit> = sources.mapNotNull { it.value.getOrNull() }.map { { mod.update(it) } } + val outdated get() = updates.isEmpty() + fun remove() = mod.delete() + override val name: String = mod.name + override val summary: String by lazy { mod.metadata.sources.bestSummary } + override val description: String by lazy { sources.bestDescription ?: mod.description.joinToString(separator = "\n") } + } + + class Available(private val mod: ModSource, private val instance: Instance) : ModState { + fun install() { + //TODO thread and possibly show progress + ModManager.download(mod, instance.modsDir.resolve(mod.shortName + ModPath.EXT_IMOD), instance.mds) + .write() + } + override val name: String = mod.name + override val summary: String = mod.summary + override val description: String = mod.description + } + } + + fun ModState(mod: ModSource): ModState { + val installed = mds.mods.filter { it.metadata.sources.keys.any { mod.projectMatches(it) } } + return if (installed.isEmpty()) ModState.Available(mod, instance) + else ModState.Installed(installed[0]) + } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/launcher/AccountsTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/launcher/AccountsTab.kt index b0ba746..f07253f 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/launcher/AccountsTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/launcher/AccountsTab.kt @@ -8,7 +8,7 @@ import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager import org.gnome.gtk.* -class AccountsTab(window: Window?) : SectionedSettingsTab(window) { +class AccountsTab(window: Window?) : SectionedSettingsTab(window) { init { section(null) { build() diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/launcher/GeneralTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/launcher/GeneralTab.kt index 4286d11..4ff1dbc 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/launcher/GeneralTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/launcher/GeneralTab.kt @@ -5,7 +5,7 @@ import io.gitlab.jfronny.inceptum.common.model.inceptum.UpdateChannel import io.gitlab.jfronny.inceptum.gtk.control.settings.SectionedSettingsTab import org.gnome.gtk.Window -class GeneralTab(window: Window?) : SectionedSettingsTab(window) { +class GeneralTab(window: Window?) : SectionedSettingsTab(window) { init { section(null) { row("settings.general.snapshots", "settings.general.snapshots.subtitle") { diff --git a/launcher-gtk/src/main/resources/inceptum.properties b/launcher-gtk/src/main/resources/inceptum.properties index 4ade455..0713167 100644 --- a/launcher-gtk/src/main/resources/inceptum.properties +++ b/launcher-gtk/src/main/resources/inceptum.properties @@ -59,8 +59,7 @@ instance.settings.general.args.client.subtitle=Arguments to add to Minecraft Cli instance.settings.general.args.server.subtitle=Arguments to add to Minecraft Servers instance.settings.export=Export instance.settings.mods=Mods -instance.settings.mods.unsupported=Mod management is currently unavailable in the GTK UI.\ -Please use the ImGUI or CLI to manage mods for now. +instance.settings.mods.select=Select a mod to view information about it instance.settings.export.title=%1$s instance.settings.export.subtitle=Export this Pack as a %1$s %2$s file instance.settings.export.version=Version @@ -112,4 +111,9 @@ menu.file.new.file.error=Could not import Instance menu.file.new.new=Create instance.settings.mods.local=Local instance.settings.mods.modrinth=Modrinth -instance.settings.mods.curseforge=CurseForge \ No newline at end of file +instance.settings.mods.curseforge=CurseForge +instance.settings.mods.download=Download +instance.settings.mods.delete=Delete +instance.settings.mods.update=Update +instance.settings.mods.unknown=Unknown +instance.settings.mods.unknown.description=Unknown mod state \ No newline at end of file diff --git a/launcher-gtk/src/main/resources/inceptum_de.properties b/launcher-gtk/src/main/resources/inceptum_de.properties index 357e474..a2982f7 100644 --- a/launcher-gtk/src/main/resources/inceptum_de.properties +++ b/launcher-gtk/src/main/resources/inceptum_de.properties @@ -59,8 +59,7 @@ instance.settings.general.args.client.subtitle=Argumente f instance.settings.general.args.server.subtitle=Argumente für Minecraft-Server instance.settings.export=Export instance.settings.mods=Mods -instance.settings.mods.unsupported=Die Verwaltung von Modifikationen ist momentan noch in Entwicklung.\ -Bitte verwenden Sie vorerst die ImGUI oder CLI, um Mods zu verwalten. +instance.settings.mods.select=Wählen sie eine Mod um Informationen über sie zu sehen instance.settings.export.title=%1$s instance.settings.export.subtitle=Dieses Pack als %2$s für %1$s exportieren instance.settings.export.version=Version @@ -112,4 +111,9 @@ menu.file.new.file.error=Konnte Instanz nicht importieren menu.file.new.new=Erstellen instance.settings.mods.local=Lokal instance.settings.mods.modrinth=Modrinth -instance.settings.mods.curseforge=CurseForge \ No newline at end of file +instance.settings.mods.curseforge=CurseForge +instance.settings.mods.download=Herunterladen +instance.settings.mods.delete=Löschen +instance.settings.mods.update=Aktualisieren +instance.settings.mods.unknown=Unbekannt +instance.settings.mods.unknown.description=Mod in unbekanntem Zustand \ No newline at end of file diff --git a/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java b/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java index 7299f75..6f334a3 100644 --- a/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java +++ b/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java @@ -93,29 +93,13 @@ public class AddModWindow extends Window { ImGui.text("Installed"); } else { if (ImGui.button("Add##" + projectId)) { - ModrinthVersion stable = null; - ModrinthVersion beta = null; - ModrinthVersion latest = null; - for (ModrinthVersion version : ModrinthApi.getVersions(projectId)) { - if (version.game_versions().contains(instance.getGameVersion()) && version.loaders().contains("fabric")) { - latest = version; - if (version.version_type() == ModrinthVersion.VersionType.beta || version.version_type() == ModrinthVersion.VersionType.release) { - beta = version; - } - if (version.version_type() == ModrinthVersion.VersionType.release) { - stable = version; - } - } - } - if (stable != null) beta = stable; - if (beta != null) latest = beta; + ModrinthVersion latest = ModrinthApi.getLatestVersion(projectId, instance.getGameVersion()); if (latest == null) { LauncherEnv.showError("No valid version could be identified for this mod", "No version found"); } else { - ModrinthVersion finalLatest = latest; new Thread(() -> { try { - ModManager.download(new ModrinthModSource(finalLatest.id()), instance.getModsDir().resolve((mod.slug() == null ? projectId : mod.slug()) + ModPath.EXT_IMOD), instance.mds()).write(); + ModManager.download(new ModrinthModSource(latest.id()), instance.getModsDir().resolve((mod.slug() == null ? projectId : mod.slug()) + ModPath.EXT_IMOD), instance.mds()).write(); } catch (IOException e) { LauncherEnv.showError("Could not download mod", e); } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/CurseforgeApi.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/CurseforgeApi.java index 43b03b3..004eea6 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/CurseforgeApi.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/CurseforgeApi.java @@ -57,6 +57,10 @@ public class CurseforgeApi { return checkDistribution(Net.downloadObject(API_URL + "mods/" + id, GC_GetModResponse::read, API_KEY).data()); } + public static String getDescription(int id) throws IOException { + return Net.downloadObject(API_URL + "mods/" + id + "/description", GC_GetModDescriptionResponse::read, API_KEY).data(); + } + private static CurseforgeMod checkDistribution(CurseforgeMod mod) { if (!mod.allowModDistribution()) { throw new IllegalArgumentException("The author of the mod \"" + mod.slug() + "\" has chosen to deliberately break your ability of downloading it.\n" diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/ModrinthApi.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/ModrinthApi.java index 1814bb4..7cb556e 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/ModrinthApi.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/ModrinthApi.java @@ -4,6 +4,7 @@ import io.gitlab.jfronny.gson.compile.util.GList; import io.gitlab.jfronny.gson.stream.JsonReader; import io.gitlab.jfronny.inceptum.common.Net; import io.gitlab.jfronny.inceptum.launcher.model.modrinth.*; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.StringReader; @@ -43,6 +44,22 @@ public class ModrinthApi { return Net.downloadObject(API_HOST + "v2/version/" + id, GC_ModrinthVersion::read); } + public static ModrinthLatest getLatestVersions(String mod, String gameVersion) throws IOException { + ModrinthVersion stable = null; + ModrinthVersion beta = null; + ModrinthVersion latest = null; + for (ModrinthVersion version : ModrinthApi.getVersions(mod)) { + if (version.game_versions().contains(gameVersion) && version.loaders().contains("fabric")) { + latest = version; + if (version.version_type() == ModrinthVersion.VersionType.beta || version.version_type() == ModrinthVersion.VersionType.release) + beta = version; + if (version.version_type() == ModrinthVersion.VersionType.release) + stable = version; + } + } + return new ModrinthLatest(stable, beta, latest); + } + public static ModrinthVersion getVersionByHash(String sha1) throws IOException { return Net.downloadObject(API_HOST + "v2/version_file/" + sha1 + "?algorithm=sha1", GC_ModrinthVersion::read); } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/curseforge/response/GetModDescriptionResponse.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/curseforge/response/GetModDescriptionResponse.java new file mode 100644 index 0000000..cc66ffc --- /dev/null +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/curseforge/response/GetModDescriptionResponse.java @@ -0,0 +1,8 @@ +package io.gitlab.jfronny.inceptum.launcher.model.curseforge.response; + +import io.gitlab.jfronny.gson.compile.annotations.GSerializable; +import io.gitlab.jfronny.inceptum.common.GsonPreset; + +@GSerializable(configure = GsonPreset.Api.class) +public record GetModDescriptionResponse(String data) { +} diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/inceptum/ModMeta.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/inceptum/ModMeta.java index 7c34fd6..384484a 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/inceptum/ModMeta.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/inceptum/ModMeta.java @@ -3,6 +3,7 @@ package io.gitlab.jfronny.inceptum.launcher.model.inceptum; import io.gitlab.jfronny.commons.HashUtils; import io.gitlab.jfronny.commons.data.MutCollection; import io.gitlab.jfronny.commons.data.delegate.DelegateMap; +import io.gitlab.jfronny.commons.serialize.gson.api.v1.Ignore; import io.gitlab.jfronny.gson.compile.annotations.GPrefer; import io.gitlab.jfronny.gson.compile.annotations.GSerializable; import io.gitlab.jfronny.inceptum.common.GsonPreset; @@ -11,7 +12,9 @@ import io.gitlab.jfronny.inceptum.launcher.api.CurseforgeApi; import io.gitlab.jfronny.inceptum.launcher.api.ModrinthApi; import io.gitlab.jfronny.inceptum.launcher.gson.ModMetaSourcesAdapter; import io.gitlab.jfronny.inceptum.launcher.model.curseforge.response.FingerprintMatchesResponse; +import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod; import io.gitlab.jfronny.inceptum.launcher.system.source.*; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -34,6 +37,29 @@ public record ModMeta( public Sources() { super(MutCollection.mapOf()); } + + private Optional getPreferredMetadataSource() { + return keySet().stream().max((left, right) -> { + if (left.equals(right)) return 0; + if (left instanceof ModrinthModSource) return 1; + if (right instanceof ModrinthModSource) return -1; + if (left instanceof CurseforgeModSource) return 1; + if (right instanceof CurseforgeModSource) return -1; + return 1; + }); + } + + public @NotNull String getBestSummary() { + return getPreferredMetadataSource() + .map(ModSource::getSummary) + .orElse("Local Mod"); + } + + public @Nullable String getBestDescription() { + return getPreferredMetadataSource() + .map(ModSource::getDescription) + .orElse(null); + } } @GPrefer diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/modrinth/ModrinthLatest.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/modrinth/ModrinthLatest.java new file mode 100644 index 0000000..a937664 --- /dev/null +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/model/modrinth/ModrinthLatest.java @@ -0,0 +1,20 @@ +package io.gitlab.jfronny.inceptum.launcher.model.modrinth; + +import org.jetbrains.annotations.Nullable; + +public record ModrinthLatest(@Nullable ModrinthVersion stable, @Nullable ModrinthVersion beta, @Nullable ModrinthVersion latest) { + public @Nullable ModrinthVersion get(ModrinthVersion.VersionType type) { + return switch (type) { + case alpha -> latest; + case beta -> beta; + case release -> stable; + }; + } + + public @Nullable ModrinthVersion getBest() { + if (stable != null) return stable; + if (beta != null) return beta; + if (latest != null) return latest; + return null; + } +} diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/CurseforgeModSource.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/CurseforgeModSource.java index 38b71e3..2a42fef 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/CurseforgeModSource.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/CurseforgeModSource.java @@ -1,6 +1,7 @@ package io.gitlab.jfronny.inceptum.launcher.system.source; import io.gitlab.jfronny.commons.HashUtils; +import io.gitlab.jfronny.commons.StringFormatter; import io.gitlab.jfronny.commons.cache.MemoryOperationResultCache; import io.gitlab.jfronny.commons.tuple.Triple; import io.gitlab.jfronny.commons.tuple.Tuple; @@ -102,11 +103,35 @@ public final class CurseforgeModSource implements ModSource { return current.fileName(); } + @Override + public String getDescription() { + try { + return CurseforgeApi.getDescription(mod.id()); + } catch (IOException e) { + return "Could not get description\n\n" + StringFormatter.toString(e); + } + } + + @Override + public String getSummary() { + return mod.summary(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ModSource ms && equals(ms); + } + @Override public boolean equals(ModSource other) { return other instanceof CurseforgeModSource cu && cu.projectId == projectId && cu.fileId == fileId; } + @Override + public boolean projectMatches(ModSource other) { + return other instanceof CurseforgeModSource cu && cu.projectId == projectId; + } + public int getFileId() { return fileId; } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/DirectModSource.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/DirectModSource.java index ead6ccd..ca7fff9 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/DirectModSource.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/DirectModSource.java @@ -57,8 +57,31 @@ public record DirectModSource(String fileName, String url, Set depend return fileName; } + @Override + public String getDescription() { + return "Downloaded directly, no description is available"; + } + + @Override + public String getSummary() { + return "Downloaded directly, no description is available"; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ModSource ms && equals(ms); + } + @Override public boolean equals(ModSource other) { - return false; + return other instanceof DirectModSource dm + && dm.url.equals(url) + && dm.fileName.equals(fileName) + && dm.dependencies.equals(dependencies); + } + + @Override + public boolean projectMatches(ModSource other) { + return other instanceof DirectModSource dm && dm.url.equals(url); } } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModSource.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModSource.java index 45b820b..0b6ddf4 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModSource.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModSource.java @@ -26,8 +26,14 @@ public interface ModSource { String getFileName(); + String getDescription(); + + String getSummary(); + boolean equals(ModSource other); + boolean projectMatches(ModSource other); + default Path getJarPath() { return MetaHolder.LIBRARIES_DIR.resolve("com").resolve(getName()).resolve(getFileName()); } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModrinthModSource.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModrinthModSource.java index 7cba70e..7952761 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModrinthModSource.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/source/ModrinthModSource.java @@ -56,23 +56,7 @@ public final class ModrinthModSource implements ModSource { @Override public Optional getUpdate(String gameVersion) throws IOException { return UPDATE_CACHE.get(Tuple.of(versionId, gameVersion), () -> { - ModrinthVersion stable = null; - ModrinthVersion beta = null; - ModrinthVersion latest = null; - for (ModrinthVersion version : ModrinthApi.getVersions(getModId())) { - if (version.game_versions().contains(gameVersion) && version.loaders().contains("fabric")) { - latest = version; - if (version.version_type() == ModrinthVersion.VersionType.beta || version.version_type() == ModrinthVersion.VersionType.release) - beta = version; - if (version.version_type() == ModrinthVersion.VersionType.release) - stable = version; - } - } - ModrinthVersion next = switch (current.version_type()) { - case alpha -> latest; - case beta -> beta; - case release -> stable; - }; + ModrinthVersion next = ModrinthApi.getLatestVersions(getModId(), gameVersion).get(current.version_type()); if (next == null) return Optional.empty(); if (next.version_number().equals(current.version_number())) return Optional.empty(); return Optional.of(new ModrinthModSource(next.id())); @@ -99,11 +83,31 @@ public final class ModrinthModSource implements ModSource { return current.files().get(0).filename(); } + @Override + public String getDescription() { + return mod.body(); + } + + @Override + public String getSummary() { + return mod.description(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ModSource ms && equals(ms); + } + @Override public boolean equals(ModSource other) { return other instanceof ModrinthModSource ms && ms.getModId().equals(getModId()) && ms.versionId.equals(versionId); } + @Override + public boolean projectMatches(ModSource other) { + return other instanceof ModrinthModSource ms && ms.getModId().equals(getModId()); + } + public String getVersionId() { return versionId; } From 8aa0555a2aa493a6ac4f692c3943f817b7a7a164 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 19 Aug 2023 15:32:09 +0200 Subject: [PATCH 03/16] fix: use deleteIfExists to work around potential race condition --- .../jfronny/inceptum/launcher/system/instance/Instance.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/instance/Instance.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/instance/Instance.java index 9c138c0..bbf00a2 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/instance/Instance.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/instance/Instance.java @@ -116,7 +116,7 @@ public record Instance(String id, Path path, InstanceMeta meta, ModsDirScanner m try { if (ProcessUtils.isProcessAlive(Files.readString(path.resolve(LOCK_NAME)))) return true; - Files.delete(path.resolve(LOCK_NAME)); + Files.deleteIfExists(path.resolve(LOCK_NAME)); } catch (IOException e) { Utils.LOGGER.error("Could not read running lock of " + getName(), e); } From 5faa505235d52f528701d55d98ae14689205383c Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 19 Aug 2023 15:32:42 +0200 Subject: [PATCH 04/16] fix: wrap Entry.setText to prevent segfault for empty strings --- build.gradle.kts | 2 +- launcher-gtk/build.gradle.kts | 1 + .../gitlab/jfronny/inceptum/gtk/control/KEntry.kt | 3 ++- .../io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt | 14 +++++++++++++- .../gtk/window/create/NewInstanceWindow.kt | 3 ++- .../gtk/window/dialog/StringInputDialog.kt | 3 ++- .../gtk/window/settings/instance/GeneralTab.kt | 7 ++----- 7 files changed, 23 insertions(+), 10 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ecea4fe..7ef8e81 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,7 +17,7 @@ val jbAnnotationsVersion by extra("24.0.1") val lwjglVersion by extra("3.3.2") val imguiVersion by extra("1.86.10") // launcher-gtk -val javagiVersion by extra("0.6.0") +val javagiVersion by extra("0.6.1") val flavorProp: String by extra(prop("flavor", "custom")) if (!setOf("custom", "maven", "fat", "windows", "linux", "macos").contains(flavorProp)) throw IllegalStateException("Unsupported flavor: $flavorProp") diff --git a/launcher-gtk/build.gradle.kts b/launcher-gtk/build.gradle.kts index 5c20bc7..8cabde0 100644 --- a/launcher-gtk/build.gradle.kts +++ b/launcher-gtk/build.gradle.kts @@ -20,6 +20,7 @@ repositories { maven("https://jitpack.io") { content { includeGroup("com.github.jwharm.java-gi") + includeGroup("com.github.jwharm") } } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt index defb4a3..5698704 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt @@ -1,5 +1,6 @@ package io.gitlab.jfronny.inceptum.gtk.control +import io.gitlab.jfronny.inceptum.gtk.util.kText import org.gnome.gtk.Entry import java.util.function.Consumer @@ -7,7 +8,7 @@ class KEntry(value: String? = ""): Entry() { private val onChange = ArrayList>() init { - text = value ?: "" + kText = value ?: "" onChanged { onChange.forEach { it.accept(text) } } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt index 8fd7536..7465271 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt @@ -2,6 +2,8 @@ package io.gitlab.jfronny.inceptum.gtk.util import io.gitlab.jfronny.inceptum.gtk.control.ILabel import org.gnome.adw.ActionRow +import org.gnome.gtk.Entry +import org.gnome.gtk.EntryBuffer import org.gnome.gtk.Label import org.gnome.gtk.MessageDialog import org.gnome.gtk.Widget @@ -31,4 +33,14 @@ var MessageDialog.markup: String set(value) { setMarkup(value) } get() = throw NotImplementedError() -fun ActionRow.fixSubtitle() = ILabel.theme(firstChild!!.lastChild!!.prevSibling!!.lastChild as Label, ILabel.Mode.SUBTITLE) \ No newline at end of file +fun ActionRow.fixSubtitle() = ILabel.theme(firstChild!!.lastChild!!.prevSibling!!.lastChild as Label, ILabel.Mode.SUBTITLE) + +// Work around a segfault with empty entries +var Entry.kText: String? + get() = text + set(value) { + if (value == "") buffer.clear() + else text = value + } + +fun EntryBuffer.clear() = deleteText(0, length) \ No newline at end of file diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt index bc52ccb..4a21d48 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt @@ -10,6 +10,7 @@ import io.gitlab.jfronny.inceptum.gtk.control.KEntry import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant import io.gitlab.jfronny.inceptum.gtk.schedule import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.kText import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi @@ -103,7 +104,7 @@ class NewInstanceWindow(app: Application) : KAssistant(app) { append(entry) onOpen { name = InstanceNameTool.getDefaultName(gameVersion!!.id, useFabric) - entry.text = name + entry.kText = name } setComplete(true) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/StringInputDialog.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/StringInputDialog.kt index 98fe1b8..f7f6be0 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/StringInputDialog.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/StringInputDialog.kt @@ -1,5 +1,6 @@ package io.gitlab.jfronny.inceptum.gtk.window.dialog +import io.gitlab.jfronny.inceptum.gtk.util.kText import org.gnome.gtk.* class StringInputDialog(parent: Window?, flags: DialogFlags, type: MessageType, buttons: ButtonsType, message: String, value: String) : MessageDialog(parent, flags, type, buttons, message) { @@ -7,7 +8,7 @@ class StringInputDialog(parent: Window?, flags: DialogFlags, type: MessageType, init { (messageArea as Box).append(entry) - entry.text = value + entry.kText = value } val input: String get() = entry.text diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt index 75ee020..d46a6c3 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt @@ -8,10 +8,7 @@ import io.gitlab.jfronny.inceptum.common.MetaHolder import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.control.ILabel import io.gitlab.jfronny.inceptum.gtk.control.settings.SectionedSettingsTab -import io.gitlab.jfronny.inceptum.gtk.util.I18n -import io.gitlab.jfronny.inceptum.gtk.util.Memory -import io.gitlab.jfronny.inceptum.gtk.util.markup -import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray +import io.gitlab.jfronny.inceptum.gtk.util.* import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi import io.gitlab.jfronny.inceptum.launcher.api.McApi import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList @@ -150,7 +147,7 @@ class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab if (responseId == ResponseType.ACCEPT.value) { val file = dialog.file!!.path - if (file != null) entry.text = file + if (file != null) entry.kText = file } } dialog.show() From f091cb7a2b769091ad1c0af583f66812ac453923 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 19 Aug 2023 15:52:24 +0200 Subject: [PATCH 05/16] fix: add quickAction suffix --- .../jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt index 948365e..e748ca3 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/ModsTab.kt @@ -195,6 +195,7 @@ class ModsTab(window: InstanceSettingsWindow) : SettingsTab Date: Sat, 19 Aug 2023 15:53:09 +0200 Subject: [PATCH 06/16] chore: move logging in kotlin code to Log object --- .../io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt | 9 +++++---- .../kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt | 5 +++-- .../kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt | 5 +++-- .../io/gitlab/jfronny/inceptum/gtk/IdleTaskQueue.kt | 4 ++-- .../jfronny/inceptum/gtk/control/assistant/KAssistant.kt | 3 ++- .../inceptum/gtk/control/settings/SettingsWindow.kt | 2 ++ .../io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt | 3 ++- .../kotlin/io/gitlab/jfronny/inceptum/gtk/util/Log.kt | 6 ++++++ .../kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt | 4 ++-- .../io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt | 6 +++--- .../inceptum/gtk/window/create/NewInstanceWindow.kt | 5 +++-- .../inceptum/gtk/window/dialog/MicrosoftLoginDialog.kt | 7 ++++--- .../gtk/window/dialog/ProcessStateWatcherDialog.kt | 5 +++-- .../inceptum/gtk/window/settings/instance/GeneralTab.kt | 2 +- 14 files changed, 41 insertions(+), 25 deletions(-) create mode 100644 launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Log.kt diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt index 7740590..333680e 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt @@ -3,6 +3,7 @@ package io.gitlab.jfronny.inceptum.gtk import io.gitlab.jfronny.commons.StringFormatter import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog import io.gitlab.jfronny.inceptum.gtk.window.dialog.StringInputDialog import io.gitlab.jfronny.inceptum.launcher.LauncherEnv.EnvBackend @@ -16,7 +17,7 @@ object GtkEnvBackend : EnvBackend { var dialogParent: Window? = null override fun showError(message: String, title: String) { - Utils.LOGGER.error(message) + Log.error(message) simpleDialog(message, title, null, null) } @@ -25,12 +26,12 @@ object GtkEnvBackend : EnvBackend { } override fun showInfo(message: String, title: String) { - Utils.LOGGER.info(message) + Log.info(message) simpleDialog(message, title, null, null) } override fun showOkCancel(message: String, title: String, ok: Runnable, cancel: Runnable, defaultCancel: Boolean) { - Utils.LOGGER.info(message) + Log.info(message) simpleDialog(message, title, ok, cancel) } @@ -117,7 +118,7 @@ object GtkEnvBackend : EnvBackend { } ResponseType.DELETE_EVENT -> dialog.destroy() - else -> Utils.LOGGER.error("Unexpected response type: $responseId") + else -> Log.error("Unexpected response type: $responseId") } } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt index 925be2a..24fb435 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt @@ -3,6 +3,7 @@ package io.gitlab.jfronny.inceptum.gtk import io.gitlab.jfronny.inceptum.common.BuildMetadata import io.gitlab.jfronny.inceptum.common.MetaHolder import io.gitlab.jfronny.inceptum.common.Utils +import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.window.MainWindow import io.gitlab.jfronny.inceptum.launcher.LauncherEnv import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager @@ -19,8 +20,8 @@ object GtkMain { @JvmStatic fun main(args: Array) { LauncherEnv.initialize(GtkEnvBackend) - Utils.LOGGER.info("Launching Inceptum v" + BuildMetadata.VERSION) - Utils.LOGGER.info("Loading from " + MetaHolder.BASE_PATH) + Log.info("Launching Inceptum v" + BuildMetadata.VERSION) + Log.info("Loading from " + MetaHolder.BASE_PATH) exitProcess(try { showGui(args) } catch (_: Throwable) { diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt index f7df6df..83db82b 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt @@ -6,6 +6,7 @@ import io.gitlab.jfronny.inceptum.common.MetaHolder import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.window.AboutWindow import io.gitlab.jfronny.inceptum.gtk.window.create.NewInstanceWindow import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog @@ -155,7 +156,7 @@ object GtkMenubar { } } } catch (e: IOException) { - Utils.LOGGER.error("Could not generate launch menu", e) + Log.error("Could not generate launch menu", e) } } @@ -182,7 +183,7 @@ object GtkMenubar { try { Steps.reDownload(instance, state) } catch (e: IOException) { - Utils.LOGGER.error("Could not fetch instance, trying to start anyways", e) + Log.error("Could not fetch instance, trying to start anyways", e) } if (state.isCancelled) return@show state.updateStep("Starting Game") diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/IdleTaskQueue.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/IdleTaskQueue.kt index 54a8c54..38af799 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/IdleTaskQueue.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/IdleTaskQueue.kt @@ -1,6 +1,6 @@ package io.gitlab.jfronny.inceptum.gtk -import io.gitlab.jfronny.inceptum.common.Utils +import io.gitlab.jfronny.inceptum.gtk.util.Log import java.util.* private val SCHEDULED: Queue = ArrayDeque() @@ -15,7 +15,7 @@ fun runScheduledTasks() { try { r!!.run() } catch (t: Throwable) { - Utils.LOGGER.error("Could not run scheduled task", t) + Log.error("Could not run scheduled task", t) } } } \ No newline at end of file diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt index e4292c6..ba094af 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt @@ -1,6 +1,7 @@ package io.gitlab.jfronny.inceptum.gtk.control.assistant import io.gitlab.jfronny.inceptum.common.Utils +import io.gitlab.jfronny.inceptum.gtk.util.Log import org.gnome.gtk.Application import org.gnome.gtk.Assistant import org.gnome.gtk.AssistantPageType @@ -13,7 +14,7 @@ open class KAssistant(app: Application) : Assistant() { onPrepare { next -> val page = pages.firstOrNull { it.handle() == next.handle() } if (page == null) { - Utils.LOGGER.error("Unknown page opened in assistant") + Log.error("Unknown page opened in assistant") } else { page.emitOpen() } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt index 3d048f3..833a9e4 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt @@ -1,6 +1,8 @@ package io.gitlab.jfronny.inceptum.gtk.control.settings +import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.Log import org.gnome.adw.HeaderBar import org.gnome.adw.ViewStack import org.gnome.adw.ViewSwitcherBar diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt index 1b490d5..32a2cc5 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt @@ -3,6 +3,7 @@ package io.gitlab.jfronny.inceptum.gtk.menu import io.gitlab.jfronny.commons.throwable.ThrowingRunnable import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.Log import org.gnome.gio.* import org.gnome.glib.Variant import org.gnome.glib.VariantType @@ -51,7 +52,7 @@ class MenuBuilder private constructor(map: ActionMap, menu: Menu, prefix: String try { onClick.run() } catch (e: Throwable) { - Utils.LOGGER.error("Could not execute action", e) + Log.error("Could not execute action", e) } } val menuItem = MenuItem(label, groupName + internalName) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Log.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Log.kt new file mode 100644 index 0000000..841d03f --- /dev/null +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Log.kt @@ -0,0 +1,6 @@ +package io.gitlab.jfronny.inceptum.gtk.util + +import io.gitlab.jfronny.commons.log.Logger +import io.gitlab.jfronny.inceptum.common.Utils + +object Log : Logger by Utils.LOGGER \ No newline at end of file diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt index ed0a972..cdf41d2 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt @@ -35,12 +35,12 @@ object Memory { return if (memTotal.isPresent()) { parseDecimalMemorySizeToBinary(memTotal.get()) } else { - Utils.LOGGER.error("Could not find total memory") + Log.error("Could not find total memory") 32 * GB } } } catch (e: IOException) { - Utils.LOGGER.error("Could not get total memory", e) + Log.error("Could not get total memory", e) return 32 * GB } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt index b1d6f0b..7e4aae7 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt @@ -112,7 +112,7 @@ class MainWindow(app: Application) : ApplicationWindow(app) { try { setupDirWatcher() } catch (e: IOException) { - Utils.LOGGER.error( + Log.error( "Could not set up watch service, live updates of the instance dir will be unavailable", e ) @@ -126,7 +126,7 @@ class MainWindow(app: Application) : ApplicationWindow(app) { try { if (isw.poll()) generateWindowBody() } catch (e: IOException) { - Utils.LOGGER.error("Could not run update task", e) + Log.error("Could not run update task", e) } GLib.SOURCE_CONTINUE } @@ -160,7 +160,7 @@ class MainWindow(app: Application) : ApplicationWindow(app) { stack.queueResize() stack.queueDraw() } catch (e: IOException) { - Utils.LOGGER.error("Could not generate window body", e) + Log.error("Could not generate window body", e) } } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt index 4a21d48..92c350f 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt @@ -10,6 +10,7 @@ import io.gitlab.jfronny.inceptum.gtk.control.KEntry import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant import io.gitlab.jfronny.inceptum.gtk.schedule import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.util.kText import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog @@ -147,7 +148,7 @@ class NewInstanceWindow(app: Application) : KAssistant(app) { try { JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name)) } catch (e: IOException) { - Utils.LOGGER.error("Could not delete instance dir", e) + Log.error("Could not delete instance dir", e) } return@Thread } @@ -156,7 +157,7 @@ class NewInstanceWindow(app: Application) : KAssistant(app) { } } catch (e: Throwable) { pState.cancel() - Utils.LOGGER.error("Could not create instance") + Log.error("Could not create instance") failureMessage = StringFormatter.toString(e) isFailure = true } finally { diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/MicrosoftLoginDialog.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/MicrosoftLoginDialog.kt index e4ba9f4..9698324 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/MicrosoftLoginDialog.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/MicrosoftLoginDialog.kt @@ -2,6 +2,7 @@ package io.gitlab.jfronny.inceptum.gtk.window.dialog import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAccount import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAuthAPI import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAuthServer @@ -28,7 +29,7 @@ class MicrosoftLoginDialog( try { server.start() } catch (e: Exception) { - Utils.LOGGER.error("Could not start mc login server", e) + Log.error("Could not start mc login server", e) } val finalize = Runnable { server.close() @@ -46,7 +47,7 @@ class MicrosoftLoginDialog( destroy() } - else -> Utils.LOGGER.error("Unexpected response type: $responseId") + else -> Log.error("Unexpected response type: $responseId") } } val btn = Button.newWithLabel(I18n["auth.open-browser"]) @@ -55,7 +56,7 @@ class MicrosoftLoginDialog( try { Utils.openWebBrowser(URI(MicrosoftAuthAPI.MICROSOFT_LOGIN_URL)) } catch (e: URISyntaxException) { - Utils.LOGGER.error("Could not open browser", e) + Log.error("Could not open browser", e) } } onCloseRequest { diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt index 8943f50..bea2b63 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt @@ -6,6 +6,7 @@ import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend import io.gitlab.jfronny.inceptum.gtk.schedule import io.gitlab.jfronny.inceptum.gtk.util.I18n +import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.launcher.util.ProcessState import org.gnome.glib.GLib import org.gnome.gtk.* @@ -39,7 +40,7 @@ class ProcessStateWatcherDialog( } ResponseType.DELETE_EVENT -> destroy() - else -> Utils.LOGGER.error("Unexpected response type: $responseId") + else -> Log.error("Unexpected response type: $responseId") } } onCloseRequest { @@ -65,7 +66,7 @@ class ProcessStateWatcherDialog( executor.run() } catch (e: Throwable) { state.cancel() - Utils.LOGGER.error(errorMessage, e) + Log.error(errorMessage, e) GtkEnvBackend.simpleDialog( parent, StringFormatter.toString(e), diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt index d46a6c3..aeecef3 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt @@ -141,7 +141,7 @@ class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab From e19d7cfb3bf60916dab3d303883c4ad081922c82 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 19 Aug 2023 15:54:27 +0200 Subject: [PATCH 07/16] chore: optimize imports --- .../kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt | 1 - .../main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt | 1 - .../kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt | 2 -- .../io/gitlab/jfronny/inceptum/gtk/control/KDropDown.kt | 1 - .../jfronny/inceptum/gtk/control/assistant/KAssistant.kt | 1 - .../jfronny/inceptum/gtk/control/settings/SettingsWindow.kt | 2 -- .../io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt | 1 - .../kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt | 1 - .../kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt | 6 +----- .../jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt | 1 - .../inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt | 1 - 11 files changed, 1 insertion(+), 17 deletions(-) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt index 333680e..f7dd950 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt @@ -1,7 +1,6 @@ package io.gitlab.jfronny.inceptum.gtk import io.gitlab.jfronny.commons.StringFormatter -import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.window.dialog.MicrosoftLoginDialog diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt index 24fb435..04d0240 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMain.kt @@ -2,7 +2,6 @@ package io.gitlab.jfronny.inceptum.gtk import io.gitlab.jfronny.inceptum.common.BuildMetadata import io.gitlab.jfronny.inceptum.common.MetaHolder -import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.Log import io.gitlab.jfronny.inceptum.gtk.window.MainWindow import io.gitlab.jfronny.inceptum.launcher.LauncherEnv diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt index 83db82b..35ca35e 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt @@ -3,7 +3,6 @@ package io.gitlab.jfronny.inceptum.gtk import io.gitlab.jfronny.commons.OSUtils import io.gitlab.jfronny.commons.io.JFiles import io.gitlab.jfronny.inceptum.common.MetaHolder -import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.Log @@ -22,7 +21,6 @@ import io.gitlab.jfronny.inceptum.launcher.system.launch.InstanceLauncher import io.gitlab.jfronny.inceptum.launcher.system.launch.LaunchType import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps import io.gitlab.jfronny.inceptum.launcher.util.ProcessState -import org.gnome.gdk.Clipboard import org.gnome.gio.Cancellable import org.gnome.gtk.* import java.awt.Toolkit diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KDropDown.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KDropDown.kt index 85252f5..fa3c4e7 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KDropDown.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KDropDown.kt @@ -6,7 +6,6 @@ import org.gnome.gtk.PropertyExpression import org.gnome.gtk.StringList import org.gnome.gtk.StringObject import org.jetbrains.annotations.PropertyKey -import java.util.ArrayList import java.util.function.IntConsumer class KDropDown(options: Array, private val stringify: (T) -> String, selected: Int): DropDown(options.toModel(stringify), null) { diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt index ba094af..f784510 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/assistant/KAssistant.kt @@ -1,6 +1,5 @@ package io.gitlab.jfronny.inceptum.gtk.control.assistant -import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.Log import org.gnome.gtk.Application import org.gnome.gtk.Assistant diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt index 833a9e4..3d048f3 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/settings/SettingsWindow.kt @@ -1,8 +1,6 @@ package io.gitlab.jfronny.inceptum.gtk.control.settings -import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.I18n -import io.gitlab.jfronny.inceptum.gtk.util.Log import org.gnome.adw.HeaderBar import org.gnome.adw.ViewStack import org.gnome.adw.ViewSwitcherBar diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt index 32a2cc5..2a4dd93 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt @@ -1,7 +1,6 @@ package io.gitlab.jfronny.inceptum.gtk.menu import io.gitlab.jfronny.commons.throwable.ThrowingRunnable -import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.Log import org.gnome.gio.* diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt index cdf41d2..f9fa510 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/Memory.kt @@ -1,7 +1,6 @@ package io.gitlab.jfronny.inceptum.gtk.util import io.gitlab.jfronny.commons.OSUtils -import io.gitlab.jfronny.inceptum.common.Utils import java.io.IOException import java.nio.file.Files import java.nio.file.Path diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt index 7465271..ddc6041 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt @@ -2,11 +2,7 @@ package io.gitlab.jfronny.inceptum.gtk.util import io.gitlab.jfronny.inceptum.gtk.control.ILabel import org.gnome.adw.ActionRow -import org.gnome.gtk.Entry -import org.gnome.gtk.EntryBuffer -import org.gnome.gtk.Label -import org.gnome.gtk.MessageDialog -import org.gnome.gtk.Widget +import org.gnome.gtk.* var Widget.margin: Int set(value) { diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt index 92c350f..a7f034c 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt @@ -4,7 +4,6 @@ import io.gitlab.jfronny.commons.StringFormatter import io.gitlab.jfronny.commons.io.JFiles import io.gitlab.jfronny.inceptum.common.InceptumConfig import io.gitlab.jfronny.inceptum.common.MetaHolder -import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.control.KDropDown import io.gitlab.jfronny.inceptum.gtk.control.KEntry import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt index bea2b63..9514d0d 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt @@ -2,7 +2,6 @@ package io.gitlab.jfronny.inceptum.gtk.window.dialog import io.gitlab.jfronny.commons.StringFormatter import io.gitlab.jfronny.commons.throwable.ThrowingRunnable -import io.gitlab.jfronny.inceptum.common.Utils import io.gitlab.jfronny.inceptum.gtk.GtkEnvBackend import io.gitlab.jfronny.inceptum.gtk.schedule import io.gitlab.jfronny.inceptum.gtk.util.I18n From 32a01547c077420572ee906e8557b54d943c314c Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 19 Aug 2023 16:05:07 +0200 Subject: [PATCH 08/16] build: get rid of toolchains --- .woodpecker.yml | 8 ++++---- buildSrc/src/main/kotlin/inceptum.java.gradle.kts | 7 ------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/.woodpecker.yml b/.woodpecker.yml index 0f77c96..138b08a 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -3,7 +3,7 @@ pipeline: export_metadata: - image: gradle:jdk19-jammy + image: gradle:jdk20-jammy pull: true commands: - mkdir public @@ -15,20 +15,20 @@ pipeline: commands: - ./platform_jars.sh build_wrapper: - image: gradle:jdk19-jammy + image: gradle:jdk20-jammy commands: - gradle --build-cache :wrapper:build -Pflavor=windows -Ppublic -Ptimestamp=${CI_PIPELINE_STARTED} - cp wrapper/build/libs/*.exe public/wrapper.exe - cp wrapper/build/libs/*-all.jar public/wrapper.jar publish_debug: - image: gradle:jdk19-jammy + image: gradle:jdk20-jammy commands: - gradle --build-cache build publish -Pflavor=maven -Ppublic -Ptimestamp=${CI_PIPELINE_STARTED} secrets: [ maven_token, maven_name ] when: - branch: master publish_release: - image: gradle:jdk19-jammy + image: gradle:jdk20-jammy commands: - gradle --build-cache build publish -Pflavor=maven -Ppublic -Prelease secrets: [ maven_token, maven_name ] diff --git a/buildSrc/src/main/kotlin/inceptum.java.gradle.kts b/buildSrc/src/main/kotlin/inceptum.java.gradle.kts index af4cac0..f166941 100644 --- a/buildSrc/src/main/kotlin/inceptum.java.gradle.kts +++ b/buildSrc/src/main/kotlin/inceptum.java.gradle.kts @@ -3,12 +3,6 @@ plugins { `maven-publish` } -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(20)) - } -} - repositories { mavenCentral() maven("https://maven.frohnmeyer-wds.de/artifacts") @@ -42,7 +36,6 @@ afterEvaluate { if (hasProperty("offline")) { tasks.withType(JavaExec::class) { environment("G_ORIGINAL_EXECUTABLE", executable ?: "java") - //TODO once we are not using a toolchain, just do executable(rootDir.resolve("buildSrc/java-offline")) val originalMetadata = javaLauncher.get().metadata val field = org.gradle.api.internal.provider.AbstractProperty::class.java.getDeclaredField("value") field.isAccessible = true From b1b82c423af1f9fe6895fa36c0f2eba33e458686 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 19 Aug 2023 16:13:45 +0200 Subject: [PATCH 09/16] fix: prevent segfault in simpleDialog --- .../io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt index f7dd950..b9a5cc3 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt @@ -74,10 +74,11 @@ object GtkEnvBackend : EnvBackend { ok: Runnable?, cancel: Runnable? ) { - val dialog = AlertDialog("") - dialog.message = title - dialog.detail = markup - dialog.modal = true + val dialog = AlertDialog.builder() + .message(title) + .detail(markup) + .modal(true) + .build() when { cancel == null -> { dialog.setButtons(arrayOf(I18n["ok"])) From 98cc37405a6ba848a3eabb70bb726e41d177a2a5 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 19 Aug 2023 16:19:50 +0200 Subject: [PATCH 10/16] fix: update AddModWindow for ModrinthApi change --- .../io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java b/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java index 6f334a3..cf9a6fc 100644 --- a/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java +++ b/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java @@ -93,7 +93,7 @@ public class AddModWindow extends Window { ImGui.text("Installed"); } else { if (ImGui.button("Add##" + projectId)) { - ModrinthVersion latest = ModrinthApi.getLatestVersion(projectId, instance.getGameVersion()); + ModrinthVersion latest = ModrinthApi.getLatestVersions(projectId, instance.getGameVersion()).latest(); if (latest == null) { LauncherEnv.showError("No valid version could be identified for this mod", "No version found"); } else { From e14294fdd642163c65db03f22360709a76292279 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 19 Aug 2023 16:20:17 +0200 Subject: [PATCH 11/16] chore: perform more actions in the builder stage for simpleDialog --- .../jfronny/inceptum/gtk/GtkEnvBackend.kt | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt index b9a5cc3..bc11618 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkEnvBackend.kt @@ -78,30 +78,25 @@ object GtkEnvBackend : EnvBackend { .message(title) .detail(markup) .modal(true) - .build() when { - cancel == null -> { - dialog.setButtons(arrayOf(I18n["ok"])) - dialog.defaultButton = 0 - dialog.cancelButton = -1 - } - ok == null -> { - dialog.setButtons(arrayOf("Cancel")) - dialog.defaultButton = -1 - dialog.cancelButton = 0 - } - else -> { - dialog.setButtons(arrayOf("OK", "Cancel")) - dialog.defaultButton = 0 - dialog.cancelButton = 1 - } + cancel == null -> dialog.buttons(arrayOf(I18n["ok"])) + .defaultButton(0) + .cancelButton(-1) + ok == null -> dialog.buttons(arrayOf("Cancel")) + .defaultButton(-1) + .cancelButton(0) + else -> dialog.buttons(arrayOf("OK", "Cancel")) + .defaultButton(0) + .cancelButton(1) } - dialog.choose(parent, Cancellable()) { _, res, _ -> - val result = dialog.chooseFinish(res) - val cancelIdx = dialog.cancelButton - val defaultIdx = dialog.defaultButton - if (result == cancelIdx) cancel?.run() - if (result == defaultIdx) ok?.run() + dialog.build().apply { + choose(parent, Cancellable()) { _, res, _ -> + val result = chooseFinish(res) + val cancelIdx = cancelButton + val defaultIdx = defaultButton + if (result == cancelIdx) cancel?.run() + if (result == defaultIdx) ok?.run() + } } } From 04d8121ca28cdbfb094d975151ce09012561aa20 Mon Sep 17 00:00:00 2001 From: JFronny Date: Mon, 16 Oct 2023 16:00:57 +0200 Subject: [PATCH 12/16] fix: update java-gi and, in doing so, fix segfault --- build.gradle.kts | 2 +- launcher-gtk/build.gradle.kts | 12 +++--------- .../io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt | 3 +-- .../inceptum/gtk/control/KSignalListItemFactory.kt | 8 ++++---- .../io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt | 8 -------- .../inceptum/gtk/window/create/NewInstanceWindow.kt | 3 +-- .../inceptum/gtk/window/dialog/StringInputDialog.kt | 3 +-- .../gtk/window/settings/instance/GeneralTab.kt | 2 +- launcher-gtk/src/main/kotlin/module-info.java | 3 ++- packaging/arch-linux | 2 +- 10 files changed, 15 insertions(+), 31 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7ef8e81..c49a8ca 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,7 +17,7 @@ val jbAnnotationsVersion by extra("24.0.1") val lwjglVersion by extra("3.3.2") val imguiVersion by extra("1.86.10") // launcher-gtk -val javagiVersion by extra("0.6.1") +val javagiVersion by extra("0.7.2") val flavorProp: String by extra(prop("flavor", "custom")) if (!setOf("custom", "maven", "fat", "windows", "linux", "macos").contains(flavorProp)) throw IllegalStateException("Unsupported flavor: $flavorProp") diff --git a/launcher-gtk/build.gradle.kts b/launcher-gtk/build.gradle.kts index 8cabde0..ea2b718 100644 --- a/launcher-gtk/build.gradle.kts +++ b/launcher-gtk/build.gradle.kts @@ -17,20 +17,14 @@ samWithReceiver { repositories { mavenLocal() - maven("https://jitpack.io") { - content { - includeGroup("com.github.jwharm.java-gi") - includeGroup("com.github.jwharm") - } - } } dependencies { val javagiVersion: String by rootProject.extra - implementation("com.github.jwharm.java-gi:glib:$javagiVersion") - implementation("com.github.jwharm.java-gi:gtk:$javagiVersion") - implementation("com.github.jwharm.java-gi:adwaita:$javagiVersion") + implementation("io.github.jwharm.javagi:glib:$javagiVersion") + implementation("io.github.jwharm.javagi:gtk:$javagiVersion") + implementation("io.github.jwharm.javagi:adw:$javagiVersion") implementation(project(":launcher")) } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt index 5698704..defb4a3 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KEntry.kt @@ -1,6 +1,5 @@ package io.gitlab.jfronny.inceptum.gtk.control -import io.gitlab.jfronny.inceptum.gtk.util.kText import org.gnome.gtk.Entry import java.util.function.Consumer @@ -8,7 +7,7 @@ class KEntry(value: String? = ""): Entry() { private val onChange = ArrayList>() init { - kText = value ?: "" + text = value ?: "" onChanged { onChange.forEach { it.accept(text) } } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KSignalListItemFactory.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KSignalListItemFactory.kt index 4942a72..7d60899 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KSignalListItemFactory.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/control/KSignalListItemFactory.kt @@ -1,13 +1,13 @@ package io.gitlab.jfronny.inceptum.gtk.control -import io.github.jwharm.javagi.base.Signal +import io.github.jwharm.javagi.gobject.SignalConnection import org.gnome.gtk.ListItem import org.gnome.gtk.SignalListItemFactory import org.gnome.gtk.StringObject import org.gnome.gtk.Widget abstract class KSignalListItemFactory : SignalListItemFactory() { - private val toDisconnect: MutableMap>> = HashMap() + private val toDisconnect: MutableMap>> = HashMap() init { onSetup { val li = it as ListItem @@ -41,14 +41,14 @@ abstract class KSignalListItemFactory : SignalListItemF } interface BindContext: ActionContext { - fun registerForUnbind(signal: Signal<*>) + fun registerForUnbind(signal: SignalConnection<*>) } interface UnbindContext: ActionContext { } private inner class BindContextImpl(private val id: String, override val listItem: ListItem) : BindContext { - override fun registerForUnbind(signal: Signal<*>) { + override fun registerForUnbind(signal: SignalConnection<*>) { toDisconnect.computeIfAbsent(id) { _ -> HashSet() } .add(signal) } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt index ddc6041..ca03727 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/util/UIExt.kt @@ -31,12 +31,4 @@ var MessageDialog.markup: String fun ActionRow.fixSubtitle() = ILabel.theme(firstChild!!.lastChild!!.prevSibling!!.lastChild as Label, ILabel.Mode.SUBTITLE) -// Work around a segfault with empty entries -var Entry.kText: String? - get() = text - set(value) { - if (value == "") buffer.clear() - else text = value - } - fun EntryBuffer.clear() = deleteText(0, length) \ No newline at end of file diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt index a7f034c..f2f30a4 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt @@ -10,7 +10,6 @@ import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant import io.gitlab.jfronny.inceptum.gtk.schedule import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.Log -import io.gitlab.jfronny.inceptum.gtk.util.kText import io.gitlab.jfronny.inceptum.gtk.util.toTypedArray import io.gitlab.jfronny.inceptum.gtk.window.dialog.ProcessStateWatcherDialog import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi @@ -104,7 +103,7 @@ class NewInstanceWindow(app: Application) : KAssistant(app) { append(entry) onOpen { name = InstanceNameTool.getDefaultName(gameVersion!!.id, useFabric) - entry.kText = name + entry.text = name } setComplete(true) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/StringInputDialog.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/StringInputDialog.kt index f7f6be0..98fe1b8 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/StringInputDialog.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/StringInputDialog.kt @@ -1,6 +1,5 @@ package io.gitlab.jfronny.inceptum.gtk.window.dialog -import io.gitlab.jfronny.inceptum.gtk.util.kText import org.gnome.gtk.* class StringInputDialog(parent: Window?, flags: DialogFlags, type: MessageType, buttons: ButtonsType, message: String, value: String) : MessageDialog(parent, flags, type, buttons, message) { @@ -8,7 +7,7 @@ class StringInputDialog(parent: Window?, flags: DialogFlags, type: MessageType, init { (messageArea as Box).append(entry) - entry.kText = value + entry.text = value } val input: String get() = entry.text diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt index aeecef3..fc1eb4b 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt @@ -147,7 +147,7 @@ class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab if (responseId == ResponseType.ACCEPT.value) { val file = dialog.file!!.path - if (file != null) entry.kText = file + if (file != null) entry.text = file } } dialog.show() diff --git a/launcher-gtk/src/main/kotlin/module-info.java b/launcher-gtk/src/main/kotlin/module-info.java index 5d1a639..ccd720a 100644 --- a/launcher-gtk/src/main/kotlin/module-info.java +++ b/launcher-gtk/src/main/kotlin/module-info.java @@ -4,7 +4,8 @@ module io.gitlab.jfronny.inceptum.launcher.gtk { requires kotlin.stdlib; requires org.gnome.glib; requires org.gnome.gtk; - requires org.gnome.adwaita; + requires org.gnome.adw; + requires org.gnome.pango; // Should theoretically already be included transitively through inceptum.launcher and inceptum.common requires io.gitlab.jfronny.commons; diff --git a/packaging/arch-linux b/packaging/arch-linux index 28770e5..19ebde7 160000 --- a/packaging/arch-linux +++ b/packaging/arch-linux @@ -1 +1 @@ -Subproject commit 28770e5269128412d8d51a03aa6c072a8eff10cb +Subproject commit 19ebde77adad3b97e733d98f37a59c828138f53e From 9e1c20737ddafd19ad7f594cac7d00eafe27b3e9 Mon Sep 17 00:00:00 2001 From: JFronny Date: Mon, 16 Oct 2023 16:14:46 +0200 Subject: [PATCH 13/16] style: don't explicitly depend on gtk transitive dependencies --- launcher-gtk/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher-gtk/build.gradle.kts b/launcher-gtk/build.gradle.kts index ea2b718..6368c1e 100644 --- a/launcher-gtk/build.gradle.kts +++ b/launcher-gtk/build.gradle.kts @@ -22,8 +22,8 @@ repositories { dependencies { val javagiVersion: String by rootProject.extra - implementation("io.github.jwharm.javagi:glib:$javagiVersion") - implementation("io.github.jwharm.javagi:gtk:$javagiVersion") + //implementation("io.github.jwharm.javagi:glib:$javagiVersion") + //implementation("io.github.jwharm.javagi:gtk:$javagiVersion") implementation("io.github.jwharm.javagi:adw:$javagiVersion") implementation(project(":launcher")) } From 5cc650921bb56ef0723cada16d8e07ca067df272 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 21 Oct 2023 15:50:35 +0200 Subject: [PATCH 14/16] fix: prevent instance not exiting setup stage when redownload cancelled --- .../gtk/window/create/NewInstanceWindow.kt | 11 ++---- .../window/settings/instance/GeneralTab.kt | 2 +- .../inceptum/imgui/window/GuiUtil.java | 10 ++--- .../dialog/ProcessStateWatcherWindow.java | 9 ++++- .../launcher/system/setup/SetupStepInfo.java | 26 +++++++++++++ .../inceptum/launcher/system/setup/Steps.java | 38 ++++++++++--------- .../system/setup/steps/WriteMetadataStep.java | 1 - 7 files changed, 62 insertions(+), 35 deletions(-) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt index f2f30a4..534d212 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/create/NewInstanceWindow.kt @@ -1,9 +1,7 @@ package io.gitlab.jfronny.inceptum.gtk.window.create import io.gitlab.jfronny.commons.StringFormatter -import io.gitlab.jfronny.commons.io.JFiles import io.gitlab.jfronny.inceptum.common.InceptumConfig -import io.gitlab.jfronny.inceptum.common.MetaHolder import io.gitlab.jfronny.inceptum.gtk.control.KDropDown import io.gitlab.jfronny.inceptum.gtk.control.KEntry import io.gitlab.jfronny.inceptum.gtk.control.assistant.KAssistant @@ -22,7 +20,6 @@ import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps import org.gnome.glib.GLib import org.gnome.gtk.* -import java.io.IOException class NewInstanceWindow(app: Application) : KAssistant(app) { @@ -143,21 +140,19 @@ class NewInstanceWindow(app: Application) : KAssistant(app) { try { for (step in Steps.STEPS) { if (state.isCancelled) { - try { - JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name)) - } catch (e: IOException) { - Log.error("Could not delete instance dir", e) - } + state.tryRemoveInstance() return@Thread } pState.incrementStep(step.name) step.execute(state) } + state.clearSetupLock() } catch (e: Throwable) { pState.cancel() Log.error("Could not create instance") failureMessage = StringFormatter.toString(e) isFailure = true + state.tryRemoveInstance() } finally { finished = true schedule { setComplete(true) } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt index fc1eb4b..77b7825 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt @@ -40,7 +40,7 @@ class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab { for (Step step : Steps.STEPS) { if (state.isCancelled()) { - try { - JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name())); - } catch (IOException e) { - Utils.LOGGER.error("Could not delete instance dir", e); - } + state.tryRemoveInstance(); return; } pState.incrementStep(step.getName()); step.execute(state); } + state.clearSetupLock(); LauncherEnv.showInfo("The instance was successfully created. You can now launch it using the main menu", "Successfully installed"); - })); + }, t -> state.tryRemoveInstance())); } } diff --git a/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/dialog/ProcessStateWatcherWindow.java b/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/dialog/ProcessStateWatcherWindow.java index 652ca24..5aa1649 100644 --- a/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/dialog/ProcessStateWatcherWindow.java +++ b/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/dialog/ProcessStateWatcherWindow.java @@ -1,16 +1,22 @@ package io.gitlab.jfronny.inceptum.imgui.window.dialog; import imgui.ImGui; +import io.gitlab.jfronny.commons.ref.R; import io.gitlab.jfronny.commons.throwable.ThrowingRunnable; import io.gitlab.jfronny.inceptum.imgui.window.Window; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; +import java.util.function.Consumer; + public class ProcessStateWatcherWindow extends Window { private final ProcessState state; private boolean finished; - public ProcessStateWatcherWindow(String title, String errorMessage, ProcessState state, ThrowingRunnable executor) { + this(title, errorMessage, state, executor, R::nop); + } + + public ProcessStateWatcherWindow(String title, String errorMessage, ProcessState state, ThrowingRunnable executor, Consumer onFail) { super(title); this.state = state; new Thread(() -> { @@ -18,6 +24,7 @@ public class ProcessStateWatcherWindow extends Window { executor.run(); } catch (Throwable e) { state.cancel(); + onFail.accept(e); LauncherEnv.showError(errorMessage, e); } finally { finished = true; diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/SetupStepInfo.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/SetupStepInfo.java index 07e3f18..7fcb0d7 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/SetupStepInfo.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/SetupStepInfo.java @@ -1,9 +1,16 @@ package io.gitlab.jfronny.inceptum.launcher.system.setup; +import io.gitlab.jfronny.commons.io.JFiles; +import io.gitlab.jfronny.inceptum.common.MetaHolder; +import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo; +import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; +import java.io.IOException; +import java.nio.file.Files; + public record SetupStepInfo(VersionInfo version, LoaderInfo loader, String name, @@ -15,4 +22,23 @@ public record SetupStepInfo(VersionInfo version, public boolean isCancelled() { return currentState.isCancelled(); } + + public void tryRemoveInstance() { + try { + removeInstance(); + } catch (IOException e) { + Utils.LOGGER.error("Could not delete instance dir", e); + } + } + + public void removeInstance() throws IOException { + JFiles.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(name)); + } + + public void clearSetupLock() { + try { + Files.deleteIfExists(MetaHolder.INSTANCE_DIR.resolve(name).resolve(Instance.SETUP_LOCK_NAME)); + } catch (IOException ignored) { + } + } } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/Steps.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/Steps.java index 2ca6f4b..28a7e44 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/Steps.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/Steps.java @@ -15,11 +15,11 @@ import java.util.*; public class Steps { public static Set STEPS = new LinkedHashSet<>(List.of( new SetupDirsStep(), + new WriteMetadataStep(), new DownloadJavaStep(), new DownloadClientStep(), new DownloadLibrariesStep(), new DownloadAssetsStep(), - new WriteMetadataStep(), new RunMdsStep() )); @@ -29,24 +29,28 @@ public class Steps { public static void reDownload(Instance instance, ProcessState state) throws IOException { if (instance.isLocked()) return; - boolean found = false; - for (VersionsListInfo version : McApi.getVersions().versions()) { - if (version.id.equals(instance.getGameVersion())) { - found = true; - VersionInfo vi = McApi.getVersionInfo(version); - if (instance.isFabric()) - vi = FabricMetaApi.addFabric(vi, instance.getLoaderVersion(), FabricMetaApi.FabricVersionInfoType.Both); - LoaderInfo li = instance.isFabric() - ? new LoaderInfo(LoaderInfo.Type.Fabric, instance.getLoaderVersion()) - : LoaderInfo.NONE; - SetupStepInfo info = new SetupStepInfo(vi, li, instance.getName(), state); - for (Step step : Steps.STEPS) { - state.incrementStep(step.getName()); - step.execute(info); - if (state.isCancelled()) return; + try { + boolean found = false; + for (VersionsListInfo version : McApi.getVersions().versions()) { + if (version.id.equals(instance.getGameVersion())) { + found = true; + VersionInfo vi = McApi.getVersionInfo(version); + if (instance.isFabric()) + vi = FabricMetaApi.addFabric(vi, instance.getLoaderVersion(), FabricMetaApi.FabricVersionInfoType.Both); + LoaderInfo li = instance.isFabric() + ? new LoaderInfo(LoaderInfo.Type.Fabric, instance.getLoaderVersion()) + : LoaderInfo.NONE; + SetupStepInfo info = new SetupStepInfo(vi, li, instance.getName(), state); + for (Step step : Steps.STEPS) { + state.incrementStep(step.getName()); + step.execute(info); + if (state.isCancelled()) return; + } } } + if (!found) throw new IOException("Could not identify minecraft version " + instance.getGameVersion()); + } finally { + instance.setSetupLock(false); } - if (!found) throw new IOException("Could not identify minecraft version " + instance.getGameVersion()); } } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/steps/WriteMetadataStep.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/steps/WriteMetadataStep.java index 0a6b19d..cd1cc0a 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/steps/WriteMetadataStep.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/system/setup/steps/WriteMetadataStep.java @@ -22,7 +22,6 @@ public class WriteMetadataStep implements Step { meta.gameVersion = info.version().id; GC_InstanceMeta.write(meta, metaPath); } - Instance.setSetupLock(instance, false); if (!Files.exists(instance.resolve(".gitignore"))) { Files.writeString(instance.resolve(".gitignore"), """ realms_persistence.json From 475717b6b45106e98ee779bbb6fb62840b329e02 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 21 Oct 2023 16:49:49 +0200 Subject: [PATCH 15/16] chore: use setVisible instead of show --- .../kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt | 6 +++--- .../io/gitlab/jfronny/inceptum/gtk/window/AboutWindow.kt | 2 +- .../io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt | 2 +- .../inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt | 2 +- .../inceptum/gtk/window/settings/instance/GeneralTab.kt | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt index 35ca35e..25e407a 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt @@ -79,7 +79,7 @@ object GtkMenubar { @JvmStatic fun generateNewMenu(app: Application) { newMenu!!.clear() - newMenu!!.button("new") { NewInstanceWindow(app).show() } + newMenu!!.button("new") { NewInstanceWindow(app).visible = true } newMenu!!.button("file") { val dialog = FileChooserNative( I18n["menu.file.new.file"], @@ -202,11 +202,11 @@ object GtkMenubar { @JvmStatic fun generateAccountsMenu(app: Application) { accountsMenu!!.clear() - accountsMenu!!.button("new") { MicrosoftLoginDialog(GtkEnvBackend.dialogParent).show() } + accountsMenu!!.button("new") { MicrosoftLoginDialog(GtkEnvBackend.dialogParent).visible = true } accountsMenu!!.button("manage") { val window = LauncherSettingsWindow(app) window.activePage = "settings.accounts" - window.show() + window.visible = true } val accounts: MutableList = ArrayList(AccountManager.getAccounts()) accounts.add(null) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/AboutWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/AboutWindow.kt index 19e41f1..07e80af 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/AboutWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/AboutWindow.kt @@ -25,7 +25,7 @@ class AboutWindow : AboutDialog() { companion object { @JvmStatic fun createAndShow() { - AboutWindow().show() + AboutWindow().visible = true } } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt index 7e4aae7..8de4852 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/MainWindow.kt @@ -54,7 +54,7 @@ class MainWindow(app: Application) : ApplicationWindow(app) { val uiMenu = MenuBuilder(app, Menu(), "hamburger") uiMenu.button("support") { Utils.openWebBrowser(URI("https://git.frohnmeyer-wds.de/JfMods/Inceptum/issues")) } - uiMenu.button("preferences") { LauncherSettingsWindow(app).show() } + uiMenu.button("preferences") { LauncherSettingsWindow(app).visible = true } uiMenu.button("about") { AboutWindow.createAndShow() } val menuButton = MenuButton() menuButton.iconName = "open-menu-symbolic" diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt index 9514d0d..29b6e53 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/dialog/ProcessStateWatcherDialog.kt @@ -95,7 +95,7 @@ class ProcessStateWatcherDialog( executor: ThrowingRunnable<*> ): ProcessStateWatcherDialog { val dialog = ProcessStateWatcherDialog(parent, title, errorMessage, state, executor) - dialog.show() + dialog.visible = true return dialog } } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt index 77b7825..97b1a20 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/window/settings/instance/GeneralTab.kt @@ -230,7 +230,7 @@ class GeneralTab(window: InstanceSettingsWindow) : SectionedSettingsTab {} } } - dialog.show() + dialog.visible = true } } row("instance.directory", "instance.directory.subtitle") { From c94c8b59affd566f8f949f4455c2e7e7519fdc47 Mon Sep 17 00:00:00 2001 From: JFronny Date: Sat, 21 Oct 2023 17:38:55 +0200 Subject: [PATCH 16/16] fix: prevent segfault by not exporting account menu. Why does this work? No idea. But it seems to fix the crash. --- .../main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt | 3 ++- .../kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt index 25e407a..a32a086 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/GtkMenubar.kt @@ -22,6 +22,7 @@ import io.gitlab.jfronny.inceptum.launcher.system.launch.LaunchType import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps import io.gitlab.jfronny.inceptum.launcher.util.ProcessState import org.gnome.gio.Cancellable +import org.gnome.gio.Menu import org.gnome.gtk.* import java.awt.Toolkit import java.awt.datatransfer.DataFlavor @@ -67,7 +68,7 @@ object GtkMenubar { file.button("exit") { app.quit() } launchMenu = menu.submenu("launch") generateLaunchMenu(app) - accountsMenu = menu.submenu("account") + accountsMenu = MenuBuilder(app, Menu(), "account") // this should ideally be menu.submenu("account"), but that causes a segfault generateAccountsMenu(app) val help = menu.submenu("help") help.button("about") { AboutWindow.createAndShow() } diff --git a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt index 2a4dd93..667f10d 100644 --- a/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt +++ b/launcher-gtk/src/main/kotlin/io/gitlab/jfronny/inceptum/gtk/menu/MenuBuilder.kt @@ -1,11 +1,11 @@ package io.gitlab.jfronny.inceptum.gtk.menu +import io.github.jwharm.javagi.glib.types.VariantTypes import io.gitlab.jfronny.commons.throwable.ThrowingRunnable import io.gitlab.jfronny.inceptum.gtk.util.I18n import io.gitlab.jfronny.inceptum.gtk.util.Log import org.gnome.gio.* import org.gnome.glib.Variant -import org.gnome.glib.VariantType import org.gnome.gtk.Application import org.gnome.gtk.MenuButton import org.gnome.gtk.PopoverMenu @@ -88,7 +88,7 @@ class MenuBuilder private constructor(map: ActionMap, menu: Menu, prefix: String ): BuiltRadioItem { var name = name name = prefix + name - val action = SimpleAction.newStateful(name, VariantType("i"), Variant.newInt32(options.indexOf(initial))) + val action = SimpleAction.newStateful(name, VariantTypes.INT32, Variant.newInt32(options.indexOf(initial))) addAction(name, action) action.onActivate { variant: Variant? -> action.state = variant