Experimental curseforge export support and more refactoring
This commit is contained in:
parent
c944f42c20
commit
c03813c446
Binary file not shown.
|
@ -35,7 +35,7 @@ allprojects {
|
|||
}
|
||||
|
||||
ext {
|
||||
lwjglVersion = '3.2.3'
|
||||
lwjglVersion = '3.3.0'
|
||||
imguiVersion = '1.86.0'
|
||||
log4jVersion = '2.14.1'
|
||||
flavorProp = project.hasProperty('flavor') ? project.getProperty('flavor') : 'custom'
|
||||
|
@ -67,7 +67,7 @@ dependencies {
|
|||
|
||||
implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
|
||||
|
||||
['', '-opengl', '-glfw'].each {
|
||||
['', '-opengl', '-glfw', '-tinyfd'].each {
|
||||
implementation "org.lwjgl:lwjgl$it:$lwjglVersion"
|
||||
if (flavor == 'windows' || flavor == 'fat') implementation "org.lwjgl:lwjgl$it::natives-windows"
|
||||
if (flavor == 'linux' || flavor == 'fat') implementation "org.lwjgl:lwjgl$it::natives-linux"
|
||||
|
|
|
@ -5,7 +5,7 @@ import io.gitlab.jfronny.inceptum.frontend.cli.Commands;
|
|||
import io.gitlab.jfronny.inceptum.frontend.gui.dialog.AlertWindow;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.dialog.TextBoxWindow;
|
||||
import io.gitlab.jfronny.inceptum.gson.*;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.microsoft.OauthTokenResponse;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.MinecraftArgument;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.Rules;
|
||||
|
@ -24,6 +24,15 @@ public class Inceptum {
|
|||
public static boolean IS_GUI;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (Wrapper.class.getClassLoader() != Inceptum.class.getClassLoader()) {
|
||||
throw new IllegalStateException("Mismatching classloader between two classes. Something is wrong here");
|
||||
}
|
||||
if (args.length > 0 && args[0].equals("wrapper")) {
|
||||
if (WrapperStrap.class.getClassLoader() == Inceptum.class.getClassLoader()) {
|
||||
throw new IllegalStateException("The WrapperStrap classloader does not match the inceptum loader. Are you using the latest wrapper?");
|
||||
}
|
||||
}
|
||||
|
||||
GsonHolder.registerTypeAdapter(MinecraftArgument.class, new MinecraftArgumentDeserializer());
|
||||
GsonHolder.registerTypeAdapter(Rules.class, new RulesDeserializer());
|
||||
GsonHolder.registerTypeAdapter(OauthTokenResponse.class, new OauthTokenResponseDeserializer());
|
||||
|
|
|
@ -5,7 +5,8 @@ import io.gitlab.jfronny.inceptum.frontend.cli.Command;
|
|||
import io.gitlab.jfronny.inceptum.frontend.cli.CommandArgs;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.Config;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
|
@ -165,10 +166,15 @@ public class GitCommand extends Command {
|
|||
}
|
||||
|
||||
public static String getName(String url) throws URISyntaxException {
|
||||
String name;
|
||||
name = new URIish(url).getHumanishName();
|
||||
name = name.replaceAll("^\\.*", "");
|
||||
return name;
|
||||
try {
|
||||
String name;
|
||||
name = new URIish(url).getHumanishName();
|
||||
name = name.replaceAll("^\\.*", "");
|
||||
return name;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new URISyntaxException(url, "Could not extract name");
|
||||
}
|
||||
}
|
||||
|
||||
public static void clone(String url, String name) throws GitAPIException, IOException {
|
||||
|
@ -189,7 +195,7 @@ public class GitCommand extends Command {
|
|||
Utils.deleteRecursive(instanceDir);
|
||||
throw new FileNotFoundException("Invalid repository: Contains no instance.json");
|
||||
}
|
||||
Steps.reDownload(instanceDir, state -> {});
|
||||
Steps.reDownload(instanceDir, Steps.createProcessState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,14 +4,13 @@ import io.gitlab.jfronny.inceptum.Inceptum;
|
|||
import io.gitlab.jfronny.inceptum.frontend.cli.BaseInstanceCommand;
|
||||
import io.gitlab.jfronny.inceptum.frontend.cli.Command;
|
||||
import io.gitlab.jfronny.inceptum.frontend.cli.CommandArgs;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLock;
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.launch.ClientLauncher;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.launch.InstanceLauncher;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLauncher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -85,7 +84,7 @@ public class LaunchCommand extends BaseInstanceCommand {
|
|||
instance.arguments.server.addAll(args.after(0));
|
||||
}
|
||||
try {
|
||||
Steps.reDownload(instanceDir, state -> {});
|
||||
Steps.reDownload(instanceDir, Steps.createProcessState());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -98,7 +97,7 @@ public class LaunchCommand extends BaseInstanceCommand {
|
|||
}
|
||||
else {
|
||||
AccountManager.loadAccounts();
|
||||
ClientLauncher.launch(instanceDir, instance);
|
||||
InstanceLauncher.launchClient(instanceDir, instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import io.gitlab.jfronny.inceptum.frontend.cli.BaseInstanceCommand;
|
|||
import io.gitlab.jfronny.inceptum.frontend.cli.Command;
|
||||
import io.gitlab.jfronny.inceptum.frontend.cli.CommandArgs;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.ModManager;
|
||||
import io.gitlab.jfronny.inceptum.util.ModsDirScanner;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
|
@ -105,7 +105,7 @@ public class ModCommand extends Command {
|
|||
mods.add(p);
|
||||
}
|
||||
ModsDirScanner mds = ModsDirScanner.get(instancePath.resolve("mods"), meta);
|
||||
if (!ignoreDependencies && !mds.scanComplete()) {
|
||||
if (!ignoreDependencies && !mds.isComplete()) {
|
||||
Utils.LOGGER.error("Scanning mods dir to search for dependencies. This might take a while");
|
||||
mds.runOnce((path, mod) -> System.out.println("Scanned " + path));
|
||||
}
|
||||
|
|
|
@ -8,10 +8,11 @@ import io.gitlab.jfronny.inceptum.InceptumGui;
|
|||
import io.gitlab.jfronny.inceptum.model.curseforge.CurseforgeMod;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.ModDescription;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.CurseforgeModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModDownload;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModrinthModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.PathUtil;
|
||||
import io.gitlab.jfronny.inceptum.util.source.CurseforgeModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModDownload;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModrinthModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.modrinth.ModrinthSearchResult;
|
||||
import io.gitlab.jfronny.inceptum.model.modrinth.ModrinthVersion;
|
||||
import io.gitlab.jfronny.inceptum.util.ModsDirScanner;
|
||||
|
@ -131,7 +132,7 @@ public class AddModWindow extends Window {
|
|||
ModrinthVersion finalLatest = latest;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
download(new ModrinthModSource(finalLatest.id), modsDir.resolve((mod.slug == null ? mod.mod_id : mod.slug) + ".imod"), mds).write();
|
||||
download(new ModrinthModSource(finalLatest.id), modsDir.resolve((mod.slug == null ? mod.mod_id : mod.slug) + PathUtil.EXT_IMOD), mds).write();
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not download mod", e);
|
||||
}
|
||||
|
@ -199,7 +200,7 @@ public class AddModWindow extends Window {
|
|||
CurseforgeMod.GameVersionLatestFile finalLatest = latest;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
download(new CurseforgeModSource(mod.id, finalLatest.projectFileId), modsDir.resolve((mod.slug == null ? mod.id : mod.slug) + ".imod"), mds).write();
|
||||
download(new CurseforgeModSource(mod.id, finalLatest.projectFileId), modsDir.resolve((mod.slug == null ? mod.id : mod.slug) + PathUtil.EXT_IMOD), mds).write();
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not download mod", e);
|
||||
}
|
||||
|
@ -235,7 +236,7 @@ public class AddModWindow extends Window {
|
|||
ModDownload md = ms.download();
|
||||
ModDescription manifest = ModDescription.of(md.sha1(), md.murmur2(), ms, mds.getGameVersion());
|
||||
for (ModSource dependency : ms.getDependencies()) {
|
||||
DownloadMeta depMan = download(dependency, metaFile.getParent().resolve(dependency.getShortName() + ".imod"), mds);
|
||||
DownloadMeta depMan = download(dependency, metaFile.getParent().resolve(dependency.getShortName() + PathUtil.EXT_IMOD), mds);
|
||||
depMan.description.dependents.add(md.file().getFileName().toString());
|
||||
manifest.dependencies.add(depMan.download.file().getFileName().toString());
|
||||
depMan.write();
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.dialog.ProcessStateWatcherWindow;
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Steps;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
public class GuiUtil {
|
||||
public static void reload() {
|
||||
try {
|
||||
List<Path> paths = Utils.ls(MetaHolder.INSTANCE_DIR);
|
||||
ProcessState state = Steps.createProcessState().extend(paths.size());
|
||||
InceptumGui.open(new ProcessStateWatcherWindow("Reloading data", "Could not reload resources", state, cToken -> {
|
||||
for (Path path : paths) {
|
||||
Steps.reDownload(path, state);
|
||||
}
|
||||
}, null));
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not reload", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void reload(Path instanceDir) {
|
||||
ProcessState state = Steps.createProcessState();
|
||||
InceptumGui.open(new ProcessStateWatcherWindow("Reloading data", "Could not reload resources", state, cToken -> {
|
||||
Steps.reDownload(instanceDir, state);
|
||||
}, null));
|
||||
}
|
||||
|
||||
public static void createInstance(SetupStepInfo state) {
|
||||
ProcessState pState = Steps.createProcessState();
|
||||
pState.updateStep("Starting install process");
|
||||
InceptumGui.open(new ProcessStateWatcherWindow("Creating Instance", "Could not create instance", pState, cToken -> {
|
||||
for (Step step : Steps.STEPS) {
|
||||
if (cToken.get()) return;
|
||||
step.execute(state, cToken);
|
||||
}
|
||||
Inceptum.showInfo("The instance was successfully created. You can now launch it using the main menu", "Successfully installed");
|
||||
}, () -> {
|
||||
try {
|
||||
Utils.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(state.name()));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not delete instance dir", e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
|
||||
import imgui.ImGui;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class InstanceCreateProcessWindow extends Window {
|
||||
private final SetupStepInfo stepInfo;
|
||||
private final AtomicBoolean finalize = new AtomicBoolean(false);
|
||||
|
||||
public InstanceCreateProcessWindow(SetupStepInfo stepInfo) {
|
||||
super("Creating Instance");
|
||||
this.stepInfo = stepInfo;
|
||||
new Thread(this::creationThread).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (finalize.get()) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
ImGui.textUnformatted(stepInfo.currentState().get());
|
||||
if (ImGui.button("Cancel")) finalize.set(true);
|
||||
}
|
||||
|
||||
private void creationThread() {
|
||||
if (Files.exists(MetaHolder.INSTANCE_DIR.resolve(stepInfo.name()))) {
|
||||
finalize.set(true);
|
||||
return;
|
||||
}
|
||||
Utils.LOGGER.info("Starting install process");
|
||||
try {
|
||||
for (Step step : Steps.STEPS) {
|
||||
if (finalize.get()) {
|
||||
cleanUp();
|
||||
return;
|
||||
}
|
||||
step.execute(stepInfo, finalize);
|
||||
}
|
||||
finalize.set(true);
|
||||
Inceptum.showInfo("The instance was successfully created. You can now launch it using the main menu", "Successfully installed");
|
||||
close();
|
||||
} catch (Throwable e) {
|
||||
Inceptum.showError("Could not create the instance", e);
|
||||
close();
|
||||
cleanUp();
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanUp() {
|
||||
try {
|
||||
Utils.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(stepInfo.name()));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not delete instance dir", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
finalize.set(true);
|
||||
}
|
||||
}
|
|
@ -7,14 +7,20 @@ import imgui.type.ImString;
|
|||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.control.InstanceManageControls;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.dialog.ProcessStateWatcherWindow;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.Config;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.*;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.Status;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.IndexDiff;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -179,17 +185,9 @@ public class InstanceEditWindow extends Window {
|
|||
}
|
||||
}
|
||||
if (filterUpdates.get() && !updatesFound) continue;
|
||||
final String disabledSuffix = ".disabled";
|
||||
final String imodDisabledSuffix = ".disabled.imod";
|
||||
String fName = mod.path().getFileName().toString();
|
||||
boolean wasEnabled = !fName.endsWith(disabledSuffix) && !fName.endsWith(imodDisabledSuffix);
|
||||
boolean wasEnabled = PathUtil.isEnabled(mod.path());
|
||||
if (ImGui.checkbox("##" + mod.getName(), wasEnabled)) {
|
||||
if (fName.endsWith(disabledSuffix))
|
||||
fName = fName.substring(0, fName.length() - disabledSuffix.length());
|
||||
if (fName.endsWith(imodDisabledSuffix))
|
||||
fName = fName.substring(0, fName.length() - imodDisabledSuffix.length()) + ".imod";
|
||||
if (wasEnabled) fName += fName.endsWith(".imod") ? imodDisabledSuffix : disabledSuffix;
|
||||
Path newSel = mod.path().getParent().resolve(fName);
|
||||
Path newSel = PathUtil.toggle(mod.path());
|
||||
try {
|
||||
Files.move(mod.path(), newSel);
|
||||
if (mod.path().equals(selected)) selected = newSel;
|
||||
|
@ -230,7 +228,7 @@ public class InstanceEditWindow extends Window {
|
|||
ImGui.sameLine();
|
||||
if (ImGui.button("Update to " + ms.get().getVersion())) {
|
||||
try {
|
||||
Path imodPath = md.imod().isPresent() ? md.imod().get() : path.resolve("mods").resolve(ms.get().getShortName() + ".imod");
|
||||
Path imodPath = md.imod().isPresent() ? md.imod().get() : path.resolve("mods").resolve(ms.get().getShortName() + PathUtil.EXT_IMOD);
|
||||
AddModWindow.DownloadMeta dm = AddModWindow.download(ms.get(), imodPath, mds);
|
||||
Files.delete(md.path());
|
||||
if (md.imod().isPresent() && Files.exists(md.imod().get()))
|
||||
|
@ -266,26 +264,42 @@ public class InstanceEditWindow extends Window {
|
|||
ImGui.endTabItem();
|
||||
}
|
||||
if (git != null && ImGui.beginTabItem("Git")) {
|
||||
if (ImGui.button("Commit")) {
|
||||
try {
|
||||
Inceptum.getInput("Commit message", "Commit at t" + System.currentTimeMillis(), message -> {
|
||||
try {
|
||||
git.commit()
|
||||
.setAll(true)
|
||||
.setMessage(message)
|
||||
.setSign(ConfigHolder.CONFIG.git.signCommits)
|
||||
.setAuthor(ConfigHolder.CONFIG.git.commitUsername, ConfigHolder.CONFIG.git.commitMail)
|
||||
.setCredentialsProvider(credentialsProvider)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
Inceptum.showError("Could not commit", e);
|
||||
}
|
||||
},() -> {});
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not show dialog", e);
|
||||
}
|
||||
Status status = null;
|
||||
try {
|
||||
status = git.status().call();
|
||||
} catch (GitAPIException e) {
|
||||
Utils.LOGGER.error("Could not check repo status", e);
|
||||
}
|
||||
|
||||
if (status != null && status.isClean()) {
|
||||
ImGui.text("There are un-committed changes");
|
||||
for (String change : status.getUncommittedChanges()) {
|
||||
ImGui.bulletText(change);
|
||||
}
|
||||
for (String s : status.getUntracked()) {
|
||||
ImGui.bulletText(s);
|
||||
}
|
||||
if (ImGui.button("Commit")) {
|
||||
try {
|
||||
Inceptum.getInput("Commit message", "Commit at t" + System.currentTimeMillis(), message -> {
|
||||
try {
|
||||
git.commit()
|
||||
.setAll(true)
|
||||
.setMessage(message)
|
||||
.setSign(ConfigHolder.CONFIG.git.signCommits)
|
||||
.setAuthor(ConfigHolder.CONFIG.git.commitUsername, ConfigHolder.CONFIG.git.commitMail)
|
||||
.setCredentialsProvider(credentialsProvider)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
Inceptum.showError("Could not commit", e);
|
||||
}
|
||||
},() -> {});
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not show dialog", e);
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button("Push")) {
|
||||
try {
|
||||
git.push()
|
||||
|
@ -336,6 +350,30 @@ public class InstanceEditWindow extends Window {
|
|||
}
|
||||
ImGui.endTabItem();
|
||||
}
|
||||
if (ImGui.beginTabItem("Export")) {
|
||||
if (mds.isComplete()) {
|
||||
if (ImGui.button("CurseForge")) {
|
||||
try (MemoryStack stack = MemoryStack.stackPush()) {
|
||||
PointerBuffer aFilterPatterns = stack.mallocPointer(2);
|
||||
aFilterPatterns.put(stack.UTF8("*.zip"));
|
||||
aFilterPatterns.flip();
|
||||
String p = TinyFileDialogs.tinyfd_saveFileDialog("Export Pack", "", aFilterPatterns, "CurseForge packs (*.zip)");
|
||||
if (p != null) {
|
||||
ProcessState state = new ProcessState(InstanceExporter.STEP_COUNT, "Initializing...");
|
||||
InceptumGui.open(new ProcessStateWatcherWindow("Exporting", "Could not export pack", state, cToken -> {
|
||||
Path exportPath = Path.of(p);
|
||||
InstanceExporter.exportCurseZip(state, path, instance, mds, git, exportPath);
|
||||
Inceptum.showInfo(path.getFileName().toString() + " has been successfully exported to " + exportPath, "Successfully exported");
|
||||
}, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImGui.text("The mods directory scan must be completed.\nThe progress for this can be observed in the mods tab");
|
||||
}
|
||||
ImGui.endTabItem();
|
||||
}
|
||||
ImGui.endTabBar();
|
||||
}
|
||||
}
|
||||
|
@ -357,7 +395,7 @@ public class InstanceEditWindow extends Window {
|
|||
super.close();
|
||||
if (git != null) git.close();
|
||||
if (reDownload) {
|
||||
InceptumGui.open(new ReDownloadWatcherWindow(path));
|
||||
GuiUtil.reload(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ import imgui.type.ImInt;
|
|||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.control.InstanceView;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.MapAppender;
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
|
@ -46,16 +45,7 @@ public class MainWindow extends Window {
|
|||
Utils.clearDirectory(MetaHolder.LIBRARIES_DIR, path -> !path.startsWith(MetaHolder.LIBRARIES_DIR.resolve("io/gitlab/jfronny")));
|
||||
Utils.clearDirectory(MetaHolder.NATIVES_DIR, path -> !path.endsWith("forceload"));
|
||||
Utils.clearDirectory(MetaHolder.CACHE_DIR);
|
||||
ReDownloadWatcherWindow window = new ReDownloadWatcherWindow("Re-Downloading");
|
||||
InceptumGui.open(window);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Steps.reDownload(window.getConsumer());
|
||||
window.close();
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not execute refresh task", e);
|
||||
}
|
||||
}).start();
|
||||
GuiUtil.reload();
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not execute refresh task", e);
|
||||
}
|
||||
|
|
|
@ -5,19 +5,20 @@ import imgui.type.ImString;
|
|||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.frontend.cli.commands.GitCommand;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.control.InstanceManageControls;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Steps;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class NewInstanceWindow extends Window {
|
||||
private final InstanceManageControls imc = new InstanceManageControls(null);
|
||||
private final ImString inceptumRepo = new ImString(InceptumGui.INPUT_FIELD_LENGTH);
|
||||
private final ImString inceptumName = new ImString(InceptumGui.INPUT_FIELD_LENGTH);
|
||||
private String inceptumNamePrev = "";
|
||||
public NewInstanceWindow() {
|
||||
super("New Instance");
|
||||
}
|
||||
|
@ -30,10 +31,10 @@ public class NewInstanceWindow extends Window {
|
|||
imc.versionBox(ver -> {});
|
||||
imc.nameBox("OK", name -> {
|
||||
try {
|
||||
InceptumGui.open(new InstanceCreateProcessWindow(new SetupStepInfo(imc.getVersionInfo(),
|
||||
GuiUtil.createInstance(new SetupStepInfo(imc.getVersionInfo(),
|
||||
imc.getLoaderInfo(),
|
||||
name,
|
||||
new AtomicReference<>("Initializing"))));
|
||||
Steps.createProcessState()));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not initialize instance creation", e);
|
||||
}
|
||||
|
@ -42,9 +43,11 @@ public class NewInstanceWindow extends Window {
|
|||
ImGui.endTabItem();
|
||||
}
|
||||
if (ImGui.beginTabItem("Inceptum")) {
|
||||
if (ImGui.inputTextWithHint("URL", "Repo to download", inceptumRepo) && (inceptumName.isEmpty() || inceptumName.get().isEmpty())) {
|
||||
if (ImGui.inputTextWithHint("URL", "Repo to download", inceptumRepo)
|
||||
&& (inceptumName.isEmpty() || inceptumName.get().isEmpty() || inceptumName.get().equals(inceptumNamePrev))) {
|
||||
try {
|
||||
inceptumName.set(GitCommand.CloneCommand.getName(inceptumRepo.get()));
|
||||
inceptumNamePrev = inceptumName.get();
|
||||
} catch (URISyntaxException ignored) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
|
||||
import imgui.ImGui;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Steps;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ReDownloadWatcherWindow extends Window {
|
||||
private SetupStepInfo info;
|
||||
public ReDownloadWatcherWindow(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public ReDownloadWatcherWindow(Path reDownloadPath) {
|
||||
this("Reloading data");
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Steps.reDownload(reDownloadPath, getConsumer());
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not reload resources", e);
|
||||
}
|
||||
close();
|
||||
}).start();
|
||||
}
|
||||
|
||||
public Consumer<SetupStepInfo> getConsumer() {
|
||||
return newInfo -> info = newInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (info == null) ImGui.text("Reloading");
|
||||
else ImGui.textUnformatted(info.currentState().get());
|
||||
}
|
||||
}
|
|
@ -3,12 +3,12 @@ package io.gitlab.jfronny.inceptum.frontend.gui.control;
|
|||
import imgui.ImGui;
|
||||
import imgui.flag.ImGuiTableFlags;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Steps;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLock;
|
||||
import io.gitlab.jfronny.inceptum.util.launch.ClientLauncher;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.InstanceEditWindow;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLauncher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -48,11 +48,11 @@ public class InstanceView {
|
|||
if (runDisabled) ImGui.beginDisabled();
|
||||
if (ImGui.button(path.getFileName().toString())) {
|
||||
try {
|
||||
Steps.reDownload(path, state -> {});
|
||||
Steps.reDownload(path, Steps.createProcessState());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ClientLauncher.launch(path, instance);
|
||||
InstanceLauncher.launchClient(path, instance);
|
||||
}
|
||||
if (runDisabled) ImGui.endDisabled();
|
||||
ImGui.tableNextColumn();
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.dialog;
|
||||
|
||||
import imgui.ImGui;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import io.gitlab.jfronny.inceptum.util.lambda.ThrowingConsumer;
|
||||
import org.eclipse.jgit.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class ProcessStateWatcherWindow extends Window {
|
||||
private final ProcessState state;
|
||||
private final Runnable cancel;
|
||||
private final AtomicBoolean canceled = new AtomicBoolean(false);
|
||||
private boolean finished;
|
||||
|
||||
public ProcessStateWatcherWindow(String title, String errorMessage, ProcessState state, ThrowingConsumer<AtomicBoolean, ?> executor, @Nullable Runnable cancel) {
|
||||
super(title);
|
||||
this.state = state;
|
||||
this.cancel = cancel;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
executor.consume(canceled);
|
||||
if (canceled.get()) cancel.run();
|
||||
finished = true;
|
||||
} catch (Throwable e) {
|
||||
Inceptum.showError(errorMessage, e);
|
||||
}
|
||||
close();
|
||||
}).start();
|
||||
}
|
||||
|
||||
public ProcessState getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
ImGui.progressBar(state.getProgress());
|
||||
ImGui.textUnformatted(state.getCurrentStep());
|
||||
if (cancel != null && ImGui.button("Cancel")) {
|
||||
canceled.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (finished) {
|
||||
super.close();
|
||||
}
|
||||
else if (cancel != null) {
|
||||
canceled.set(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ package io.gitlab.jfronny.inceptum.gson;
|
|||
|
||||
import com.google.gson.*;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedHashMap;
|
||||
|
|
|
@ -2,10 +2,10 @@ package io.gitlab.jfronny.inceptum.gson;
|
|||
|
||||
import com.google.gson.*;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.CurseforgeModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.DirectModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModrinthModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.CurseforgeModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.DirectModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModrinthModSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package io.gitlab.jfronny.inceptum.model.curseforge;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class CurseforgeModpackManifest {
|
||||
public Minecraft minecraft;
|
||||
public String manifestType;
|
||||
public Integer manifestVersion;
|
||||
public String name;
|
||||
public String version;
|
||||
public String author;
|
||||
public Set<File> files;
|
||||
public String overrides;
|
||||
|
||||
public static class Minecraft {
|
||||
public String version;
|
||||
public Set<ModLoader> modLoaders;
|
||||
|
||||
public static class ModLoader {
|
||||
public String id;
|
||||
public Boolean primary;
|
||||
}
|
||||
}
|
||||
|
||||
public static class File {
|
||||
public Integer projectID;
|
||||
public Integer fileID;
|
||||
public Boolean required;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.curseforge.CurseforgeFingerprint;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.CurseforgeModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModrinthModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.CurseforgeModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModrinthModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.HashUtils;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.api.CurseforgeApi;
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package io.gitlab.jfronny.inceptum.util;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.curseforge.CurseforgeModpackManifest;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.util.source.CurseforgeModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class InstanceExporter {
|
||||
public static final int STEP_COUNT = 3;
|
||||
private static final String OVERRIDES_DIR_DEFAULT = "overrides";
|
||||
|
||||
public static void exportCurseZip(ProcessState state, Path instanceDir, InstanceMeta meta, ModsDirScanner mds, Git git, Path exportPath) throws IOException, URISyntaxException, GitAPIException {
|
||||
if (Files.exists(exportPath)) Files.delete(exportPath);
|
||||
try (FileSystem fs = Utils.openZipFile(exportPath, true)) {
|
||||
state.incrementStep("Preparing basic manifest");
|
||||
CurseforgeModpackManifest manifest = new CurseforgeModpackManifest();
|
||||
manifest.minecraft = new CurseforgeModpackManifest.Minecraft();
|
||||
manifest.minecraft.version = meta.getMinecraftVersion();
|
||||
manifest.minecraft.modLoaders = new LinkedHashSet<>();
|
||||
if (meta.isFabric()) {
|
||||
CurseforgeModpackManifest.Minecraft.ModLoader loader = new CurseforgeModpackManifest.Minecraft.ModLoader();
|
||||
loader.id = "fabric-" + meta.getLoaderVersion();
|
||||
loader.primary = true;
|
||||
manifest.minecraft.modLoaders.add(loader);
|
||||
}
|
||||
manifest.manifestType = "minecraftModpack";
|
||||
manifest.manifestVersion = 1;
|
||||
manifest.name = instanceDir.getFileName().toString();
|
||||
manifest.version = git.log().setMaxCount(1).call().iterator().next().getId().getName();
|
||||
manifest.author = ConfigHolder.CONFIG.git.commitUsername;
|
||||
manifest.overrides = OVERRIDES_DIR_DEFAULT;
|
||||
Path overrides = fs.getPath(OVERRIDES_DIR_DEFAULT);
|
||||
Files.createDirectories(overrides);
|
||||
if (meta.isFabric()) {
|
||||
state.incrementStep("Adding mods");
|
||||
manifest.files = new LinkedHashSet<>();
|
||||
if (!mds.isComplete()) throw new IOException("Mods dir scan is not yet completed");
|
||||
modsLoop: for (ModsDirScanner.IWModDescription mod : mds.getMods()) {
|
||||
if (!PathUtil.isEnabled(mod.path())) return;
|
||||
state.updateStep(mod.path().toString());
|
||||
if (PathUtil.isImod(mod.path())) {
|
||||
Set<ModSource> sources = mod.mod().get().sources.keySet();
|
||||
for (ModSource source : sources) {
|
||||
if (source instanceof CurseforgeModSource cms) {
|
||||
CurseforgeModpackManifest.File f = new CurseforgeModpackManifest.File();
|
||||
f.projectID = cms.getProjectId();
|
||||
f.fileID = cms.getFileId();
|
||||
f.required = true;
|
||||
manifest.files.add(f);
|
||||
continue modsLoop;
|
||||
}
|
||||
}
|
||||
// Not available on CF
|
||||
for (ModSource source : sources) {
|
||||
Path jarPath = source.getJarPath();
|
||||
Files.copy(jarPath, jarPath.resolve(mod.path().getFileName().toString()));
|
||||
continue modsLoop;
|
||||
}
|
||||
}
|
||||
Path md = overrides.resolve("mods");
|
||||
Files.createDirectories(md);
|
||||
Files.copy(mod.path(), md.resolve(mod.path().getFileName().toString()));
|
||||
}
|
||||
}
|
||||
state.incrementStep("Adding files");
|
||||
List<Path> discovered = new ArrayList<>();
|
||||
try (TreeWalk treeWalk = new TreeWalk(git.getRepository())) {
|
||||
treeWalk.addTree(new FileTreeIterator(git.getRepository()));
|
||||
treeWalk.setRecursive(false);
|
||||
while (treeWalk.next()) {
|
||||
if (treeWalk.getPathString().startsWith("mods")) continue;
|
||||
discovered.add(instanceDir.resolve(treeWalk.getPathString()));
|
||||
}
|
||||
}
|
||||
for (Path l : discovered) {
|
||||
String fn = l.getFileName().toString();
|
||||
if (fn.equals("mods") || fn.startsWith(".")) continue;
|
||||
state.updateStep(fn);
|
||||
Path target = overrides.resolve(fn);
|
||||
if (Files.isDirectory(l)) {
|
||||
Utils.copyContent(l, target);
|
||||
}
|
||||
else Files.copy(l, target);
|
||||
}
|
||||
Utils.writeObject(fs.getPath("manifest.json"), manifest);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +1,17 @@
|
|||
package io.gitlab.jfronny.inceptum.util.launch;
|
||||
package io.gitlab.jfronny.inceptum.util;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.steps.DownloadLibrariesStep;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.ArtifactInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.ModDescription;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.install.steps.DownloadLibrariesStep;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.MinecraftArgument;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionsListInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.*;
|
||||
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.McApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AuthInfo;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -24,6 +25,38 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class InstanceLauncher {
|
||||
public static void launchClient(Path path, InstanceMeta instance) {
|
||||
if (AccountManager.accountMissing() && ConfigHolder.CONFIG.enforceAccount) {
|
||||
Inceptum.showError("You have not set up an account.\nDoing so is required to play Minecraft", "Not authenticated");
|
||||
return;
|
||||
}
|
||||
AuthInfo authInfo = AccountManager.getSelectedAccount();
|
||||
if (authInfo.equals(AccountManager.NULL_AUTH)) {
|
||||
try {
|
||||
String sysUser = System.getProperty("user.name");
|
||||
if (ConfigHolder.CONFIG.offlineAccountLastName == null)
|
||||
ConfigHolder.CONFIG.offlineAccountLastName = sysUser;
|
||||
Inceptum.getInput("User name", ConfigHolder.CONFIG.offlineAccountLastName, name -> {
|
||||
ConfigHolder.CONFIG.offlineAccountLastName = name.equals(sysUser) ? null : name;
|
||||
ConfigHolder.saveConfig();
|
||||
AuthInfo infoNew = new AuthInfo(name, authInfo.uuid(), authInfo.accessToken(), authInfo.userType());
|
||||
launchClient(path, instance, infoNew);
|
||||
}, () -> {});
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Failed to request input", e);
|
||||
}
|
||||
}
|
||||
else launchClient(path, instance, authInfo);
|
||||
}
|
||||
|
||||
private static void launchClient(Path path, InstanceMeta instance, AuthInfo authInfo) {
|
||||
try {
|
||||
launch(path, instance, LaunchType.Client, false, authInfo);
|
||||
} catch (LaunchException | IOException e) {
|
||||
Inceptum.showError("Could not launch client", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void launch(Path instancePath, InstanceMeta instance, LaunchType launchType, boolean restart, AuthInfo authInfo) throws LaunchException, IOException {
|
||||
if (authInfo == null) throw new LaunchException("authInfo is null");
|
||||
VersionsListInfo versionDataSimple = getVersion(instance.getMinecraftVersion());
|
||||
|
@ -33,7 +66,7 @@ public class InstanceLauncher {
|
|||
FabricMetaApi.addFabric(versionInfo, instance.getLoaderVersion(), launchType.fabricMetaType);
|
||||
}
|
||||
// Ensure libs/assets are present
|
||||
DownloadLibrariesStep.execute(versionInfo, new AtomicBoolean(false), new AtomicReference<>());
|
||||
DownloadLibrariesStep.execute(versionInfo, new AtomicBoolean(false), new ProcessState());
|
||||
// Prepare arguments
|
||||
List<String> args = new LinkedList<>();
|
||||
// JVM path
|
||||
|
@ -62,10 +95,7 @@ public class InstanceLauncher {
|
|||
StringBuilder fabricAddMods = new StringBuilder("-Dfabric.addMods=");
|
||||
Path mods = instancePath.resolve("mods");
|
||||
if (Files.exists(mods)) {
|
||||
for (Path imod : Utils.ls(mods, path -> {
|
||||
String fn = path.getFileName().toString();
|
||||
return fn.endsWith(".imod") && !fn.endsWith(".disabled.imod");
|
||||
})) {
|
||||
for (Path imod : Utils.ls(mods, path -> PathUtil.isImod(path) && PathUtil.isEnabled(path))) {
|
||||
String fn = imod.getFileName().toString();
|
||||
if (Files.exists(imod.getParent().resolve(fn.substring(0, fn.length() - 5))))
|
||||
continue;
|
|
@ -1,9 +1,10 @@
|
|||
package io.gitlab.jfronny.inceptum.util;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import io.gitlab.jfronny.inceptum.model.fabric.FabricModJson;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.ModDescription;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.lambda.ThrowingConsumer;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
@ -43,7 +44,7 @@ public class ModsDirScanner implements Closeable {
|
|||
return mds;
|
||||
}
|
||||
|
||||
public boolean scanComplete() {
|
||||
public boolean isComplete() {
|
||||
if (!Files.isDirectory(modsDir)) return true;
|
||||
try {
|
||||
for (Path path : Utils.ls(modsDir)) {
|
||||
|
@ -68,8 +69,7 @@ public class ModsDirScanner implements Closeable {
|
|||
Set<IWModDescription> mods = new TreeSet<>();
|
||||
if (Files.isDirectory(modsDir)) {
|
||||
for (Path path : Utils.ls(modsDir)) {
|
||||
String fn = path.getFileName().toString();
|
||||
if (fn.endsWith(".imod") && Files.exists(path.getParent().resolve(fn.substring(0, fn.length() - 5))))
|
||||
if (PathUtil.isImod(path) && Files.exists(PathUtil.trimImod(path)))
|
||||
continue;
|
||||
mods.add(get(path));
|
||||
}
|
||||
|
@ -107,55 +107,63 @@ public class ModsDirScanner implements Closeable {
|
|||
return;
|
||||
}
|
||||
for (Path mods : Utils.ls(modsDir)) {
|
||||
if (!Files.exists(mods)) continue;
|
||||
if (disposed) return;
|
||||
if (Files.isDirectory(mods)) {
|
||||
discovered.accept(mods, new IWModDescription(mods));
|
||||
scannedPaths.add(mods);
|
||||
} else {
|
||||
if (mods.toString().endsWith(".jar") || mods.toString().endsWith(".jar.disabled")) {
|
||||
final var imod = new Object() {
|
||||
Path i = mods.getParent().resolve(mods.getFileName() + ".imod");
|
||||
ModDescription md;
|
||||
};
|
||||
// mod description
|
||||
if (!Files.exists(imod.i)) {
|
||||
Utils.writeObject(imod.i, ModDescription.of(mods));
|
||||
}
|
||||
imod.md = Utils.loadObject(imod.i, ModDescription.class);
|
||||
evaluateSources(imod.md, mods, imod.i, newImod -> {
|
||||
imod.i = newImod;
|
||||
imod.md = Utils.loadObject(imod.i, ModDescription.class);
|
||||
});
|
||||
discovered.accept(imod.i, new IWModDescription(mods, Optional.of(imod.md), getFmj(mods, imod.md), Optional.of(imod.i)));
|
||||
scannedPaths.add(mods);
|
||||
}
|
||||
else if (mods.toString().endsWith(".imod") || mods.toString().endsWith(".imod.disabled")) {
|
||||
String fn = mods.getFileName().toString();
|
||||
Path modFile = mods.getParent().resolve(fn.substring(0, fn.length() - 5));
|
||||
final var imod = new Object() {
|
||||
Path i = mods;
|
||||
ModDescription md = Utils.loadObject(mods, ModDescription.class);
|
||||
};
|
||||
evaluateSources(imod.md, modFile, imod.i, newImod -> {
|
||||
imod.i = newImod;
|
||||
imod.md = Utils.loadObject(imod.i, ModDescription.class);
|
||||
});
|
||||
discovered.accept(imod.i, new IWModDescription(imod.i, Optional.of(imod.md), getFmj(modFile, imod.md), Optional.of(imod.i)));
|
||||
scannedPaths.add(mods);
|
||||
}
|
||||
else {
|
||||
discovered.accept(mods, new IWModDescription(mods));
|
||||
scannedPaths.add(mods);
|
||||
}
|
||||
}
|
||||
scanFile(mods, discovered);
|
||||
}
|
||||
Thread.sleep(100);
|
||||
} catch (IOException | URISyntaxException | InterruptedException e) {
|
||||
} catch (IOException | InterruptedException e) {
|
||||
Utils.LOGGER.error("Could not list mods", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanFile(Path file, BiConsumer<Path, IWModDescription> discovered) {
|
||||
if (!Files.exists(file)) return;
|
||||
if (Files.isDirectory(file)) {
|
||||
discovered.accept(file, new IWModDescription(file));
|
||||
scannedPaths.add(file);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (PathUtil.isJar(file)) {
|
||||
final var imod = new Object() {
|
||||
Path i = file.getParent().resolve(file.getFileName() + PathUtil.EXT_IMOD);
|
||||
ModDescription md;
|
||||
};
|
||||
// mod description
|
||||
if (!Files.exists(imod.i)) {
|
||||
Utils.writeObject(imod.i, ModDescription.of(file));
|
||||
}
|
||||
imod.md = Utils.loadObject(imod.i, ModDescription.class);
|
||||
evaluateSources(imod.md, file, imod.i, newImod -> {
|
||||
imod.i = newImod;
|
||||
imod.md = Utils.loadObject(imod.i, ModDescription.class);
|
||||
});
|
||||
discovered.accept(imod.i, new IWModDescription(file, Optional.of(imod.md), getFmj(file, imod.md), Optional.of(imod.i)));
|
||||
scannedPaths.add(file);
|
||||
return;
|
||||
}
|
||||
if (PathUtil.isImod(file)) {
|
||||
String fn = file.getFileName().toString();
|
||||
Path modFile = file.getParent().resolve(fn.substring(0, fn.length() - 5));
|
||||
final var imod = new Object() {
|
||||
Path i = file;
|
||||
ModDescription md = Utils.loadObject(file, ModDescription.class);
|
||||
};
|
||||
evaluateSources(imod.md, modFile, imod.i, newImod -> {
|
||||
imod.i = newImod;
|
||||
imod.md = Utils.loadObject(imod.i, ModDescription.class);
|
||||
});
|
||||
discovered.accept(imod.i, new IWModDescription(imod.i, Optional.of(imod.md), getFmj(modFile, imod.md), Optional.of(imod.i)));
|
||||
scannedPaths.add(file);
|
||||
return;
|
||||
}
|
||||
discovered.accept(file, new IWModDescription(file));
|
||||
scannedPaths.add(file);
|
||||
} catch (IOException | URISyntaxException | JsonParseException 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 {
|
||||
boolean modified = false;
|
||||
if (md.initialize(getGameVersion())) {
|
||||
|
@ -170,7 +178,7 @@ public class ModsDirScanner implements Closeable {
|
|||
}
|
||||
if (selectedSource != null && Files.exists(modFile)) {
|
||||
Files.delete(modFile);
|
||||
Path newImod = imodFile.getParent().resolve(selectedSource.getShortName() + ".imod");
|
||||
Path newImod = imodFile.getParent().resolve(selectedSource.getShortName() + PathUtil.EXT_IMOD);
|
||||
Files.move(imodFile, newImod);
|
||||
imodFile = newImod;
|
||||
modified = true;
|
||||
|
@ -241,9 +249,7 @@ public class ModsDirScanner implements Closeable {
|
|||
this(path,
|
||||
Files.isDirectory(path) ? Optional.empty() : Optional.of(ModDescription.of(path)),
|
||||
Optional.empty(),
|
||||
Files.exists(path.getParent().resolve(path.getFileName().toString() + ".imod"))
|
||||
? Optional.of(path.getParent().resolve(path.getFileName().toString() + ".imod"))
|
||||
: Optional.empty());
|
||||
Files.exists(PathUtil.appendImod(path)) ? Optional.of(PathUtil.appendImod(path)) : Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package io.gitlab.jfronny.inceptum.util;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class PathUtil {
|
||||
public static final String EXT_DISABLED = ".disabled";
|
||||
public static final String EXT_IMOD = ".imod";
|
||||
public static final String EXT_IMOD_DISABLED2 = EXT_DISABLED + EXT_IMOD;
|
||||
public static final String EXT_IMOD_DISABLED = EXT_IMOD + EXT_DISABLED;
|
||||
public static final String EXT_JAR = ".jar";
|
||||
public static final String EXT_JAR_DISABLED = EXT_JAR + EXT_DISABLED;
|
||||
|
||||
public static boolean isImod(Path p) {
|
||||
return fn(p).endsWith(EXT_IMOD) || fn(p).endsWith(EXT_IMOD_DISABLED);
|
||||
}
|
||||
|
||||
public static Path trimImod(Path p) {
|
||||
String fileName = fn(p);
|
||||
fileName = fileName.endsWith(EXT_IMOD_DISABLED)
|
||||
? fileName.substring(0, fileName.length() - EXT_IMOD_DISABLED.length())
|
||||
: fileName.endsWith(EXT_IMOD_DISABLED2)
|
||||
? fileName.substring(0, fileName.length() - EXT_IMOD_DISABLED2.length())
|
||||
: fileName.substring(0, fileName.length() - EXT_IMOD.length());
|
||||
return p.getParent().resolve(fileName);
|
||||
}
|
||||
|
||||
public static Path appendImod(Path p) {
|
||||
return p.getParent().resolve(fn(p) + EXT_IMOD);
|
||||
}
|
||||
|
||||
public static boolean isJar(Path p) {
|
||||
return fn(p).endsWith(EXT_JAR) || fn(p).endsWith(EXT_JAR_DISABLED);
|
||||
}
|
||||
|
||||
public static boolean isEnabled(Path p) {
|
||||
return !fn(p).endsWith(EXT_DISABLED) && !fn(p).endsWith(EXT_IMOD_DISABLED2);
|
||||
}
|
||||
|
||||
public static Path enable(Path p) {
|
||||
String fileName = fn(p);
|
||||
fileName = fileName.endsWith(EXT_IMOD_DISABLED2)
|
||||
? fileName.substring(0, fileName.length() - EXT_IMOD_DISABLED2.length())
|
||||
: fileName.substring(0, fileName.length() - EXT_DISABLED.length());
|
||||
return p.getParent().resolve(fileName);
|
||||
}
|
||||
|
||||
public static Path disable(Path p) {
|
||||
String fileName = fn(p);
|
||||
fileName = fileName.endsWith(EXT_IMOD)
|
||||
? fileName.substring(0, fileName.length() - EXT_IMOD.length()) + EXT_IMOD_DISABLED2
|
||||
: fileName + EXT_DISABLED;
|
||||
return p.getParent().resolve(fileName);
|
||||
}
|
||||
|
||||
public static Path toggle(Path p) {
|
||||
return isEnabled(p) ? disable(p) : enable(p);
|
||||
}
|
||||
|
||||
private static String fn(Path p) {
|
||||
return p.getFileName().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package io.gitlab.jfronny.inceptum.util;
|
||||
|
||||
public class ProcessState {
|
||||
private final int maxSteps;
|
||||
private int stepIndex;
|
||||
private String stepDescription;
|
||||
|
||||
public ProcessState() {
|
||||
this(0, "");
|
||||
}
|
||||
|
||||
public ProcessState(int maxSteps, String defaultText) {
|
||||
this(maxSteps, defaultText, 0);
|
||||
}
|
||||
|
||||
private ProcessState(int maxSteps, String stepDescription, int stepIndex) {
|
||||
if (maxSteps < 0) throw new IllegalArgumentException("maxSteps must be a positive integer");
|
||||
this.maxSteps = maxSteps;
|
||||
this.stepIndex = stepIndex;
|
||||
this.stepDescription = stepDescription;
|
||||
}
|
||||
|
||||
public ProcessState extend(int multiplier) {
|
||||
return new ProcessState(maxSteps * multiplier, stepDescription, stepIndex);
|
||||
}
|
||||
|
||||
public void incrementStep(String description) {
|
||||
this.stepIndex++;
|
||||
updateStep(description);
|
||||
}
|
||||
|
||||
public void updateStep(String description) {
|
||||
this.stepDescription = description;
|
||||
Utils.LOGGER.info(description);
|
||||
}
|
||||
|
||||
public String getCurrentStep() {
|
||||
return stepDescription;
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
return ((float)stepIndex) / maxSteps;
|
||||
}
|
||||
}
|
|
@ -1,17 +1,15 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install;
|
||||
package io.gitlab.jfronny.inceptum.util.install;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public record SetupStepInfo(VersionInfo version,
|
||||
LoaderInfo loader,
|
||||
String name,
|
||||
AtomicReference<String> currentState) {
|
||||
ProcessState currentState) {
|
||||
public void setState(String state) {
|
||||
currentState.set(state);
|
||||
Utils.LOGGER.info(state);
|
||||
currentState.updateStep(state);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install;
|
||||
package io.gitlab.jfronny.inceptum.util.install;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
@ -1,16 +1,17 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install;
|
||||
package io.gitlab.jfronny.inceptum.util.install;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.steps.*;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionsListInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLock;
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.McApi;
|
||||
import io.gitlab.jfronny.inceptum.util.install.steps.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
@ -18,8 +19,6 @@ import java.util.LinkedHashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Steps {
|
||||
public static Set<Step> STEPS = new LinkedHashSet<>(List.of(
|
||||
|
@ -31,17 +30,21 @@ public class Steps {
|
|||
new WriteMetadataStep())
|
||||
);
|
||||
|
||||
public static void reDownload(Consumer<SetupStepInfo> update) throws IOException {
|
||||
public static ProcessState createProcessState() {
|
||||
return new ProcessState(STEPS.size(), "Initializing");
|
||||
}
|
||||
|
||||
public static void reDownload(ProcessState state) throws IOException {
|
||||
Utils.ls(MetaHolder.INSTANCE_DIR, p -> {
|
||||
try {
|
||||
reDownload(p, update);
|
||||
reDownload(p, state);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not execute refresh task", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void reDownload(Path instance, Consumer<SetupStepInfo> update) throws IOException {
|
||||
public static void reDownload(Path instance, ProcessState state) throws IOException {
|
||||
if (InstanceLock.isLocked(instance)) return;
|
||||
InstanceMeta im = Utils.loadObject(instance.resolve("instance.json"), InstanceMeta.class);
|
||||
boolean found = false;
|
||||
|
@ -53,9 +56,9 @@ public class Steps {
|
|||
LoaderInfo li = im.isFabric()
|
||||
? new LoaderInfo(LoaderInfo.Type.Fabric, im.getLoaderVersion())
|
||||
: LoaderInfo.NONE;
|
||||
SetupStepInfo info = new SetupStepInfo(vi, li, instance.getFileName().toString(), new AtomicReference<>("Reloading"));
|
||||
update.accept(info);
|
||||
SetupStepInfo info = new SetupStepInfo(vi, li, instance.getFileName().toString(), state);
|
||||
for (Step step : Steps.STEPS) {
|
||||
state.incrementStep("Starting " + step.getClass().getSimpleName());
|
||||
step.execute(info, new AtomicBoolean(false));
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
|
||||
package io.gitlab.jfronny.inceptum.util.install.steps;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.util.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.AssetIndex;
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.api.McApi;
|
|
@ -1,7 +1,7 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
|
||||
package io.gitlab.jfronny.inceptum.util.install.steps;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.util.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.model.ComparableVersion;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.MojangFileDownload;
|
|
@ -1,7 +1,7 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
|
||||
package io.gitlab.jfronny.inceptum.util.install.steps;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.util.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.JvmFileInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.MojangFileDownload;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
|
@ -1,7 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
|
||||
package io.gitlab.jfronny.inceptum.util.install.steps;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import io.gitlab.jfronny.inceptum.util.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.ArtifactInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
|
@ -15,7 +16,6 @@ import java.nio.file.FileSystem;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class DownloadLibrariesStep implements Step {
|
||||
@Override
|
||||
|
@ -23,13 +23,12 @@ public class DownloadLibrariesStep implements Step {
|
|||
execute(info.version(), stopThread, info.currentState());
|
||||
}
|
||||
|
||||
public static void execute(VersionInfo version, AtomicBoolean stopThread, AtomicReference<String> currentState) throws IOException {
|
||||
public static void execute(VersionInfo version, AtomicBoolean stopThread, ProcessState currentState) throws IOException {
|
||||
for (ArtifactInfo artifact : VersionInfoLibraryResolver.getRelevant(version)) {
|
||||
if (stopThread.get()) return;
|
||||
Path path = MetaHolder.LIBRARIES_DIR.resolve(artifact.path);
|
||||
if (!Files.exists(path)) {
|
||||
currentState.set("Downloading library: " + artifact.path);
|
||||
Utils.LOGGER.info(currentState.get());
|
||||
currentState.updateStep("Downloading library: " + artifact.path);
|
||||
if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent());
|
||||
if (!artifact.url.endsWith(".jar")) {
|
||||
Utils.LOGGER.info("Not a valid URL for a jar: " + artifact.url);
|
||||
|
@ -42,8 +41,7 @@ public class DownloadLibrariesStep implements Step {
|
|||
}
|
||||
}
|
||||
if (artifact.isNative) {
|
||||
currentState.set("Extracting natives");
|
||||
Utils.LOGGER.info(currentState.get());
|
||||
currentState.updateStep("Extracting natives");
|
||||
try (FileSystem libFs = Utils.openZipFile(path, false)) {
|
||||
Utils.copyContent(libFs.getPath("."), MetaHolder.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(version.id)));
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
|
||||
package io.gitlab.jfronny.inceptum.util.install.steps;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.util.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLock;
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
|
||||
package io.gitlab.jfronny.inceptum.util.install.steps;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.util.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.install.Step;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLock;
|
|
@ -1,44 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.util.launch;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AuthInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ClientLauncher {
|
||||
public static void launch(Path path, InstanceMeta instance) {
|
||||
if (AccountManager.accountMissing() && ConfigHolder.CONFIG.enforceAccount) {
|
||||
Inceptum.showError("You have not set up an account.\nDoing so is required to play Minecraft", "Not authenticated");
|
||||
return;
|
||||
}
|
||||
AuthInfo authInfo = AccountManager.getSelectedAccount();
|
||||
if (authInfo.equals(AccountManager.NULL_AUTH)) {
|
||||
try {
|
||||
String sysUser = System.getProperty("user.name");
|
||||
if (ConfigHolder.CONFIG.offlineAccountLastName == null)
|
||||
ConfigHolder.CONFIG.offlineAccountLastName = sysUser;
|
||||
Inceptum.getInput("User name", ConfigHolder.CONFIG.offlineAccountLastName, name -> {
|
||||
ConfigHolder.CONFIG.offlineAccountLastName = name.equals(sysUser) ? null : name;
|
||||
ConfigHolder.saveConfig();
|
||||
AuthInfo infoNew = new AuthInfo(name, authInfo.uuid(), authInfo.accessToken(), authInfo.userType());
|
||||
launchI(path, instance, infoNew);
|
||||
}, () -> {});
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Failed to request input", e);
|
||||
}
|
||||
}
|
||||
else launchI(path, instance, authInfo);
|
||||
}
|
||||
|
||||
private static void launchI(Path path, InstanceMeta instance, AuthInfo authInfo) {
|
||||
try {
|
||||
InstanceLauncher.launch(path, instance, InstanceLauncher.LaunchType.Client, false, authInfo);
|
||||
} catch (InstanceLauncher.LaunchException | IOException e) {
|
||||
Inceptum.showError("Could not launch client", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.source;
|
||||
package io.gitlab.jfronny.inceptum.util.source;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.curseforge.CurseforgeDependency;
|
||||
import io.gitlab.jfronny.inceptum.model.curseforge.CurseforgeFile;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.source;
|
||||
package io.gitlab.jfronny.inceptum.util.source;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.util.HashUtils;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.source;
|
||||
package io.gitlab.jfronny.inceptum.util.source;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.source;
|
||||
package io.gitlab.jfronny.inceptum.util.source;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum.source;
|
||||
package io.gitlab.jfronny.inceptum.util.source;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.modrinth.ModrinthMod;
|
||||
import io.gitlab.jfronny.inceptum.model.modrinth.ModrinthVersion;
|
|
@ -7,7 +7,7 @@ plugins {
|
|||
}
|
||||
|
||||
application {
|
||||
mainClass = 'io.gitlab.jfronny.inceptum.Wrapper'
|
||||
mainClass = 'io.gitlab.jfronny.inceptum.WrapperStrap'
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.gitlab.jfronny.inceptum.util.*;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -20,7 +21,7 @@ import java.util.stream.Stream;
|
|||
public class Wrapper {
|
||||
private static final Path INCEPTUM_LIB_DIR = MetaHolder.BASE_PATH.resolve("libraries/io/gitlab/jfronny/inceptum/Inceptum");
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
System.out.println("Inceptum Wrapper v" + MetaHolder.VERSION.version + " (" + MetaHolder.VERSION.flavor + ")");
|
||||
ConfigHolder.load();
|
||||
if (!Files.exists(INCEPTUM_LIB_DIR)) downloadLatest();
|
||||
|
@ -32,15 +33,13 @@ public class Wrapper {
|
|||
if (localBinary.isEmpty()) {
|
||||
throw new FileNotFoundException("Could not identify or download a valid binary");
|
||||
}
|
||||
List<String> newArgs = new ArrayList<>();
|
||||
newArgs.add(JvmUtils.getJvm());
|
||||
newArgs.add("-jar");
|
||||
newArgs.add(localBinary.get().toString());
|
||||
newArgs.add("wrapper");
|
||||
newArgs.addAll(Arrays.asList(args));
|
||||
new ProcessBuilder(newArgs.toArray(new String[0]))
|
||||
.inheritIO()
|
||||
.start();
|
||||
String[] newArgs = new String[args.length + 1];
|
||||
newArgs[0] = "wrapper";
|
||||
System.arraycopy(args, 0, newArgs, 1, args.length);
|
||||
System.out.println("Starting Inceptum ClassLoader");
|
||||
WrapperStrap.switchEnv(localBinary.get().toUri().toURL(),
|
||||
"io.gitlab.jfronny.inceptum.Inceptum",
|
||||
newArgs);
|
||||
}
|
||||
|
||||
private static void downloadLatest() throws IOException {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package io.gitlab.jfronny.inceptum;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
public class WrapperStrap {
|
||||
private static final ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
System.out.println("Starting Inceptum Wrapper ClassLoader");
|
||||
switchEnv(WrapperStrap.class.getProtectionDomain().getCodeSource().getLocation(),
|
||||
"io.gitlab.jfronny.inceptum.Wrapper",
|
||||
args);
|
||||
}
|
||||
|
||||
public static void switchEnv(URL url, String mainClass, String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
ClassLoader cl = new URLClassLoader(new URL[] {url}, WrapperStrap.cl);
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
cl
|
||||
.loadClass(mainClass)
|
||||
.getDeclaredMethod("main", String[].class)
|
||||
.invoke(null, new Object[] {args});
|
||||
}
|
||||
}
|
|
@ -180,7 +180,7 @@ public class Utils {
|
|||
|
||||
public static void copyContent(Path source, Path destination, CopyOption... copyOptions) throws IOException {
|
||||
if (!Files.exists(destination)) Files.createDirectories(destination);
|
||||
if(Files.isDirectory(source)) {
|
||||
if (Files.isDirectory(source)) {
|
||||
try (Stream<Path> paths = Files.walk(source)) {
|
||||
for (Path path : paths.toList()) {
|
||||
if (source.equals(path)) continue;
|
||||
|
@ -190,7 +190,7 @@ public class Utils {
|
|||
else Files.copy(path, d);
|
||||
}
|
||||
}
|
||||
} else if(Files.exists(source)) {
|
||||
} else if (Files.exists(source)) {
|
||||
Path target = destination.resolve(source.getFileName().toString());
|
||||
if (!Files.exists(target)
|
||||
|| Arrays.asList(copyOptions).contains(StandardCopyOption.REPLACE_EXISTING))
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package io.gitlab.jfronny.inceptum.util.lambda;
|
||||
|
||||
public interface ThrowingRunnable<TEx extends Throwable> {
|
||||
void run() throws TEx;
|
||||
}
|
Loading…
Reference in New Issue