diff --git a/launcher-gtk/src/main/java/extensions/manifold/rt/api/Array/ArrayExt.java b/launcher-gtk/src/main/java/extensions/manifold/rt/api/Array/ArrayExt.java new file mode 100644 index 0000000..e515ea3 --- /dev/null +++ b/launcher-gtk/src/main/java/extensions/manifold/rt/api/Array/ArrayExt.java @@ -0,0 +1,16 @@ +package extensions.manifold.rt.api.Array; + +import manifold.ext.rt.api.Extension; +import manifold.ext.rt.api.This; + +import java.lang.reflect.Array; + +@Extension +public class ArrayExt { + public static int indexOf(@This Object array, Object elem) { + for (int i = 0, len = Array.getLength(array); i < len; i++) { + if (Array.get(array, i).equals(elem)) return i; + } + return -1; + } +} diff --git a/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/GtkTest.java b/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/GtkTest.java index 3e07f95..d9a74ea 100644 --- a/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/GtkTest.java +++ b/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/GtkTest.java @@ -1,13 +1,11 @@ package io.gitlab.jfronny.inceptum.gtk; -import io.gitlab.jfronny.inceptum.gtk.control.Dropdown; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import org.gtk.gio.ListStore; import org.gtk.gobject.GObject; import org.gtk.gtk.*; import java.io.IOException; -import java.util.function.Function; public class GtkTest extends ApplicationWindow { private final String searchTextWidget; diff --git a/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/control/IRow.java b/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/control/IRow.java index f934547..d6cd9cb 100644 --- a/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/control/IRow.java +++ b/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/control/IRow.java @@ -39,9 +39,9 @@ public class IRow extends Box { append(btn); } - public void setDropdown(String[] options, int defaultIndex, IntConsumer changed) { + public DropDown setDropdown(String[] options, int defaultIndex, IntConsumer changed) { firstChild.hexpand = true; - DropDown btn = DropDown.newFromStrings(options); + DropDown btn = new DropDown(new StringList(options), null); btn.valign = Align.CENTER; btn.halign = Align.END; btn.selected = defaultIndex; @@ -49,9 +49,10 @@ public class IRow extends Box { changed.accept(btn.selected); }); append(btn); + return btn; } - public void setCheckbox(@PropertyKey(resourceBundle = I18n.BUNDLE) String text, boolean value, Consumer changed) { + public CheckButton setCheckbox(@PropertyKey(resourceBundle = I18n.BUNDLE) String text, boolean value, Consumer changed) { firstChild.hexpand = true; CheckButton btn = CheckButton.newWithLabel(I18n.get(text)); btn.valign = Align.CENTER; @@ -59,6 +60,7 @@ public class IRow extends Box { btn.active = value; btn.onToggled(() -> changed.accept(btn.active)); append(btn); + return btn; } public Entry setEntry(String value, Consumer onChanged) { diff --git a/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/window/edit/GeneralTab.java b/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/window/edit/GeneralTab.java index d090853..c3b9571 100644 --- a/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/window/edit/GeneralTab.java +++ b/launcher-gtk/src/main/java/io/gitlab/jfronny/inceptum/gtk/window/edit/GeneralTab.java @@ -3,20 +3,24 @@ package io.gitlab.jfronny.inceptum.gtk.window.edit; import io.gitlab.jfronny.commons.ArgumentsTokenizer; import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.inceptum.common.*; -import io.gitlab.jfronny.inceptum.gtk.control.*; +import io.gitlab.jfronny.inceptum.gtk.control.ILabel; import io.gitlab.jfronny.inceptum.gtk.util.I18n; import io.gitlab.jfronny.inceptum.gtk.window.InstanceSettingsWindow; +import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi; import io.gitlab.jfronny.inceptum.launcher.api.McApi; +import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionsList; import io.gitlab.jfronny.inceptum.launcher.system.instance.*; +import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser; +import org.gtk.gobject.BindingFlags; import org.gtk.gtk.*; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Date; -import java.util.List; +import java.util.*; +import java.util.stream.Stream; public class GeneralTab extends SettingsTab { private static final VersionsList VERSIONS = McApi.getVersions(); @@ -43,21 +47,73 @@ public class GeneralTab extends SettingsTab { row.append(apply); }); section("instance.settings.general.game", section -> { - var row = section.row("instance.settings.general.game.version", "instance.settings.general.game.version.subtitle"); - String[] versions = VERSIONS.versions.stream() - .filter(s -> InceptumConfig.snapshots || s.type.equals("release")) - .map(s -> s.id) - .toArray(String[]::new); - int def = 0; - for (int i = 0; i < versions.length; i++) if (versions[i].equals(VERSIONS.latest.release)) def = i; - row.setDropdown( - versions, - def, - i -> { - instance.meta.gameVersion = versions[i]; + { + var ref = new Object() { + CheckButton fabricEnabled = null; + Runnable versionChanged = null; + DropDown fabricVersion = null; + String defaultFabric = null; + String[] fabricVersions = null; + }; + var gameRow = section.row("instance.settings.general.game.version", "instance.settings.general.game.version.subtitle"); + String[] versions = VERSIONS.versions.stream() + .filter(s -> InceptumConfig.snapshots || s.type.equals("release")) + .map(s -> s.id) + .toArray(String[]::new); + int def = 0; + for (int i = 0; i < versions.length; i++) if (versions[i].equals(instance.gameVersion)) def = i; + gameRow.setDropdown( + versions, + def, + i -> { + instance.meta.gameVersion = instance.isFabric + ? GameVersionParser.createVersionWithFabric(versions[i], instance.loaderVersion) + : versions[i]; + instance.writeMeta(); + ref.versionChanged.run(); + }); + var fabricRow = section.row("instance.settings.general.game.fabric.enabled", "instance.settings.general.game.fabric.enabled.subtitle"); + var loaderRow = section.row("instance.settings.general.game.fabric.version", "instance.settings.general.game.fabric.version.subtitle"); + loaderRow.visible = instance.isFabric; + ref.fabricEnabled = fabricRow.setCheckbox("instance.settings.general.game.fabric.enabled", instance.isFabric, bl -> { + if (bl) { + if (ref.fabricVersions != null && ref.fabricVersions.length != 0 && ref.defaultFabric != null) { + instance.meta.gameVersion = GameVersionParser.createVersionWithFabric(instance.gameVersion, ref.defaultFabric); + instance.writeMeta(); + } else { + ref.fabricEnabled.active = false; + } + } else { + instance.meta.gameVersion = instance.gameVersion; instance.writeMeta(); - }); - //TODO Fabric support (checkbox) + dropdown: Loader version + } + }); + ref.fabricEnabled.bindProperty("active", loaderRow, "visible", BindingFlags.DEFAULT); + ref.versionChanged = () -> { + var ver = VERSIONS.versions.stream() + .filter(s -> s.id.equals(instance.gameVersion)) + .findFirst() + .map(FabricMetaApi::getLoaderVersions) + .map(s -> s.toArray(FabricVersionLoaderInfo[]::new)); + ref.defaultFabric = instance.isFabric ? instance.loaderVersion : ver + .map(Arrays::stream) + .map(a -> a.filter(s -> s.loader.stable)) + .flatMap(Stream::findFirst) + .map(s -> s.loader.version) + .orElse(null); + ref.fabricVersions = ver.map(Arrays::stream) + .map(a -> a.map(s -> s.loader.version).toArray(String[]::new)) + .orElse(null); + if (ref.fabricVersions == null || ref.fabricVersions.length == 0) { + ref.fabricEnabled.active = false; + } else if (ref.fabricVersion != null) ref.fabricVersion.model = new StringList(ref.fabricVersions); + }; + ref.versionChanged.run(); + ref.fabricVersion = loaderRow.setDropdown(ref.fabricVersions, ref.fabricVersions.indexOf(ref.defaultFabric), i -> { + instance.meta.gameVersion = i == -1 ? instance.gameVersion : GameVersionParser.createVersionWithFabric(instance.gameVersion, ref.fabricVersions[i]); + instance.writeMeta(); + }); + } //TODO Custom Java (checkbox) + String: path //TODO minMem/maxMem (slider?) }); diff --git a/launcher-gtk/src/main/resources/inceptum.properties b/launcher-gtk/src/main/resources/inceptum.properties index a695471..b7ac639 100644 --- a/launcher-gtk/src/main/resources/inceptum.properties +++ b/launcher-gtk/src/main/resources/inceptum.properties @@ -83,4 +83,8 @@ settings.snapshots=Snapshots settings.update-channel=Update Channel settings.snapshots.subtitle=Whether to show snapshots in the version selector for new instances settings.update-channel.subtitle=The update channel. I personnaly recommend the CI channel as it gest the latest features and fixes more quickly, but it might be more unstable -settings.author-name.subtitle=The author name to add to packs where the metadata format requires specifying one \ No newline at end of file +settings.author-name.subtitle=The author name to add to packs where the metadata format requires specifying one +instance.settings.general.game.fabric.enabled=Fabric +instance.settings.general.game.fabric.enabled.subtitle=Whether the Fabric Loader should be used for this instance +instance.settings.general.game.fabric.version=Fabric Version +instance.settings.general.game.fabric.version.subtitle=Version of the Fabric Loader to use \ 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 aee271b..d5d7417 100644 --- a/launcher-gtk/src/main/resources/inceptum_de.properties +++ b/launcher-gtk/src/main/resources/inceptum_de.properties @@ -83,4 +83,8 @@ settings.snapshots=Vorschauversionen settings.update-channel=Updatekanal settings.snapshots.subtitle=Ob Vorschauversionen im Versions-Auswahlmenü gezeigt werden sollen settings.update-channel.subtitle=Der Update-Kanal. Ich empfehle den etwas instabileren, aber häufiger aktualisierten CI-Kanal -settings.author-name.subtitle=Der Name, der bei Modpack-Exporten, deren Metadaten einen Autor angeben, aufgelistet werden soll \ No newline at end of file +settings.author-name.subtitle=Der Name, der bei Modpack-Exporten, deren Metadaten einen Autor angeben, aufgelistet werden soll +instance.settings.general.game.fabric.enabled=Fabric +instance.settings.general.game.fabric.enabled.subtitle=Ob Fabric-Loader für diese Instanz aktiviert werden soll +instance.settings.general.game.fabric.version=Fabric-Version +instance.settings.general.game.fabric.version.subtitle=Zu verwendende Version des Fabric-Loaders \ No newline at end of file diff --git a/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/control/InstanceManageControls.java b/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/control/InstanceManageControls.java index 454965a..ca27195 100644 --- a/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/control/InstanceManageControls.java +++ b/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/control/InstanceManageControls.java @@ -21,7 +21,6 @@ import java.util.function.Consumer; public class InstanceManageControls { private static final VersionsList VERSIONS = McApi.getVersions(); - private static final MemoryOperationResultCache> LOADER_INFO_CACHE = new MemoryOperationResultCache<>(Utils.CACHE_SIZE); private static final MemoryOperationResultCache, VersionInfo> VERSION_INFO_CACHE = new MemoryOperationResultCache<>(Utils.CACHE_SIZE); private final ImInt version = new ImInt(0); @@ -44,7 +43,7 @@ public class InstanceManageControls { version.set(getVersions(snapshots.get()).indexOf(selected)); name.set(instance == null ? InstanceNameTool.getDefaultName(selected.id, fabric.get()) : instance.name); fabric.set(instance == null || instance.isFabric); - List versions = fabricLoaderInfo; + List versions = FabricMetaApi.getLoaderVersions(selected); for (int i = 0, fabricLoaderInfoSize = versions.size(); i < fabricLoaderInfoSize; i++) { FabricVersionLoaderInfo version = versions[i]; if (instance != null && instance.isFabric @@ -93,7 +92,8 @@ public class InstanceManageControls { selected = vil[version.get()]; exchangeNameIfDefault(prev.id, fabric.get()); } - if (fabricLoaderInfo.isEmpty()) { + List versions = FabricMetaApi.getLoaderVersions(selected); + if (versions.isEmpty()) { fabric.set(false); exchangeNameIfDefault(selected.id, true); } else { @@ -102,7 +102,6 @@ public class InstanceManageControls { } if (fabric.get()) { ImGui.sameLine(); - List versions = fabricLoaderInfo; if (ImGui.combo("Loader", fabricVersion, versions.stream().map(info -> info.loader.version).toArray(String[]::new))) { selectedFabric = versions.get(fabricVersion.get()); } @@ -146,8 +145,4 @@ public class InstanceManageControls { res.removeIf(info -> !snapshots && !info.type.equals("release")); return res; } - - private List getFabricLoaderInfo() { - return LOADER_INFO_CACHE.get(selected, () -> FabricMetaApi.getLoaderVersions(selected)); - } } diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/FabricMetaApi.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/FabricMetaApi.java index e91d461..18500bc 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/FabricMetaApi.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/FabricMetaApi.java @@ -1,9 +1,11 @@ package io.gitlab.jfronny.inceptum.launcher.api; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo.GC_FabricVersionLoaderInfo; +import io.gitlab.jfronny.commons.cache.MemoryOperationResultCache; 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.common.Utils; import io.gitlab.jfronny.inceptum.common.model.maven.ArtifactMeta; import io.gitlab.jfronny.inceptum.launcher.model.fabric.*; import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library; @@ -16,13 +18,16 @@ import java.util.*; public class FabricMetaApi { private static final String META_URL = "https://meta.fabricmc.net/"; + private static final MemoryOperationResultCache> LOADER_VERSIONS_CACHE = new MemoryOperationResultCache<>(Utils.CACHE_SIZE); public static List getLoaderVersions(VersionsListInfo version) { try { - return Net.downloadObject(META_URL + "v2/versions/loader/" + version.id, s -> { - try (JsonReader r = new JsonReader(new StringReader(s))) { - return GList.read(r, GC_FabricVersionLoaderInfo::read); - } + return LOADER_VERSIONS_CACHE.get(version, () -> { + return Net.downloadObject(META_URL + "v2/versions/loader/" + version.id, s -> { + try (JsonReader r = new JsonReader(new StringReader(s))) { + return GList.read(r, GC_FabricVersionLoaderInfo::read); + } + }); }); } catch (IOException e) { throw new RuntimeException("Could not get fabric loader versions", e); diff --git a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/McApi.java b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/McApi.java index d8a4bd8..68cc032 100644 --- a/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/McApi.java +++ b/launcher/src/main/java/io/gitlab/jfronny/inceptum/launcher/api/McApi.java @@ -6,8 +6,7 @@ import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.mojang.J import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo.GC_VersionInfo; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionsList.GC_VersionsList; import io.gitlab.jfronny.commons.OSUtils; -import io.gitlab.jfronny.inceptum.common.MetaHolder; -import io.gitlab.jfronny.inceptum.common.Net; +import io.gitlab.jfronny.inceptum.common.*; import io.gitlab.jfronny.inceptum.launcher.model.mojang.*; import java.io.IOException;