Inceptum/src/main/java/io/gitlab/jfronny/inceptum/windows/control/InstanceView.java

160 lines
8.4 KiB
Java
Raw Normal View History

2021-10-30 16:12:39 +02:00
package io.gitlab.jfronny.inceptum.windows.control;
import imgui.ImGui;
import imgui.flag.ImGuiTableFlags;
import io.gitlab.jfronny.inceptum.Inceptum;
2021-10-30 19:26:59 +02:00
import io.gitlab.jfronny.inceptum.install.steps.DownloadLibrariesStep;
2021-10-30 16:12:39 +02:00
import io.gitlab.jfronny.inceptum.model.inceptum.ArtifactInfo;
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.ProcessUtils;
import io.gitlab.jfronny.inceptum.util.Utils;
import io.gitlab.jfronny.inceptum.util.VersionInfoLibraryResolver;
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.windows.InstanceEditWindow;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
2021-10-30 19:26:59 +02:00
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
2021-10-30 16:12:39 +02:00
public class InstanceView {
public static void draw(List<Path> paths) {
if (ImGui.beginTable("Instances", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.Borders)) {
for (Path path : paths) {
if (Files.exists(path.resolve("inceptum.setup.lock"))) {
ImGui.tableNextColumn();
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())) launch(path, instance);
ImGui.tableNextColumn();
2021-10-30 19:26:59 +02:00
if (ImGui.button("Edit##" + path)) Inceptum.open(new InstanceEditWindow(path, instance));
2021-10-30 16:12:39 +02:00
if (disabled) ImGui.endDisabled();
}
ImGui.endTable();
}
}
private static void launch(Path path, InstanceMeta instance) {
for (VersionsListInfo version : McApi.getVersions().versions) {
if (version.id.equals(instance.getMinecraftVersion())) {
try {
List<String> args = new ArrayList<>();
VersionInfo info = McApi.getVersionInfo(version);
if (instance.isFabric()) {
FabricMetaApi.addFabric(info, instance.getLoaderVersion());
}
2021-10-30 19:26:59 +02:00
args.add(Objects.requireNonNullElseGet(instance.java, () ->
Utils.getJvmMain(Inceptum.NATIVES_DIR
.resolve(info.javaVersion.component)
.resolve(Integer.toString(info.javaVersion.majorVersion)))
.toAbsolutePath().toString()));
DownloadLibrariesStep.execute(info, new AtomicBoolean(false), new AtomicReference<>());
2021-10-30 16:12:39 +02:00
StringBuilder classPath = new StringBuilder();
for (ArtifactInfo 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 custom JVM args
if (info.arguments != null) args.addAll(parse(info.arguments.jvm, info, instance, classPath.toString(), path.toAbsolutePath().toString()));
if (instance.minMem != null) args.add("-Xms" + instance.minMem);
if (instance.maxMem != null) args.add("-Xmx" + instance.maxMem);
if (info.minecraftArguments != null) {
args.add("-cp");
args.add(classPath.toString());
args.add("-Djava.library.path=" + Inceptum.NATIVES_DIR.resolve(instance.getMinecraftVersion()).toAbsolutePath());
}
args.add(info.mainClass);
if (info.arguments != null) args.addAll(parse(info.arguments.game, info, instance, classPath.toString(), path.toAbsolutePath().toString()));
2021-10-30 19:26:59 +02:00
else if (info.minecraftArguments != null) {
2021-10-30 16:12:39 +02:00
for (String s : info.minecraftArguments.split(" ")) {
args.add(expandArg(s, info, instance, classPath.toString(), path.toAbsolutePath().toString()));
}
}
2021-10-30 19:26:59 +02:00
else {
Inceptum.LOGGER.error("Could not launch: No valid argument source found");
return;
}
2021-10-30 16:12:39 +02:00
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();
}
}
}
}
private static 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()) {
res.add(expandArg(s, info, instance, classPath, gameDirectory));
}
}
return res;
}
private static String expandArg(String arg, VersionInfo info, InstanceMeta instance, String classPath, String gameDirectory) {
AuthInfo authInfo = AccountManager.getSelectedAccount();
return arg
// game args
.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_index_name}", info.assets)
.replace("${auth_uuid}", authInfo.uuid())
.replace("${auth_access_token}", authInfo.accessToken())
.replace("${user_type}", authInfo.userType())
.replace("${version_type}", info.type)
.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("${launcher_name}", "Inceptum")
.replace("${launcher_version}", Inceptum.VERSION.version)
.replace("${classpath}", classPath)
.replace("${user_properties}", "{}");
}
}