Inceptum/launcher-imgui/src/main/java/io/gitlab/jfronny/inceptum/imgui/window/AddModWindow.java

190 lines
9.7 KiB
Java

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<CurseforgeMod> 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<CurseforgeMod> 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);
}
}
}