Refactor mods once again

This commit is contained in:
Johannes Frohnmeyer 2022-10-27 20:54:55 +02:00
parent 7e42e6b02f
commit ff7dddbd35
Signed by: Johannes
GPG Key ID: E76429612C2929F4
67 changed files with 641 additions and 509 deletions

View File

@ -5,7 +5,7 @@ All of these are subject to change, though automatic migrations will likely be p
## inceptum.json (Main Config) ## inceptum.json (Main Config)
```json ```json5
{ {
// Whether to show snapshots in the version selector for new instances // Whether to show snapshots in the version selector for new instances
"snapshots": false, "snapshots": false,
@ -38,7 +38,7 @@ It stores your minecraft account login and CAN BE USED TO IMPERSONATE YOU!
Please note that all entries except for "version" are optional Please note that all entries except for "version" are optional
```json ```json5
{ {
// The version to use for launching this // The version to use for launching this
// Can be a fabric loader version (as seen here) or a normal minecraft version (like "1.17.1") // Can be a fabric loader version (as seen here) or a normal minecraft version (like "1.17.1")
@ -74,7 +74,7 @@ Please note that all entries except for "version" are optional
## *.imod (Mod Metadata) ## *.imod (Mod Metadata)
```json ```json5
{ {
// Where the JAR file for this mod can be obtained // Where the JAR file for this mod can be obtained
"sources": [ "sources": [
@ -121,6 +121,8 @@ Please note that all entries except for "version" are optional
// A list of dependencies by their file names // A list of dependencies by their file names
"dependencies": [ "dependencies": [
"someOtherMod.imod" "someOtherMod.imod"
] ],
// Whether this mod was explicitly installed (used during mod removal)
"explicit": true
} }
``` ```

View File

@ -1,11 +1,9 @@
package io.gitlab.jfronny.inceptum.cli; package io.gitlab.jfronny.inceptum.cli;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import io.gitlab.jfronny.inceptum.launcher.util.InstanceList;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;

View File

@ -1,10 +1,8 @@
package io.gitlab.jfronny.inceptum.cli.commands; package io.gitlab.jfronny.inceptum.cli.commands;
import io.gitlab.jfronny.inceptum.cli.*; import io.gitlab.jfronny.inceptum.cli.*;
import io.gitlab.jfronny.inceptum.common.R; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.exporter.Exporters;
import io.gitlab.jfronny.inceptum.launcher.system.export.Exporters;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
import java.nio.file.Paths; import java.nio.file.Paths;

View File

@ -3,10 +3,10 @@ package io.gitlab.jfronny.inceptum.cli.commands;
import io.gitlab.jfronny.inceptum.cli.*; import io.gitlab.jfronny.inceptum.cli.*;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.system.launch.*; import io.gitlab.jfronny.inceptum.launcher.system.launch.*;
import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager; import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager;
import io.gitlab.jfronny.inceptum.launcher.system.install.Steps; import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;

View File

@ -5,8 +5,8 @@ import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.cli.Command; import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs; import io.gitlab.jfronny.inceptum.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.util.InstanceList; import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;

View File

@ -4,15 +4,15 @@ import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.commons.throwable.ThrowingBiFunction; import io.gitlab.jfronny.commons.throwable.ThrowingBiFunction;
import io.gitlab.jfronny.inceptum.cli.*; import io.gitlab.jfronny.inceptum.cli.*;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.util.ModManager; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModManager;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner; import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource; import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import io.gitlab.jfronny.inceptum.launcher.util.Unchecked;
import java.io.FileNotFoundException; import java.io.*;
import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
@ -54,8 +54,8 @@ public class ModCommand extends Command {
} }
System.out.println("Scanning installed mods, this might take a while"); System.out.println("Scanning installed mods, this might take a while");
instance.mds().runOnce((path, mod) -> { instance.mds().runOnce((path, mod) -> {
boolean hasSources = mod.mod().isPresent() && !mod.mod().get().sources.isEmpty(); boolean hasSources = !mod.getMetadata().sources.isEmpty();
boolean updatable = hasSources && mod.mod().get().sources.values().stream().anyMatch(Optional::isPresent); boolean updatable = hasSources && mod.getMetadata().sources.values().stream().anyMatch(Optional::isPresent);
if (filterUpdatable && !updatable) return; if (filterUpdatable && !updatable) return;
System.out.println("- " + path.getFileName().toString()); System.out.println("- " + path.getFileName().toString());
System.out.println(" " + mod.getName()); System.out.println(" " + mod.getName());
@ -64,7 +64,7 @@ public class ModCommand extends Command {
} }
if (hasSources) { if (hasSources) {
System.out.println(" Sources:"); System.out.println(" Sources:");
for (Map.Entry<ModSource, Optional<ModSource>> entry : mod.mod().get().sources.entrySet()) { for (Map.Entry<ModSource, Optional<ModSource>> entry : mod.getMetadata().sources.entrySet()) {
System.out.println(" - " + entry.getKey().getName() + " (" + entry.getKey().getVersion() + ")"); System.out.println(" - " + entry.getKey().getName() + " (" + entry.getKey().getVersion() + ")");
System.out.println(" Local: " + entry.getKey().getJarPath().toString()); System.out.println(" Local: " + entry.getKey().getJarPath().toString());
if (entry.getValue().isPresent()) if (entry.getValue().isPresent())
@ -116,7 +116,7 @@ public class ModCommand extends Command {
} }
for (Path mod : mods) { for (Path mod : mods) {
try { try {
ModManager.delete(instance, mds.get(mod)); mds.get(mod).delete();
} catch (IOException e) { } catch (IOException e) {
Utils.LOGGER.error("Could not delete " + mod, e); Utils.LOGGER.error("Could not delete " + mod, e);
return; return;
@ -166,35 +166,25 @@ public class ModCommand extends Command {
} }
for (Path mod : mods) { for (Path mod : mods) {
try { try {
Utils.LOGGER.info("Updating " + mod); mds.get(mod).delete();
ModManager.delete(instance, mds.get(mod));
Mod md = mds.get(mod); Mod md = mds.get(mod);
if (md.mod().isEmpty()) { md.getMetadata().sources.values().stream()
throw new IOException("Could not load mod description"); .filter(Optional::isPresent)
} .map(Optional::get)
boolean found = false; .findFirst()
for (Map.Entry<ModSource, Optional<ModSource>> source : md.mod().get().sources.entrySet()) { .ifPresentOrElse(update -> {
Optional<ModSource> ms = source.getValue(); try {
if (ms.isPresent()) { Utils.LOGGER.info("Updating " + mod + " to " + update.getVersion());
try { md.update(update);
Utils.LOGGER.info("Updating to " + ms.get().getVersion()); Utils.LOGGER.info("Update completed");
Path imodPath = md.imod().isPresent() ? md.imod().get() : instance.modsDir().resolve(ms.get().getShortName() + ModPath.EXT_IMOD); } catch (IOException e) {
ModManager.DownloadMeta dm = ModManager.download(ms.get(), imodPath, mds); throw new Unchecked(e);
Files.delete(md.path()); }
if (md.imod().isPresent() && Files.exists(md.imod().get())) }, () -> Utils.LOGGER.error("Could not find any update for " + mod));
Files.delete(md.imod().get());
dm.write();
mds.invalidate(imodPath);
Utils.LOGGER.info("Update completed");
found = true;
} catch (IOException e) {
throw new IOException("Update failed", e);
}
}
}
if (!found) Utils.LOGGER.error("Could not find any update");
} catch (IOException e) { } catch (IOException e) {
throw new IOException("Could not delete " + mod, e); throw new IOException("Could not delete " + mod, e);
} catch (Unchecked e) {
throw new IOException("Could not delete " + mod, e.exception);
} }
} }
} }

View File

@ -10,10 +10,10 @@ import io.gitlab.jfronny.inceptum.gtk.window.NewInstanceWindow;
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager; import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager;
import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAccount; import io.gitlab.jfronny.inceptum.launcher.api.account.MicrosoftAccount;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.system.install.Steps; import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps;
import io.gitlab.jfronny.inceptum.launcher.system.launch.InstanceLauncher; import io.gitlab.jfronny.inceptum.launcher.system.launch.InstanceLauncher;
import io.gitlab.jfronny.inceptum.launcher.util.InstanceList; import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;

View File

@ -5,7 +5,7 @@ import ch.bailu.gtk.bridge.ListIndex;
import ch.bailu.gtk.gtk.*; import ch.bailu.gtk.gtk.*;
import ch.bailu.gtk.pango.EllipsizeMode; import ch.bailu.gtk.pango.EllipsizeMode;
import ch.bailu.gtk.type.Str; import ch.bailu.gtk.type.Str;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import java.util.List; import java.util.List;

View File

@ -8,7 +8,7 @@ import ch.bailu.gtk.type.Str;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.gtk.GtkMenubar; import io.gitlab.jfronny.inceptum.gtk.GtkMenubar;
import io.gitlab.jfronny.inceptum.gtk.util.I18n; import io.gitlab.jfronny.inceptum.gtk.util.I18n;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import java.util.List; import java.util.List;

View File

@ -2,7 +2,7 @@ package io.gitlab.jfronny.inceptum.gtk.control;
import ch.bailu.gtk.gtk.*; import ch.bailu.gtk.gtk.*;
import ch.bailu.gtk.type.*; import ch.bailu.gtk.type.*;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
public class InstanceThumbnail extends Stack { public class InstanceThumbnail extends Stack {
private static final Str SPINNER = new Str("spinner"); private static final Str SPINNER = new Str("spinner");

View File

@ -14,8 +14,8 @@ import io.gitlab.jfronny.inceptum.gtk.control.InstanceGridEntryFactory;
import io.gitlab.jfronny.inceptum.gtk.control.InstanceListEntryFactory; import io.gitlab.jfronny.inceptum.gtk.control.InstanceListEntryFactory;
import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder; import io.gitlab.jfronny.inceptum.gtk.menu.MenuBuilder;
import io.gitlab.jfronny.inceptum.gtk.util.I18n; import io.gitlab.jfronny.inceptum.gtk.util.I18n;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.util.InstanceList; import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;

View File

@ -5,17 +5,14 @@ import imgui.ImGuiIO;
import imgui.flag.ImGuiConfigFlags; import imgui.flag.ImGuiConfigFlags;
import imgui.gl3.ImGuiImplGl3; import imgui.gl3.ImGuiImplGl3;
import imgui.glfw.ImGuiImplGlfw; import imgui.glfw.ImGuiImplGlfw;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.commons.log.*; import io.gitlab.jfronny.commons.log.*;
import io.gitlab.jfronny.inceptum.common.model.inceptum.UpdateMetadata; import io.gitlab.jfronny.inceptum.common.model.inceptum.UpdateMetadata;
import io.gitlab.jfronny.inceptum.imgui.window.MainWindow; import io.gitlab.jfronny.inceptum.imgui.window.MainWindow;
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
import io.gitlab.jfronny.inceptum.common.*; import io.gitlab.jfronny.inceptum.common.*;
import io.gitlab.jfronny.inceptum.imgui.window.Window; import io.gitlab.jfronny.inceptum.imgui.window.Window;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager; import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner; import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import io.gitlab.jfronny.inceptum.launcher.util.InstanceList;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.lwjgl.PointerBuffer; import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.*; import org.lwjgl.glfw.*;

View File

@ -7,12 +7,12 @@ import io.gitlab.jfronny.commons.tuple.Tuple;
import io.gitlab.jfronny.inceptum.common.*; import io.gitlab.jfronny.inceptum.common.*;
import io.gitlab.jfronny.inceptum.imgui.window.GuiUtil; import io.gitlab.jfronny.inceptum.imgui.window.GuiUtil;
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo; import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.LoaderInfo; import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.*; import io.gitlab.jfronny.inceptum.launcher.model.mojang.*;
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi; import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.launcher.api.McApi; import io.gitlab.jfronny.inceptum.launcher.api.McApi;
import io.gitlab.jfronny.inceptum.launcher.util.InstanceNameTool; import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceNameTool;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.IOException; import java.io.IOException;

View File

@ -5,10 +5,10 @@ import imgui.flag.ImGuiTableFlags;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.imgui.GuiMain; import io.gitlab.jfronny.inceptum.imgui.GuiMain;
import io.gitlab.jfronny.inceptum.imgui.window.edit.InstanceEditWindow; import io.gitlab.jfronny.inceptum.imgui.window.edit.InstanceEditWindow;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.system.launch.InstanceLauncher; import io.gitlab.jfronny.inceptum.launcher.system.launch.InstanceLauncher;
import io.gitlab.jfronny.inceptum.launcher.util.InstanceList; import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import io.gitlab.jfronny.inceptum.launcher.system.install.Steps; import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;

View File

@ -6,21 +6,18 @@ import imgui.type.ImString;
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeMod; import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeMod;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.modrinth.*; import io.gitlab.jfronny.inceptum.launcher.model.modrinth.*;
import io.gitlab.jfronny.inceptum.launcher.system.source.*; import io.gitlab.jfronny.inceptum.launcher.system.source.*;
import io.gitlab.jfronny.inceptum.launcher.util.ModManager; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModManager;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import io.gitlab.jfronny.inceptum.launcher.api.CurseforgeApi; import io.gitlab.jfronny.inceptum.launcher.api.CurseforgeApi;
import io.gitlab.jfronny.inceptum.launcher.api.ModrinthApi; import io.gitlab.jfronny.inceptum.launcher.api.ModrinthApi;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.List; import java.util.List;
public class AddModWindow extends Window { public class AddModWindow extends Window {
@ -90,8 +87,7 @@ public class AddModWindow extends Window {
ImGui.tableNextColumn(); ImGui.tableNextColumn();
boolean alreadyPresent = false; boolean alreadyPresent = false;
for (Mod mdsMod : instance.getMods()) { for (Mod mdsMod : instance.getMods()) {
alreadyPresent = mdsMod.mod().isPresent() alreadyPresent = mdsMod.getMetadata().sources.keySet().stream()
&& mdsMod.mod().get().sources.keySet().stream()
.anyMatch(s -> s instanceof ModrinthModSource ms .anyMatch(s -> s instanceof ModrinthModSource ms
&& ms.getModId().equals(mod.project_id)); && ms.getModId().equals(mod.project_id));
if (alreadyPresent) if (alreadyPresent)
@ -166,8 +162,7 @@ public class AddModWindow extends Window {
ImGui.tableNextColumn(); ImGui.tableNextColumn();
boolean alreadyPresent = false; boolean alreadyPresent = false;
for (Mod mdsMod : instance.mds().getMods()) { for (Mod mdsMod : instance.mds().getMods()) {
alreadyPresent = mdsMod.mod().isPresent() alreadyPresent = mdsMod.getMetadata().sources.keySet().stream()
&& mdsMod.mod().get().sources.keySet().stream()
.anyMatch(s -> s instanceof CurseforgeModSource ms .anyMatch(s -> s instanceof CurseforgeModSource ms
&& ms.getProjectId() == mod.id); && ms.getProjectId() == mod.id);
if (alreadyPresent) if (alreadyPresent)

View File

@ -6,9 +6,9 @@ import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.imgui.GuiMain; import io.gitlab.jfronny.inceptum.imgui.GuiMain;
import io.gitlab.jfronny.inceptum.imgui.window.dialog.ProcessStateWatcherWindow; import io.gitlab.jfronny.inceptum.imgui.window.dialog.ProcessStateWatcherWindow;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.system.install.*; import io.gitlab.jfronny.inceptum.launcher.system.setup.*;
import io.gitlab.jfronny.inceptum.launcher.util.InstanceList; import io.gitlab.jfronny.inceptum.launcher.system.instance.InstanceList;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
import java.io.IOException; import java.io.IOException;

View File

@ -8,8 +8,8 @@ import io.gitlab.jfronny.inceptum.imgui.control.InstanceManageControls;
import io.gitlab.jfronny.inceptum.imgui.window.dialog.ProcessStateWatcherWindow; import io.gitlab.jfronny.inceptum.imgui.window.dialog.ProcessStateWatcherWindow;
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
import io.gitlab.jfronny.inceptum.launcher.system.importer.Importers; import io.gitlab.jfronny.inceptum.launcher.system.importer.Importers;
import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo; import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import io.gitlab.jfronny.inceptum.launcher.system.install.Steps; import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
import java.io.IOException; import java.io.IOException;

View File

@ -7,12 +7,11 @@ import io.gitlab.jfronny.inceptum.imgui.control.Tab;
import io.gitlab.jfronny.inceptum.imgui.window.dialog.ProcessStateWatcherWindow; import io.gitlab.jfronny.inceptum.imgui.window.dialog.ProcessStateWatcherWindow;
import io.gitlab.jfronny.inceptum.imgui.window.dialog.TextBoxWindow; import io.gitlab.jfronny.inceptum.imgui.window.dialog.TextBoxWindow;
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
import io.gitlab.jfronny.inceptum.launcher.system.export.Exporter; import io.gitlab.jfronny.inceptum.launcher.system.exporter.Exporter;
import io.gitlab.jfronny.inceptum.launcher.system.export.Exporters; import io.gitlab.jfronny.inceptum.launcher.system.exporter.Exporters;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths;
public class ExportTab extends Tab { public class ExportTab extends Tab {
private final InstanceEditWindow window; private final InstanceEditWindow window;

View File

@ -4,7 +4,7 @@ import imgui.ImGui;
import io.gitlab.jfronny.inceptum.imgui.control.Tab; import io.gitlab.jfronny.inceptum.imgui.control.Tab;
import io.gitlab.jfronny.inceptum.imgui.window.GuiUtil; import io.gitlab.jfronny.inceptum.imgui.window.GuiUtil;
import io.gitlab.jfronny.inceptum.imgui.window.Window; import io.gitlab.jfronny.inceptum.imgui.window.Window;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;

View File

@ -7,9 +7,9 @@ import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.imgui.GuiMain; import io.gitlab.jfronny.inceptum.imgui.GuiMain;
import io.gitlab.jfronny.inceptum.imgui.control.Tab; import io.gitlab.jfronny.inceptum.imgui.control.Tab;
import io.gitlab.jfronny.inceptum.imgui.window.AddModWindow; import io.gitlab.jfronny.inceptum.imgui.window.AddModWindow;
import io.gitlab.jfronny.inceptum.launcher.util.ModManager; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModManager;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource; import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import java.io.IOException; import java.io.IOException;
@ -59,10 +59,9 @@ public class ModsTab extends Tab {
float scannedPercentage = 0; float scannedPercentage = 0;
boolean hasUnScanned = false; boolean hasUnScanned = false;
for (Mod mod : modSet) { for (Mod mod : modSet) {
if (window.instance.mds().hasScanned(mod.path())) scannedPercentage++; if (window.instance.mds().hasScanned(mod)) scannedPercentage++;
else hasUnScanned = true; else hasUnScanned = true;
if (mod.mod().isEmpty()) continue; for (Optional<ModSource> value : mod.getMetadata().sources.values()) {
for (Optional<ModSource> value : mod.mod().get().sources.values()) {
if (value.isPresent()) { if (value.isPresent()) {
updatesFound = true; updatesFound = true;
break; break;
@ -80,25 +79,21 @@ public class ModsTab extends Tab {
ImGui.separator(); ImGui.separator();
for (Mod mod : modSet) { for (Mod mod : modSet) {
updatesFound = false; updatesFound = false;
if (mod.mod().isPresent()) { for (Optional<ModSource> value : mod.getMetadata().sources.values()) {
for (Optional<ModSource> value : mod.mod().get().sources.values()) { updatesFound |= value.isPresent();
updatesFound |= value.isPresent();
}
} }
if (filterUpdates.get() && !updatesFound) continue; if (filterUpdates.get() && !updatesFound) continue;
boolean wasEnabled = ModPath.isEnabled(mod.path()); if (ImGui.checkbox("##" + mod.getName(), mod.isEnabled())) {
if (ImGui.checkbox("##" + mod.getName(), wasEnabled)) { Path newSel = ModPath.toggle(mod.getMetadataPath());
Path newSel = ModPath.toggle(mod.path());
try { try {
Files.move(mod.path(), newSel); Files.move(mod.getMetadataPath(), newSel);
if (mod.path().equals(selected)) selected = newSel; if (mod.getMetadataPath().equals(selected)) selected = newSel;
mod = new Mod(newSel, mod);
} catch (IOException e) { } catch (IOException e) {
LauncherEnv.showError("Could not change disabled state", e); LauncherEnv.showError("Could not change disabled state", e);
} }
} }
ImGui.sameLine(); ImGui.sameLine();
if (ImGui.button(mod.getName())) selected = mod.path(); if (ImGui.button(mod.getName())) selected = mod.getMetadataPath();
} }
} catch (IOException e) { } catch (IOException e) {
Utils.LOGGER.error("Could not show mod list", e); Utils.LOGGER.error("Could not show mod list", e);
@ -116,41 +111,31 @@ public class ModsTab extends Tab {
ImGui.text(s); ImGui.text(s);
} }
ImGui.separator(); ImGui.separator();
if (md.mod().isPresent()) { Map<ModSource, Optional<ModSource>> sources = md.getMetadata().sources;
Map<ModSource, Optional<ModSource>> sources = md.mod().get().sources; ImGui.text("Sources:");
ImGui.text("Sources:"); if (sources.isEmpty())
if (sources.isEmpty()) ImGui.bulletText("Local Drive");
ImGui.bulletText("Local Drive"); else {
else { for (Map.Entry<ModSource, Optional<ModSource>> source : sources.entrySet()) {
for (Map.Entry<ModSource, Optional<ModSource>> source : sources.entrySet()) { ImGui.bulletText(source.getKey().getName());
ImGui.bulletText(source.getKey().getName()); source.getValue().ifPresent(update -> {
Optional<ModSource> ms = source.getValue(); ImGui.sameLine();
if (ms.isPresent()) { if (ImGui.button("Update to " + update.getVersion())) {
ImGui.sameLine(); try {
if (ImGui.button("Update to " + ms.get().getVersion())) { selected = md.update(update);
try { } catch (IOException e) {
Path imodPath = md.imod().isPresent() ? md.imod().get() : window.instance.modsDir().resolve(ms.get().getShortName() + ModPath.EXT_IMOD); LauncherEnv.showError("Update failed", e);
ModManager.DownloadMeta dm = ModManager.download(ms.get(), imodPath, window.instance.mds());
Files.delete(md.path());
if (md.imod().isPresent() && Files.exists(md.imod().get()))
Files.delete(md.imod().get());
dm.write();
selected = imodPath;
window.instance.mds().invalidate(imodPath);
} catch (IOException e) {
LauncherEnv.showError("Update failed", e);
}
} }
} }
} });
} }
} }
if (ImGui.button("Delete")) { if (ImGui.button("Delete")) {
if (md.mod().isPresent() && !md.mod().get().dependents.isEmpty()) if (!md.getMetadata().dependents.isEmpty())
LauncherEnv.showError("This mod still has the following dependent mods installed: " + String.join(", ", md.mod().get().dependents), "Dependents present"); LauncherEnv.showError("This mod still has the following dependent mods installed: " + String.join(", ", md.getMetadata().dependents), "Dependents present");
else { else {
try { try {
delete(md); md.delete();
} catch (IOException e) { } catch (IOException e) {
LauncherEnv.showError("Couldn't delete the file", e); LauncherEnv.showError("Couldn't delete the file", e);
} }
@ -163,10 +148,6 @@ public class ModsTab extends Tab {
ImGui.endGroup(); ImGui.endGroup();
} }
private void delete(Mod md) throws IOException {
ModManager.delete(window.instance, md);
}
@Override @Override
protected boolean canShow() { protected boolean canShow() {
return window.instance.isFabric(); return window.instance.isFabric();

View File

@ -4,8 +4,8 @@ import io.gitlab.jfronny.gson.reflect.TypeToken;
import io.gitlab.jfronny.inceptum.common.Net; import io.gitlab.jfronny.inceptum.common.Net;
import io.gitlab.jfronny.inceptum.common.api.MavenApi; import io.gitlab.jfronny.inceptum.common.api.MavenApi;
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricVersionLoaderInfo; 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.*; import io.gitlab.jfronny.inceptum.launcher.model.mojang.*;
import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -53,7 +53,7 @@ public class FabricMetaApi {
floader.name = ver.intermediary.maven; floader.name = ver.intermediary.maven;
libs.add(convertLib(floader)); libs.add(convertLib(floader));
result.libraries = List.copyOf(libs); result.libraries = List.copyOf(libs);
result.id = InstanceMeta.floaderPrefix + fabricVersion + "-" + version.id; result.id = GameVersionParser.floaderPrefix + fabricVersion + "-" + version.id;
return result; return result;
} }

View File

@ -1,13 +1,9 @@
package io.gitlab.jfronny.inceptum.launcher.model.inceptum; package io.gitlab.jfronny.inceptum.launcher.model.inceptum;
import io.gitlab.jfronny.commons.serialize.gson.api.Ignore;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
public class InstanceMeta { public class InstanceMeta {
@Ignore
public static final String floaderPrefix = "fabric-loader-";
public String version; public String version;
public String java; public String java;
public Long minMem; public Long minMem;
@ -15,22 +11,6 @@ public class InstanceMeta {
public Long lastLaunched; public Long lastLaunched;
public Arguments arguments; public Arguments arguments;
public boolean isFabric() {
return version.startsWith(floaderPrefix);
}
public String getMinecraftVersion() {
return getMinecraftVersion(version);
}
public static String getMinecraftVersion(String id) {
return id.startsWith(floaderPrefix) ? id.substring(id.lastIndexOf('-') + 1) : id;
}
public String getLoaderVersion() {
return isFabric() ? version.substring(floaderPrefix.length()).split("-")[0] : "";
}
public static class Arguments { public static class Arguments {
public List<String> jvm; public List<String> jvm;
public List<String> client; public List<String> client;

View File

@ -14,12 +14,13 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.*; import java.util.*;
public class ModDescription { public class ModMeta {
public Map<ModSource, Optional<ModSource>> sources; //key: source, value: update public Map<ModSource, Optional<ModSource>> sources; //key: source, value: update
public String sha1; public String sha1;
public Long murmur2; public Long murmur2;
public List<String> dependents; // by file name public List<String> dependents; // by file name
public List<String> dependencies; // by file name public List<String> dependencies; // by file name
public boolean explicit = true;
public boolean initialize(String gameVersion) { public boolean initialize(String gameVersion) {
boolean modrinth = false; boolean modrinth = false;
@ -53,23 +54,25 @@ public class ModDescription {
return changed; return changed;
} }
public static ModDescription of(Path mod) { public static ModMeta of(Path mod) {
ModDescription res = new ModDescription(); ModMeta res = new ModMeta();
res.sources = new LinkedHashMap<>(); res.sources = new LinkedHashMap<>();
try { if (!Files.isDirectory(mod)) {
byte[] data = Files.readAllBytes(mod); try {
res.sha1 = HashUtils.sha1(data); byte[] data = Files.readAllBytes(mod);
res.murmur2 = HashUtils.murmur2(data); res.sha1 = HashUtils.sha1(data);
} catch (IOException e) { res.murmur2 = HashUtils.murmur2(data);
Utils.LOGGER.error("Could not read file hash", e); } catch (IOException e) {
Utils.LOGGER.error("Could not read file hash", e);
}
} }
res.dependents = new ArrayList<>(); res.dependents = new ArrayList<>();
res.dependencies = new ArrayList<>(); res.dependencies = new ArrayList<>();
return res; return res;
} }
public static ModDescription of(String sha1, Long murmur2, @Nullable ModSource knownSource, String gameVersion) { public static ModMeta of(String sha1, Long murmur2, @Nullable ModSource knownSource, String gameVersion) {
ModDescription res = new ModDescription(); ModMeta res = new ModMeta();
res.sources = new LinkedHashMap<>(); res.sources = new LinkedHashMap<>();
res.sha1 = sha1; res.sha1 = sha1;
res.murmur2 = murmur2; res.murmur2 = murmur2;

View File

@ -1,68 +0,0 @@
package io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricModJson;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModDescription;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
public record Mod(Path path, Optional<ModDescription> mod, Optional<FabricModJson> fmj, Optional<Path> imod) implements Comparable<Mod> {
public String getName() {
if (fmj.isEmpty()) return path.getFileName().toString();
String base;
if (fmj.get().name != null) base = fmj.get().name;
else if (fmj.get().id != null) base = fmj.get().id;
else {
base = path.getFileName().toString();
if (Files.isDirectory(path))
base += '/';
}
if (fmj.get().version != null) base += ' ' + fmj.get().version;
return base;
}
public String[] getDescription() {
try {
if (fmj.isPresent() && fmj.get().description != null) {
return fmj.get().description.split("\n");
} else if (Files.isDirectory(path)) {
return JFiles.listNames(path);
}
} catch (IOException e) {
Utils.LOGGER.error("Could not get description", e);
}
return new String[]{"No description is available", "This mod may have been added manually"};
}
/**
* Generates a description with only the path and no additional information
*
* @param path The path of the mod entry
*/
public Mod(Path path) {
this(path,
Files.isDirectory(path) ? Optional.empty() : Optional.of(ModDescription.of(path)),
Optional.empty(),
ModPath.hasImod(path) ? Optional.of(ModPath.appendImod(path)) : Optional.empty());
}
/**
* Generates a new mod description based on an existing one with an adjusted path
*
* @param path The new path to use
* @param base The mod description to copy
*/
public Mod(Path path, Mod base) {
this(path, base.mod, base.fmj, base.imod);
}
@Override
public int compareTo(Mod o) {
return getName().compareTo(o.getName());
}
}

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.system.export; package io.gitlab.jfronny.inceptum.launcher.system.exporter;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;

View File

@ -1,14 +1,13 @@
package io.gitlab.jfronny.inceptum.launcher.system.export; package io.gitlab.jfronny.inceptum.launcher.system.exporter;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.InceptumConfig; import io.gitlab.jfronny.inceptum.common.InceptumConfig;
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeModpackManifest; import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeModpackManifest;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.source.CurseforgeModSource; 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.ModSource;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -48,26 +47,18 @@ public class CurseForgeExporter extends Exporter<CurseforgeModpackManifest> {
@Override @Override
protected void addMods(Path root, Instance instance, Iterable<Mod> mods, CurseforgeModpackManifest manifest, Path modsOverrides) throws IOException { protected void addMods(Path root, Instance instance, Iterable<Mod> mods, CurseforgeModpackManifest manifest, Path modsOverrides) throws IOException {
modsLoop: for(Mod mod : mods) { modsLoop: for(Mod mod : mods) {
if (ModPath.isImod(mod.path())) { if (mod.needsInject()) {
Set<ModSource> sources = mod.mod().orElseThrow().sources.keySet(); Set<ModSource> sources = mod.getMetadata().sources.keySet();
for (ModSource source : sources) { for (ModSource source : sources) {
if (source instanceof CurseforgeModSource cms) { if (source instanceof CurseforgeModSource cms) {
manifest.files.add(cms.toManifest()); manifest.files.add(cms.toManifest());
continue modsLoop; continue modsLoop;
} }
} }
// Not available on CF
for (ModSource source : sources) {
Files.createDirectories(modsOverrides);
Files.copy(source.getJarPath(), modsOverrides.resolve(mod.path().getFileName().toString()));
continue modsLoop;
}
} else {
Files.createDirectories(modsOverrides);
Files.copy(mod.path(), modsOverrides.resolve(mod.path().getFileName().toString()));
continue modsLoop;
} }
throw new FileNotFoundException("Could not find mod file for " + mod.path()); // Not available on CF
Files.createDirectories(modsOverrides);
Files.copy(mod.getJarPath(), modsOverrides.resolve(mod.getJarPath().getFileName().toString()));
} }
JFiles.writeObject(root.resolve("manifest.json"), manifest); JFiles.writeObject(root.resolve("manifest.json"), manifest);
} }

View File

@ -1,12 +1,9 @@
package io.gitlab.jfronny.inceptum.launcher.system.export; package io.gitlab.jfronny.inceptum.launcher.system.exporter;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.system.instance.*;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.util.*; import io.gitlab.jfronny.inceptum.launcher.util.*;
import io.gitlab.jfronny.inceptum.launcher.util.ignore.IgnoringWalk; import io.gitlab.jfronny.inceptum.launcher.util.gitignore.IgnoringWalk;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -37,8 +34,8 @@ public abstract class Exporter<Manifest> {
if (instance.isFabric()) { if (instance.isFabric()) {
state.incrementStep("Adding mods"); state.incrementStep("Adding mods");
addMods(root, instance, new StreamIterable<>(instance.getMods().stream().filter(mod -> { addMods(root, instance, new StreamIterable<>(instance.getMods().stream().filter(mod -> {
if (!ModPath.isEnabled(mod.path())) return false; if (!mod.isEnabled()) return false;
state.updateStep(mod.path().toString()); state.updateStep(mod.getName());
return true; return true;
})), manifest, overrides.resolve("mods")); })), manifest, overrides.resolve("mods"));
} }

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.system.export; package io.gitlab.jfronny.inceptum.launcher.system.exporter;
import java.util.List; import java.util.List;

View File

@ -1,13 +1,12 @@
package io.gitlab.jfronny.inceptum.launcher.system.export; package io.gitlab.jfronny.inceptum.launcher.system.exporter;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.modrinth.ModrinthModpackManifest; import io.gitlab.jfronny.inceptum.launcher.model.modrinth.ModrinthModpackManifest;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource; import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModrinthModSource; import io.gitlab.jfronny.inceptum.launcher.system.source.ModrinthModSource;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -41,26 +40,18 @@ public class ModrinthExporter extends Exporter<ModrinthModpackManifest> {
@Override @Override
protected void addMods(Path root, Instance instance, Iterable<Mod> mods, ModrinthModpackManifest manifest, Path modsOverrides) throws IOException { protected void addMods(Path root, Instance instance, Iterable<Mod> mods, ModrinthModpackManifest manifest, Path modsOverrides) throws IOException {
modsLoop: for(Mod mod : mods) { modsLoop: for(Mod mod : mods) {
if (ModPath.isImod(mod.path())) { if (mod.needsInject()) {
Set<ModSource> sources = mod.mod().orElseThrow().sources.keySet(); Set<ModSource> sources = mod.getMetadata().sources.keySet();
for (ModSource source : sources) { for (ModSource source : sources) {
if (source instanceof ModrinthModSource cms) { if (source instanceof ModrinthModSource cms) {
manifest.files.add(cms.toManifest()); manifest.files.add(cms.toManifest());
continue modsLoop; continue modsLoop;
} }
} }
// Not available on modrinth
for (ModSource source : sources) {
Files.createDirectories(modsOverrides);
Files.copy(source.getJarPath(), modsOverrides.resolve(mod.path().getFileName().toString()));
continue modsLoop;
}
} else {
Files.createDirectories(modsOverrides);
Files.copy(mod.path(), modsOverrides.resolve(mod.path().getFileName().toString()));
continue modsLoop;
} }
throw new FileNotFoundException("Could not find mod file for " + mod.path()); // Not available on modrinth
Files.createDirectories(modsOverrides);
Files.copy(mod.getJarPath(), modsOverrides.resolve(mod.getJarPath().getFileName().toString()));
} }
JFiles.writeObject(root.resolve("modrinth.index.json"), manifest); JFiles.writeObject(root.resolve("modrinth.index.json"), manifest);
} }

View File

@ -1,12 +1,11 @@
package io.gitlab.jfronny.inceptum.launcher.system.export; package io.gitlab.jfronny.inceptum.launcher.system.exporter;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.multimc.MMCPackMeta; import io.gitlab.jfronny.inceptum.launcher.model.multimc.MMCPackMeta;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource; import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath; import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
@ -82,20 +81,7 @@ public class MultiMCExporter extends Exporter<MMCPackMeta> {
@Override @Override
protected void addMods(Path root, Instance instance, Iterable<Mod> mods, MMCPackMeta mmcPackMeta, Path modsOverrides) throws IOException { protected void addMods(Path root, Instance instance, Iterable<Mod> mods, MMCPackMeta mmcPackMeta, Path modsOverrides) throws IOException {
modsLoop: for (Mod mod : mods) { Files.createDirectories(modsOverrides);
if (ModPath.isImod(mod.path())) { for (Mod mod : mods) Files.copy(mod.getJarPath(), modsOverrides.resolve(mod.getJarPath().getFileName().toString()));
Set<ModSource> sources = mod.mod().orElseThrow().sources.keySet();
for (ModSource source : sources) {
Files.createDirectories(modsOverrides);
Files.copy(source.getJarPath(), modsOverrides.resolve(mod.path().getFileName().toString()));
continue modsLoop;
}
} else {
Files.createDirectories(modsOverrides);
Files.copy(mod.path(), modsOverrides.resolve(mod.path().getFileName().toString()));
continue modsLoop;
}
throw new FileNotFoundException("Could not find mod file for " + mod.path());
}
} }
} }

View File

@ -2,7 +2,8 @@ package io.gitlab.jfronny.inceptum.launcher.system.importer;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeModpackManifest; import io.gitlab.jfronny.inceptum.launcher.model.curseforge.CurseforgeModpackManifest;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModDescription; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModMeta;
import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import io.gitlab.jfronny.inceptum.launcher.system.source.*; import io.gitlab.jfronny.inceptum.launcher.system.source.*;
import io.gitlab.jfronny.inceptum.launcher.util.*; import io.gitlab.jfronny.inceptum.launcher.util.*;
@ -42,7 +43,7 @@ public class CurseForgeImporter extends Importer<CurseforgeModpackManifest> {
CurseforgeModSource source = new CurseforgeModSource(file.projectID, file.fileID); CurseforgeModSource source = new CurseforgeModSource(file.projectID, file.fileID);
state.updateStep("Downloading " + source.getName()); state.updateStep("Downloading " + source.getName());
ModDownload download = source.download(); ModDownload download = source.download();
ModDescription imod = ModDescription.of(download.sha1(), download.murmur2(), source, manifest.minecraft.version); ModMeta imod = ModMeta.of(download.sha1(), download.murmur2(), source, manifest.minecraft.version);
Files.createDirectories(modsPath); Files.createDirectories(modsPath);
JFiles.writeObject(modsPath.resolve(source.getShortName() + ModPath.EXT_IMOD), imod); JFiles.writeObject(modsPath.resolve(source.getShortName() + ModPath.EXT_IMOD), imod);
} }

View File

@ -6,8 +6,8 @@ import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi; import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.launcher.api.McApi; import io.gitlab.jfronny.inceptum.launcher.api.McApi;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.*;
import io.gitlab.jfronny.inceptum.launcher.system.install.Steps; import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps;
import io.gitlab.jfronny.inceptum.launcher.util.*; import io.gitlab.jfronny.inceptum.launcher.util.*;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -41,7 +41,7 @@ public abstract class Importer<T> {
return gameVersion; return gameVersion;
} else { } else {
FabricMetaApi.getLoaderVersion(gameVersion, fabricVersion); FabricMetaApi.getLoaderVersion(gameVersion, fabricVersion);
return InstanceMeta.floaderPrefix + fabricVersion + '-' + gameVersion; return GameVersionParser.floaderPrefix + fabricVersion + '-' + gameVersion;
} }
} }

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.inceptum.launcher.system.importer; package io.gitlab.jfronny.inceptum.launcher.system.importer;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.system.install.Steps; import io.gitlab.jfronny.inceptum.launcher.system.setup.Steps;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
import java.io.IOException; import java.io.IOException;

View File

@ -1,10 +1,11 @@
package io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt; package io.gitlab.jfronny.inceptum.launcher.system.instance;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.R; import io.gitlab.jfronny.inceptum.common.R;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner; import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessUtils; import io.gitlab.jfronny.inceptum.launcher.util.ProcessUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -81,7 +82,15 @@ public record Instance(String id, Path path, InstanceMeta meta, ModsDirScanner m
} }
public boolean isFabric() { public boolean isFabric() {
return meta.isFabric(); return GameVersionParser.isFabric(meta.version);
}
public String getMinecraftVersion() {
return GameVersionParser.getMinecraftVersion(meta.version);
}
public String getLoaderVersion() {
return GameVersionParser.getLoaderVersion(meta.version);
} }
public boolean isSetupLocked() { public boolean isSetupLocked() {

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.util; package io.gitlab.jfronny.inceptum.launcher.system.instance;
import io.gitlab.jfronny.commons.cache.FileBackedRef; import io.gitlab.jfronny.commons.cache.FileBackedRef;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
@ -6,7 +6,7 @@ import io.gitlab.jfronny.commons.throwable.ThrowingConsumer;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.util; package io.gitlab.jfronny.inceptum.launcher.system.instance;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt; package io.gitlab.jfronny.inceptum.launcher.system.instance;
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricLoaderVersion; import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricLoaderVersion;

View File

@ -0,0 +1,37 @@
package io.gitlab.jfronny.inceptum.launcher.system.instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModMeta;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Set;
public abstract class Mod implements Comparable<Mod> {
public abstract String getName();
public abstract String[] getDescription();
public abstract boolean needsInject();
public abstract Path getJarPath();
public abstract Path getMetadataPath();
public abstract void delete() throws IOException;
public abstract Path update(ModSource update) throws IOException;
public abstract Set<Mod> getDependencies();
public abstract Set<Mod> getDependents();
public abstract void removeDependency(Mod dependency) throws IOException;
public abstract void removeDependent(Mod dependent) throws IOException;
public abstract ModMeta getMetadata();
public abstract boolean isEnabled();
@Override
public int compareTo(@NotNull Mod mod) {
return getName().compareTo(mod.getName());
}
@Override
public String toString() {
return getName();
}
}

View File

@ -0,0 +1,37 @@
package io.gitlab.jfronny.inceptum.launcher.system.instance;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModMeta;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModDownload;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import java.io.IOException;
import java.nio.file.Path;
public class ModManager {
public static DownloadMeta download(ModSource ms, Path metaFile, ModsDirScanner mds) throws IOException {
for (Mod value : mds.getMods()) {
for (ModSource source : value.getMetadata().sources.keySet()) {
if (ms.equals(source)) {
return new DownloadMeta(new ModDownload(value.getMetadata().sha1, value.getMetadata().murmur2, value.getJarPath()), value.getMetadata(), source, metaFile);
}
}
}
ModDownload md = ms.download();
ModMeta manifest = ModMeta.of(md.sha1(), md.murmur2(), ms, mds.getGameVersion());
for (ModSource depSrc : ms.getDependencies(mds.getGameVersion())) {
DownloadMeta depMeta = download(depSrc, metaFile.getParent().resolve(depSrc.getShortName() + ModPath.EXT_IMOD), mds);
depMeta.meta.dependents.add(metaFile.getFileName().toString());
manifest.dependencies.add(depMeta.metaFile.getFileName().toString());
depMeta.write();
}
return new DownloadMeta(md, manifest, ms, metaFile);
}
public record DownloadMeta(ModDownload download, ModMeta meta, ModSource source, Path metaFile) {
public void write() throws IOException {
JFiles.writeObject(metaFile, meta);
}
}
}

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.util; package io.gitlab.jfronny.inceptum.launcher.system.instance;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;

View File

@ -6,13 +6,14 @@ import io.gitlab.jfronny.inceptum.common.api.MavenApi;
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv; import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
import io.gitlab.jfronny.inceptum.common.*; import io.gitlab.jfronny.inceptum.common.*;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.*; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.*;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.*; import io.gitlab.jfronny.inceptum.launcher.model.mojang.*;
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi; import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.launcher.api.McApi; import io.gitlab.jfronny.inceptum.launcher.api.McApi;
import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager; import io.gitlab.jfronny.inceptum.launcher.api.account.AccountManager;
import io.gitlab.jfronny.inceptum.launcher.api.account.AuthInfo; import io.gitlab.jfronny.inceptum.launcher.api.account.AuthInfo;
import io.gitlab.jfronny.inceptum.launcher.system.install.steps.DownloadLibrariesStep; import io.gitlab.jfronny.inceptum.launcher.system.setup.steps.DownloadLibrariesStep;
import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource; import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import io.gitlab.jfronny.inceptum.launcher.util.*; import io.gitlab.jfronny.inceptum.launcher.util.*;
@ -105,7 +106,7 @@ public class InstanceLauncher {
String fn = imod.getFileName().toString(); String fn = imod.getFileName().toString();
if (Files.exists(imod.getParent().resolve(fn.substring(0, fn.length() - 5)))) if (Files.exists(imod.getParent().resolve(fn.substring(0, fn.length() - 5))))
continue; continue;
Map<ModSource, Optional<ModSource>> sources = JFiles.readObject(imod, ModDescription.class).sources; Map<ModSource, Optional<ModSource>> sources = JFiles.readObject(imod, ModMeta.class).sources;
if (sources.isEmpty()) throw new LaunchException(".imod without attached jar contains no sources"); if (sources.isEmpty()) throw new LaunchException(".imod without attached jar contains no sources");
ModSource ms = List.copyOf(sources.keySet()).get(0); ModSource ms = List.copyOf(sources.keySet()).get(0);
Path p = ms.getJarPath().toAbsolutePath(); Path p = ms.getJarPath().toAbsolutePath();

View File

@ -1,93 +1,73 @@
package io.gitlab.jfronny.inceptum.launcher.system.mds; package io.gitlab.jfronny.inceptum.launcher.system.mds;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.commons.throwable.ThrowingConsumer;
import io.gitlab.jfronny.gson.JsonParseException; import io.gitlab.jfronny.gson.JsonParseException;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricModJson; import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricModJson;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModDescription; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModMeta;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath; import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.mds.noop.NoopMod;
import io.gitlab.jfronny.inceptum.launcher.system.instance.ModPath;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource; import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import org.jetbrains.annotations.Nullable;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.nio.file.*; import java.nio.file.*;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.function.*;
import java.util.function.BiConsumer;
public record FileScanTask(Path file, BiConsumer<Path, Mod> discovered, public record FileScanTask(ProtoInstance instance, Path file, BiConsumer<Path, Mod> discovered, String gameVersion) implements Runnable {
String gameVersion) implements Runnable {
@Override @Override
public void run() { public void run() {
if (!Files.exists(file)) return; if (!Files.exists(file)) return;
if (Files.isDirectory(file)) { if (Files.isDirectory(file)) return; // Directories are not supported
discovered.accept(file, new Mod(file));
return;
}
try { try {
if (ModPath.isJar(file)) { if (ModPath.isJar(file)) {
final var imod = new Object() { final MetadataRef imod = new MetadataRef(file.getParent().resolve(file.getFileName() + ModPath.EXT_IMOD), ModMeta::of);
Path i = file.getParent().resolve(file.getFileName() + ModPath.EXT_IMOD); evaluateSources(file, imod);
ModDescription md; discovered.accept(imod.imodPath, new MdsMod(instance, imod.imodPath, file, false, imod.meta, getFmj(file, imod.meta)));
}; } else if (ModPath.isImod(file)) {
// mod description
if (!Files.exists(imod.i)) {
JFiles.writeObject(imod.i, ModDescription.of(file));
}
imod.md = JFiles.readObject(imod.i, ModDescription.class);
evaluateSources(imod.md, file, imod.i, newImod -> {
imod.i = newImod;
imod.md = JFiles.readObject(imod.i, ModDescription.class);
});
discovered.accept(imod.i, new Mod(file, Optional.of(imod.md), getFmj(file, imod.md), Optional.of(imod.i)));
return;
}
if (ModPath.isImod(file)) {
String fn = file.getFileName().toString(); String fn = file.getFileName().toString();
Path modFile = file.getParent().resolve(fn.substring(0, fn.length() - ModPath.EXT_IMOD.length())); Path modFile = file.getParent().resolve(fn.substring(0, fn.length() - ModPath.EXT_IMOD.length()));
final var imod = new Object() { final MetadataRef imod = new MetadataRef(file, null);
Path i = file; evaluateSources(modFile, imod);
ModDescription md = JFiles.readObject(file, ModDescription.class); boolean managedJar = !Files.exists(modFile);
}; discovered.accept(imod.imodPath, new MdsMod(instance, imod.imodPath, managedJar ? imod.jarPath : modFile, managedJar, imod.meta, getFmj(modFile, imod.meta)));
evaluateSources(imod.md, modFile, imod.i, newImod -> { } else discovered.accept(file, new NoopMod(file));
imod.i = newImod;
imod.md = JFiles.readObject(imod.i, ModDescription.class);
});
discovered.accept(imod.i, new Mod(imod.i, Optional.of(imod.md), getFmj(modFile, imod.md), Optional.of(imod.i)));
return;
}
discovered.accept(file, new Mod(file));
} catch (IOException | URISyntaxException | JsonParseException e) { } catch (IOException | URISyntaxException | JsonParseException e) {
Utils.LOGGER.error("Could not scan file for mod info", e); Utils.LOGGER.error("Could not scan file for mod info", e);
} }
} }
private <TEx extends Throwable> void evaluateSources(ModDescription md, Path modFile, Path imodFile, ThrowingConsumer<Path, TEx> imodModified) throws IOException, TEx { private <TEx extends Throwable> void evaluateSources(Path modFile, MetadataRef ref) throws IOException, TEx {
boolean modified = false; boolean modified = false;
if (md.initialize(gameVersion)) { if (ref.meta.initialize(gameVersion)) {
JFiles.writeObject(imodFile, md); JFiles.writeObject(ref.imodPath, ref.meta);
modified = true; modified = true;
} }
ModSource selectedSource = null; ModSource selectedSource = null;
for (ModSource source : md.sources.keySet()) { for (ModSource source : ref.meta.sources.keySet()) {
source.getUpdate(gameVersion); source.getUpdate(gameVersion);
if (!Files.exists(source.getJarPath())) source.download(); if (!Files.exists(source.getJarPath())) source.download();
selectedSource = source; selectedSource = source;
} }
if (selectedSource != null && Files.exists(modFile)) { if (selectedSource != null) {
Files.delete(modFile); if (Files.exists(modFile)) {
Path newImod = imodFile.getParent().resolve(selectedSource.getShortName() + ModPath.EXT_IMOD); Files.delete(modFile);
Files.move(imodFile, newImod); Path newImod = ref.imodPath.getParent().resolve(selectedSource.getShortName() + ModPath.EXT_IMOD);
imodFile = newImod; Files.move(ref.imodPath, newImod);
modified = true; ref.imodPath = newImod;
modified = true;
}
ref.jarPath = selectedSource.getJarPath();
} }
if (modified) imodModified.accept(imodFile); if (modified) ref.update();
} }
private Optional<FabricModJson> getFmj(Path modJarDefault, ModDescription md) throws IOException, URISyntaxException { private @Nullable FabricModJson getFmj(Path modJarDefault, ModMeta md) throws IOException, URISyntaxException {
if (!Files.exists(modJarDefault)) { if (!Files.exists(modJarDefault)) {
if (md.sources.isEmpty()) { if (md.sources.isEmpty()) {
throw new FileNotFoundException("Mod " + modJarDefault.getFileName().toString() + " doesn't specify a source and has no file"); throw new FileNotFoundException("Mod " + modJarDefault.getFileName().toString() + " doesn't specify a source and has no file");
@ -95,9 +75,25 @@ public record FileScanTask(Path file, BiConsumer<Path, Mod> discovered,
modJarDefault = List.copyOf(md.sources.keySet()).get(0).getJarPath(); modJarDefault = List.copyOf(md.sources.keySet()).get(0).getJarPath();
} }
try (FileSystem fs = Utils.openZipFile(modJarDefault, false)) { try (FileSystem fs = Utils.openZipFile(modJarDefault, false)) {
return Files.exists(fs.getPath("fabric.mod.json")) Path fmjPath = fs.getPath("fabric.mod.json");
? Optional.of(JFiles.readObject(fs.getPath("fabric.mod.json"), FabricModJson.class)) if (!Files.exists(fmjPath)) return null;
: Optional.empty(); return JFiles.readObject(fmjPath, FabricModJson.class);
}
}
private static class MetadataRef {
public MetadataRef(Path imodPath, @Nullable Function<Path, ModMeta> defaultMeta) throws IOException {
this.imodPath = imodPath;
if (!Files.exists(imodPath) && defaultMeta != null) JFiles.writeObject(imodPath, defaultMeta.apply(imodPath));
if (Files.exists(imodPath)) update();
}
public Path imodPath;
public Path jarPath; // filled in from evaluateSources
public ModMeta meta;
public void update() throws IOException {
this.meta = JFiles.readObject(imodPath, ModMeta.class);
} }
} }
} }

View File

@ -0,0 +1,136 @@
package io.gitlab.jfronny.inceptum.launcher.system.mds;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.launcher.model.fabric.FabricModJson;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModMeta;
import io.gitlab.jfronny.inceptum.launcher.system.instance.*;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import org.jetbrains.annotations.Nullable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Set;
import java.util.stream.Collectors;
public class MdsMod extends Mod {
private final ProtoInstance instance;
private final Path imodPath;
private final Path jarPath;
private final boolean managedJar;
private final ModMeta meta;
private final @Nullable FabricModJson fmj;
MdsMod(ProtoInstance instance, Path imodPath, Path jarPath, boolean managedJar, ModMeta meta, @Nullable FabricModJson fmj) {
this.instance = instance;
this.imodPath = imodPath;
this.jarPath = jarPath;
this.managedJar = managedJar;
this.meta = meta;
this.fmj = fmj;
}
@Override
public String getName() {
String fileName = imodPath.getFileName().toString();
if (fmj == null) return fileName;
String name = fmj.name == null ? fmj.id == null ? fileName : fmj.id : fmj.name;
if (fmj.version != null) name += ' ' + fmj.version;
return name;
}
@Override
public String[] getDescription() {
if (fmj != null && fmj.description != null) return fmj.description.split("\n");
else return new String[] {"No description is available", "You may need to wait for its metadata to be scanned"};
}
@Override
public boolean needsInject() {
return managedJar;
}
@Override
public Path getJarPath() {
return jarPath;
}
@Override
public Path getMetadataPath() {
return imodPath;
}
@Override
public void delete() throws IOException {
Files.delete(imodPath);
if (!managedJar) Files.delete(jarPath);
if (meta != null) {
for (Mod dependency : getDependencies()) dependency.removeDependent(this);
for (Mod dependent : getDependents()) dependent.removeDependency(this);
}
}
@Override
public Path update(ModSource update) throws IOException {
ModManager.DownloadMeta download = ModManager.download(update, imodPath, instance.mds);
Files.delete(imodPath);
download.write();
for (String dependency : meta.dependencies) {
if (!download.meta().dependencies.contains(dependency)) {
instance.mds.get(instance.modsDir.resolve(dependency)).removeDependent(this);
}
}
instance.mds.invalidate(this);
return download.metaFile();
}
@Override
public Set<Mod> getDependencies() {
return meta.dependencies.stream()
.map(instance.modsDir::resolve)
.map(instance.mds::get)
.collect(Collectors.toUnmodifiableSet());
}
@Override
public Set<Mod> getDependents() {
return meta.dependents.stream()
.map(instance.modsDir::resolve)
.map(instance.mds::get)
.collect(Collectors.toUnmodifiableSet());
}
@Override
public void removeDependency(Mod dependency) throws IOException {
meta.dependencies.remove(meta.dependencies.stream()
.filter(s -> dependency.equals(instance.mds.get(instance.modsDir.resolve(s))))
.findFirst()
.orElseThrow(FileNotFoundException::new));
write();
}
@Override
public void removeDependent(Mod dependent) throws IOException {
meta.dependents.remove(meta.dependents.stream()
.filter(s -> dependent.equals(instance.mds.get(instance.modsDir.resolve(s))))
.findFirst()
.orElseThrow(FileNotFoundException::new));
write();
if (!meta.explicit && meta.dependents.isEmpty()) delete();
}
@Override
public ModMeta getMetadata() {
return meta;
}
@Override
public boolean isEnabled() {
return ModPath.isEnabled(imodPath);
}
private void write() throws IOException {
JFiles.writeObject(imodPath, meta);
}
}

View File

@ -1,7 +1,9 @@
package io.gitlab.jfronny.inceptum.launcher.system.mds; package io.gitlab.jfronny.inceptum.launcher.system.mds;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; 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.mds.noop.NoopMds;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
@ -11,9 +13,9 @@ import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
public interface ModsDirScanner extends Closeable { public interface ModsDirScanner extends Closeable {
static ModsDirScanner get(Path modsDir, InstanceMeta instance) throws IOException { static ModsDirScanner get(Path modsDir, InstanceMeta meta) throws IOException {
if (Files.exists(modsDir)) return ModsDirScannerImpl.get(modsDir, instance); if (Files.exists(modsDir)) return ModsDirScannerImpl.get(modsDir, meta);
return new NoopMds(instance.getMinecraftVersion()); return new NoopMds(meta.getMinecraftVersion());
} }
static void closeAll() { static void closeAll() {
@ -32,7 +34,15 @@ public interface ModsDirScanner extends Closeable {
void invalidate(Path path); void invalidate(Path path);
default void invalidate(Mod mod) {
invalidate(mod.getMetadataPath());
}
boolean hasScanned(Path path); boolean hasScanned(Path path);
default boolean hasScanned(Mod mod) {
return hasScanned(mod.getMetadataPath());
}
void runOnce(BiConsumer<Path, Mod> discovered); void runOnce(BiConsumer<Path, Mod> discovered);
} }

View File

@ -4,8 +4,8 @@ import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.R; import io.gitlab.jfronny.inceptum.common.R;
import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.common.Utils;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; import io.gitlab.jfronny.inceptum.launcher.system.instance.*;
import io.gitlab.jfronny.inceptum.launcher.util.ModPath; import io.gitlab.jfronny.inceptum.launcher.system.mds.noop.NoopMod;
import java.io.IOException; import java.io.IOException;
import java.nio.file.*; import java.nio.file.*;
@ -21,14 +21,12 @@ class ModsDirScannerImpl implements ModsDirScanner {
private final Map<Path, Mod> descriptions = new HashMap<>(); private final Map<Path, Mod> descriptions = new HashMap<>();
private final Set<Path> scannedPaths = new HashSet<>(); private final Set<Path> scannedPaths = new HashSet<>();
private final Thread th; private final Thread th;
private final Path modsDir; private final ProtoInstance instance;
private final InstanceMeta instance;
private final WatchService service; private final WatchService service;
private boolean disposed = false; private boolean disposed = false;
private ModsDirScannerImpl(Path modsDir, InstanceMeta instance) throws IOException { private ModsDirScannerImpl(Path modsDir, InstanceMeta instance) throws IOException {
this.modsDir = modsDir; this.instance = new ProtoInstance(modsDir, this, instance);
this.instance = instance;
this.th = new Thread(this::scanTaskInternal, "mds-" + modsDir.getParent().getFileName()); this.th = new Thread(this::scanTaskInternal, "mds-" + modsDir.getParent().getFileName());
this.service = FileSystems.getDefault().newWatchService(); this.service = FileSystems.getDefault().newWatchService();
modsDir.register(service, ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE); modsDir.register(service, ENTRY_MODIFY, ENTRY_CREATE, ENTRY_DELETE);
@ -48,9 +46,9 @@ class ModsDirScannerImpl implements ModsDirScanner {
@Override @Override
public boolean isComplete() { public boolean isComplete() {
if (!Files.isDirectory(modsDir)) return true; if (!Files.isDirectory(instance.modsDir)) return true;
try { try {
for (Path path : JFiles.list(modsDir)) { for (Path path : JFiles.list(instance.modsDir)) {
if (!descriptions.containsKey(path)) return false; if (!descriptions.containsKey(path)) return false;
} }
} catch (IOException e) { } catch (IOException e) {
@ -67,14 +65,14 @@ class ModsDirScannerImpl implements ModsDirScanner {
@Override @Override
public String getGameVersion() { public String getGameVersion() {
return instance.getMinecraftVersion(); return instance.meta.getMinecraftVersion();
} }
@Override @Override
public Set<Mod> getMods() throws IOException { public Set<Mod> getMods() throws IOException {
Set<Mod> mods = new TreeSet<>(); Set<Mod> mods = new TreeSet<>();
if (Files.isDirectory(modsDir)) { if (Files.isDirectory(instance.modsDir)) {
for (Path path : JFiles.list(modsDir)) { for (Path path : JFiles.list(instance.modsDir)) {
if (ModPath.isImod(path) && Files.exists(ModPath.trimImod(path))) if (ModPath.isImod(path) && Files.exists(ModPath.trimImod(path)))
continue; continue;
mods.add(get(path)); mods.add(get(path));
@ -85,10 +83,8 @@ class ModsDirScannerImpl implements ModsDirScanner {
@Override @Override
public Mod get(Path path) { public Mod get(Path path) {
if (!descriptions.containsKey(path)) { if (!Files.isRegularFile(path)) return null;
// not yet scanned if (!descriptions.containsKey(path)) return new NoopMod(path); // not yet scanned
descriptions.put(path, new Mod(path));
}
return descriptions.get(path); return descriptions.get(path);
} }
@ -112,36 +108,36 @@ class ModsDirScannerImpl implements ModsDirScanner {
@Override @Override
public void runOnce(BiConsumer<Path, Mod> discovered) { public void runOnce(BiConsumer<Path, Mod> discovered) {
try { try {
if (!Files.isDirectory(modsDir)) { if (!Files.isDirectory(instance.modsDir)) {
return; return;
} }
Set<Future<?>> tasks = new HashSet<>(); Set<Future<?>> tasks = new HashSet<>();
String mc = instance.getMinecraftVersion(); String mc = instance.meta.getMinecraftVersion();
discovered = discovered.andThen((path, iwModDescription) -> { discovered = discovered.andThen((path, iwModDescription) -> {
scannedPaths.add(path); scannedPaths.add(path);
descriptions.put(path, iwModDescription); descriptions.put(path, iwModDescription);
}); });
Set<Path> toScan; Set<Path> toScan;
if (descriptions.isEmpty()) { if (descriptions.isEmpty()) {
toScan = Set.copyOf(JFiles.list(modsDir)); toScan = Set.copyOf(JFiles.list(instance.modsDir));
} else { } else {
toScan = new HashSet<>(); toScan = new HashSet<>();
WatchKey key = service.poll(); WatchKey key = service.poll();
if (key != null) { if (key != null) {
for (WatchEvent<?> event : key.pollEvents()) { for (WatchEvent<?> event : key.pollEvents()) {
if (event.context() instanceof Path p) { if (event.context() instanceof Path p) {
toScan.add(modsDir.resolve(p)); toScan.add(instance.modsDir.resolve(p));
} }
} }
if (!key.reset()) Utils.LOGGER.warn("Could not reset config watch key"); if (!key.reset()) Utils.LOGGER.warn("Could not reset config watch key");
} }
JFiles.listTo(modsDir, path -> { JFiles.listTo(instance.modsDir, path -> {
if (!descriptions.containsKey(path)) if (!descriptions.containsKey(path))
toScan.add(path); toScan.add(path);
}); });
} }
for (Path p : toScan) { for (Path p : toScan) {
tasks.add(POOL.submit(new FileScanTask(p, discovered, mc))); tasks.add(POOL.submit(new FileScanTask(instance, p, discovered, mc)));
} }
for (Future<?> task : tasks) { for (Future<?> task : tasks) {
try { try {
@ -165,6 +161,6 @@ class ModsDirScannerImpl implements ModsDirScanner {
@Override @Override
public void close() { public void close() {
disposed = true; disposed = true;
SCANNERS.remove(modsDir); SCANNERS.remove(instance.modsDir);
} }
} }

View File

@ -0,0 +1,17 @@
package io.gitlab.jfronny.inceptum.launcher.system.mds;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import java.nio.file.Path;
public class ProtoInstance {
public final Path modsDir;
public final ModsDirScanner mds;
public final InstanceMeta meta;
public ProtoInstance(Path modsDir, ModsDirScanner mds, InstanceMeta meta) {
this.modsDir = modsDir;
this.mds = mds;
this.meta = meta;
}
}

View File

@ -1,6 +1,7 @@
package io.gitlab.jfronny.inceptum.launcher.system.mds; package io.gitlab.jfronny.inceptum.launcher.system.mds.noop;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod; import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
@ -33,7 +34,7 @@ public record NoopMds(String gameVersion) implements ModsDirScanner {
@Override @Override
public Mod get(Path path) { public Mod get(Path path) {
return new Mod(path); return new NoopMod(path);
} }
@Override @Override

View File

@ -0,0 +1,84 @@
package io.gitlab.jfronny.inceptum.launcher.system.mds.noop;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModMeta;
import io.gitlab.jfronny.inceptum.launcher.system.instance.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Set;
public class NoopMod extends Mod {
private final Path path;
private final ModMeta meta;
public NoopMod(Path path) {
this.path = path;
this.meta = ModMeta.of(path);
}
@Override
public String getName() {
return path.getFileName().toString();
}
@Override
public String[] getDescription() {
return new String[] {
"Noop mod",
"Any actions on this mod are unsupported"
};
}
@Override
public boolean needsInject() {
return false;
}
@Override
public Path getJarPath() {
return path;
}
@Override
public Path getMetadataPath() {
return path;
}
@Override
public void delete() throws IOException {
}
@Override
public Path update(ModSource update) throws IOException {
return path;
}
@Override
public Set<Mod> getDependencies() {
return Set.of();
}
@Override
public Set<Mod> getDependents() {
return Set.of();
}
@Override
public void removeDependency(Mod dependency) throws IOException {
}
@Override
public void removeDependent(Mod dependent) throws IOException {
}
@Override
public ModMeta getMetadata() {
return meta;
}
@Override
public boolean isEnabled() {
return true;
}
}

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.inceptum.launcher.system.install; package io.gitlab.jfronny.inceptum.launcher.system.setup;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.LoaderInfo; import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo; import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.system.install; package io.gitlab.jfronny.inceptum.launcher.system.setup;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;

View File

@ -1,12 +1,12 @@
package io.gitlab.jfronny.inceptum.launcher.system.install; package io.gitlab.jfronny.inceptum.launcher.system.setup;
import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi; import io.gitlab.jfronny.inceptum.launcher.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.launcher.api.McApi; import io.gitlab.jfronny.inceptum.launcher.api.McApi;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.LoaderInfo; import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo; import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionsListInfo; import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionsListInfo;
import io.gitlab.jfronny.inceptum.launcher.system.install.steps.*; import io.gitlab.jfronny.inceptum.launcher.system.setup.steps.*;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.ProcessState;
import java.io.IOException; import java.io.IOException;

View File

@ -1,10 +1,10 @@
package io.gitlab.jfronny.inceptum.launcher.system.install.steps; package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.AssetIndex; import io.gitlab.jfronny.inceptum.launcher.model.mojang.AssetIndex;
import io.gitlab.jfronny.inceptum.launcher.api.McApi; import io.gitlab.jfronny.inceptum.launcher.api.McApi;
import io.gitlab.jfronny.inceptum.launcher.system.install.Step; import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo; import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;

View File

@ -1,11 +1,11 @@
package io.gitlab.jfronny.inceptum.launcher.system.install.steps; package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import io.gitlab.jfronny.commons.ComparableVersion; import io.gitlab.jfronny.commons.ComparableVersion;
import io.gitlab.jfronny.inceptum.common.*; import io.gitlab.jfronny.inceptum.common.*;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.MojangFileDownload; import io.gitlab.jfronny.inceptum.launcher.model.mojang.MojangFileDownload;
import io.gitlab.jfronny.inceptum.launcher.system.install.Step; import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo; import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -19,7 +19,7 @@ public class DownloadClientStep implements Step {
Path serverPath = MetaHolder.LIBRARIES_DIR.resolve("net/minecraft/server"); Path serverPath = MetaHolder.LIBRARIES_DIR.resolve("net/minecraft/server");
if (!Files.exists(clientPath)) Files.createDirectories(clientPath); if (!Files.exists(clientPath)) Files.createDirectories(clientPath);
if (!Files.exists(serverPath)) Files.createDirectories(serverPath); if (!Files.exists(serverPath)) Files.createDirectories(serverPath);
String minecraftVersion = InstanceMeta.getMinecraftVersion(info.version().id); String minecraftVersion = GameVersionParser.getMinecraftVersion(info.version().id);
clientPath = clientPath.resolve(minecraftVersion + ".jar"); clientPath = clientPath.resolve(minecraftVersion + ".jar");
serverPath = serverPath.resolve(minecraftVersion + ".jar"); serverPath = serverPath.resolve(minecraftVersion + ".jar");
try { try {

View File

@ -1,11 +1,11 @@
package io.gitlab.jfronny.inceptum.launcher.system.install.steps; package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.common.Net; import io.gitlab.jfronny.inceptum.common.Net;
import io.gitlab.jfronny.inceptum.launcher.api.McApi; import io.gitlab.jfronny.inceptum.launcher.api.McApi;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.*; import io.gitlab.jfronny.inceptum.launcher.model.mojang.*;
import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo; import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import io.gitlab.jfronny.inceptum.launcher.system.install.Step; import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;

View File

@ -1,16 +1,14 @@
package io.gitlab.jfronny.inceptum.launcher.system.install.steps; package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.*; import io.gitlab.jfronny.inceptum.common.*;
import io.gitlab.jfronny.inceptum.common.api.GitlabApi; import io.gitlab.jfronny.inceptum.common.api.GitlabApi;
import io.gitlab.jfronny.inceptum.common.api.MavenApi; import io.gitlab.jfronny.inceptum.common.api.MavenApi;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ArtifactInfo; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ArtifactInfo;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo; import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.launcher.system.install.Step; import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
import io.gitlab.jfronny.inceptum.launcher.util.ProcessState; import io.gitlab.jfronny.inceptum.launcher.util.*;
import io.gitlab.jfronny.inceptum.launcher.util.VersionInfoLibraryResolver; import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -43,7 +41,7 @@ public class DownloadLibrariesStep implements Step {
if (artifact.isNative) { if (artifact.isNative) {
currentState.updateStep("Extracting natives"); currentState.updateStep("Extracting natives");
try (FileSystem libFs = Utils.openZipFile(path, false)) { try (FileSystem libFs = Utils.openZipFile(path, false)) {
JFiles.copyRecursive(libFs.getPath("."), MetaHolder.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(version.id))); JFiles.copyRecursive(libFs.getPath("."), MetaHolder.NATIVES_DIR.resolve(GameVersionParser.getMinecraftVersion(version.id)));
} catch (Throwable t) { } catch (Throwable t) {
Files.delete(path); Files.delete(path);
throw new IOException("Could not extract native", t); throw new IOException("Could not extract native", t);

View File

@ -1,11 +1,11 @@
package io.gitlab.jfronny.inceptum.launcher.system.install.steps; package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.system.install.Step; import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner; import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo; import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;

View File

@ -1,11 +1,11 @@
package io.gitlab.jfronny.inceptum.launcher.system.install.steps; package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.system.instance.LoaderInfo;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.LoaderInfo; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
import io.gitlab.jfronny.inceptum.launcher.system.install.Step; import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo; import io.gitlab.jfronny.inceptum.launcher.util.GameVersionParser;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@ -33,6 +33,6 @@ public class SetupDirsStep implements Step {
if (!Files.exists(eulaTxt)) { if (!Files.exists(eulaTxt)) {
Files.writeString(eulaTxt, "eula=true"); Files.writeString(eulaTxt, "eula=true");
} }
Files.createDirectories(MetaHolder.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(info.version().id))); Files.createDirectories(MetaHolder.NATIVES_DIR.resolve(GameVersionParser.getMinecraftVersion(info.version().id)));
} }
} }

View File

@ -1,11 +1,11 @@
package io.gitlab.jfronny.inceptum.launcher.system.install.steps; package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.MetaHolder;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance; import io.gitlab.jfronny.inceptum.launcher.system.instance.Instance;
import io.gitlab.jfronny.inceptum.launcher.system.install.Step; import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
import io.gitlab.jfronny.inceptum.launcher.system.install.SetupStepInfo; import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;

View File

@ -0,0 +1,17 @@
package io.gitlab.jfronny.inceptum.launcher.util;
public class GameVersionParser {
private static final String FABRIC_PREFIX = "fabric-loader-";
public static boolean isFabric(String version) {
return version.startsWith(FABRIC_PREFIX);
}
public static String getMinecraftVersion(String version) {
return version.startsWith(FABRIC_PREFIX) ? version.substring(version.lastIndexOf('-') + 1) : version;
}
public static String getLoaderVersion(String version) {
return !isFabric(version) ? null : version.substring(FABRIC_PREFIX.length(), version.lastIndexOf('-'));
}
}

View File

@ -1,57 +0,0 @@
package io.gitlab.jfronny.inceptum.launcher.util;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ModDescription;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Instance;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.rt.Mod;
import io.gitlab.jfronny.inceptum.launcher.system.mds.ModsDirScanner;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModDownload;
import io.gitlab.jfronny.inceptum.launcher.system.source.ModSource;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ModManager {
public static void delete(Instance instance, Mod md) throws IOException {
JFiles.deleteRecursive(md.path());
if (md.imod().isPresent() && Files.exists(md.imod().get())) Files.delete(md.imod().get());
if (md.mod().isPresent()) {
for (String dependency : md.mod().get().dependencies) {
Path dep = instance.modsDir().resolve(dependency);
Mod dmd = instance.mds().get(dep);
if (dmd.mod().isPresent()) {
dmd.mod().get().dependencies.remove(md.path().getFileName().toString());
if (dmd.mod().get().dependencies.isEmpty()) delete(instance, dmd);
else if (dmd.imod().isPresent()) JFiles.writeObject(dmd.imod().get(), dmd.mod().get());
}
}
}
}
public static DownloadMeta download(ModSource ms, Path metaFile, ModsDirScanner mds) throws IOException {
for (Mod value : mds.getMods()) {
if (value.mod().isEmpty()) continue;
for (ModSource source : value.mod().get().sources.keySet()) {
if (ms.equals(source)) {
return new DownloadMeta(new ModDownload(value.mod().get().sha1, value.mod().get().murmur2, value.path()), value.mod().get(), source, metaFile);
}
}
}
ModDownload md = ms.download();
ModDescription manifest = ModDescription.of(md.sha1(), md.murmur2(), ms, mds.getGameVersion());
for (ModSource dependency : ms.getDependencies(mds.getGameVersion())) {
DownloadMeta depMan = download(dependency, metaFile.getParent().resolve(dependency.getShortName() + ModPath.EXT_IMOD), mds);
depMan.description.dependents.add(md.file().getFileName().toString());
manifest.dependencies.add(depMan.download.file().getFileName().toString());
depMan.write();
}
return new DownloadMeta(md, manifest, ms, metaFile);
}
public record DownloadMeta(ModDownload download, ModDescription description, ModSource source, Path metaFile) {
public void write() throws IOException {
JFiles.writeObject(metaFile, description);
}
}
}

View File

@ -0,0 +1,9 @@
package io.gitlab.jfronny.inceptum.launcher.util;
public class Unchecked extends RuntimeException {
public final Exception exception;
public Unchecked(Exception exception) {
this.exception = exception;
}
}

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.util.ignore; package io.gitlab.jfronny.inceptum.launcher.util.gitignore;
import java.util.*; import java.util.*;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.util.ignore; package io.gitlab.jfronny.inceptum.launcher.util.gitignore;
import java.util.List; import java.util.List;
import java.util.function.Predicate; import java.util.function.Predicate;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.util.ignore; package io.gitlab.jfronny.inceptum.launcher.util.gitignore;
import java.io.IOException; import java.io.IOException;
import java.io.UncheckedIOException; import java.io.UncheckedIOException;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.util.ignore; package io.gitlab.jfronny.inceptum.launcher.util.gitignore;
import java.util.function.Function; import java.util.function.Function;
import java.util.regex.*; import java.util.regex.*;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.launcher.util.ignore; package io.gitlab.jfronny.inceptum.launcher.util.gitignore;
public class Replacers { public class Replacers {
public static final Replacer TRAILING_SPACES = new Replacer( public static final Replacer TRAILING_SPACES = new Replacer(

@ -1 +1 @@
Subproject commit fe0b2fdc3361a5a085a316b73e25aec635c50863 Subproject commit c93246e29670814079791a5ebe0e62a824cd52e9