Some refactorings and proxy support for HttpUtils

This commit is contained in:
Johannes Frohnmeyer 2022-01-18 18:43:39 +01:00
parent f6ac14b266
commit b69ffeed30
Signed by: Johannes
GPG Key ID: E76429612C2929F4
75 changed files with 626 additions and 522 deletions

View File

@ -1,95 +1,61 @@
package io.gitlab.jfronny.inceptum;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import io.gitlab.jfronny.inceptum.cli.CommandResolution;
import io.gitlab.jfronny.inceptum.cli.Commands;
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.gson.*;
import io.gitlab.jfronny.inceptum.model.ComparableVersion;
import io.gitlab.jfronny.inceptum.model.inceptum.Config;
import io.gitlab.jfronny.inceptum.model.inceptum.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;
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.ModsDirScanner;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.McApi;
import io.gitlab.jfronny.inceptum.windows.dialog.AlertWindow;
import io.gitlab.jfronny.inceptum.windows.dialog.TextBoxWindow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Scanner;
import java.util.function.Consumer;
public class Inceptum {
public static final Path CACHE_DIR = MetaHolder.BASE_PATH.resolve("cache");
public static final Path INSTANCE_DIR = MetaHolder.BASE_PATH.resolve("instances");
public static final Path ASSETS_DIR = MetaHolder.BASE_PATH.resolve("assets");
public static final Path LIBRARIES_DIR = MetaHolder.BASE_PATH.resolve("libraries");
public static final Path NATIVES_DIR = MetaHolder.BASE_PATH.resolve("natives");
private static final Path CONFIG_PATH = MetaHolder.BASE_PATH.resolve("inceptum.json");
public static final Path ACCOUNTS_PATH = MetaHolder.BASE_PATH.resolve("accounts.json");
public static final Path FORCE_LOAD_PATH = NATIVES_DIR.resolve("forceload");
public static final Logger LOGGER = LoggerFactory.getLogger("Inceptum");
public static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(MinecraftArgument.class, new MinecraftArgumentDeserializer())
.registerTypeAdapter(Rules.class, new RulesDeserializer())
.registerTypeAdapter(OauthTokenResponse.class, new OauthTokenResponseDeserializer())
.registerTypeAdapter(ComparableVersion.class, new ComparableVersionAdapter())
.registerTypeAdapter(ModSource.class, new ModSourceTypeAdapter())
.registerTypeAdapter(ModSourceMapDeserializer.modSourceMapType, new ModSourceMapDeserializer())
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
.excludeFieldsWithModifiers(Modifier.PRIVATE)
.addSerializationExclusionStrategy(new GsonIgnoreExclusionStrategy())
.setPrettyPrinting()
.create();
public static Config CONFIG;
public static boolean IS_GUI;
public static void main(String[] args) throws Exception {
GsonHolder.registerTypeAdapter(MinecraftArgument.class, new MinecraftArgumentDeserializer());
GsonHolder.registerTypeAdapter(Rules.class, new RulesDeserializer());
GsonHolder.registerTypeAdapter(OauthTokenResponse.class, new OauthTokenResponseDeserializer());
GsonHolder.registerTypeAdapter(ModSource.class, new ModSourceTypeAdapter());
GsonHolder.registerTypeAdapter(ModSourceMapDeserializer.modSourceMapType, new ModSourceMapDeserializer());
CommandResolution command = Commands.resolve(args, false);
if (command.command().enableLog()) {
LOGGER.info("Launching Inceptum v" + MetaHolder.VERSION.version + " (" + MetaHolder.VERSION.flavor + ")");
LOGGER.info("Loading from " + MetaHolder.BASE_PATH);
Utils.LOGGER.info("Launching Inceptum v" + MetaHolder.VERSION.version + " (" + MetaHolder.VERSION.flavor + ")");
Utils.LOGGER.info("Loading from " + MetaHolder.BASE_PATH);
}
if (!Files.exists(CONFIG_PATH.getParent())) Files.createDirectories(CONFIG_PATH.getParent());
if (!Files.exists(CONFIG_PATH)) {
Path gLaunch2 = MetaHolder.BASE_PATH.resolve("glaunch2.json");
if (Files.exists(gLaunch2)) {
Files.move(gLaunch2, CONFIG_PATH);
}
else {
Utils.writeObject(CONFIG_PATH, new Config());
}
}
CONFIG = Utils.loadObject(CONFIG_PATH, Config.class);
if (!Files.exists(CACHE_DIR)) Files.createDirectories(CACHE_DIR);
ConfigHolder.load();
if (!Files.exists(MetaHolder.CACHE_DIR)) Files.createDirectories(MetaHolder.CACHE_DIR);
try {
McApi.getVersions();
Utils.clearDirectory(CACHE_DIR);
Utils.clearDirectory(MetaHolder.CACHE_DIR);
}
catch (IOException e) {
Inceptum.LOGGER.error("Could not connect to the internet");
Utils.LOGGER.error("Could not connect to the internet");
}
if (!Files.exists(INSTANCE_DIR)) Files.createDirectories(INSTANCE_DIR);
if (!Files.exists(ASSETS_DIR)) Files.createDirectories(ASSETS_DIR);
if (!Files.exists(LIBRARIES_DIR)) Files.createDirectories(LIBRARIES_DIR);
if (Files.exists(FORCE_LOAD_PATH)) {
Inceptum.LOGGER.info("Force-Loading libraries:");
Utils.ls(FORCE_LOAD_PATH, path -> {
Inceptum.LOGGER.info("Loading " + path);
if (!Files.exists(MetaHolder.INSTANCE_DIR)) Files.createDirectories(MetaHolder.INSTANCE_DIR);
if (!Files.exists(MetaHolder.ASSETS_DIR)) Files.createDirectories(MetaHolder.ASSETS_DIR);
if (!Files.exists(MetaHolder.LIBRARIES_DIR)) Files.createDirectories(MetaHolder.LIBRARIES_DIR);
if (Files.exists(MetaHolder.FORCE_LOAD_PATH)) {
Utils.LOGGER.info("Force-Loading libraries:");
Utils.ls(MetaHolder.FORCE_LOAD_PATH, path -> {
Utils.LOGGER.info("Loading " + path);
try {
System.load(path.toAbsolutePath().toString());
}
catch (UnsatisfiedLinkError le) {
LOGGER.error("Could not load library", le);
Utils.LOGGER.error("Could not load library", le);
}
});
}
@ -98,26 +64,18 @@ public class Inceptum {
ModsDirScanner.closeAll();
}
public static void saveConfig() {
try {
Utils.writeObject(CONFIG_PATH, CONFIG);
} catch (IOException e) {
LOGGER.error("Could not save config", e);
}
}
public static void showError(String message, String title) {
LOGGER.error(message);
Utils.LOGGER.error(message);
if (IS_GUI) InceptumGui.WINDOWS.add(new AlertWindow(title, message));
}
public static void showError(String message, Throwable t) {
LOGGER.error(message, t);
Utils.LOGGER.error(message, t);
if (IS_GUI) InceptumGui.WINDOWS.add(new AlertWindow(message, t.toString()));
}
public static void showInfo(String message, String title) {
LOGGER.info(message);
Utils.LOGGER.info(message);
if (IS_GUI) InceptumGui.WINDOWS.add(new AlertWindow(title, message));
}
@ -126,7 +84,7 @@ public class Inceptum {
}
public static void showOkCancel(String message, String title, Runnable ok, Runnable cancel, boolean defaultCancel) {
LOGGER.info(message);
Utils.LOGGER.info(message);
if (IS_GUI) InceptumGui.WINDOWS.add(new AlertWindow(title, message, ok, cancel));
else if (!defaultCancel) ok.run();
}

View File

@ -5,12 +5,14 @@ import imgui.ImGuiIO;
import imgui.flag.ImGuiConfigFlags;
import imgui.gl3.ImGuiImplGl3;
import imgui.glfw.ImGuiImplGlfw;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.frontend.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.ModsDirScanner;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
import io.gitlab.jfronny.inceptum.windows.Window;
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
import org.lwjgl.glfw.Callbacks;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
@ -41,14 +43,14 @@ public class InceptumGui {
public static void main(CommandArgs args, Runnable exec) {
AccountManager.loadAccounts();
Inceptum.LOGGER.info("Initializing UI");
Utils.LOGGER.info("Initializing UI");
try {
for (Path path : Utils.ls(Inceptum.INSTANCE_DIR)) {
for (Path path : Utils.ls(MetaHolder.INSTANCE_DIR)) {
if (Files.exists(path.resolve("instance.json")))
ModsDirScanner.get(path, Utils.loadObject(path.resolve("instance.json"), InstanceMeta.class)).start();
}
} catch (IOException e) {
Inceptum.LOGGER.error("Could not initialize MDS");
Utils.LOGGER.error("Could not initialize MDS");
}
init();
exec.run();
@ -206,7 +208,7 @@ public class InceptumGui {
}
public static void applyTheme() {
if (Inceptum.CONFIG.darkTheme) ImGui.styleColorsDark();
if (ConfigHolder.CONFIG.darkTheme) ImGui.styleColorsDark();
else ImGui.styleColorsLight();
}
}

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.inceptum.cli;
package io.gitlab.jfronny.inceptum.frontend.cli;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
@ -32,20 +32,20 @@ public abstract class BaseInstanceCommand extends Command {
@Override
protected void invoke(CommandArgs args) {
if (args.length == 0) {
Inceptum.LOGGER.error("You must specify an instance to commit in");
Utils.LOGGER.error("You must specify an instance to commit in");
return;
}
Path instancePath = Inceptum.INSTANCE_DIR.resolve(args.get(0));
Path instancePath = MetaHolder.INSTANCE_DIR.resolve(args.get(0));
Path instanceMetaPath = instancePath.resolve("instance.json");
if (!Files.exists(instanceMetaPath)) {
Inceptum.LOGGER.error("Invalid instance: \"" + args.get(0) + "\"");
Utils.LOGGER.error("Invalid instance: \"" + args.get(0) + "\"");
return;
}
InstanceMeta meta;
try {
meta = Utils.loadObject(instanceMetaPath, InstanceMeta.class);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not read instance metadata", e);
Utils.LOGGER.error("Could not read instance metadata", e);
return;
}
invoke(args.subArgs(), instancePath, meta);

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.cli;
package io.gitlab.jfronny.inceptum.frontend.cli;
import java.util.*;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.cli;
package io.gitlab.jfronny.inceptum.frontend.cli;
import java.util.*;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.cli;
package io.gitlab.jfronny.inceptum.frontend.cli;
import java.util.List;

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.inceptum.cli;
package io.gitlab.jfronny.inceptum.frontend.cli;
import io.gitlab.jfronny.inceptum.cli.commands.*;
import io.gitlab.jfronny.inceptum.frontend.cli.commands.*;
import java.util.ArrayList;
import java.util.Arrays;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.cli;
package io.gitlab.jfronny.inceptum.frontend.cli;
import java.util.ArrayList;
import java.util.List;

View File

@ -1,11 +1,11 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.cli.CommandResolution;
import io.gitlab.jfronny.inceptum.cli.Commands;
import io.gitlab.jfronny.inceptum.frontend.cli.Command;
import io.gitlab.jfronny.inceptum.frontend.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.frontend.cli.CommandResolution;
import io.gitlab.jfronny.inceptum.frontend.cli.Commands;
import io.gitlab.jfronny.inceptum.util.ArgumentTokenizer;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.nio.file.Files;
import java.nio.file.Path;
@ -20,18 +20,18 @@ public class BatchCommand extends Command {
@Override
protected void invoke(CommandArgs args) {
if (args.length == 0) {
Inceptum.LOGGER.error("Could not start batch execution: No source file specified");
Utils.LOGGER.error("Could not start batch execution: No source file specified");
return;
}
Set<CommandResolution> resolved = new LinkedHashSet<>();
for (String arg : args) {
Path p = Path.of(arg);
if (!Files.exists(p)) {
Inceptum.LOGGER.error("Could not find " + p);
Utils.LOGGER.error("Could not find " + p);
return;
}
if (Files.isDirectory(p)) {
Inceptum.LOGGER.error("Path is a directory: " + p);
Utils.LOGGER.error("Path is a directory: " + p);
return;
}
try {
@ -42,7 +42,7 @@ public class BatchCommand extends Command {
resolved.add(resolution);
}
} catch (Exception e) {
Inceptum.LOGGER.error("Could not read file", e);
Utils.LOGGER.error("Could not read file", e);
return;
}
}

View File

@ -1,12 +1,13 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.cli.BaseInstanceCommand;
import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.install.Steps;
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.model.inceptum.Config;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
@ -33,7 +34,7 @@ public class GitCommand extends Command {
@Override
protected void invoke(CommandArgs args) {
Inceptum.LOGGER.error("No known git command was specified");
Utils.LOGGER.error("No known git command was specified");
}
private static abstract class BaseGitCommand extends BaseInstanceCommand {
@ -44,13 +45,13 @@ public class GitCommand extends Command {
@Override
protected void invoke(CommandArgs args, Path instancePath, InstanceMeta meta) {
try (Git git = Git.open(instancePath.toFile())) {
Config.GitConfig.GitAuth config = Inceptum.CONFIG.git.instanceAuths.get(instancePath.getFileName().toString());
Config.GitConfig.GitAuth config = ConfigHolder.CONFIG.git.instanceAuths.get(instancePath.getFileName().toString());
boolean changed = false;
if (Inceptum.CONFIG.git == null) {
Inceptum.CONFIG.git = new Config.GitConfig();
if (ConfigHolder.CONFIG.git == null) {
ConfigHolder.CONFIG.git = new Config.GitConfig();
changed = true;
}
if (changed) Inceptum.saveConfig();
if (changed) ConfigHolder.saveConfig();
invoke(args.subArgs(), instancePath, git, config.username != null && config.password != null
? new UsernamePasswordCredentialsProvider(config.username, config.password)
: CredentialsProvider.getDefault());
@ -75,8 +76,8 @@ public class GitCommand extends Command {
.setMessage(args.length > 1
? String.join(" ", args.getArgs())
: "Commit at t" + System.currentTimeMillis())
.setSign(Inceptum.CONFIG.git.signCommits)
.setAuthor(Inceptum.CONFIG.git.commitUsername, Inceptum.CONFIG.git.commitMail)
.setSign(ConfigHolder.CONFIG.git.signCommits)
.setAuthor(ConfigHolder.CONFIG.git.commitUsername, ConfigHolder.CONFIG.git.commitMail)
.setCredentialsProvider(credentials)
.call();
} catch (GitAPIException e) {
@ -164,7 +165,7 @@ public class GitCommand extends Command {
System.err.println("Invalid name: " + name);
return;
}
Path instanceDir = Inceptum.INSTANCE_DIR.resolve(name);
Path instanceDir = MetaHolder.INSTANCE_DIR.resolve(name);
if (Files.exists(instanceDir)) {
System.err.println("An instance by that name already exists");
return;

View File

@ -1,12 +1,12 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
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.windows.MainWindow;
import io.gitlab.jfronny.inceptum.frontend.gui.MainWindow;
import java.io.IOException;
import java.net.URI;

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.cli.*;
import io.gitlab.jfronny.inceptum.frontend.cli.*;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import java.util.List;

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.frontend.cli.Command;
import io.gitlab.jfronny.inceptum.frontend.cli.CommandArgs;
import java.net.URLClassLoader;
import java.util.Arrays;

View File

@ -1,12 +1,13 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.cli.BaseInstanceCommand;
import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
import io.gitlab.jfronny.inceptum.install.Steps;
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.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;
@ -46,22 +47,22 @@ public class LaunchCommand extends BaseInstanceCommand {
@Override
protected void invoke(CommandArgs args, Path instancePath, InstanceMeta meta) {
if (args.length == 0) {
Inceptum.LOGGER.error("You must provide an instance name or path");
Utils.LOGGER.error("You must provide an instance name or path");
return;
}
String pArg = args.get(0);
Path instanceDir = Files.exists(Path.of(pArg)) ? Path.of(pArg) : Inceptum.INSTANCE_DIR.resolve(pArg);
Path instanceDir = Files.exists(Path.of(pArg)) ? Path.of(pArg) : MetaHolder.INSTANCE_DIR.resolve(pArg);
if (!Files.exists(instanceDir.resolve("instance.json"))) {
Inceptum.LOGGER.error("Not a valid instance");
Utils.LOGGER.error("Not a valid instance");
return;
}
if (InstanceLock.isSetupLocked(instanceDir)) {
Inceptum.LOGGER.error("This instance is still being set up");
Utils.LOGGER.error("This instance is still being set up");
return;
}
try {
if (InstanceLock.isRunningLocked(instanceDir)) {
Inceptum.LOGGER.error("This instance is already running");
Utils.LOGGER.error("This instance is already running");
return;
}
} catch (IOException e) {

View File

@ -1,10 +1,10 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
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.util.InstanceLock;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
@ -20,7 +20,7 @@ public class ListCommand extends Command {
@Override
protected void invoke(CommandArgs args) {
try {
List<Path> paths = Utils.ls(Inceptum.INSTANCE_DIR);
List<Path> paths = Utils.ls(MetaHolder.INSTANCE_DIR);
if (paths.isEmpty()) System.out.println("No instances are currently present");
for (Path path : paths) {
if (!Files.exists(path.resolve("instance.json"))) {
@ -36,7 +36,7 @@ public class ListCommand extends Command {
try {
instance = Utils.loadObject(path.resolve("instance.json"), InstanceMeta.class);
} catch (IOException e) {
Inceptum.LOGGER.error(" Could not load instance.json", e);
Utils.LOGGER.error(" Could not load instance.json", e);
continue;
}
System.out.println(" Status: " + (InstanceLock.isRunningLocked(path) ? "Running" : "Stopped"));

View File

@ -1,13 +1,13 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.cli.BaseInstanceCommand;
import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
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.ModManager;
import io.gitlab.jfronny.inceptum.util.ModsDirScanner;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
import java.nio.file.Files;
@ -25,7 +25,7 @@ public class ModCommand extends Command {
@Override
protected void invoke(CommandArgs args) {
Inceptum.LOGGER.error("No known mod command was specified");
Utils.LOGGER.error("No known mod command was specified");
}
public static class ModListCommand extends BaseInstanceCommand {
@ -88,32 +88,32 @@ public class ModCommand extends Command {
@Override
protected void invoke(CommandArgs args, Path instancePath, InstanceMeta meta) {
if (!meta.isFabric()) {
Inceptum.LOGGER.error("This is not a fabric instance");
Utils.LOGGER.error("This is not a fabric instance");
return;
}
if (args.length == 0) {
Inceptum.LOGGER.error("You must specify mods to remove");
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)) {
Inceptum.LOGGER.error("Nonexistant mod file: " + p);
Utils.LOGGER.error("Nonexistant mod file: " + p);
return;
}
mods.add(p);
}
ModsDirScanner mds = ModsDirScanner.get(instancePath.resolve("mods"), meta);
if (!ignoreDependencies && !mds.scanComplete()) {
Inceptum.LOGGER.error("Scanning mods dir to search for dependencies. This might take a while");
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 {
ModManager.delete(new ModsDirScanner.IWModDescription(mod), instancePath.resolve("mods"), mds);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not delete " + mod, e);
Utils.LOGGER.error("Could not delete " + mod, e);
return;
}
}

View File

@ -1,8 +1,7 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.cli.Command;
import io.gitlab.jfronny.inceptum.cli.CommandArgs;
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.*;
@ -52,16 +51,16 @@ public class UpdateCheckCommand extends Command {
}
public static UpdateInfo getUpdate() {
return UpdateChecker.check(Inceptum.CONFIG.channel, MetaHolder.VERSION.version, MetaHolder.VERSION.flavor, channel -> {
Inceptum.LOGGER.error("No stable version was found, switching to experimental channel");
Inceptum.CONFIG.channel = channel;
Inceptum.saveConfig();
}, Inceptum.LOGGER::info, Inceptum.LOGGER::error, Inceptum.LOGGER::error);
return UpdateChecker.check(ConfigHolder.CONFIG.channel, MetaHolder.VERSION.version, MetaHolder.VERSION.flavor, channel -> {
Utils.LOGGER.error("No stable version was found, switching to experimental channel");
ConfigHolder.CONFIG.channel = channel;
ConfigHolder.saveConfig();
}, Utils.LOGGER::info, Utils.LOGGER::error, Utils.LOGGER::error);
}
public static void update(UpdateInfo source, boolean relaunch) throws IOException, URISyntaxException {
Inceptum.LOGGER.info("Downloading " + source.url());
Path jarPath = Inceptum.LIBRARIES_DIR.resolve("io/gitlab/jfronny/inceptum/Inceptum")
Utils.LOGGER.info("Downloading " + source.url());
Path jarPath = MetaHolder.LIBRARIES_DIR.resolve("io/gitlab/jfronny/inceptum/Inceptum")
.resolve(source.newVersion().toString())
.resolve("Inceptum-" + source.newVersion() + '-' + OSCheck.OS.getMojName() + ".jar")
.toAbsolutePath();

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.inceptum.cli.commands;
package io.gitlab.jfronny.inceptum.frontend.cli.commands;
import io.gitlab.jfronny.inceptum.cli.*;
import io.gitlab.jfronny.inceptum.frontend.cli.*;
public class WrapperCommand extends Command {
public WrapperCommand() {

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.ImGui;
import io.gitlab.jfronny.inceptum.Inceptum;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.ImGui;
import imgui.flag.ImGuiTableFlags;
@ -218,7 +218,7 @@ public class AddModWindow extends Window {
ImGui.endTabBar();
}
} catch (IOException | URISyntaxException e) {
Inceptum.LOGGER.error("Something went wrong while rendering an AddModWindow", e);
Utils.LOGGER.error("Something went wrong while rendering an AddModWindow", e);
}
}

View File

@ -1,11 +1,11 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.ImGui;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.install.Step;
import io.gitlab.jfronny.inceptum.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.model.inceptum.install.Steps;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
@ -33,11 +33,11 @@ public class InstanceCreateProcessWindow extends Window {
}
private void creationThread() {
if (Files.exists(Inceptum.INSTANCE_DIR.resolve(stepInfo.name()))) {
if (Files.exists(MetaHolder.INSTANCE_DIR.resolve(stepInfo.name()))) {
finalize.set(true);
return;
}
Inceptum.LOGGER.info("Starting install process");
Utils.LOGGER.info("Starting install process");
try {
for (Step step : Steps.STEPS) {
if (finalize.get()) {
@ -58,9 +58,15 @@ public class InstanceCreateProcessWindow extends Window {
private void cleanUp() {
try {
Utils.deleteRecursive(Inceptum.INSTANCE_DIR.resolve(stepInfo.name()));
Utils.deleteRecursive(MetaHolder.INSTANCE_DIR.resolve(stepInfo.name()));
} catch (IOException e) {
Inceptum.LOGGER.error("Could not delete instance dir", e);
Utils.LOGGER.error("Could not delete instance dir", e);
}
}
@Override
public void close() {
super.close();
finalize.set(true);
}
}

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.ImGui;
import imgui.flag.ImGuiInputTextFlags;
@ -6,11 +6,11 @@ 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.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.*;
import io.gitlab.jfronny.inceptum.windows.control.InstanceManageControls;
import java.io.IOException;
import java.nio.file.Files;
@ -43,8 +43,8 @@ public class InstanceEditWindow extends Window {
mds.start();
customJava = new ImBoolean(instance.java != null);
imc = new InstanceManageControls(instance);
if (Inceptum.CONFIG.git.instanceAuths.containsKey(name)) {
Config.GitConfig.GitAuth config = Inceptum.CONFIG.git.instanceAuths.get(name);
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);
}
@ -62,7 +62,7 @@ public class InstanceEditWindow extends Window {
}
} catch (IOException e) {
ImGui.text("Could not read lock state on this instance");
Inceptum.LOGGER.error("Could not read lock state", e);
Utils.LOGGER.error("Could not read lock state", e);
}
lastTabWasMods = false;
if (ImGui.beginTabBar("InstanceEdit" + path)) {
@ -72,7 +72,7 @@ public class InstanceEditWindow extends Window {
}
imc.nameBox("Rename", name -> {
try {
Path newPath = Inceptum.INSTANCE_DIR.resolve(name);
Path newPath = MetaHolder.INSTANCE_DIR.resolve(name);
Files.move(path, newPath);
InceptumGui.open(new InstanceEditWindow(newPath, instance));
close();
@ -115,7 +115,7 @@ public class InstanceEditWindow extends Window {
try {
Files.createDirectories(path.resolve("mods"));
} catch (IOException e) {
Inceptum.LOGGER.error("Could not create mods directory which was missing from this modded instance", e);
Utils.LOGGER.error("Could not create mods directory which was missing from this modded instance", e);
}
}
ImGui.beginChild("mods select", 200, 0);
@ -254,12 +254,12 @@ public class InstanceEditWindow extends Window {
boolean update = ImGui.inputText("Username", gitUsername);
update |= ImGui.inputText("Password", gitPassword, ImGuiInputTextFlags.Password);
if (update) {
if (!Inceptum.CONFIG.git.instanceAuths.containsKey(name))
Inceptum.CONFIG.git.instanceAuths.put(name, new Config.GitConfig.GitAuth());
Config.GitConfig.GitAuth config = Inceptum.CONFIG.git.instanceAuths.get(name);
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();
Inceptum.saveConfig();
ConfigHolder.saveConfig();
}
ImGui.endTabItem();
}
@ -275,7 +275,7 @@ public class InstanceEditWindow extends Window {
try {
Utils.writeObject(path.resolve("instance.json"), instance);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not write instance config", e);
Utils.LOGGER.error("Could not write instance config", e);
}
}

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.ImGui;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.ImGui;
import imgui.flag.ImGuiWindowFlags;
@ -6,13 +6,15 @@ import imgui.type.ImBoolean;
import imgui.type.ImInt;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.install.Steps;
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;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
import io.gitlab.jfronny.inceptum.util.api.account.AuthInfo;
import io.gitlab.jfronny.inceptum.util.api.account.MicrosoftAccount;
import io.gitlab.jfronny.inceptum.windows.control.InstanceView;
import java.io.IOException;
import java.nio.file.Files;
@ -21,7 +23,7 @@ import java.util.List;
import java.util.function.Predicate;
public class MainWindow extends Window {
private final ImBoolean darkTheme = new ImBoolean(Inceptum.CONFIG.darkTheme);
private final ImBoolean darkTheme = new ImBoolean(ConfigHolder.CONFIG.darkTheme);
private final ImBoolean debugTools = new ImBoolean(false);
private final ImInt accountIndex = new ImInt(AccountManager.getSelectedIndex());
public MainWindow() {
@ -40,10 +42,10 @@ public class MainWindow extends Window {
if (ImGui.menuItem("New Instance")) InceptumGui.open(new NewInstanceWindow());
if (ImGui.menuItem("Re-download resources")) {
try {
Utils.clearDirectory(Inceptum.ASSETS_DIR);
Utils.clearDirectory(Inceptum.LIBRARIES_DIR, path -> !path.startsWith(Inceptum.LIBRARIES_DIR.resolve("io/gitlab/jfronny")));
Utils.clearDirectory(Inceptum.NATIVES_DIR, path -> !path.endsWith("forceload"));
Utils.clearDirectory(Inceptum.CACHE_DIR);
Utils.clearDirectory(MetaHolder.ASSETS_DIR);
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(() -> {
@ -82,8 +84,8 @@ public class MainWindow extends Window {
}
if (ImGui.beginMenu("Settings")) {
if (ImGui.checkbox("Dark Theme", darkTheme)) {
Inceptum.CONFIG.darkTheme = darkTheme.get();
Inceptum.saveConfig();
ConfigHolder.CONFIG.darkTheme = darkTheme.get();
ConfigHolder.saveConfig();
InceptumGui.applyTheme();
}
ImGui.endMenu();
@ -102,10 +104,10 @@ public class MainWindow extends Window {
List<Path> paths;
try {
if (!Files.exists(Inceptum.INSTANCE_DIR)) Files.createDirectories(Inceptum.INSTANCE_DIR);
paths = Utils.ls(Inceptum.INSTANCE_DIR, (Predicate<Path>) Files::isDirectory);
if (!Files.exists(MetaHolder.INSTANCE_DIR)) Files.createDirectories(MetaHolder.INSTANCE_DIR);
paths = Utils.ls(MetaHolder.INSTANCE_DIR, (Predicate<Path>) Files::isDirectory);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not list instances");
Utils.LOGGER.error("Could not list instances");
return;
}
if (paths.isEmpty()) {

View File

@ -1,8 +1,9 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import com.sun.net.httpserver.HttpServer;
import imgui.ImGui;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.gson.GsonHolder;
import io.gitlab.jfronny.inceptum.model.microsoft.*;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
@ -35,7 +36,7 @@ public class MicrosoftLoginWindow extends Window {
try {
startServer();
} catch (Exception e) {
Inceptum.LOGGER.error("Could not start mc login server", e);
Utils.LOGGER.error("Could not start mc login server", e);
}
}
@ -47,7 +48,7 @@ public class MicrosoftLoginWindow extends Window {
try {
Utils.openWebBrowser(new URI(MICROSOFT_LOGIN_URL));
} catch (URISyntaxException e) {
Inceptum.LOGGER.error("Could not open browser", e);
Utils.LOGGER.error("Could not open browser", e);
}
}
}
@ -70,7 +71,7 @@ public class MicrosoftLoginWindow extends Window {
if (query.containsKey("error")) {
respCode = 500;
respStr = "Error logging in. Check console for more information";
Inceptum.LOGGER.error("Error logging into Microsoft account: " + URLDecoder
Utils.LOGGER.error("Error logging into Microsoft account: " + URLDecoder
.decode(query.get("error_description"), StandardCharsets.UTF_8.toString()));
}
else if (query.containsKey("code")) {
@ -79,7 +80,7 @@ public class MicrosoftLoginWindow extends Window {
respCode = 200;
respStr = "Login complete. You can now close this window and go back to Inceptum";
} catch (Exception e) {
Inceptum.LOGGER.error("Error acquiring accessToken", e);
Utils.LOGGER.error("Error acquiring accessToken", e);
respCode = 500;
respStr = "Error logging in. Check console for more information";
}
@ -136,7 +137,7 @@ public class MicrosoftLoginWindow extends Window {
Store store = MicrosoftAuthAPI.getMcEntitlements(loginResponse.accessToken);
Inceptum.LOGGER.info(Inceptum.GSON.toJson(store));
Utils.LOGGER.info(GsonHolder.getGson().toJson(store));
if (!(store.items.stream().anyMatch(i -> i.name.equalsIgnoreCase("product_minecraft"))
&& store.items.stream().anyMatch(i -> i.name.equalsIgnoreCase("game_minecraft")))) {

View File

@ -1,9 +1,9 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.windows.control.InstanceManageControls;
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 java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
@ -25,7 +25,7 @@ public class NewInstanceWindow extends Window {
name,
new AtomicReference<>("Initializing"))));
} catch (IOException e) {
Inceptum.LOGGER.error("Could not initialize instance creation", e);
Utils.LOGGER.error("Could not initialize instance creation", e);
}
close();
});

View File

@ -1,9 +1,9 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.ImGui;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.install.Steps;
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;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.windows;
package io.gitlab.jfronny.inceptum.frontend.gui;
import imgui.flag.ImGuiWindowFlags;
import imgui.type.ImBoolean;

View File

@ -1,16 +1,17 @@
package io.gitlab.jfronny.inceptum.windows.control;
package io.gitlab.jfronny.inceptum.frontend.gui.control;
import imgui.ImGui;
import imgui.type.ImBoolean;
import imgui.type.ImInt;
import imgui.type.ImString;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.fabric.FabricVersionLoaderInfo;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.model.mojang.VersionsList;
import io.gitlab.jfronny.inceptum.model.mojang.VersionsListInfo;
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.util.api.McApi;
@ -30,7 +31,7 @@ public class InstanceManageControls {
private final ImInt version = new ImInt(0);
private final ImString name = new ImString("", MAX_NAME_LENGTH);
private final ImInt fabricVersion = new ImInt(0);
private final ImBoolean snapshots = new ImBoolean(Inceptum.CONFIG.snapshots);
private final ImBoolean snapshots = new ImBoolean(ConfigHolder.CONFIG.snapshots);
private final ImBoolean fabric = new ImBoolean(true);
private VersionsListInfo selected;
private FabricVersionLoaderInfo selectedFabric;
@ -63,7 +64,7 @@ public class InstanceManageControls {
ImGui.inputTextWithHint("Name", "Select a name", name);
if (!Utils.VALID_FILENAME.matcher(name.get()).matches())
ImGui.text("Invalid name");
else if (Files.exists(Inceptum.INSTANCE_DIR.resolve(name.get())))
else if (Files.exists(MetaHolder.INSTANCE_DIR.resolve(name.get())))
ImGui.text("Already exists");
else if (ImGui.button(okText)) {
ok.accept(name.get());
@ -72,23 +73,23 @@ public class InstanceManageControls {
public void snapshotsBox() {
if (ImGui.checkbox("Show snapshots", snapshots)) {
boolean prev = Inceptum.CONFIG.snapshots;
Inceptum.CONFIG.snapshots = snapshots.get();
Inceptum.saveConfig();
boolean prev = ConfigHolder.CONFIG.snapshots;
ConfigHolder.CONFIG.snapshots = snapshots.get();
ConfigHolder.saveConfig();
//fix version index
int i = getVersions(Inceptum.CONFIG.snapshots).indexOf(getVersions(prev).get(version.get()));
int i = getVersions(ConfigHolder.CONFIG.snapshots).indexOf(getVersions(prev).get(version.get()));
if (i == -1) version.set(0);
else version.set(i);
}
}
public void versionBox(Consumer<String> modifiedVersion) {
List<VersionsListInfo> vil = getVersions(Inceptum.CONFIG.snapshots);
List<VersionsListInfo> vil = getVersions(ConfigHolder.CONFIG.snapshots);
String originalStr = null;
try {
originalStr = getVersionInfo().id;
} catch (IOException e) {
Inceptum.LOGGER.error("Could not get version string", e);
Utils.LOGGER.error("Could not get version string", e);
}
if (ImGui.combo("Version", version, vil.stream().map(info -> info.id).toArray(String[]::new))) {
VersionsListInfo prev = selected;
@ -120,7 +121,7 @@ public class InstanceManageControls {
if (originalStr != null && !originalStr.equals(getVersionInfo().id))
modifiedVersion.accept(getVersionInfo().id);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not compare version string", e);
Utils.LOGGER.error("Could not compare version string", e);
}
}

View File

@ -1,15 +1,14 @@
package io.gitlab.jfronny.inceptum.windows.control;
package io.gitlab.jfronny.inceptum.frontend.gui.control;
import imgui.ImGui;
import imgui.flag.ImGuiTableFlags;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.InceptumGui;
import io.gitlab.jfronny.inceptum.install.Steps;
import io.gitlab.jfronny.inceptum.model.inceptum.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.windows.InstanceEditWindow;
import io.gitlab.jfronny.inceptum.frontend.gui.InstanceEditWindow;
import java.io.IOException;
import java.nio.file.Files;
@ -28,14 +27,14 @@ public class InstanceView {
continue;
}
if (!Files.exists(path.resolve("instance.json"))) {
Inceptum.LOGGER.error("Invalid instance (doesn't contain instance.json): " + path);
Utils.LOGGER.error("Invalid instance (doesn't contain instance.json): " + path);
continue;
}
InstanceMeta instance;
try {
instance = Utils.loadObject(path.resolve("instance.json"), InstanceMeta.class);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not load instance.json", e);
Utils.LOGGER.error("Could not load instance.json", e);
continue;
}
ImGui.tableNextColumn();

View File

@ -1,8 +1,8 @@
package io.gitlab.jfronny.inceptum.windows.dialog;
package io.gitlab.jfronny.inceptum.frontend.gui.dialog;
import imgui.ImGui;
import imgui.flag.ImGuiWindowFlags;
import io.gitlab.jfronny.inceptum.windows.Window;
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
public class AlertWindow extends Window {
private final String message;

View File

@ -1,8 +1,8 @@
package io.gitlab.jfronny.inceptum.windows.dialog;
package io.gitlab.jfronny.inceptum.frontend.gui.dialog;
import imgui.ImGui;
import imgui.type.ImString;
import io.gitlab.jfronny.inceptum.windows.Window;
import io.gitlab.jfronny.inceptum.frontend.gui.Window;
import java.util.function.Consumer;

View File

@ -1,29 +0,0 @@
package io.gitlab.jfronny.inceptum.install.steps;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.install.Step;
import io.gitlab.jfronny.inceptum.model.mojang.AssetIndex;
import io.gitlab.jfronny.inceptum.util.api.McApi;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class DownloadAssetsStep implements Step {
@Override
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
Path o = Inceptum.ASSETS_DIR.resolve("objects");
for (Map.Entry<String, AssetIndex.Asset> entry : McApi.getAssetIndex(info.version()).objects.entrySet()) {
if (stopThread.get()) return;
Path fPath = o.resolve(entry.getValue().hash.substring(0, 2));
if (!Files.exists(fPath)) Files.createDirectories(fPath);
fPath = fPath.resolve(entry.getValue().hash);
if (Files.exists(fPath)) continue;
info.setState("Downloading asset: " + entry.getKey());
McApi.downloadAsset(entry.getValue(), fPath);
}
}
}

View File

@ -1,55 +0,0 @@
package io.gitlab.jfronny.inceptum.install.steps;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.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;
import io.gitlab.jfronny.inceptum.util.Utils;
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.concurrent.atomic.AtomicBoolean;
public class DownloadClientStep implements Step {
@Override
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
Path clientPath = Inceptum.LIBRARIES_DIR.resolve("net/minecraft/client");
Path serverPath = Inceptum.LIBRARIES_DIR.resolve("net/minecraft/server");
if (!Files.exists(clientPath)) Files.createDirectories(clientPath);
if (!Files.exists(serverPath)) Files.createDirectories(serverPath);
String minecraftVersion = InstanceMeta.getMinecraftVersion(info.version().id);
clientPath = clientPath.resolve(minecraftVersion + ".jar");
serverPath = serverPath.resolve(minecraftVersion + ".jar");
if (!Files.exists(clientPath)) {
MojangFileDownload client = info.version().downloads.client;
info.setState("Downloading Client");
Utils.downloadFile(client.url, client.sha1, clientPath);
}
Inceptum.LOGGER.info(serverPath.toString());
if (!Files.exists(serverPath)) {
MojangFileDownload server = info.version().downloads.server;
if (new ComparableVersion(minecraftVersion).compareTo("1.18") >= 0) {
info.setState("Downloading Bundler");
Path p = Files.createTempFile("bundler", ".jar");
Utils.downloadFile(server.url, server.sha1, p);
try (FileSystem fs = Utils.openZipFile(p, false)) {
Files.copy(fs.getPath("META-INF", "versions", minecraftVersion, "server-" + minecraftVersion + ".jar"),
serverPath);
} catch (URISyntaxException e) {
Files.delete(p);
throw new IOException("Could not open bundler zip", e);
}
Files.delete(p);
}
else {
info.setState("Downloading Server");
Utils.downloadFile(server.url, server.sha1, serverPath);
}
}
}
}

View File

@ -1,16 +1,17 @@
package io.gitlab.jfronny.inceptum.model.inceptum;
import io.gitlab.jfronny.inceptum.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.HashUtils;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.CurseforgeApi;
import io.gitlab.jfronny.inceptum.util.api.ModrinthApi;
import org.eclipse.jgit.annotations.Nullable;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
@ -49,7 +50,7 @@ public class ModDescription {
changed = true;
}
}
catch (IOException e) {
catch (IOException | URISyntaxException e) {
// not found
}
}
@ -64,7 +65,7 @@ public class ModDescription {
res.sha1 = HashUtils.sha1(data);
res.murmur2 = HashUtils.murmur2(data);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not read file hash", e);
Utils.LOGGER.error("Could not read file hash", e);
}
res.dependents = new ArrayList<>();
res.dependencies = new ArrayList<>();
@ -87,7 +88,7 @@ public class ModDescription {
try {
sources.put(source, source.getUpdate(gameVersion));
} catch (IOException e) {
Inceptum.LOGGER.error("Could not check " + source.getName() + " for updates", e);
Utils.LOGGER.error("Could not check " + source.getName() + " for updates", e);
}
}
}

View File

@ -1,8 +1,8 @@
package io.gitlab.jfronny.inceptum.install;
package io.gitlab.jfronny.inceptum.model.inceptum.install;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.util.concurrent.atomic.AtomicReference;
@ -12,6 +12,6 @@ public record SetupStepInfo(VersionInfo version,
AtomicReference<String> currentState) {
public void setState(String state) {
currentState.set(state);
Inceptum.LOGGER.info(state);
Utils.LOGGER.info(state);
}
}

View File

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

View File

@ -1,12 +1,13 @@
package io.gitlab.jfronny.inceptum.install;
package io.gitlab.jfronny.inceptum.model.inceptum.install;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.steps.*;
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.Utils;
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.util.api.McApi;
@ -31,7 +32,7 @@ public class Steps {
);
public static void reDownload(Consumer<SetupStepInfo> update) throws IOException {
Utils.ls(Inceptum.INSTANCE_DIR, p -> {
Utils.ls(MetaHolder.INSTANCE_DIR, p -> {
try {
reDownload(p, update);
} catch (IOException e) {

View File

@ -0,0 +1,34 @@
package io.gitlab.jfronny.inceptum.model.inceptum.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.model.mojang.AssetIndex;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.api.McApi;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
public class DownloadAssetsStep implements Step {
@Override
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
Path o = MetaHolder.ASSETS_DIR.resolve("objects");
try {
for (Map.Entry<String, AssetIndex.Asset> entry : McApi.getAssetIndex(info.version()).objects.entrySet()) {
if (stopThread.get()) return;
Path fPath = o.resolve(entry.getValue().hash.substring(0, 2));
if (!Files.exists(fPath)) Files.createDirectories(fPath);
fPath = fPath.resolve(entry.getValue().hash);
if (Files.exists(fPath)) continue;
info.setState("Downloading asset: " + entry.getKey());
McApi.downloadAsset(entry.getValue(), fPath);
}
} catch (URISyntaxException e) {
throw new IOException("Could not download assets", e);
}
}
}

View File

@ -0,0 +1,59 @@
package io.gitlab.jfronny.inceptum.model.inceptum.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.model.ComparableVersion;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.mojang.MojangFileDownload;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
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.concurrent.atomic.AtomicBoolean;
public class DownloadClientStep implements Step {
@Override
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
Path clientPath = MetaHolder.LIBRARIES_DIR.resolve("net/minecraft/client");
Path serverPath = MetaHolder.LIBRARIES_DIR.resolve("net/minecraft/server");
if (!Files.exists(clientPath)) Files.createDirectories(clientPath);
if (!Files.exists(serverPath)) Files.createDirectories(serverPath);
String minecraftVersion = InstanceMeta.getMinecraftVersion(info.version().id);
clientPath = clientPath.resolve(minecraftVersion + ".jar");
serverPath = serverPath.resolve(minecraftVersion + ".jar");
try {
if (!Files.exists(clientPath)) {
MojangFileDownload client = info.version().downloads.client;
info.setState("Downloading Client");
Utils.downloadFile(client.url, client.sha1, clientPath);
}
Utils.LOGGER.info(serverPath.toString());
if (!Files.exists(serverPath)) {
MojangFileDownload server = info.version().downloads.server;
if (new ComparableVersion(minecraftVersion).compareTo("1.18") >= 0) {
info.setState("Downloading Bundler");
Path p = Files.createTempFile("bundler", ".jar");
Utils.downloadFile(server.url, server.sha1, p);
try (FileSystem fs = Utils.openZipFile(p, false)) {
Files.copy(fs.getPath("META-INF", "versions", minecraftVersion, "server-" + minecraftVersion + ".jar"),
serverPath);
} catch (URISyntaxException e) {
Files.delete(p);
throw new IOException("Could not open bundler zip", e);
}
Files.delete(p);
}
else {
info.setState("Downloading Server");
Utils.downloadFile(server.url, server.sha1, serverPath);
}
}
} catch (URISyntaxException e) {
throw new IOException("Could not download client", e);
}
}
}

View File

@ -1,15 +1,16 @@
package io.gitlab.jfronny.inceptum.install.steps;
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.install.Step;
import io.gitlab.jfronny.inceptum.model.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.model.inceptum.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;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.McApi;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
@ -19,7 +20,7 @@ public class DownloadJavaStep implements Step {
@Override
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
VersionInfo.JavaVersion ver = info.version().javaVersion;
Path jvmDir = Inceptum.NATIVES_DIR.resolve(ver.component).resolve(Integer.toString(ver.majorVersion));
Path jvmDir = MetaHolder.NATIVES_DIR.resolve(ver.component).resolve(Integer.toString(ver.majorVersion));
if (Files.exists(jvmDir)) return;
info.setState("Downloading JVM");
Files.createDirectories(jvmDir);
@ -29,7 +30,11 @@ public class DownloadJavaStep implements Step {
case "file" -> {
MojangFileDownload mf = entry.getValue().downloads.raw;
info.setState("jvm: Downloading " + tPath);
Utils.downloadFile(mf.url, mf.sha1, tPath);
try {
Utils.downloadFile(mf.url, mf.sha1, tPath);
} catch (URISyntaxException e) {
throw new IOException("Could not download jvm", e);
}
if (entry.getValue().executable) {
if (!tPath.toFile().setExecutable(true))
info.setState("Could not set executable bit for " + tPath);
@ -38,8 +43,8 @@ public class DownloadJavaStep implements Step {
case "directory" -> Files.createDirectories(tPath);
}
}
if (Files.exists(Inceptum.FORCE_LOAD_PATH)) {
Utils.copyContent(Inceptum.FORCE_LOAD_PATH, jvmDir.resolve("bin"));
if (Files.exists(MetaHolder.FORCE_LOAD_PATH)) {
Utils.copyContent(MetaHolder.FORCE_LOAD_PATH, jvmDir.resolve("bin"));
}
}
}

View File

@ -1,15 +1,16 @@
package io.gitlab.jfronny.inceptum.install.steps;
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.install.Step;
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.ArtifactInfo;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.VersionInfoLibraryResolver;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
@ -25,22 +26,26 @@ public class DownloadLibrariesStep implements Step {
public static void execute(VersionInfo version, AtomicBoolean stopThread, AtomicReference<String> currentState) throws IOException {
for (ArtifactInfo artifact : VersionInfoLibraryResolver.getRelevant(version)) {
if (stopThread.get()) return;
Path path = Inceptum.LIBRARIES_DIR.resolve(artifact.path);
Path path = MetaHolder.LIBRARIES_DIR.resolve(artifact.path);
if (!Files.exists(path)) {
currentState.set("Downloading library: " + artifact.path);
Inceptum.LOGGER.info(currentState.get());
Utils.LOGGER.info(currentState.get());
if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent());
if (!artifact.url.endsWith(".jar")) {
Inceptum.LOGGER.info("Not a valid URL for a jar: " + artifact.url);
Utils.LOGGER.info("Not a valid URL for a jar: " + artifact.url);
continue;
}
Utils.downloadFile(artifact.url, artifact.sha1, path);
try {
Utils.downloadFile(artifact.url, artifact.sha1, path);
} catch (URISyntaxException e) {
throw new IOException("Could not download library", e);
}
}
if (artifact.isNative) {
currentState.set("Extracting natives");
Inceptum.LOGGER.info(currentState.get());
Utils.LOGGER.info(currentState.get());
try (FileSystem libFs = Utils.openZipFile(path, false)) {
Utils.copyContent(libFs.getPath("."), Inceptum.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(version.id)));
Utils.copyContent(libFs.getPath("."), MetaHolder.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(version.id)));
}
catch (Throwable t) {
Files.delete(path);

View File

@ -1,11 +1,11 @@
package io.gitlab.jfronny.inceptum.install.steps;
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.install.Step;
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.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
import io.gitlab.jfronny.inceptum.util.InstanceLock;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import java.io.IOException;
import java.nio.file.Files;
@ -16,7 +16,7 @@ public class SetupDirsStep implements Step {
@Override
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
info.setState("Setting up instance dirs");
Path iDir = Inceptum.INSTANCE_DIR.resolve(info.name());
Path iDir = MetaHolder.INSTANCE_DIR.resolve(info.name());
InstanceLock.setSetupLock(iDir, true);
if (!Files.exists(iDir)) {
Files.createDirectories(iDir.resolve("resourcepacks"));
@ -33,6 +33,6 @@ public class SetupDirsStep implements Step {
if (!Files.exists(eulaTxt)) {
Files.writeString(eulaTxt, "eula=true");
}
Files.createDirectories(Inceptum.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(info.version().id)));
Files.createDirectories(MetaHolder.NATIVES_DIR.resolve(InstanceMeta.getMinecraftVersion(info.version().id)));
}
}

View File

@ -1,23 +1,15 @@
package io.gitlab.jfronny.inceptum.install.steps;
package io.gitlab.jfronny.inceptum.model.inceptum.install.steps;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
import io.gitlab.jfronny.inceptum.install.Step;
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.InstanceMeta;
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
import io.gitlab.jfronny.inceptum.util.InstanceLock;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.GpgSigner;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.transport.ChainingCredentialsProvider;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.NetRCCredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.util.SystemReader;
import java.io.IOException;
import java.nio.file.Files;
@ -28,7 +20,7 @@ public class WriteMetadataStep implements Step {
@Override
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
info.setState("Writing metadata");
Path instance = Inceptum.INSTANCE_DIR.resolve(info.name());
Path instance = MetaHolder.INSTANCE_DIR.resolve(info.name());
Path metaDir = instance.resolve("instance.json");
InstanceMeta meta = new InstanceMeta();
meta.version = info.version().id;
@ -56,7 +48,7 @@ public class WriteMetadataStep implements Step {
.setAll(true)
.setMessage("Initial commit")
.setSign(false)
.setAuthor(Inceptum.CONFIG.git.commitUsername, Inceptum.CONFIG.git.commitMail)
.setAuthor(ConfigHolder.CONFIG.git.commitUsername, ConfigHolder.CONFIG.git.commitMail)
.call();
} catch (GitAPIException e) {
Inceptum.showError("Could not initialize Git", e);

View File

@ -8,6 +8,7 @@ import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.CurseforgeApi;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashSet;
@ -30,7 +31,11 @@ public final class CurseforgeModSource implements ModSource {
@Override
public ModDownload download() throws IOException {
Path path = getJarPath();
Utils.downloadFile(current.downloadUrl, path);
try {
Utils.downloadFile(current.downloadUrl, path);
} catch (URISyntaxException e) {
throw new IOException("Could not download file", e);
}
byte[] data = Files.readAllBytes(path);
return new ModDownload(HashUtils.sha1(data), HashUtils.murmur2(data), path);
}

View File

@ -4,6 +4,7 @@ import io.gitlab.jfronny.inceptum.util.HashUtils;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
@ -17,7 +18,11 @@ public record DirectModSource(String fileName, String url, Set<ModSource> depend
@Override
public ModDownload download() throws IOException {
Path p = getJarPath();
Utils.downloadFile(url, p); //TODO test
try {
Utils.downloadFile(url, p); //TODO test
} catch (URISyntaxException e) {
throw new IOException("Could not download file", e);
}
byte[] data = Files.readAllBytes(p);
return new ModDownload(HashUtils.sha1(data), HashUtils.murmur2(data), p);
}

View File

@ -1,6 +1,6 @@
package io.gitlab.jfronny.inceptum.model.inceptum.source;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import java.io.IOException;
import java.nio.file.Path;
@ -17,6 +17,6 @@ public interface ModSource {
String getFileName();
boolean equals(ModSource other);
default Path getJarPath() {
return Inceptum.LIBRARIES_DIR.resolve("com").resolve(getName()).resolve(getFileName());
return MetaHolder.LIBRARIES_DIR.resolve("com").resolve(getName()).resolve(getFileName());
}
}

View File

@ -7,6 +7,7 @@ import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.api.ModrinthApi;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashSet;
@ -28,7 +29,11 @@ public final class ModrinthModSource implements ModSource {
public ModDownload download() throws IOException {
ModrinthVersion.File file = current.files.get(0);
Path path = getJarPath();
Utils.downloadFile(file.url, file.hashes.sha1, path);
try {
Utils.downloadFile(file.url, file.hashes.sha1, path);
} catch (URISyntaxException e) {
throw new IOException("Could not download file", e);
}
return new ModDownload(file.hashes.sha1, HashUtils.murmur2(Files.readAllBytes(path)), path);
}

View File

@ -1,10 +1,10 @@
package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.Inceptum;
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.lambda.ThrowingConsumer;
import java.io.Closeable;
import java.io.FileNotFoundException;
@ -152,7 +152,7 @@ public class ModsDirScanner implements Closeable {
}
Thread.sleep(100);
} catch (IOException | URISyntaxException | InterruptedException e) {
Inceptum.LOGGER.error("Could not list mods", e);
Utils.LOGGER.error("Could not list mods", e);
}
}
@ -228,7 +228,7 @@ public class ModsDirScanner implements Closeable {
return Utils.lsVi(path);
}
} catch (IOException e) {
Inceptum.LOGGER.error("Could not get description", e);
Utils.LOGGER.error("Could not get description", e);
}
return new String[] {"No description is available", "This mod may have been added manually"};
}

View File

@ -1,6 +1,5 @@
package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.OSType;
import java.io.BufferedReader;
@ -29,7 +28,7 @@ public class ProcessUtils {
}
return false;
} catch (Exception e) {
Inceptum.LOGGER.error("Could not get process state", e);
Utils.LOGGER.error("Could not get process state", e);
return true;
}
}

View File

@ -1,6 +1,5 @@
package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.inceptum.ArtifactInfo;
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
@ -16,7 +15,7 @@ public class VersionInfoLibraryResolver {
artifacts.add(new ArtifactInfo(library.downloads.classifiers.get(library.natives.get(OSCheck.OS.getMojName())), true));
}
if (library.downloads.artifact == null) {
Inceptum.LOGGER.info("Null library artifact @ " + library.name);
Utils.LOGGER.info("Null library artifact @ " + library.name);
continue;
}
artifacts.add(new ArtifactInfo(library.downloads.artifact, false));

View File

@ -9,6 +9,7 @@ import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
@ -39,7 +40,7 @@ public class CurseforgeApi {
return Utils.downloadObject(API_URL + "addon/" + modId + "/file/" + fileId, CurseforgeFile.class);
}
public static CurseforgeFingerprint checkFingerprint(String hash) throws IOException {
public static CurseforgeFingerprint checkFingerprint(String hash) throws IOException, URISyntaxException {
return HttpUtils.post(API_URL + "fingerprint").bodyJson("[" + hash + "]").sendJson(CurseforgeFingerprint.class);
}
}

View File

@ -1,11 +1,12 @@
package io.gitlab.jfronny.inceptum.util.api;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.model.mojang.*;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.OSCheck;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
@ -26,14 +27,14 @@ public class McApi {
return downloadObject(listInfo.url, listInfo.sha1, VersionInfo.class);
}
public static AssetIndex getAssetIndex(VersionInfo info) throws IOException {
Path file = Inceptum.ASSETS_DIR.resolve("indexes");
public static AssetIndex getAssetIndex(VersionInfo info) throws IOException, URISyntaxException {
Path file = MetaHolder.ASSETS_DIR.resolve("indexes");
if (!Files.exists(file)) Files.createDirectories(file);
file = file.resolve(info.assetIndex.url.substring(info.assetIndex.url.lastIndexOf("/") + 1));
try {
Utils.downloadFile(info.assetIndex.url, info.assetIndex.sha1, file);
}
catch (IOException e) {
catch (IOException | URISyntaxException e) {
if (!Files.exists(file)) throw e;
}
return Utils.loadObject(file, AssetIndex.class);
@ -58,7 +59,7 @@ public class McApi {
throw new IOException("JVM not found");
}
public static void downloadAsset(AssetIndex.Asset asset, Path path) throws IOException {
public static void downloadAsset(AssetIndex.Asset asset, Path path) throws IOException, URISyntaxException {
String url = "http://resources.download.minecraft.net/" + asset.hash.substring(0, 2) + "/" + asset.hash;
Utils.downloadFile(url, asset.hash, path);
}

View File

@ -2,6 +2,8 @@ package io.gitlab.jfronny.inceptum.util.api.account;
import com.google.gson.reflect.TypeToken;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.util.ConfigHolder;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.Utils;
import java.io.IOException;
@ -20,7 +22,7 @@ public class AccountManager {
if (SELECTED_ACCOUNT == null) return NULL_AUTH;
else if (SELECTED_ACCOUNT.ensureAccessTokenValid(a -> {})) return new AuthInfo(SELECTED_ACCOUNT);
else {
Inceptum.LOGGER.error("Couldn't login properly, using offline mode");
Utils.LOGGER.error("Couldn't login properly, using offline mode");
return NULL_AUTH;
}
}
@ -40,28 +42,28 @@ public class AccountManager {
public static void saveAccounts() {
try {
Utils.writeObject(Inceptum.ACCOUNTS_PATH, ACCOUNTS);
Utils.writeObject(MetaHolder.ACCOUNTS_PATH, ACCOUNTS);
} catch (IOException e) {
Inceptum.LOGGER.error("Could not save accounts", e);
Utils.LOGGER.error("Could not save accounts", e);
}
}
public static void loadAccounts() {
Inceptum.LOGGER.info("Loading accounts");
if (Files.exists(Inceptum.ACCOUNTS_PATH)) {
Utils.LOGGER.info("Loading accounts");
if (Files.exists(MetaHolder.ACCOUNTS_PATH)) {
try {
ACCOUNTS.addAll(Utils.loadObject(Inceptum.ACCOUNTS_PATH, abstractAccountListType));
ACCOUNTS.addAll(Utils.loadObject(MetaHolder.ACCOUNTS_PATH, abstractAccountListType));
} catch (IOException e) {
Inceptum.LOGGER.error("Could not load accounts", e);
Utils.LOGGER.error("Could not load accounts", e);
}
}
for (MicrosoftAccount account : ACCOUNTS) {
account.refreshAccessToken();
if (account.accountId.equalsIgnoreCase(Inceptum.CONFIG.lastAccount)) {
if (account.accountId.equalsIgnoreCase(ConfigHolder.CONFIG.lastAccount)) {
SELECTED_ACCOUNT = account;
}
}
Inceptum.LOGGER.info("Finished loading accounts");
Utils.LOGGER.info("Finished loading accounts");
}
public static void addAccount(MicrosoftAccount account) {
@ -86,15 +88,15 @@ public class AccountManager {
public static void switchAccount(MicrosoftAccount account) {
if (account == null) {
Inceptum.LOGGER.info("Logging out");
Utils.LOGGER.info("Logging out");
SELECTED_ACCOUNT = null;
Inceptum.CONFIG.lastAccount = null;
ConfigHolder.CONFIG.lastAccount = null;
} else {
Inceptum.LOGGER.info("Changed account to " + account);
Utils.LOGGER.info("Changed account to " + account);
SELECTED_ACCOUNT = account;
Inceptum.CONFIG.lastAccount = account.accountId;
ConfigHolder.CONFIG.lastAccount = account.accountId;
}
Inceptum.saveConfig();
ConfigHolder.saveConfig();
}
public static Object getAccountByName(String username) {

View File

@ -6,9 +6,11 @@ import io.gitlab.jfronny.inceptum.model.microsoft.LoginResponse;
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.windows.MicrosoftLoginWindow;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.frontend.gui.MicrosoftLoginWindow;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Optional;
@ -88,7 +90,7 @@ public class MicrosoftAccount {
return accessToken;
}
public String getCurrentUsername() throws IOException {
public String getCurrentUsername() throws IOException, URISyntaxException {
Profile profile = MicrosoftAuthAPI.getMcProfile(accessToken);
if (profile.name == null) throw new IOException("Got null name");
return profile.name;
@ -98,7 +100,7 @@ public class MicrosoftAccount {
this.refreshAccessToken();
}
public String getSkinUrl() throws IOException {
public String getSkinUrl() throws IOException, URISyntaxException {
Profile profile = MicrosoftAuthAPI.getMcProfile(accessToken);
return Optional.of(profile.skins).orElse(new ArrayList<>())
.stream()
@ -115,13 +117,13 @@ public class MicrosoftAccount {
public boolean refreshAccessToken(boolean force) {
try {
if (force || new Date().after(this.oauthToken.expiresAt)) {
Inceptum.LOGGER.info("Oauth token expired. Attempting to refresh");
Utils.LOGGER.info("Oauth token expired. Attempting to refresh");
OauthTokenResponse oauthTokenResponse = MicrosoftAuthAPI.refreshAccessToken(oauthToken.refreshToken);
if (oauthTokenResponse == null) {
mustLogin = true;
AccountManager.saveAccounts();
Inceptum.LOGGER.error("Failed to refresh accessToken");
Utils.LOGGER.error("Failed to refresh accessToken");
return false;
}
@ -131,14 +133,14 @@ public class MicrosoftAccount {
}
if (force || new Date().after(this.xstsAuth.notAfter)) {
Inceptum.LOGGER.info("xsts auth expired. Attempting to get new auth");
Utils.LOGGER.info("xsts auth expired. Attempting to get new auth");
XboxLiveAuthResponse xboxLiveAuthResponse = MicrosoftAuthAPI.getXBLToken(this.oauthToken.accessToken);
this.xstsAuth = MicrosoftAuthAPI.getXstsToken(xboxLiveAuthResponse.token);
if (xstsAuth == null) {
mustLogin = true;
AccountManager.saveAccounts();
Inceptum.LOGGER.error("Failed to get XBLToken");
Utils.LOGGER.error("Failed to get XBLToken");
return false;
}
@ -151,7 +153,7 @@ public class MicrosoftAccount {
if (loginResponse == null) {
mustLogin = true;
AccountManager.saveAccounts();
Inceptum.LOGGER.error("Failed to login to Minecraft");
Utils.LOGGER.error("Failed to login to Minecraft");
return false;
}
@ -168,7 +170,7 @@ public class MicrosoftAccount {
mustLogin = true;
AccountManager.saveAccounts();
Inceptum.LOGGER.error("Exception refreshing accessToken", e);
Utils.LOGGER.error("Exception refreshing accessToken", e);
return false;
}
@ -190,13 +192,13 @@ public class MicrosoftAccount {
return;
}
Inceptum.LOGGER.info("Access Token has expired. Attempting to refresh it.");
Utils.LOGGER.info("Access Token has expired. Attempting to refresh it.");
try {
isValid.accept(refreshAccessToken());
return;
} catch (Exception e) {
Inceptum.LOGGER.error("Exception while attempting to refresh access token", e);
Utils.LOGGER.error("Exception while attempting to refresh access token", e);
}
isValid.accept(false);

View File

@ -4,6 +4,7 @@ import io.gitlab.jfronny.inceptum.model.microsoft.*;
import io.gitlab.jfronny.inceptum.util.HttpUtils;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -29,7 +30,7 @@ public class MicrosoftAuthAPI {
public static final String MICROSOFT_MINECRAFT_STORE_URL = "https://api.minecraftservices.com/entitlements/mcstore";
public static final String MICROSOFT_MINECRAFT_PROFILE_URL = "https://api.minecraftservices.com/minecraft/profile";
public static OauthTokenResponse tradeCodeForAccessToken(String code) throws IOException {
public static OauthTokenResponse tradeCodeForAccessToken(String code) throws IOException, URISyntaxException {
return HttpUtils.post(MICROSOFT_AUTH_TOKEN_URL)
.bodyForm(Map.of("client_id", MICROSOFT_LOGIN_CLIENT_ID,
"code", code,
@ -39,7 +40,7 @@ public class MicrosoftAuthAPI {
.sendJson(OauthTokenResponse.class);
}
public static OauthTokenResponse refreshAccessToken(String refreshToken) throws IOException {
public static OauthTokenResponse refreshAccessToken(String refreshToken) throws IOException, URISyntaxException {
return HttpUtils.post(MICROSOFT_AUTH_TOKEN_URL)
.bodyForm(Map.of("client_id", MICROSOFT_LOGIN_CLIENT_ID,
"refresh_token", refreshToken,
@ -48,7 +49,7 @@ public class MicrosoftAuthAPI {
.sendJson(OauthTokenResponse.class);
}
public static XboxLiveAuthResponse getXBLToken(String accessToken) throws IOException {
public static XboxLiveAuthResponse getXBLToken(String accessToken) throws IOException, URISyntaxException {
Map<Object, Object> properties = new HashMap<>();
properties.put("AuthMethod", "RPS");
properties.put("SiteName", "user.auth.xboxlive.com");
@ -65,7 +66,7 @@ public class MicrosoftAuthAPI {
.sendJson(XboxLiveAuthResponse.class);
}
public static XboxLiveAuthResponse getXstsToken(String xblToken) throws IOException {
public static XboxLiveAuthResponse getXstsToken(String xblToken) throws IOException, URISyntaxException {
Map<Object, Object> properties = new HashMap<>();
properties.put("SandboxId", "RETAIL");
@ -84,7 +85,7 @@ public class MicrosoftAuthAPI {
.sendJson(XboxLiveAuthResponse.class);
}
public static LoginResponse loginToMinecraft(String xstsToken) throws IOException {
public static LoginResponse loginToMinecraft(String xstsToken) throws IOException, URISyntaxException {
Map<Object, Object> data = new HashMap<Object, Object>();
data.put("identityToken", xstsToken);
@ -93,11 +94,11 @@ public class MicrosoftAuthAPI {
.sendJson(LoginResponse.class);
}
public static Store getMcEntitlements(String accessToken) throws IOException {
public static Store getMcEntitlements(String accessToken) throws IOException, URISyntaxException {
return HttpUtils.get(MICROSOFT_MINECRAFT_STORE_URL).bearer(accessToken).sendJson(Store.class);
}
public static Profile getMcProfile(String accessToken) throws IOException {
public static Profile getMcProfile(String accessToken) throws IOException, URISyntaxException {
return HttpUtils.get(MICROSOFT_MINECRAFT_PROFILE_URL).bearer(accessToken).sendJson(Profile.class);
}
}

View File

@ -2,6 +2,7 @@ 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;
@ -10,7 +11,7 @@ import java.nio.file.Path;
public class ClientLauncher {
public static void launch(Path path, InstanceMeta instance) {
if (AccountManager.accountMissing() && Inceptum.CONFIG.enforceAccount) {
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;
}
@ -18,11 +19,11 @@ public class ClientLauncher {
if (authInfo.equals(AccountManager.NULL_AUTH)) {
try {
String sysUser = System.getProperty("user.name");
if (Inceptum.CONFIG.offlineAccountLastName == null)
Inceptum.CONFIG.offlineAccountLastName = sysUser;
Inceptum.getInput("User name", Inceptum.CONFIG.offlineAccountLastName, name -> {
Inceptum.CONFIG.offlineAccountLastName = name.equals(sysUser) ? null : name;
Inceptum.saveConfig();
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);
}, () -> {});

View File

@ -1,7 +1,6 @@
package io.gitlab.jfronny.inceptum.util.launch;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.install.steps.DownloadLibrariesStep;
import io.gitlab.jfronny.inceptum.model.inceptum.install.steps.DownloadLibrariesStep;
import io.gitlab.jfronny.inceptum.model.inceptum.ArtifactInfo;
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
import io.gitlab.jfronny.inceptum.model.inceptum.ModDescription;
@ -39,17 +38,17 @@ public class InstanceLauncher {
List<String> args = new LinkedList<>();
// JVM path
args.add(Objects.requireNonNullElseGet(instance.java, () ->
JvmUtils.getJvmMain(Inceptum.NATIVES_DIR
JvmUtils.getJvmMain(MetaHolder.NATIVES_DIR
.resolve(versionInfo.javaVersion.component)
.resolve(Integer.toString(versionInfo.javaVersion.majorVersion)))
.toAbsolutePath().toString()));
// Java classpath
StringBuilder classPath = new StringBuilder();
for (ArtifactInfo artifact : VersionInfoLibraryResolver.getRelevant(versionInfo)) {
classPath.append(Inceptum.LIBRARIES_DIR.resolve(artifact.path).toAbsolutePath());
classPath.append(MetaHolder.LIBRARIES_DIR.resolve(artifact.path).toAbsolutePath());
classPath.append(File.pathSeparatorChar);
}
Path gameJar = Inceptum.LIBRARIES_DIR.resolve("net/minecraft/" + launchType.name).resolve(versionDataSimple.id + ".jar").toAbsolutePath();
Path gameJar = MetaHolder.LIBRARIES_DIR.resolve("net/minecraft/" + launchType.name).resolve(versionDataSimple.id + ".jar").toAbsolutePath();
classPath.append(gameJar);
// JVM arguments
if (launchType == LaunchType.Client && versionInfo.arguments != null) args.addAll(parse(versionInfo.arguments.jvm, versionInfo, instance, classPath.toString(), instancePath.toAbsolutePath().toString(), authInfo));
@ -57,7 +56,7 @@ public class InstanceLauncher {
if (instance.maxMem != null) args.add("-Xmx" + instance.maxMem);
if (instance.arguments != null && instance.arguments.jvm != null) args.addAll(instance.arguments.jvm);
// Native library path
args.add("-Djava.library.path=" + Inceptum.NATIVES_DIR.resolve(instance.getMinecraftVersion()).toAbsolutePath());
args.add("-Djava.library.path=" + MetaHolder.NATIVES_DIR.resolve(instance.getMinecraftVersion()).toAbsolutePath());
// Fabric imods
if (instance.isFabric()) {
StringBuilder fabricAddMods = new StringBuilder("-Dfabric.addMods=");
@ -109,7 +108,7 @@ public class InstanceLauncher {
}
}
// Log command used to start
Inceptum.LOGGER.info(String.join(" ", args));
Utils.LOGGER.info(String.join(" ", args));
// Create process
ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[0]));
pb.directory(instancePath.toFile());
@ -121,7 +120,7 @@ public class InstanceLauncher {
proc.set(pb.start());
InstanceLock.setRunningLock(instancePath, proc.get().pid());
} catch (IOException e) {
Inceptum.LOGGER.error("Could not start " + launchType.name, e);
Utils.LOGGER.error("Could not start " + launchType.name, e);
}
};
starterRunner.run();
@ -131,12 +130,12 @@ public class InstanceLauncher {
try {
proc.get().waitFor();
} catch (InterruptedException e) {
Inceptum.LOGGER.error("Could not wait for server to finish", e);
Utils.LOGGER.error("Could not wait for server to finish", e);
}
Inceptum.LOGGER.info("Restarting server");
Utils.LOGGER.info("Restarting server");
starterRunner.run();
if (!proc.get().isAlive()) {
Inceptum.LOGGER.error("Could not restart server");
Utils.LOGGER.error("Could not restart server");
return;
}
}
@ -184,7 +183,7 @@ public class InstanceLauncher {
.replace("${auth_player_name}", authInfo.name())
.replace("${version_name}", instance.getMinecraftVersion())
.replace("${game_directory}", gameDirectory)
.replace("${assets_root}", Inceptum.ASSETS_DIR.toAbsolutePath().toString())
.replace("${assets_root}", MetaHolder.ASSETS_DIR.toAbsolutePath().toString())
.replace("${assets_index_name}", info.assets)
.replace("${auth_uuid}", authInfo.uuid())
.replace("${auth_access_token}", authInfo.accessToken())
@ -193,7 +192,7 @@ public class InstanceLauncher {
.replace("${resolution_width}", "1920") //TODO has_custom_resolution
.replace("${resolution_height}", "1080") //TODO has_custom_resolution
// jvm args
.replace("${natives_directory}", Inceptum.NATIVES_DIR.resolve(instance.getMinecraftVersion()).toAbsolutePath().toString())
.replace("${natives_directory}", MetaHolder.NATIVES_DIR.resolve(instance.getMinecraftVersion()).toAbsolutePath().toString())
.replace("${launcher_name}", "Inceptum")
.replace("${launcher_version}", MetaHolder.VERSION.version.toString())
.replace("${classpath}", classPath)

View File

@ -16,6 +16,8 @@ repositories {
dependencies {
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'org.slf4j:slf4j-api:1.7.32'
implementation 'ch.qos.logback:logback-classic:1.2.10'
}
processResources {

View File

@ -3,10 +3,7 @@ package io.gitlab.jfronny.inceptum;
import io.gitlab.jfronny.inceptum.model.ComparableVersion;
import io.gitlab.jfronny.inceptum.model.inceptum.UpdateChannel;
import io.gitlab.jfronny.inceptum.model.inceptum.UpdateInfo;
import io.gitlab.jfronny.inceptum.util.JvmUtils;
import io.gitlab.jfronny.inceptum.util.MetaHolder;
import io.gitlab.jfronny.inceptum.util.OSCheck;
import io.gitlab.jfronny.inceptum.util.UpdateChecker;
import io.gitlab.jfronny.inceptum.util.*;
import java.io.FileNotFoundException;
import java.io.IOException;
@ -25,6 +22,7 @@ public class Wrapper {
public static void main(String[] args) throws IOException {
System.out.println("Inceptum Wrapper v" + MetaHolder.VERSION.version + " (" + MetaHolder.VERSION.flavor + ")");
ConfigHolder.load();
if (!Files.exists(INCEPTUM_LIB_DIR)) downloadLatest();
Optional<Path> localBinary = selectLocalBinary();
if (localBinary.isEmpty()) {

View File

@ -0,0 +1,37 @@
package io.gitlab.jfronny.inceptum.gson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapterFactory;
import io.gitlab.jfronny.inceptum.model.ComparableVersion;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
public class GsonHolder {
private static final GsonBuilder builder = new GsonBuilder()
.registerTypeAdapter(ComparableVersion.class, new ComparableVersionAdapter())
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
.excludeFieldsWithModifiers(Modifier.PRIVATE)
.addSerializationExclusionStrategy(new GsonIgnoreExclusionStrategy())
.setPrettyPrinting();
private static boolean clean = false;
private static Gson gson;
public static Gson getGson() {
if (!clean) {
gson = builder.create();
clean = true;
}
return gson;
}
public static void registerTypeAdapter(Type type, Object typeAdapter) {
builder.registerTypeAdapter(type, typeAdapter);
clean = false;
}
public static void registerTypeAdapterFactory(TypeAdapterFactory factory) {
builder.registerTypeAdapterFactory(factory);
clean = false;
}
}

View File

@ -0,0 +1,33 @@
package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.model.inceptum.Config;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ConfigHolder {
public static Config CONFIG;
public static void load() throws IOException {
if (!Files.exists(MetaHolder.CONFIG_PATH.getParent())) Files.createDirectories(MetaHolder.CONFIG_PATH.getParent());
if (!Files.exists(MetaHolder.CONFIG_PATH)) {
Path gLaunch2 = MetaHolder.BASE_PATH.resolve("glaunch2.json");
if (Files.exists(gLaunch2)) {
Files.move(gLaunch2, MetaHolder.CONFIG_PATH);
}
else {
Utils.writeObject(MetaHolder.CONFIG_PATH, new Config());
}
}
CONFIG = Utils.loadObject(MetaHolder.CONFIG_PATH, Config.class);
}
public static void saveConfig() {
try {
Utils.writeObject(MetaHolder.CONFIG_PATH, CONFIG);
} catch (IOException e) {
Utils.LOGGER.error("Could not save config", e);
}
}
}

View File

@ -1,25 +1,62 @@
package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.gson.GsonHolder;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.net.*;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class HttpUtils {
private static final HttpClient CLIENT = HttpClient.newHttpClient();
static {
// Enables HTTPS proxying
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
}
private static final HttpClient CLIENT = HttpClient.newBuilder().proxy(new ProxySelector() {
@Override
public List<Proxy> select(URI uri) {
String host = System.getProperty("http.proxyHost");
String port = System.getProperty("http.proxyPort");
if (host == null || port == null)
return List.of();
if (!port.matches("\\d+")) {
Utils.LOGGER.error("Could not parse proxy settings: Port is not a number");
return List.of();
}
return List.of(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(host, Integer.parseInt(port))));
}
@Override
public void connectFailed(URI uri, SocketAddress socketAddress, IOException e) {
}
})
.followRedirects(HttpClient.Redirect.ALWAYS)
.authenticator(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
String name = System.getProperty("http.proxyUserName");
String pass = System.getProperty("http.proxyUserPassword");
if (name == null
|| pass == null
|| getRequestorType() != RequestorType.PROXY)
return super.getPasswordAuthentication();
return new PasswordAuthentication(name, pass.toCharArray());
}
})
.build();
private enum Method {
GET,
@ -28,17 +65,15 @@ public class HttpUtils {
public static class Request {
private final String url;
private HttpRequest.Builder builder;
private final HttpRequest.Builder builder;
private Method method;
public Request(Method method, String url) {
public Request(Method method, String url) throws URISyntaxException {
this.url = url.replace(" ", "%20");
try {
this.builder = HttpRequest.newBuilder().uri(new URI(this.url)).header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
this.method = method;
} catch (URISyntaxException e) {
Inceptum.LOGGER.error("Could not create request", e);
}
this.builder = HttpRequest.newBuilder()
.uri(new URI(this.url))
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
this.method = method;
}
public Request bearer(String token) {
@ -69,14 +104,6 @@ public class HttpUtils {
}
public Request bodyForm(Map<String, String> entries) {
/*StringBuilder content = new StringBuilder();
for (Map.Entry<String, String> entry : entries.entrySet()) {
if (content.length() > 0) content.append('&');
content.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
.append('=')
.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
}
return bodyForm(content.toString());*/
return bodyForm(entries.entrySet()
.stream()
.map(entry -> URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8) + '=' + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
@ -93,7 +120,7 @@ public class HttpUtils {
public Request bodyJson(Object object) {
builder.header("Content-Type", "application/json");
builder.method(method.name(), HttpRequest.BodyPublishers.ofString(Inceptum.GSON.toJson(object)));
builder.method(method.name(), HttpRequest.BodyPublishers.ofString(GsonHolder.getGson().toJson(object)));
method = null;
return this;
@ -112,7 +139,11 @@ public class HttpUtils {
if (res.statusCode() == 200) return res.body();
Optional<String> location = res.headers().firstValue("location");
if (location.isPresent() && (res.statusCode() == 302 || res.statusCode() == 307) && method == Method.GET) {
return HttpUtils.get(location.get())._send(accept, responseBodyHandler);
try {
return HttpUtils.get(location.get())._send(accept, responseBodyHandler);
} catch (URISyntaxException e) {
throw new IOException("Could not follow redirect", e);
}
}
throw new IOException("Unexpected return method: " + res.statusCode() + " (URL=" + url + ")\n" + res.body());
}
@ -135,7 +166,7 @@ public class HttpUtils {
public <T> T sendJson(Type type) throws IOException {
InputStream in = _send("application/json", HttpResponse.BodyHandlers.ofInputStream());
return in == null ? null : Inceptum.GSON.fromJson(new InputStreamReader(in), type);
return in == null ? null : GsonHolder.getGson().fromJson(new InputStreamReader(in), type);
}
private String getString(Object a) throws IOException {
@ -146,11 +177,11 @@ public class HttpUtils {
}
}
public static Request get(String url) {
public static Request get(String url) throws URISyntaxException {
return new Request(Method.GET, url);
}
public static Request post(String url) {
public static Request post(String url) throws URISyntaxException {
return new Request(Method.POST, url);
}
}

View File

@ -38,6 +38,14 @@ public class MetaHolder {
throw new RuntimeException("Could not get version info", e);
}
}
public static final Path ACCOUNTS_PATH = BASE_PATH.resolve("accounts.json");
public static final Path CONFIG_PATH = BASE_PATH.resolve("inceptum.json");
public static final Path NATIVES_DIR = BASE_PATH.resolve("natives");
public static final Path FORCE_LOAD_PATH = NATIVES_DIR.resolve("forceload");
public static final Path LIBRARIES_DIR = BASE_PATH.resolve("libraries");
public static final Path ASSETS_DIR = BASE_PATH.resolve("assets");
public static final Path INSTANCE_DIR = BASE_PATH.resolve("instances");
public static final Path CACHE_DIR = BASE_PATH.resolve("cache");
private static Path getConfigPath() {
return switch (OSCheck.OS) {

View File

@ -8,6 +8,7 @@ import io.gitlab.jfronny.inceptum.model.inceptum.UpdateInfo;
import io.gitlab.jfronny.inceptum.util.api.GitlabApi;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@ -32,13 +33,13 @@ public class UpdateChecker {
for (GitlabJob job : GitlabApi.getJobs(project, pipeline.id)) {
if (!job.name.equals("build_test")) continue;
try {
InceptumVersion iv = GitlabApi.downloadObject("projects/" + project.id + "/jobs/" + job.id + "/artifacts/version.json", InceptumVersion.class);
InceptumVersion iv = HttpUtils.get(GitlabApi.PROJECTS + project.id + "/jobs/" + job.id + "/artifacts/version.json").sendJson(InceptumVersion.class);
if (iv.jvm > jvm) {
error.accept("A newer JVM is required to use the latest inceptum version. Please update!");
continue packageLoop;
}
}
catch (IOException e) {
catch (IOException | URISyntaxException e) {
continue packageLoop;
}
}
@ -76,7 +77,7 @@ public class UpdateChecker {
if (file == null)
error.accept("No valid package was discovered");
else return new UpdateInfo("https://gitlab.com/" + project.path_with_namespace + "/-/package_files/" + file.id + "/download", file.file_sha1, new ComparableVersion(info.version));
} catch (IOException e) {
} catch (IOException | URISyntaxException e) {
showError.accept("Could not check for updates", e);
}
return null;

View File

@ -1,9 +1,13 @@
package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.inceptum.gson.GsonHolder;
import io.gitlab.jfronny.inceptum.model.OSType;
import io.gitlab.jfronny.inceptum.util.lambda.ThrowingConsumer;
import io.gitlab.jfronny.inceptum.util.lambda.ThrowingSupplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Desktop;
import java.awt.*;
import java.io.*;
import java.lang.reflect.Type;
import java.net.URI;
@ -23,14 +27,15 @@ import java.util.stream.Stream;
public class Utils {
public static final Pattern VALID_FILENAME = Pattern.compile("[a-zA-Z0-9_\\-.][a-zA-Z0-9 _\\-.]*[a-zA-Z0-9_\\-.]");
public static final Logger LOGGER = LoggerFactory.getLogger("Inceptum");
public static byte[] downloadData(String url) throws IOException {
public static byte[] downloadData(String url) throws IOException, URISyntaxException {
try (InputStream is = HttpUtils.get(url).sendInputStream()) {
return is.readAllBytes();
}
}
public static byte[] downloadData(String url, String sha1) throws IOException {
public static byte[] downloadData(String url, String sha1) throws IOException, URISyntaxException {
byte[] buf = downloadData(url);
if (sha1 == null) return buf;
if (!HashUtils.sha1(buf).equals(sha1)) throw new IOException("Invalid hash");
@ -38,26 +43,26 @@ public class Utils {
}
public static <T> T downloadObject(String url, Class<T> type) throws IOException {
return downloadObject(url, () -> HttpUtils.get(url).sendString(), s -> Inceptum.GSON.fromJson(s, type));
return downloadObject(url, () -> HttpUtils.get(url).sendString(), s -> GsonHolder.getGson().fromJson(s, type));
}
public static <T> T downloadObject(String url, Type type) throws IOException {
return downloadObject(url, () -> HttpUtils.get(url).sendString(), s -> Inceptum.GSON.fromJson(s, type));
return downloadObject(url, () -> HttpUtils.get(url).sendString(), s -> GsonHolder.getGson().fromJson(s, type));
}
public static <T> T downloadObject(String url, String sha1, Class<T> type) throws IOException {
return downloadObject(url, () -> downloadString(url, sha1), s -> Inceptum.GSON.fromJson(s, type));
return downloadObject(url, () -> downloadString(url, sha1), s -> GsonHolder.getGson().fromJson(s, type));
}
private static <T> T downloadObject(String url, ThrowingSupplier<String, IOException> sourceString, Function<String, T> builder) throws IOException {
Path cache = Inceptum.CACHE_DIR.resolve(HashUtils.sha1(url.getBytes(StandardCharsets.UTF_8)));
private static <T> T downloadObject(String url, ThrowingSupplier<String, Exception> sourceString, Function<String, T> builder) throws IOException {
Path cache = MetaHolder.CACHE_DIR.resolve(HashUtils.sha1(url.getBytes(StandardCharsets.UTF_8)));
if (Files.exists(cache))
return builder.apply(Files.readString(cache));
try {
String download = sourceString.get();
Files.writeString(cache, download);
return builder.apply(download);
} catch (IOException e) {
} catch (Exception e) {
throw new IOException("Could not download object and no cache exists (URL=" + url + ", Cache=" + cache + ")", e);
}
}
@ -79,32 +84,32 @@ public class Utils {
public static <T> T loadObject(Path file, Class<T> type) throws IOException {
try (BufferedReader br = Files.newBufferedReader(file)) {
return Inceptum.GSON.fromJson(br, type);
return GsonHolder.getGson().fromJson(br, type);
}
}
public static <T> T loadObject(Path file, Type type) throws IOException {
try (BufferedReader br = Files.newBufferedReader(file)) {
return Inceptum.GSON.fromJson(br, type);
return GsonHolder.getGson().fromJson(br, type);
}
}
public static <T> void writeObject(Path file, T object) throws IOException {
try (BufferedWriter bw = Files.newBufferedWriter(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
Inceptum.GSON.toJson(object, bw);
GsonHolder.getGson().toJson(object, bw);
}
}
public static String downloadString(String url, String sha1) throws IOException {
public static String downloadString(String url, String sha1) throws IOException, URISyntaxException {
return new String(downloadData(url, sha1), StandardCharsets.UTF_8);
}
public static void downloadFile(String url, Path path) throws IOException {
public static void downloadFile(String url, Path path) throws IOException, URISyntaxException {
if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent());
Files.write(path, downloadData(url));
}
public static void downloadFile(String url, String sha1, Path path) throws IOException {
public static void downloadFile(String url, String sha1, Path path) throws IOException, URISyntaxException {
if (!Files.exists(path.getParent())) Files.createDirectories(path.getParent());
Files.write(path, downloadData(url, sha1));
}
@ -203,7 +208,7 @@ public class Utils {
Desktop.getDesktop().browse(uri);
}
} catch (Exception e) {
Inceptum.LOGGER.error("Error opening web browser!", e);
Utils.LOGGER.error("Error opening web browser!", e);
}
}
@ -215,7 +220,7 @@ public class Utils {
Desktop.getDesktop().open(file);
}
} catch (Exception e) {
Inceptum.LOGGER.error("Error opening web browser!", e);
Utils.LOGGER.error("Error opening web browser!", e);
}
}

View File

@ -1,50 +1,42 @@
package io.gitlab.jfronny.inceptum.util.api;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import io.gitlab.jfronny.inceptum.gson.ComparableVersionAdapter;
import io.gitlab.jfronny.inceptum.model.ComparableVersion;
import io.gitlab.jfronny.inceptum.model.gitlab.*;
import io.gitlab.jfronny.inceptum.model.gitlab.GitlabJob;
import io.gitlab.jfronny.inceptum.model.gitlab.GitlabPackage;
import io.gitlab.jfronny.inceptum.model.gitlab.GitlabPackageFile;
import io.gitlab.jfronny.inceptum.model.gitlab.GitlabProject;
import io.gitlab.jfronny.inceptum.util.HttpUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URISyntaxException;
import java.util.List;
import java.util.function.Predicate;
public class GitlabApi {
private static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(ComparableVersion.class, new ComparableVersionAdapter())
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
.excludeFieldsWithModifiers(Modifier.PRIVATE)
.setPrettyPrinting()
.create();
public static final String PROJECTS = "https://gitlab.com/api/v4/projects/";
private static final Type packageInfoListType = new TypeToken<List<GitlabPackage>>() {}.getType();
private static final Type jobListType = new TypeToken<List<GitlabJob>>() {}.getType();
private static final Type packageFileInfoListType = new TypeToken<List<GitlabPackageFile>>() {}.getType();
public static GitlabProject getProject(Long projectId) throws IOException {
return downloadObject("projects/" + projectId, GitlabProject.class);
public static GitlabProject getProject(Long projectId) throws IOException, URISyntaxException {
return HttpUtils.get(PROJECTS + projectId).sendJson(GitlabProject.class);
}
public static List<GitlabPackage> getPackages(GitlabProject project) throws IOException {
List<GitlabPackage> list = downloadObject("projects/" + project.id + "/packages", packageInfoListType);
public static List<GitlabPackage> getPackages(GitlabProject project) throws IOException, URISyntaxException {
List<GitlabPackage> list = HttpUtils.get(PROJECTS + project.id + "/packages").sendJson(packageInfoListType);
list.sort((left, right) -> right.created_at.compareTo(left.created_at));
return list;
}
public static List<GitlabJob> getJobs(GitlabProject project, Long pipelineId) throws IOException {
return downloadObject("projects/" + project.id + "/pipelines/" + pipelineId + "/jobs", jobListType);
public static List<GitlabJob> getJobs(GitlabProject project, Long pipelineId) throws IOException, URISyntaxException {
return HttpUtils.get(PROJECTS + project.id + "/pipelines/" + pipelineId + "/jobs").sendJson(jobListType);
}
public static GitlabPackageFile getFile(GitlabProject project, GitlabPackage packageInfo, Predicate<GitlabPackageFile> isValid) throws IOException {
public static GitlabPackageFile getFile(GitlabProject project, GitlabPackage packageInfo, Predicate<GitlabPackageFile> isValid) throws IOException, URISyntaxException {
int page = 0;
while (true) {
List<GitlabPackageFile> files = downloadObject("projects/" + project.id + "/packages/" + packageInfo.id + "/package_files?per_page=100&page=" + ++page, packageFileInfoListType);
List<GitlabPackageFile> files = HttpUtils.get(PROJECTS + project.id + "/packages/" + packageInfo.id + "/package_files?per_page=100&page=" + ++page).sendJson(packageFileInfoListType);
if (files.isEmpty()) return null;
for (GitlabPackageFile file : files) {
if (isValid.test(file))
@ -52,10 +44,4 @@ public class GitlabApi {
}
}
}
public static <T> T downloadObject(String source, Type type) throws IOException {
try (InputStream is = new URL("https://gitlab.com/api/v4/" + source).openStream(); InputStreamReader isr = new InputStreamReader(is)) {
return GSON.fromJson(isr, type);
}
}
}

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.util;
package io.gitlab.jfronny.inceptum.util.lambda;
public interface ThrowingConsumer<T, TEx extends Throwable> {
void consume(T val) throws TEx;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.util;
package io.gitlab.jfronny.inceptum.util.lambda;
public interface ThrowingFunction<TIn, TOut, TEx extends Throwable> {
TOut apply(TIn var) throws TEx;

View File

@ -1,4 +1,4 @@
package io.gitlab.jfronny.inceptum.util;
package io.gitlab.jfronny.inceptum.util.lambda;
public interface ThrowingSupplier<T, TEx extends Throwable> {
T get() throws TEx;