Allow customizing arguments, ModUpdateCommand
This commit is contained in:
parent
3814da2013
commit
b14a8fbed1
|
@ -60,7 +60,7 @@ if (flavor == 'custom') {
|
|||
|
||||
dependencies {
|
||||
implementation 'com.google.code.gson:gson:2.8.9'
|
||||
implementation 'org.slf4j:slf4j-api:1.7.32'
|
||||
implementation 'org.slf4j:slf4j-api:1.7.33'
|
||||
implementation 'ch.qos.logback:logback-classic:1.2.10'
|
||||
implementation 'org.eclipse.jgit:org.eclipse.jgit:6.0.0.202111291000-r'
|
||||
implementation project(":wrapper")
|
||||
|
|
|
@ -15,6 +15,7 @@ Manually invoking this command WILL cause problems, so a check has been implemen
|
|||
## The "batch" command
|
||||
This command will go through every line in the file provided in its arguments and executes the command written there.
|
||||
It is intended to be used in scripts that only want to run inceptum once, such as the systemd unit in the AUR package.
|
||||
The batch command has the additional advantage of allowing caches to stay loaded between commands, making execution faster.
|
||||
For example,
|
||||
```
|
||||
git pull icesrv
|
||||
|
|
|
@ -2,8 +2,8 @@ package io.gitlab.jfronny.inceptum;
|
|||
|
||||
import io.gitlab.jfronny.inceptum.frontend.cli.CommandResolution;
|
||||
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.frontend.gui.window.dialog.AlertWindow;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.dialog.TextBoxWindow;
|
||||
import io.gitlab.jfronny.inceptum.gson.*;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.model.microsoft.OauthTokenResponse;
|
||||
|
|
|
@ -12,7 +12,7 @@ import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
|||
import io.gitlab.jfronny.inceptum.util.mds.ModsDirScanner;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.Window;
|
||||
import org.lwjgl.glfw.Callbacks;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||
|
|
|
@ -6,7 +6,7 @@ import io.gitlab.jfronny.inceptum.frontend.cli.Command;
|
|||
import io.gitlab.jfronny.inceptum.frontend.cli.CommandArgs;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.UpdateInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.MainWindow;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.MainWindow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
|
||||
|
||||
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.frontend.gui.window.AddModWindow;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.util.PathUtil;
|
||||
import io.gitlab.jfronny.inceptum.util.mds.IWModDescription;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import io.gitlab.jfronny.inceptum.util.ModManager;
|
||||
|
@ -16,10 +19,11 @@ import java.nio.file.Path;
|
|||
import java.util.*;
|
||||
|
||||
public class ModCommand extends Command {
|
||||
//TODO add (search), update
|
||||
//TODO ModAddCommand (search and install)
|
||||
public ModCommand() {
|
||||
super("Allows managing mods in instances", "", List.of("mod"), List.of(
|
||||
new ModListCommand(),
|
||||
new ModUpdateCommand(),
|
||||
new ModRemoveCommand()
|
||||
));
|
||||
}
|
||||
|
@ -76,7 +80,7 @@ public class ModCommand extends Command {
|
|||
public static class ModRemoveCommand extends BaseInstanceCommand {
|
||||
private final boolean ignoreDependencies;
|
||||
public ModRemoveCommand() {
|
||||
this("Removes a mod from an instance", List.of("remove", "delete", "rm", "del"), List.of(
|
||||
this("Removes mods from an instance", List.of("remove", "delete", "rm", "del"), List.of(
|
||||
new ModRemoveCommand("Skip dependency checks", List.of("ignore-dependencies"), List.of(), true)
|
||||
), false);
|
||||
}
|
||||
|
@ -99,8 +103,9 @@ public class ModCommand extends Command {
|
|||
Set<Path> mods = new HashSet<>();
|
||||
for (String arg : args) {
|
||||
Path p = instancePath.resolve("mods").resolve(arg);
|
||||
if (!Files.exists(p)) p = instancePath.resolve("mods").resolve(arg + ".imod");
|
||||
if (!Files.exists(p)) {
|
||||
Utils.LOGGER.error("Nonexistant mod file: " + p);
|
||||
Utils.LOGGER.error("Nonexistant mod file: " + instancePath.resolve("mods").resolve(arg));
|
||||
return;
|
||||
}
|
||||
mods.add(p);
|
||||
|
@ -112,7 +117,75 @@ public class ModCommand extends Command {
|
|||
}
|
||||
for (Path mod : mods) {
|
||||
try {
|
||||
ModManager.delete(new IWModDescription(mod), instancePath.resolve("mods"), mds);
|
||||
ModManager.delete(mds.get(mod), instancePath.resolve("mods"), mds);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not delete " + mod, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ModUpdateCommand extends BaseInstanceCommand {
|
||||
public ModUpdateCommand() {
|
||||
super("Update mods in an instance", "<mod file>...", "update", "upgrade", "up");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invoke(CommandArgs args, Path instancePath, InstanceMeta meta) {
|
||||
if (!meta.isFabric()) {
|
||||
Utils.LOGGER.error("This is not a fabric instance");
|
||||
return;
|
||||
}
|
||||
if (args.length == 0) {
|
||||
Utils.LOGGER.error("You must specify mods to remove");
|
||||
return;
|
||||
}
|
||||
Set<Path> mods = new HashSet<>();
|
||||
for (String arg : args) {
|
||||
Path p = instancePath.resolve("mods").resolve(arg);
|
||||
if (!Files.exists(p)) p = instancePath.resolve("mods").resolve(arg + ".imod");
|
||||
if (!Files.exists(p)) {
|
||||
Utils.LOGGER.error("Nonexistant mod file: " + instancePath.resolve("mods").resolve(arg));
|
||||
return;
|
||||
}
|
||||
mods.add(p);
|
||||
}
|
||||
ModsDirScanner mds = ModsDirScanner.get(instancePath.resolve("mods"), meta);
|
||||
if (!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));
|
||||
}
|
||||
for (Path mod : mods) {
|
||||
try {
|
||||
Utils.LOGGER.info("Updating " + mod);
|
||||
ModManager.delete(mds.get(mod), instancePath.resolve("mods"), mds);
|
||||
IWModDescription md = mds.get(mod);
|
||||
if (md.mod().isEmpty()) {
|
||||
Utils.LOGGER.error("Could not load mod description");
|
||||
return;
|
||||
}
|
||||
boolean found = false;
|
||||
for (Map.Entry<ModSource, Optional<ModSource>> source : md.mod().get().sources.entrySet()) {
|
||||
Optional<ModSource> ms = source.getValue();
|
||||
if (ms.isPresent()) {
|
||||
try {
|
||||
Utils.LOGGER.info("Updating to " + ms.get().getVersion());
|
||||
Path imodPath = md.imod().isPresent() ? md.imod().get() : instancePath.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()))
|
||||
Files.delete(md.imod().get());
|
||||
dm.write();
|
||||
mds.invalidate(imodPath);
|
||||
Utils.LOGGER.info("Update completed");
|
||||
found = true;
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Update failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) Utils.LOGGER.error("Could not find any update");
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not delete " + mod, e);
|
||||
return;
|
||||
|
|
|
@ -1,409 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.flag.ImGuiInputTextFlags;
|
||||
import imgui.type.ImBoolean;
|
||||
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.util.*;
|
||||
import io.gitlab.jfronny.inceptum.util.mds.IWModDescription;
|
||||
import io.gitlab.jfronny.inceptum.util.mds.ModsDirScanner;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.Status;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
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;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class InstanceEditWindow extends Window {
|
||||
private final Path path;
|
||||
private final String name;
|
||||
private final InstanceMeta instance;
|
||||
private final InstanceManageControls imc;
|
||||
private final ImBoolean customJava;
|
||||
private final ImBoolean filterUpdates = new ImBoolean();
|
||||
private final ImString customJavaPath = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
private final ImString gitUsername = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
private final ImString gitPassword = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
private final ModsDirScanner mds;
|
||||
private Path selected = null;
|
||||
private boolean reDownload = false;
|
||||
private boolean lastTabWasMods = false;
|
||||
|
||||
private final Git git;
|
||||
private CredentialsProvider credentialsProvider;
|
||||
|
||||
public InstanceEditWindow(Path path, InstanceMeta instance) {
|
||||
super(path.getFileName().toString() + " - Edit");
|
||||
name = path.getFileName().toString();
|
||||
this.path = path;
|
||||
this.instance = instance;
|
||||
mds = ModsDirScanner.get(path.resolve("mods"), instance);
|
||||
mds.start();
|
||||
customJava = new ImBoolean(instance.java != null);
|
||||
imc = new InstanceManageControls(instance);
|
||||
if (ConfigHolder.CONFIG.git.instanceAuths.containsKey(name)) {
|
||||
Config.GitConfig.GitAuth config = ConfigHolder.CONFIG.git.instanceAuths.get(name);
|
||||
gitUsername.set(config.username);
|
||||
gitPassword.set(config.password);
|
||||
credentialsProvider = new UsernamePasswordCredentialsProvider(config.username, config.password);
|
||||
}
|
||||
else credentialsProvider = CredentialsProvider.getDefault();
|
||||
Git git = null;
|
||||
try {
|
||||
git = Git.open(path.toFile());
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not open instance as git repo", e);
|
||||
}
|
||||
this.git = git;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (InstanceLock.isSetupLocked(path)) {
|
||||
ImGui.text("This instance is still being set up.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (InstanceLock.isRunningLocked(path)) {
|
||||
ImGui.text("This instance is running. Edits in this state will result in breakage.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ImGui.text("Could not read lock state on this instance");
|
||||
Utils.LOGGER.error("Could not read lock state", e);
|
||||
}
|
||||
lastTabWasMods = false;
|
||||
if (ImGui.beginTabBar("InstanceEdit" + path)) {
|
||||
if (ImGui.beginTabItem("General")) {
|
||||
if (ImGui.button("Open Directory")) {
|
||||
Utils.openFile(path.toFile());
|
||||
}
|
||||
imc.nameBox("Rename", name -> {
|
||||
try {
|
||||
Path newPath = MetaHolder.INSTANCE_DIR.resolve(name);
|
||||
Files.move(path, newPath);
|
||||
InceptumGui.open(new InstanceEditWindow(newPath, instance));
|
||||
close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
imc.snapshotsBox();
|
||||
imc.versionBox(ver -> {
|
||||
reDownload = true;
|
||||
instance.version = ver;
|
||||
save();
|
||||
});
|
||||
if (ImGui.button("Delete")) Inceptum.showOkCancel("This instance will be removed forever (a long time)", "Are you sure?", () -> {
|
||||
try {
|
||||
Utils.deleteRecursive(path);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not delete the instance", e);
|
||||
}
|
||||
close();
|
||||
}, () -> {});
|
||||
if (ImGui.checkbox("Custom Java", customJava)) {
|
||||
if (customJava.get()) {
|
||||
instance.java = JvmUtils.getJvm();
|
||||
customJavaPath.set(instance.java);
|
||||
} else {
|
||||
instance.java = null;
|
||||
}
|
||||
save();
|
||||
}
|
||||
if (customJava.get() && ImGui.inputText("Path", customJavaPath)) {
|
||||
instance.java = customJavaPath.get();
|
||||
save();
|
||||
}
|
||||
ImGui.endTabItem();
|
||||
}
|
||||
if (instance.isFabric() && ImGui.beginTabItem("Mods")) {
|
||||
lastTabWasMods = true;
|
||||
if (!Files.exists(path.resolve("mods"))) {
|
||||
try {
|
||||
Files.createDirectories(path.resolve("mods"));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not create mods directory which was missing from this modded instance", e);
|
||||
}
|
||||
}
|
||||
ImGui.beginChild("mods select", 200, 0);
|
||||
if (ImGui.button("Add")) {
|
||||
InceptumGui.WINDOWS.add(new AddModWindow(path.resolve("mods"), instance, mds));
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (Files.exists(path.resolve("mods")) && ImGui.button("Show")) {
|
||||
Utils.openFile(path.resolve("mods").toFile());
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (Files.exists(path.resolve("config")) && ImGui.button("Configs")) {
|
||||
Utils.openFile(path.resolve("config").toFile());
|
||||
}
|
||||
try {
|
||||
Set<IWModDescription> modSet = mds.getMods();
|
||||
boolean updatesFound = false;
|
||||
float scannedPercentage = 0;
|
||||
boolean hasUnScanned = false;
|
||||
for (IWModDescription mod : modSet) {
|
||||
if (mds.hasScanned(mod.path())) scannedPercentage++;
|
||||
else hasUnScanned = true;
|
||||
if (mod.mod().isEmpty()) continue;
|
||||
for (Optional<ModSource> value : mod.mod().get().sources.values()) {
|
||||
if (value.isPresent()) {
|
||||
updatesFound = true;
|
||||
break;
|
||||
}
|
||||
if (updatesFound)
|
||||
break;
|
||||
}
|
||||
}
|
||||
scannedPercentage /= modSet.size();
|
||||
if (hasUnScanned) ImGui.progressBar(scannedPercentage);
|
||||
if (updatesFound)
|
||||
ImGui.checkbox("Updatable", filterUpdates);
|
||||
else
|
||||
filterUpdates.set(false);
|
||||
ImGui.separator();
|
||||
for (IWModDescription mod : modSet) {
|
||||
updatesFound = false;
|
||||
if (mod.mod().isPresent()) {
|
||||
for (Optional<ModSource> value : mod.mod().get().sources.values()) {
|
||||
updatesFound |= value.isPresent();
|
||||
}
|
||||
}
|
||||
if (filterUpdates.get() && !updatesFound) continue;
|
||||
boolean wasEnabled = PathUtil.isEnabled(mod.path());
|
||||
if (ImGui.checkbox("##" + mod.getName(), wasEnabled)) {
|
||||
Path newSel = PathUtil.toggle(mod.path());
|
||||
try {
|
||||
Files.move(mod.path(), newSel);
|
||||
if (mod.path().equals(selected)) selected = newSel;
|
||||
mod = new IWModDescription(newSel, mod);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not change disabled state", e);
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button(mod.getName())) selected = mod.path();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ImGui.endChild();
|
||||
ImGui.sameLine();
|
||||
ImGui.beginGroup();
|
||||
if (selected == null) {
|
||||
ImGui.text("Select a mod to view settings");
|
||||
} else if (mds.hasScanned(selected)) {
|
||||
IWModDescription md = mds.get(selected);
|
||||
ImGui.text(md.getName());
|
||||
ImGui.separator();
|
||||
for (String s : md.getDescription()) {
|
||||
ImGui.text(s);
|
||||
}
|
||||
ImGui.separator();
|
||||
if (md.mod().isPresent()) {
|
||||
Map<ModSource, Optional<ModSource>> sources = md.mod().get().sources;
|
||||
ImGui.text("Sources:");
|
||||
if (sources.isEmpty())
|
||||
ImGui.bulletText("Local Drive");
|
||||
else {
|
||||
for (Map.Entry<ModSource, Optional<ModSource>> source : sources.entrySet()) {
|
||||
ImGui.bulletText(source.getKey().getName());
|
||||
Optional<ModSource> ms = source.getValue();
|
||||
if (ms.isPresent()) {
|
||||
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() + 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()))
|
||||
Files.delete(md.imod().get());
|
||||
dm.write();
|
||||
selected = imodPath;
|
||||
mds.invalidate(imodPath);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Update failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ImGui.button("Delete")) {
|
||||
if (md.mod().isPresent() && !md.mod().get().dependents.isEmpty())
|
||||
Inceptum.showError("This mod still has the following dependent mods installed: " + String.join(", ", md.mod().get().dependents), "Dependents present");
|
||||
else {
|
||||
try {
|
||||
delete(md);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Couldn't delete the file", e);
|
||||
}
|
||||
selected = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImGui.text("This mod has not yet been scanned, please be patient");
|
||||
}
|
||||
ImGui.endGroup();
|
||||
ImGui.endTabItem();
|
||||
}
|
||||
if (git != null && ImGui.beginTabItem("Git")) {
|
||||
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();
|
||||
}
|
||||
if (ImGui.button("Push")) {
|
||||
try {
|
||||
git.push()
|
||||
.setCredentialsProvider(credentialsProvider)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
Inceptum.showError("Could not push", e);
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button("Pull")) {
|
||||
try {
|
||||
git.pull()
|
||||
.setRebase(true)
|
||||
.setCredentialsProvider(credentialsProvider)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
Inceptum.showError("Could not pull", e);
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button("Reset")) {
|
||||
Inceptum.showOkCancel("This will erase all changes since the last commit.\nAre you sure?", "Are you sure?", () -> {
|
||||
try {
|
||||
git.checkout()
|
||||
.setAllPaths(true)
|
||||
.call();
|
||||
git.clean()
|
||||
.setForce(true)
|
||||
.setCleanDirectories(true)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
Inceptum.showError("Could not reset", e);
|
||||
}
|
||||
}, () -> {});
|
||||
}
|
||||
ImGui.text("Authentication");
|
||||
boolean update = ImGui.inputText("Username", gitUsername);
|
||||
update |= ImGui.inputText("Password", gitPassword, ImGuiInputTextFlags.Password);
|
||||
if (update) {
|
||||
if (!ConfigHolder.CONFIG.git.instanceAuths.containsKey(name))
|
||||
ConfigHolder.CONFIG.git.instanceAuths.put(name, new Config.GitConfig.GitAuth());
|
||||
Config.GitConfig.GitAuth config = ConfigHolder.CONFIG.git.instanceAuths.get(name);
|
||||
config.username = gitUsername.get();
|
||||
config.password = gitPassword.get();
|
||||
ConfigHolder.saveConfig();
|
||||
credentialsProvider = new UsernamePasswordCredentialsProvider(config.username, config.password);
|
||||
}
|
||||
ImGui.text("Please note that Inceptum's git integration intentionally does not cover advanced usage");
|
||||
ImGui.text("Using software intended to work with git (such as the git CLI or GitHub Desktop) is recommended");
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private void delete(IWModDescription md) throws IOException {
|
||||
ModManager.delete(md, path.resolve("mods"), mds);
|
||||
}
|
||||
|
||||
private void save() {
|
||||
try {
|
||||
Utils.writeObject(path.resolve("instance.json"), instance);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not write instance config", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
if (git != null) git.close();
|
||||
if (reDownload) {
|
||||
GuiUtil.reload(path);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFlags() {
|
||||
return lastTabWasMods ? 0 : super.getFlags();
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ import imgui.ImGui;
|
|||
import imgui.type.ImBoolean;
|
||||
import imgui.type.ImInt;
|
||||
import imgui.type.ImString;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.model.fabric.FabricVersionLoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
|
|
|
@ -7,7 +7,7 @@ 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.Utils;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.InstanceEditWindow;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.edit.InstanceEditWindow;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLauncher;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.control;
|
||||
|
||||
import imgui.ImGui;
|
||||
|
||||
public abstract class Tab {
|
||||
private final String name;
|
||||
|
||||
public Tab(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
protected abstract void renderInner();
|
||||
|
||||
public void render() {
|
||||
if (canShow() && ImGui.beginTabItem(name)) {
|
||||
renderInner();
|
||||
ImGui.endTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean canShow() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window;
|
||||
|
||||
import imgui.ImGui;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.flag.ImGuiTableFlags;
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window;
|
||||
|
||||
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.frontend.gui.window.dialog.ProcessStateWatcherWindow;
|
||||
import io.gitlab.jfronny.inceptum.util.MetaHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window;
|
||||
|
||||
import imgui.ImGui;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.flag.ImGuiWindowFlags;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import imgui.ImGui;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.type.ImString;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window;
|
||||
|
||||
import imgui.flag.ImGuiWindowFlags;
|
||||
import imgui.type.ImBoolean;
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.dialog;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window.dialog;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.flag.ImGuiWindowFlags;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.Window;
|
||||
|
||||
public class AlertWindow extends Window {
|
||||
private final String message;
|
|
@ -1,8 +1,8 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.dialog;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window.dialog;
|
||||
|
||||
import imgui.ImGui;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.Window;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import io.gitlab.jfronny.inceptum.util.lambda.ThrowingConsumer;
|
||||
import org.eclipse.jgit.annotations.Nullable;
|
|
@ -1,9 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.dialog;
|
||||
package io.gitlab.jfronny.inceptum.frontend.gui.window.dialog;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.type.ImString;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.Window;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.window.edit;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.type.ImString;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.control.Tab;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ArgumentsTab extends Tab {
|
||||
private final InstanceEditWindow window;
|
||||
private final ImString jvm = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
private final ImString client = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
private final ImString server = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
|
||||
public ArgumentsTab(InstanceEditWindow window) {
|
||||
super("Arguments");
|
||||
this.window = window;
|
||||
if (window.instance.arguments == null) window.instance.arguments = new InstanceMeta.Arguments();
|
||||
if (window.instance.arguments.jvm == null) window.instance.arguments.jvm = new LinkedList<>();
|
||||
jvm.set(String.join("\n", window.instance.arguments.jvm));
|
||||
if (window.instance.arguments.client == null) window.instance.arguments.client = new LinkedList<>();
|
||||
client.set(String.join("\n", window.instance.arguments.client));
|
||||
if (window.instance.arguments.server == null) window.instance.arguments.server = new LinkedList<>();
|
||||
server.set(String.join("\n", window.instance.arguments.server));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderInner() {
|
||||
if (ImGui.inputTextMultiline("JVM", jvm)) {
|
||||
window.instance.arguments.jvm = List.of(jvm.get().split("[\r\n]+"));
|
||||
window.save();
|
||||
}
|
||||
if (ImGui.inputTextMultiline("Client", client)) {
|
||||
window.instance.arguments.client = List.of(client.get().split("[\r\n]+"));
|
||||
window.save();
|
||||
}
|
||||
if (ImGui.inputTextMultiline("Server", server)) {
|
||||
window.instance.arguments.server = List.of(server.get().split("[\r\n]+"));
|
||||
window.save();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.window.edit;
|
||||
|
||||
import imgui.ImGui;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.control.Tab;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.dialog.ProcessStateWatcherWindow;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceExporter;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessState;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.util.tinyfd.TinyFileDialogs;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ExportTab extends Tab {
|
||||
private final InstanceEditWindow window;
|
||||
|
||||
public ExportTab(InstanceEditWindow window) {
|
||||
super("Export");
|
||||
this.window = window;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderInner() {
|
||||
if (window.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, window.path, window.instance, window.mds, window.git, exportPath);
|
||||
Inceptum.showInfo(window.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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.window.edit;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.type.ImBoolean;
|
||||
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.control.Tab;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.util.JvmUtils;
|
||||
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.nio.file.Path;
|
||||
|
||||
public class GeneralTab extends Tab {
|
||||
private final InstanceManageControls imc;
|
||||
private final InstanceEditWindow window;
|
||||
private final ImBoolean customJava;
|
||||
private final ImString customJavaPath = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
|
||||
public GeneralTab(InstanceEditWindow window) {
|
||||
super("General");
|
||||
this.window = window;
|
||||
imc = new InstanceManageControls(window.instance);
|
||||
customJava = new ImBoolean(window.instance.java != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderInner() {
|
||||
if (ImGui.button("Open Directory")) {
|
||||
Utils.openFile(window.path.toFile());
|
||||
}
|
||||
imc.nameBox("Rename", name -> {
|
||||
try {
|
||||
Path newPath = MetaHolder.INSTANCE_DIR.resolve(name);
|
||||
Files.move(window.path, newPath);
|
||||
InceptumGui.open(new InstanceEditWindow(newPath, window.instance));
|
||||
window.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
imc.snapshotsBox();
|
||||
imc.versionBox(ver -> {
|
||||
window.reDownload = true;
|
||||
window.instance.version = ver;
|
||||
window.save();
|
||||
});
|
||||
if (ImGui.button("Delete")) Inceptum.showOkCancel("This instance will be removed forever (a long time)", "Are you sure?", () -> {
|
||||
try {
|
||||
Utils.deleteRecursive(window.path);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not delete the instance", e);
|
||||
}
|
||||
window.close();
|
||||
}, () -> {});
|
||||
if (ImGui.checkbox("Custom Java", customJava)) {
|
||||
if (customJava.get()) {
|
||||
window.instance.java = JvmUtils.getJvm();
|
||||
customJavaPath.set(window.instance.java);
|
||||
} else {
|
||||
window.instance.java = null;
|
||||
}
|
||||
window.save();
|
||||
}
|
||||
if (customJava.get() && ImGui.inputText("Path", customJavaPath)) {
|
||||
window.instance.java = customJavaPath.get();
|
||||
window.save();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.window.edit;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.flag.ImGuiInputTextFlags;
|
||||
import imgui.type.ImString;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.control.Tab;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.Config;
|
||||
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import org.eclipse.jgit.api.Status;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GitTab extends Tab {
|
||||
private final InstanceEditWindow window;
|
||||
private final ImString gitUsername = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
private final ImString gitPassword = new ImString(GuiUtil.INPUT_FIELD_LENGTH);
|
||||
protected CredentialsProvider credentialsProvider;
|
||||
|
||||
public GitTab(InstanceEditWindow window) {
|
||||
super("Git");
|
||||
this.window = window;
|
||||
if (ConfigHolder.CONFIG.git.instanceAuths.containsKey(window.name)) {
|
||||
Config.GitConfig.GitAuth config = ConfigHolder.CONFIG.git.instanceAuths.get(window.name);
|
||||
gitUsername.set(config.username);
|
||||
gitPassword.set(config.password);
|
||||
credentialsProvider = new UsernamePasswordCredentialsProvider(config.username, config.password);
|
||||
}
|
||||
else credentialsProvider = CredentialsProvider.getDefault();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderInner() {
|
||||
Status status = null;
|
||||
try {
|
||||
status = window.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 {
|
||||
window.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();
|
||||
}
|
||||
if (ImGui.button("Push")) {
|
||||
try {
|
||||
window.git.push()
|
||||
.setCredentialsProvider(credentialsProvider)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
Inceptum.showError("Could not push", e);
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button("Pull")) {
|
||||
try {
|
||||
window.git.pull()
|
||||
.setRebase(true)
|
||||
.setCredentialsProvider(credentialsProvider)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
Inceptum.showError("Could not pull", e);
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button("Reset")) {
|
||||
Inceptum.showOkCancel("This will erase all changes since the last commit.\nAre you sure?", "Are you sure?", () -> {
|
||||
try {
|
||||
window.git.checkout()
|
||||
.setAllPaths(true)
|
||||
.call();
|
||||
window.git.clean()
|
||||
.setForce(true)
|
||||
.setCleanDirectories(true)
|
||||
.call();
|
||||
} catch (GitAPIException e) {
|
||||
Inceptum.showError("Could not reset", e);
|
||||
}
|
||||
}, () -> {});
|
||||
}
|
||||
ImGui.text("Authentication");
|
||||
boolean update = ImGui.inputText("Username", gitUsername);
|
||||
update |= ImGui.inputText("Password", gitPassword, ImGuiInputTextFlags.Password);
|
||||
if (update) {
|
||||
if (!ConfigHolder.CONFIG.git.instanceAuths.containsKey(window.name))
|
||||
ConfigHolder.CONFIG.git.instanceAuths.put(window.name, new Config.GitConfig.GitAuth());
|
||||
Config.GitConfig.GitAuth config = ConfigHolder.CONFIG.git.instanceAuths.get(window.name);
|
||||
config.username = gitUsername.get();
|
||||
config.password = gitPassword.get();
|
||||
ConfigHolder.saveConfig();
|
||||
credentialsProvider = new UsernamePasswordCredentialsProvider(config.username, config.password);
|
||||
}
|
||||
ImGui.text("Please note that Inceptum's git integration intentionally does not cover advanced usage");
|
||||
ImGui.text("Using software intended to work with git (such as the git CLI or GitHub Desktop) is recommended");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canShow() {
|
||||
return window.git != null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.window.edit;
|
||||
|
||||
import imgui.ImGui;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.control.Tab;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.GuiUtil;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.Window;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.util.InstanceLock;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.mds.ModsDirScanner;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class InstanceEditWindow extends Window {
|
||||
protected final Path path;
|
||||
protected final String name;
|
||||
protected final InstanceMeta instance;
|
||||
protected final ModsDirScanner mds;
|
||||
protected final Git git;
|
||||
private final List<Tab> tabs;
|
||||
protected boolean reDownload = false;
|
||||
protected boolean lastTabWasMods = false;
|
||||
|
||||
public InstanceEditWindow(Path path, InstanceMeta instance) {
|
||||
super(path.getFileName().toString() + " - Edit");
|
||||
name = path.getFileName().toString();
|
||||
this.path = path;
|
||||
this.instance = instance;
|
||||
mds = ModsDirScanner.get(path.resolve("mods"), instance);
|
||||
mds.start();
|
||||
Git git = null;
|
||||
try {
|
||||
git = Git.open(path.toFile());
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not open instance as git repo", e);
|
||||
}
|
||||
this.git = git;
|
||||
this.tabs = List.of(
|
||||
new GeneralTab(this),
|
||||
new ArgumentsTab(this),
|
||||
new ModsTab(this),
|
||||
new GitTab(this),
|
||||
new ExportTab(this)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
if (InstanceLock.isSetupLocked(path)) {
|
||||
ImGui.text("This instance is still being set up.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (InstanceLock.isRunningLocked(path)) {
|
||||
ImGui.text("This instance is running. Edits in this state will result in breakage.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ImGui.text("Could not read lock state on this instance");
|
||||
Utils.LOGGER.error("Could not read lock state", e);
|
||||
}
|
||||
lastTabWasMods = false;
|
||||
if (ImGui.beginTabBar("InstanceEdit" + path)) {
|
||||
for (Tab tab : tabs) tab.render();
|
||||
ImGui.endTabBar();
|
||||
}
|
||||
}
|
||||
|
||||
protected void save() {
|
||||
try {
|
||||
Utils.writeObject(path.resolve("instance.json"), instance);
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not write instance config", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
if (git != null) git.close();
|
||||
if (reDownload) {
|
||||
GuiUtil.reload(path);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFlags() {
|
||||
return lastTabWasMods ? 0 : super.getFlags();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
package io.gitlab.jfronny.inceptum.frontend.gui.window.edit;
|
||||
|
||||
import imgui.ImGui;
|
||||
import imgui.type.ImBoolean;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.InceptumGui;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.control.Tab;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.AddModWindow;
|
||||
import io.gitlab.jfronny.inceptum.util.ModManager;
|
||||
import io.gitlab.jfronny.inceptum.util.PathUtil;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.mds.IWModDescription;
|
||||
import io.gitlab.jfronny.inceptum.util.source.ModSource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class ModsTab extends Tab {
|
||||
private final InstanceEditWindow window;
|
||||
private final ImBoolean filterUpdates = new ImBoolean();
|
||||
private Path selected = null;
|
||||
|
||||
public ModsTab(InstanceEditWindow window) {
|
||||
super("Mods");
|
||||
this.window = window;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderInner() {
|
||||
window.lastTabWasMods = true;
|
||||
if (!Files.exists(window.path.resolve("mods"))) {
|
||||
try {
|
||||
Files.createDirectories(window.path.resolve("mods"));
|
||||
} catch (IOException e) {
|
||||
Utils.LOGGER.error("Could not create mods directory which was missing from this modded instance", e);
|
||||
}
|
||||
}
|
||||
ImGui.beginChild("mods select", 200, 0);
|
||||
if (ImGui.button("Add")) {
|
||||
InceptumGui.WINDOWS.add(new AddModWindow(window.path.resolve("mods"), window.instance, window.mds));
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (Files.exists(window.path.resolve("mods")) && ImGui.button("Show")) {
|
||||
Utils.openFile(window.path.resolve("mods").toFile());
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (Files.exists(window.path.resolve("config")) && ImGui.button("Configs")) {
|
||||
Utils.openFile(window.path.resolve("config").toFile());
|
||||
}
|
||||
try {
|
||||
Set<IWModDescription> modSet = window.mds.getMods();
|
||||
boolean updatesFound = false;
|
||||
float scannedPercentage = 0;
|
||||
boolean hasUnScanned = false;
|
||||
for (IWModDescription mod : modSet) {
|
||||
if (window.mds.hasScanned(mod.path())) scannedPercentage++;
|
||||
else hasUnScanned = true;
|
||||
if (mod.mod().isEmpty()) continue;
|
||||
for (Optional<ModSource> value : mod.mod().get().sources.values()) {
|
||||
if (value.isPresent()) {
|
||||
updatesFound = true;
|
||||
break;
|
||||
}
|
||||
if (updatesFound)
|
||||
break;
|
||||
}
|
||||
}
|
||||
scannedPercentage /= modSet.size();
|
||||
if (hasUnScanned) ImGui.progressBar(scannedPercentage);
|
||||
if (updatesFound)
|
||||
ImGui.checkbox("Updatable", filterUpdates);
|
||||
else
|
||||
filterUpdates.set(false);
|
||||
ImGui.separator();
|
||||
for (IWModDescription mod : modSet) {
|
||||
updatesFound = false;
|
||||
if (mod.mod().isPresent()) {
|
||||
for (Optional<ModSource> value : mod.mod().get().sources.values()) {
|
||||
updatesFound |= value.isPresent();
|
||||
}
|
||||
}
|
||||
if (filterUpdates.get() && !updatesFound) continue;
|
||||
boolean wasEnabled = PathUtil.isEnabled(mod.path());
|
||||
if (ImGui.checkbox("##" + mod.getName(), wasEnabled)) {
|
||||
Path newSel = PathUtil.toggle(mod.path());
|
||||
try {
|
||||
Files.move(mod.path(), newSel);
|
||||
if (mod.path().equals(selected)) selected = newSel;
|
||||
mod = new IWModDescription(newSel, mod);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Could not change disabled state", e);
|
||||
}
|
||||
}
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button(mod.getName())) selected = mod.path();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ImGui.endChild();
|
||||
ImGui.sameLine();
|
||||
ImGui.beginGroup();
|
||||
if (selected == null) {
|
||||
ImGui.text("Select a mod to view settings");
|
||||
} else if (window.mds.hasScanned(selected)) {
|
||||
IWModDescription md = window.mds.get(selected);
|
||||
ImGui.text(md.getName());
|
||||
ImGui.separator();
|
||||
for (String s : md.getDescription()) {
|
||||
ImGui.text(s);
|
||||
}
|
||||
ImGui.separator();
|
||||
if (md.mod().isPresent()) {
|
||||
Map<ModSource, Optional<ModSource>> sources = md.mod().get().sources;
|
||||
ImGui.text("Sources:");
|
||||
if (sources.isEmpty())
|
||||
ImGui.bulletText("Local Drive");
|
||||
else {
|
||||
for (Map.Entry<ModSource, Optional<ModSource>> source : sources.entrySet()) {
|
||||
ImGui.bulletText(source.getKey().getName());
|
||||
Optional<ModSource> ms = source.getValue();
|
||||
if (ms.isPresent()) {
|
||||
ImGui.sameLine();
|
||||
if (ImGui.button("Update to " + ms.get().getVersion())) {
|
||||
try {
|
||||
Path imodPath = md.imod().isPresent() ? md.imod().get() : window.path.resolve("mods").resolve(ms.get().getShortName() + PathUtil.EXT_IMOD);
|
||||
AddModWindow.DownloadMeta dm = AddModWindow.download(ms.get(), imodPath, window.mds);
|
||||
Files.delete(md.path());
|
||||
if (md.imod().isPresent() && Files.exists(md.imod().get()))
|
||||
Files.delete(md.imod().get());
|
||||
dm.write();
|
||||
selected = imodPath;
|
||||
window.mds.invalidate(imodPath);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Update failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ImGui.button("Delete")) {
|
||||
if (md.mod().isPresent() && !md.mod().get().dependents.isEmpty())
|
||||
Inceptum.showError("This mod still has the following dependent mods installed: " + String.join(", ", md.mod().get().dependents), "Dependents present");
|
||||
else {
|
||||
try {
|
||||
delete(md);
|
||||
} catch (IOException e) {
|
||||
Inceptum.showError("Couldn't delete the file", e);
|
||||
}
|
||||
selected = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImGui.text("This mod has not yet been scanned, please be patient");
|
||||
}
|
||||
ImGui.endGroup();
|
||||
}
|
||||
|
||||
private void delete(IWModDescription md) throws IOException {
|
||||
ModManager.delete(md, window.path.resolve("mods"), window.mds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canShow() {
|
||||
return window.instance.isFabric();
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ public class InstanceMeta {
|
|||
public String java;
|
||||
public Long minMem;
|
||||
public Long maxMem;
|
||||
public Arguments arguments; //TODO allow configuring in UI
|
||||
public Arguments arguments;
|
||||
|
||||
public boolean isFabric() {
|
||||
return version.startsWith(floaderPrefix);
|
||||
|
|
|
@ -7,7 +7,7 @@ import io.gitlab.jfronny.inceptum.model.microsoft.OauthTokenResponse;
|
|||
import io.gitlab.jfronny.inceptum.model.microsoft.Profile;
|
||||
import io.gitlab.jfronny.inceptum.model.microsoft.XboxLiveAuthResponse;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.MicrosoftLoginWindow;
|
||||
import io.gitlab.jfronny.inceptum.frontend.gui.window.MicrosoftLoginWindow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
|
|
@ -21,10 +21,12 @@ public class WriteMetadataStep implements Step {
|
|||
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
|
||||
info.setState("Writing metadata");
|
||||
Path instance = MetaHolder.INSTANCE_DIR.resolve(info.name());
|
||||
Path metaDir = instance.resolve("instance.json");
|
||||
InstanceMeta meta = new InstanceMeta();
|
||||
meta.version = info.version().id;
|
||||
Utils.writeObject(metaDir, meta);
|
||||
Path metaPath = instance.resolve("instance.json");
|
||||
if (!Files.exists(metaPath)) {
|
||||
InstanceMeta meta = new InstanceMeta();
|
||||
meta.version = info.version().id;
|
||||
Utils.writeObject(metaPath, meta);
|
||||
}
|
||||
InstanceLock.setSetupLock(instance, false);
|
||||
if (!Files.exists(instance.resolve(".gitignore"))) {
|
||||
Files.writeString(instance.resolve(".gitignore"), """
|
||||
|
|
|
@ -145,7 +145,7 @@ public class HttpUtils {
|
|||
throw new IOException("Could not follow redirect", e);
|
||||
}
|
||||
}
|
||||
throw new IOException("Unexpected return method: " + res.statusCode() + " (URL=" + url + ")\n" + res.body());
|
||||
throw new IOException("Unexpected return method: " + res.statusCode() + " (URL=" + url + ")");
|
||||
}
|
||||
|
||||
public void send() throws IOException {
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.nio.file.FileSystem;
|
|||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
@ -249,8 +250,14 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
private static final Map<Path, FileSystem> zipFsCache = new HashMap<>();
|
||||
public static FileSystem openZipFile(Path zip, boolean create) throws IOException, URISyntaxException {
|
||||
URI fileUri = zip.toUri();
|
||||
return FileSystems.newFileSystem(new URI("jar:" + fileUri.getScheme(), fileUri.getPath(), null), create ? Map.of("create", "true") : Map.of(), WrapperStrap.SYSTEM_LOADER);
|
||||
synchronized (zipFsCache) {
|
||||
if (!zipFsCache.containsKey(zip) || !zipFsCache.get(zip).isOpen()) {
|
||||
URI fileUri = zip.toUri();
|
||||
zipFsCache.put(zip, FileSystems.newFileSystem(new URI("jar:" + fileUri.getScheme(), fileUri.getPath(), null), create ? Map.of("create", "true") : Map.of(), WrapperStrap.SYSTEM_LOADER));
|
||||
}
|
||||
return zipFsCache.get(zip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue