package io.gitlab.jfronny.inceptum.imgui.window; import imgui.ImGui; import imgui.flag.ImGuiTableFlags; import imgui.type.ImString; import io.gitlab.jfronny.inceptum.common.Utils; 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.curseforge.CurseforgeMod; import io.gitlab.jfronny.inceptum.launcher.model.modrinth.*; import io.gitlab.jfronny.inceptum.launcher.system.instance.*; import io.gitlab.jfronny.inceptum.launcher.system.source.CurseforgeModSource; import io.gitlab.jfronny.inceptum.launcher.system.source.ModrinthModSource; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.List; public class AddModWindow extends Window { private final ImString query = new ImString("", GuiUtil.INPUT_FIELD_LENGTH); private final Instance instance; private int cfPage = 0; private int mrPage = 0; private ModrinthSearchResult mr = null; private List cf = null; public AddModWindow(Instance instance) { super(instance.getName() + " - Add Mods"); this.instance = instance; } private void reSearch() { String query = this.query.get(); new Thread(() -> { try { ModrinthSearchResult ms = ModrinthApi.search(query, mrPage, instance.getGameVersion(), ModrinthProjectType.mod); if (!this.query.get().equals(query)) return; mr = ms; List cs = CurseforgeApi.search(instance.getGameVersion(), query, cfPage, "Popularity"); if (!this.query.get().equals(query)) return; cf = cs; } catch (IOException e) { Utils.LOGGER.error("Could not run search", e); } }, "search" + query).start(); } @Override public void draw() { try { if (ImGui.inputTextWithHint("Search", "Your search query", query)) { reSearch(); } if (ImGui.beginTabBar("ModsSelect")) { if (ImGui.beginTabItem("Modrinth")) { if (mr != null) { boolean hasNext = (mr.offset() + mr.hits().size() < mr.total_hits()); if (mrPage > 0) { if (ImGui.button("Previous Page")) { mrPage--; reSearch(); } if (hasNext) ImGui.sameLine(); } if (hasNext && ImGui.button("Next Page")) { mrPage++; reSearch(); } } if (mr != null && ImGui.beginTable("mods" + instance.id(), 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) { for (ModrinthSearchResult.ModResult mod : mr.hits()) { String modId = (mod.slug() != null ? mod.slug() : mod.project_id()); final String idPrefix = "local-"; String projectId = mod.project_id().startsWith(idPrefix) ? mod.project_id().substring(idPrefix.length()) : mod.project_id(); //TODO detail view ImGui.tableNextColumn(); ImGui.text(mod.title()); ImGui.tableNextColumn(); ImGui.text(mod.description()); ImGui.tableNextColumn(); boolean alreadyPresent = false; for (Mod mdsMod : instance.getMods()) { alreadyPresent = mdsMod.getMetadata().sources().keySet().stream() .anyMatch(s -> s instanceof ModrinthModSource ms && ms.getModId().equals(projectId)); if (alreadyPresent) break; } if (alreadyPresent) { ImGui.text("Installed"); } else { if (ImGui.button("Add##" + projectId)) { 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 { new Thread(() -> { try { 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); } }).start(); } } } ImGui.sameLine(); if (ImGui.button("Web##" + projectId)) { Utils.openWebBrowser(new URI("https://modrinth.com/mod/" + modId)); } } ImGui.endTable(); } ImGui.endTabItem(); } if (ImGui.beginTabItem("Curseforge")) { if (cf != null) { boolean hasNext = cf.size() == 20; if (cfPage > 0) { if (ImGui.button("Previous Page")) { cfPage--; reSearch(); } if (hasNext) ImGui.sameLine(); } if (hasNext && ImGui.button("Next Page")) { cfPage++; reSearch(); } } if (cf != null && ImGui.beginTable("curseforge" + instance.id(), 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) { for (CurseforgeMod mod : cf) { //TODO detail view ImGui.tableNextColumn(); ImGui.text(mod.name()); ImGui.tableNextColumn(); ImGui.text(mod.summary()); ImGui.tableNextColumn(); boolean alreadyPresent = false; for (Mod mdsMod : instance.mds().getMods()) { alreadyPresent = mdsMod.getMetadata().sources().keySet().stream() .anyMatch(s -> s instanceof CurseforgeModSource ms && ms.getProjectId() == mod.id()); if (alreadyPresent) break; } if (alreadyPresent) { ImGui.text("Installed"); } else { if (ImGui.button("Add##" + mod.id())) { CurseforgeMod.LatestFileIndex latest = null; for (CurseforgeMod.LatestFileIndex file : mod.latestFilesIndexes()) { if (file.gameVersion().equals(instance.getGameVersion())) { if (latest == null) latest = file; } } if (latest == null) { LauncherEnv.showError("No valid version could be identified for this mod", "No version found"); } else { CurseforgeMod.LatestFileIndex finalLatest = latest; new Thread(() -> { try { ModManager.download(new CurseforgeModSource(mod.id(), finalLatest.fileId()), instance.getModsDir().resolve((mod.slug() == null ? mod.id() : mod.slug()) + ModPath.EXT_IMOD), instance.mds()).write(); } catch (IOException e) { LauncherEnv.showError("Could not download mod", e); } }).start(); } } } ImGui.sameLine(); if (ImGui.button("Web##" + mod.id())) { Utils.openWebBrowser(new URI(mod.links().websiteUrl())); } } ImGui.endTable(); } ImGui.endTabItem(); } ImGui.endTabBar(); } } catch (IOException | URISyntaxException e) { Utils.LOGGER.error("Something went wrong while rendering an AddModWindow", e); } } }