Initial fabric support, instance locking
This commit is contained in:
parent
d9336264b5
commit
ea2b2e5452
|
@ -11,12 +11,12 @@ import io.gitlab.jfronny.inceptum.gson.GsonIgnoreExclusionStrategy;
|
|||
import io.gitlab.jfronny.inceptum.gson.MinecraftArgumentDeserializer;
|
||||
import io.gitlab.jfronny.inceptum.gson.OauthTokenResponseDeserializer;
|
||||
import io.gitlab.jfronny.inceptum.gson.RulesDeserializer;
|
||||
import io.gitlab.jfronny.inceptum.model.InceptumVersion;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InceptumVersion;
|
||||
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.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.windows.MainWindow;
|
||||
import io.gitlab.jfronny.inceptum.windows.Window;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.install;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
import io.gitlab.jfronny.inceptum.windows.NewInstanceWindow;
|
||||
|
||||
public record SetupStepInfo(VersionInfo version,
|
||||
NewInstanceWindow.LoaderType loaderType,
|
||||
LoaderInfo loader,
|
||||
String name) {
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ 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.McApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.McApi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
|
|
@ -14,10 +14,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
public class DownloadClientStep implements Step {
|
||||
@Override
|
||||
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
|
||||
Path path = Inceptum.LIBRARIES_DIR.resolve("net/minecraft/minecraft");
|
||||
if (!Files.exists(path)) Files.createDirectories(path);
|
||||
path = path.resolve(info.version().id + ".jar");
|
||||
if (Files.exists(path)) return;
|
||||
VersionInfo.Downloads.Download client = info.version().downloads.client;
|
||||
Inceptum.LOGGER.info("Downloading client");
|
||||
Path parentPath = Inceptum.LIBRARIES_DIR.resolve("net/minecraft/minecraft");
|
||||
if (!Files.exists(parentPath)) Files.createDirectories(parentPath);
|
||||
Utils.downloadFile(client.url, client.sha1, parentPath.resolve(info.version().id + ".jar"));
|
||||
Utils.downloadFile(client.url, client.sha1, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,14 @@ public class DownloadLibrariesStep implements Step {
|
|||
for (VersionInfo.Library.Downloads.Artifact artifact : VersionInfoLibraryResolver.getRelevant(info.version())) {
|
||||
if (stopThread.get()) return;
|
||||
Path path = Inceptum.LIBRARIES_DIR.resolve(artifact.path);
|
||||
if (Files.exists(path)) return;
|
||||
if (Files.exists(path)) continue;
|
||||
//TODO allow maven-like download for fabric
|
||||
Inceptum.LOGGER.info("Downloading library: " + artifact.path);
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
Utils.downloadFile(artifact.url, artifact.sha1, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ 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.windows.NewInstanceWindow;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -16,9 +16,9 @@ public class SetupDirsStep implements Step {
|
|||
Inceptum.LOGGER.info("Setting up instance dirs");
|
||||
Path iDir = Inceptum.INSTANCE_DIR.resolve(info.name());
|
||||
if (!Files.exists(iDir)) {
|
||||
Files.createDirectories(iDir);
|
||||
Files.createDirectories(iDir.resolve("inceptum.setup.lock"));
|
||||
Files.createDirectories(iDir.resolve("config"));
|
||||
if (info.loaderType() != NewInstanceWindow.LoaderType.None)
|
||||
if (info.loader().type() != LoaderInfo.Type.None)
|
||||
Files.createDirectories(iDir.resolve("mods"));
|
||||
Files.createDirectories(iDir.resolve("resourcepacks"));
|
||||
Files.createDirectories(iDir.resolve("saves"));
|
||||
|
|
|
@ -3,10 +3,11 @@ 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.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
@ -14,10 +15,10 @@ public class WriteMetadataStep implements Step {
|
|||
@Override
|
||||
public void execute(SetupStepInfo info, AtomicBoolean stopThread) throws IOException {
|
||||
Inceptum.LOGGER.info("Writing metadata");
|
||||
Path metaDir = Inceptum.INSTANCE_DIR.resolve(info.name()).resolve("instance.json");
|
||||
Path metaDir = Inceptum.INSTANCE_DIR.resolve(info.name()).resolve("inceptum.lock");
|
||||
InstanceMeta meta = new InstanceMeta();
|
||||
meta.loaderType = info.loaderType();
|
||||
meta.version = info.version().id;
|
||||
Utils.writeObject(metaDir, meta);
|
||||
Files.delete(Inceptum.INSTANCE_DIR.resolve(info.name()).resolve("SETUP"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.model;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.gson.GsonIgnore;
|
||||
import io.gitlab.jfronny.inceptum.windows.NewInstanceWindow;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class InstanceMeta {
|
||||
public NewInstanceWindow.LoaderType loaderType;
|
||||
public String version;
|
||||
@GsonIgnore public Path instancePath;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.model.fabric;
|
||||
|
||||
public class FabricLoaderVersion {
|
||||
public String separator;
|
||||
public Integer build;
|
||||
public String maven;
|
||||
public String version;
|
||||
public Boolean stable;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.gitlab.jfronny.inceptum.model.fabric;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FabricVersionLoaderInfo {
|
||||
public FabricLoaderVersion loader;
|
||||
public IntermediaryVersion intermediary;
|
||||
|
||||
public static class WithMeta extends FabricVersionLoaderInfo {
|
||||
public LauncherMeta launcherMeta;
|
||||
|
||||
public static class LauncherMeta {
|
||||
public int version;
|
||||
public Libraries libraries;
|
||||
public MainClass mainClass;
|
||||
|
||||
public static class Libraries {
|
||||
public List<Library> client;
|
||||
public List<Library> common;
|
||||
public List<Library> server;
|
||||
|
||||
public static class Library {
|
||||
public String name;
|
||||
public String url;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MainClass {
|
||||
public String client;
|
||||
public String server;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package io.gitlab.jfronny.inceptum.model.fabric;
|
||||
|
||||
public class IntermediaryVersion {
|
||||
public String maven;
|
||||
public String version;
|
||||
public boolean stable;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.model;
|
||||
package io.gitlab.jfronny.inceptum.model.inceptum;
|
||||
|
||||
public class InceptumVersion {
|
||||
public String version;
|
|
@ -0,0 +1,18 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum;
|
||||
|
||||
public class InstanceMeta {
|
||||
private static final String floaderPrefix = "fabric-loader-";
|
||||
public String version;
|
||||
|
||||
public boolean isFabric() {
|
||||
return version.startsWith(floaderPrefix);
|
||||
}
|
||||
|
||||
public String getMinecraftVersion() {
|
||||
return isFabric() ? version.substring(version.lastIndexOf('-') + 1) : version;
|
||||
}
|
||||
|
||||
public String getLoaderVersion() {
|
||||
return isFabric() ? version.substring(floaderPrefix.length()).split("-")[0] : "";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package io.gitlab.jfronny.inceptum.model.inceptum;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.fabric.FabricLoaderVersion;
|
||||
|
||||
public record LoaderInfo(Type type, String version) {
|
||||
public static LoaderInfo NONE = new LoaderInfo(Type.None, "");
|
||||
public enum Type {
|
||||
None, Fabric
|
||||
}
|
||||
|
||||
public LoaderInfo(FabricLoaderVersion fabricVersion) {
|
||||
this(LoaderInfo.Type.Fabric, fabricVersion.version);
|
||||
}
|
||||
}
|
|
@ -3,20 +3,16 @@ package io.gitlab.jfronny.inceptum.model.mojang;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class VersionInfo {
|
||||
public class VersionInfo extends VersionsListInfo {
|
||||
public Arguments arguments;
|
||||
public AssetIndex assetIndex;
|
||||
public String assets;
|
||||
public int complianceLevel;
|
||||
public Downloads downloads;
|
||||
public String id;
|
||||
public JavaVersion javaVersion;
|
||||
public List<Library> libraries;
|
||||
public String mainClass;
|
||||
public Integer minimumLauncherVersion;
|
||||
public String releaseTime;
|
||||
public String time;
|
||||
public String type;
|
||||
|
||||
public static class Arguments {
|
||||
public List<MinecraftArgument> game;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package io.gitlab.jfronny.inceptum.util;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class ProcessUtils {
|
||||
public static boolean isProcessAlive(String pid) {
|
||||
return isProcessIdRunning(pid, Utils.OS.equals("windows")
|
||||
? "cmd /c tasklist /FI \"PID eq " + pid + "\""
|
||||
: "ps -p " + pid);
|
||||
}
|
||||
|
||||
|
||||
private static boolean isProcessIdRunning(String pid, String command) {
|
||||
try {
|
||||
Runtime rt = Runtime.getRuntime();
|
||||
Process pr = rt.exec(command);
|
||||
|
||||
InputStreamReader isReader = new InputStreamReader(pr.getInputStream());
|
||||
BufferedReader bReader = new BufferedReader(isReader);
|
||||
String strLine;
|
||||
while ((strLine= bReader.readLine()) != null) {
|
||||
if (strLine.contains(" " + pid + " ")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
Inceptum.LOGGER.error("Could not get process state", e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import java.security.MessageDigest;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Utils {
|
||||
|
@ -50,32 +51,33 @@ public class Utils {
|
|||
|
||||
public static byte[] downloadData(String url, String sha1) throws IOException {
|
||||
byte[] buf = downloadData(url);
|
||||
if (sha1 == null) return buf;
|
||||
if (!Utils.hash(buf).equals(sha1)) throw new IOException("Invalid hash");
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static <T> T downloadObject(String url, Class<T> type) throws IOException {
|
||||
return downloadObject(url, () -> HttpUtils.get(url).sendString(), type);
|
||||
return downloadObject(url, () -> HttpUtils.get(url).sendString(), s -> Inceptum.GSON.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));
|
||||
}
|
||||
|
||||
public static <T> T downloadObject(String url, String sha1, Class<T> type) throws IOException {
|
||||
return downloadObject(url, () -> downloadString(url, sha1), type);
|
||||
return downloadObject(url, () -> downloadString(url, sha1), s -> Inceptum.GSON.fromJson(s, type));
|
||||
}
|
||||
|
||||
private static <T> T downloadObject(String url, ThrowingSupplier<String, IOException> sourceString, Class<T> type) throws IOException {
|
||||
private static <T> T downloadObject(String url, ThrowingSupplier<String, IOException> sourceString, Function<String, T> builder) throws IOException {
|
||||
Path cache = Inceptum.CACHE_DIR.resolve(Integer.toString(url.hashCode()));
|
||||
try {
|
||||
String download = sourceString.get();
|
||||
Files.writeString(cache, download);
|
||||
return Inceptum.GSON.fromJson(download, type);
|
||||
return builder.apply(download);
|
||||
} catch (IOException e) {
|
||||
if (Files.exists(cache)) {
|
||||
Inceptum.LOGGER.info("Using cache for " + url, e);
|
||||
try (BufferedReader br = Files.newBufferedReader(cache)) {
|
||||
return Inceptum.GSON.fromJson(br, type);
|
||||
} catch (IOException ioE) {
|
||||
throw new IOException("Could not download object and failed loading cache", ioE);
|
||||
}
|
||||
return builder.apply(Files.readString(cache));
|
||||
} else
|
||||
throw new IOException("Could not download object and no cache exists", e);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package io.gitlab.jfronny.inceptum.util.api;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import io.gitlab.jfronny.inceptum.model.fabric.FabricVersionLoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.Rules;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionsListInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class FabricMetaApi {
|
||||
private static final Type fabricLoaderVersionListType = new TypeToken<List<FabricVersionLoaderInfo>>() {}.getType();
|
||||
private static final String META_URL = "https://meta.fabricmc.net/";
|
||||
|
||||
public static List<FabricVersionLoaderInfo> getLoaderVersions(VersionsListInfo version) {
|
||||
try {
|
||||
return Utils.downloadObject(META_URL + "v2/versions/loader/" + version.id, fabricLoaderVersionListType);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Could not get fabric loader versions", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static FabricVersionLoaderInfo getLoaderVersion(VersionsListInfo gameVersion, String fabricVersion) throws IOException {
|
||||
return Utils.downloadObject(META_URL + "v2/versions/loader/" + gameVersion.id + "/" + fabricVersion, FabricVersionLoaderInfo.WithMeta.class);
|
||||
}
|
||||
|
||||
public static void addFabric(VersionInfo version, String fabricVersion) throws IOException {
|
||||
FabricVersionLoaderInfo ver = getLoaderVersion(version, fabricVersion);
|
||||
if (!(ver instanceof FabricVersionLoaderInfo.WithMeta verWithMeta)) throw new IOException("Doesn't hold metadata");
|
||||
FabricVersionLoaderInfo.WithMeta.LauncherMeta meta = verWithMeta.launcherMeta;
|
||||
if (meta.version != 1) throw new IOException("Unsupported fabric launcherMeta version: " + meta.version);
|
||||
version.mainClass = meta.mainClass.client;
|
||||
List<VersionInfo.Library> libs = new ArrayList<>(version.libraries);
|
||||
for (FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library library : meta.libraries.common)
|
||||
libs.add(convertLib(library));
|
||||
for (FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library library : meta.libraries.client)
|
||||
libs.add(convertLib(library));
|
||||
var floader = new FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library();
|
||||
floader.name = "net.fabricmc:fabric-loader:" + fabricVersion;
|
||||
floader.url = "https://maven.fabricmc.net/";
|
||||
libs.add(convertLib(floader));
|
||||
version.libraries = List.copyOf(libs);
|
||||
version.id = "fabric-loader-" + fabricVersion + "-" + version.id;
|
||||
}
|
||||
|
||||
private static VersionInfo.Library convertLib(FabricVersionLoaderInfo.WithMeta.LauncherMeta.Libraries.Library library) {
|
||||
VersionInfo.Library res = new VersionInfo.Library();
|
||||
res.name = library.name;
|
||||
res.rules = new Rules(true);
|
||||
res.natives = new HashMap<>();
|
||||
res.downloads = new VersionInfo.Library.Downloads();
|
||||
res.downloads.classifiers = null;
|
||||
res.downloads.artifact = new VersionInfo.Library.Downloads.Artifact();
|
||||
String[] lib = library.name.split(":");
|
||||
assert lib.length == 3;
|
||||
res.downloads.artifact.path = lib[0].replace('.', '/') + '/' + lib[1] + '/' + lib[2] + '/' + lib[1] + '-' + lib[2] + ".jar";
|
||||
res.downloads.artifact.size = -1;
|
||||
res.downloads.artifact.sha1 = null;
|
||||
res.downloads.artifact.url = library.url + res.downloads.artifact.path;
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
package io.gitlab.jfronny.inceptum.util;
|
||||
package io.gitlab.jfronny.inceptum.util.api;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.AssetIndex;
|
||||
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.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.util.account;
|
||||
package io.gitlab.jfronny.inceptum.util.api.account;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.util.account;
|
||||
package io.gitlab.jfronny.inceptum.util.api.account;
|
||||
|
||||
public record AuthInfo(String name, String uuid, String accessToken, String userType) {
|
||||
public AuthInfo(MicrosoftAccount account) {
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.util.account;
|
||||
package io.gitlab.jfronny.inceptum.util.api.account;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.microsoft.LoginResponse;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum.util.account;
|
||||
package io.gitlab.jfronny.inceptum.util.api.account;
|
||||
|
||||
import io.gitlab.jfronny.inceptum.model.microsoft.*;
|
||||
import io.gitlab.jfronny.inceptum.util.HttpUtils;
|
|
@ -6,17 +6,19 @@ import imgui.flag.ImGuiWindowFlags;
|
|||
import imgui.type.ImBoolean;
|
||||
import imgui.type.ImInt;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.InstanceMeta;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.MinecraftArgument;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.mojang.VersionsListInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.MapAppender;
|
||||
import io.gitlab.jfronny.inceptum.util.ProcessUtils;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import io.gitlab.jfronny.inceptum.util.VersionInfoLibraryResolver;
|
||||
import io.gitlab.jfronny.inceptum.util.McApi;
|
||||
import io.gitlab.jfronny.inceptum.util.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.account.AuthInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.account.MicrosoftAccount;
|
||||
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.McApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AuthInfo;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.MicrosoftAccount;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -27,25 +29,9 @@ import java.util.List;
|
|||
public class MainWindow extends Window {
|
||||
private final ImBoolean darkTheme = new ImBoolean(Inceptum.CONFIG.darkTheme);
|
||||
private final ImBoolean debugTools = new ImBoolean(false);
|
||||
private final List<InstanceMeta> instances; //TODO custom ordering
|
||||
private final ImInt accountIndex = new ImInt(0);
|
||||
public MainWindow() {
|
||||
super("Inceptum");
|
||||
List<InstanceMeta> instances = new ArrayList<>();
|
||||
try {
|
||||
for (Path path : Files.list(Inceptum.INSTANCE_DIR).filter(Files::isDirectory).toList()) {
|
||||
if (Files.exists(path.resolve("instance.json"))) {
|
||||
InstanceMeta im = Utils.loadObject(path.resolve("instance.json"), InstanceMeta.class);
|
||||
im.instancePath = path;
|
||||
instances.add(im);
|
||||
} else {
|
||||
Inceptum.LOGGER.error("Invalid instance (doesn't contain instance.json): " + path);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Inceptum.LOGGER.error("Could not list present instances", e);
|
||||
}
|
||||
this.instances = List.copyOf(instances);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,56 +82,94 @@ public class MainWindow extends Window {
|
|||
ImGui.showDemoWindow();
|
||||
}
|
||||
|
||||
if (instances.isEmpty()) {
|
||||
List<Path> paths;
|
||||
try {
|
||||
paths = Files.list(Inceptum.INSTANCE_DIR).filter(Files::isDirectory).toList();
|
||||
} catch (IOException e) {
|
||||
Inceptum.LOGGER.error("Could not list instances");
|
||||
return;
|
||||
}
|
||||
if (paths.isEmpty()) {
|
||||
ImGui.text("You have not yet created an instance");
|
||||
ImGui.text("Use File->New Instance to do so");
|
||||
}
|
||||
else {
|
||||
if (ImGui.beginTable("Instances", 2, ImGuiTableFlags.Resizable | ImGuiTableFlags.Borders)) {
|
||||
for (InstanceMeta instance : instances) {
|
||||
else if (ImGui.beginTable("Instances", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) {
|
||||
for (Path path : paths) {
|
||||
if (Files.exists(path.resolve("inceptum.setup.lock"))) {
|
||||
ImGui.tableNextColumn();
|
||||
if (ImGui.button(instance.instancePath.getFileName().toString())) {
|
||||
//TODO implement fabric support
|
||||
//TODO extract launch logic to separate class
|
||||
for (VersionsListInfo version : McApi.getVersions().versions) {
|
||||
if (version.id.equals(instance.version)) {
|
||||
try {
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add("/lib/jvm/java-17-openjdk/bin/java"); //TODO allow selecting vm, detect with System.getProperty("java.home")
|
||||
VersionInfo info = McApi.getVersionInfo(version);
|
||||
StringBuilder classPath = new StringBuilder();
|
||||
for (VersionInfo.Library.Downloads.Artifact artifact : VersionInfoLibraryResolver.getRelevant(info)) {
|
||||
classPath.append(Inceptum.LIBRARIES_DIR.resolve(artifact.path).toAbsolutePath());
|
||||
classPath.append(':');
|
||||
}
|
||||
classPath.append(Inceptum.LIBRARIES_DIR.resolve("net/minecraft/minecraft").resolve(version.id + ".jar").toAbsolutePath());
|
||||
Inceptum.LOGGER.info(classPath.toString());
|
||||
//TODO -Xms{lowMem} -Xmx{maxMem}
|
||||
args.addAll(parse(info.arguments.jvm, info, instance, classPath.toString()));
|
||||
args.add(info.mainClass);
|
||||
args.addAll(parse(info.arguments.game, info, instance, classPath.toString()));
|
||||
ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[0]));
|
||||
pb.directory(instance.instancePath.toFile());
|
||||
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||
pb.start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
ImGui.text("Setting up");
|
||||
ImGui.tableNextColumn();
|
||||
ImGui.text("This instance is currently being set up");
|
||||
continue;
|
||||
}
|
||||
if (!Files.exists(path.resolve("instance.json"))) {
|
||||
Inceptum.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);
|
||||
continue;
|
||||
}
|
||||
ImGui.tableNextColumn();
|
||||
boolean disabled = false;
|
||||
if (Files.exists(path.resolve("inceptum.lock"))) {
|
||||
try {
|
||||
if (ProcessUtils.isProcessAlive(Files.readString(path.resolve("inceptum.lock"))))
|
||||
disabled = true;
|
||||
else Files.delete(path.resolve("inceptum.lock"));
|
||||
}
|
||||
catch (IOException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (disabled) ImGui.beginDisabled();
|
||||
if (ImGui.button(path.getFileName().toString())) {
|
||||
//TODO extract launch logic to separate class
|
||||
for (VersionsListInfo version : McApi.getVersions().versions) {
|
||||
if (version.id.equals(instance.getMinecraftVersion())) {
|
||||
try {
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add("/lib/jvm/java-17-openjdk/bin/java"); //TODO allow selecting vm, detect with System.getProperty("java.home")
|
||||
VersionInfo info = McApi.getVersionInfo(version);
|
||||
if (instance.isFabric()) {
|
||||
FabricMetaApi.addFabric(info, instance.getLoaderVersion());
|
||||
}
|
||||
StringBuilder classPath = new StringBuilder();
|
||||
for (VersionInfo.Library.Downloads.Artifact artifact : VersionInfoLibraryResolver.getRelevant(info)) {
|
||||
classPath.append(Inceptum.LIBRARIES_DIR.resolve(artifact.path).toAbsolutePath());
|
||||
classPath.append(':');
|
||||
}
|
||||
classPath.append(Inceptum.LIBRARIES_DIR.resolve("net/minecraft/minecraft").resolve(version.id + ".jar").toAbsolutePath());
|
||||
//TODO -Xms{lowMem} -Xmx{maxMem}
|
||||
args.addAll(parse(info.arguments.jvm, info, instance, classPath.toString(), path.toAbsolutePath().toString()));
|
||||
args.add(info.mainClass);
|
||||
args.addAll(parse(info.arguments.game, info, instance, classPath.toString(), path.toAbsolutePath().toString()));
|
||||
Inceptum.LOGGER.info(String.join(" ", args));
|
||||
ProcessBuilder pb = new ProcessBuilder(args.toArray(new String[0]));
|
||||
pb.directory(path.toFile());
|
||||
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||
Files.writeString(path.resolve("inceptum.lock"), Long.toString(pb.start().pid()));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui.tableNextColumn();
|
||||
if (ImGui.button("Edit")) {
|
||||
Inceptum.LOGGER.error("Editing not yet implemented"); //TODO allow changing name (moving), changing version, managing mods etc
|
||||
}
|
||||
}
|
||||
ImGui.endTable();
|
||||
ImGui.tableNextColumn();
|
||||
if (ImGui.button("Edit")) {
|
||||
Inceptum.LOGGER.error("Editing not yet implemented"); //TODO allow changing name (moving), changing version, managing mods etc
|
||||
}
|
||||
if (disabled) ImGui.endDisabled();
|
||||
}
|
||||
ImGui.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> parse(List<MinecraftArgument> arguments, VersionInfo info, InstanceMeta instance, String classPath) {
|
||||
private List<String> parse(List<MinecraftArgument> arguments, VersionInfo info, InstanceMeta instance, String classPath, String gameDirectory) {
|
||||
List<String> res = new ArrayList<>();
|
||||
for (MinecraftArgument argument : arguments) {
|
||||
for (String s : argument.arg()) {
|
||||
|
@ -154,8 +178,8 @@ public class MainWindow extends Window {
|
|||
res.add(s
|
||||
// game args
|
||||
.replace("${auth_player_name}", authInfo.name())
|
||||
.replace("${version_name}", info.id) //TODO fabric support
|
||||
.replace("${game_directory}", instance.instancePath.toAbsolutePath().toString())
|
||||
.replace("${version_name}", instance.getMinecraftVersion())
|
||||
.replace("${game_directory}", gameDirectory)
|
||||
.replace("${assets_root}", Inceptum.ASSETS_DIR.toAbsolutePath().toString())
|
||||
.replace("${assets_index_name}", info.assets)
|
||||
.replace("${auth_uuid}", authInfo.uuid())
|
||||
|
|
|
@ -3,9 +3,9 @@ package io.gitlab.jfronny.inceptum.windows;
|
|||
import imgui.ImGui;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.model.microsoft.*;
|
||||
import io.gitlab.jfronny.inceptum.util.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.account.MicrosoftAccount;
|
||||
import io.gitlab.jfronny.inceptum.util.account.MicrosoftAuthAPI;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.MicrosoftAccount;
|
||||
import io.gitlab.jfronny.inceptum.util.api.account.MicrosoftAuthAPI;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
import net.freeutils.httpserver.HTTPServer;
|
||||
|
||||
|
|
|
@ -6,21 +6,30 @@ import imgui.type.ImInt;
|
|||
import imgui.type.ImString;
|
||||
import io.gitlab.jfronny.inceptum.Inceptum;
|
||||
import io.gitlab.jfronny.inceptum.install.SetupStepInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.inceptum.LoaderInfo;
|
||||
import io.gitlab.jfronny.inceptum.model.fabric.FabricVersionLoaderInfo;
|
||||
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.McApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
|
||||
import io.gitlab.jfronny.inceptum.util.api.McApi;
|
||||
import io.gitlab.jfronny.inceptum.util.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class NewInstanceWindow extends Window {
|
||||
VersionsList manifest = McApi.getVersions();
|
||||
VersionsListInfo selected;
|
||||
Map<VersionsListInfo, List<FabricVersionLoaderInfo>> loaderInfoCache = new HashMap<>();
|
||||
FabricVersionLoaderInfo selectedFabric;
|
||||
ImInt version = new ImInt(0);
|
||||
ImString name = new ImString("", 128);
|
||||
ImInt fabricVersion = new ImInt(0);
|
||||
ImBoolean snapshots = new ImBoolean(Inceptum.CONFIG.snapshots);
|
||||
ImBoolean fabric = new ImBoolean(true);
|
||||
public NewInstanceWindow() {
|
||||
|
@ -29,6 +38,15 @@ public class NewInstanceWindow extends Window {
|
|||
if (Inceptum.CONFIG.snapshots)
|
||||
version.set(manifest.versions.indexOf(selected));
|
||||
name.set(getDefaultName(selected, fabric.get()));
|
||||
List<FabricVersionLoaderInfo> versions = getFabricLoaderInfo();
|
||||
for (int i = 0, fabricLoaderInfoSize = versions.size(); i < fabricLoaderInfoSize; i++) {
|
||||
FabricVersionLoaderInfo version = versions.get(i);
|
||||
if (version.loader.stable) {
|
||||
selectedFabric = version;
|
||||
fabricVersion.set(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,8 +71,14 @@ public class NewInstanceWindow extends Window {
|
|||
if (getDefaultName(selected, !fabric.get()).equals(name.get()))
|
||||
name.set(getDefaultName(selected, fabric.get()));
|
||||
}
|
||||
if (fabric.get()) {
|
||||
ImGui.sameLine();
|
||||
List<FabricVersionLoaderInfo> versions = getFabricLoaderInfo();
|
||||
if (ImGui.combo("Loader", fabricVersion, versions.stream().map(info -> info.loader.version).toArray(String[]::new))) {
|
||||
selectedFabric = versions.get(fabricVersion.get());
|
||||
}
|
||||
}
|
||||
//TODO forge
|
||||
//TODO implement fabric support
|
||||
ImGui.inputTextWithHint("Name", "Select a name", name);
|
||||
if (!Utils.VALID_FILENAME.matcher(name.get()).matches())
|
||||
ImGui.text("Invalid name");
|
||||
|
@ -63,7 +87,11 @@ public class NewInstanceWindow extends Window {
|
|||
else if (ImGui.button("OK")) {
|
||||
close();
|
||||
try {
|
||||
Inceptum.open(new InstanceCreateProcessWindow(new SetupStepInfo(McApi.getVersionInfo(selected), fabric.get() ? LoaderType.Fabric : LoaderType.None, name.get())));
|
||||
VersionInfo vi = McApi.getVersionInfo(selected);
|
||||
if (fabric.get()) FabricMetaApi.addFabric(vi, selectedFabric.loader.version);
|
||||
Inceptum.open(new InstanceCreateProcessWindow(new SetupStepInfo(vi,
|
||||
fabric.get() ? new LoaderInfo(selectedFabric.loader) : LoaderInfo.NONE,
|
||||
name.get())));
|
||||
} catch (IOException e) {
|
||||
Inceptum.LOGGER.error("Could not initialize instance creation", e);
|
||||
}
|
||||
|
@ -76,12 +104,13 @@ public class NewInstanceWindow extends Window {
|
|||
return res;
|
||||
}
|
||||
|
||||
private List<FabricVersionLoaderInfo> getFabricLoaderInfo() {
|
||||
if (!loaderInfoCache.containsKey(selected))
|
||||
loaderInfoCache.put(selected, FabricMetaApi.getLoaderVersions(selected));
|
||||
return loaderInfoCache.get(selected);
|
||||
}
|
||||
|
||||
private String getDefaultName(VersionsListInfo info, boolean fabric) {
|
||||
return fabric ? "Fabric " + info.id : info.id;
|
||||
}
|
||||
|
||||
public enum LoaderType {
|
||||
None,
|
||||
Fabric
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue