Inceptum/src/main/java/io/gitlab/jfronny/inceptum/util/ClientLauncher.java
2021-10-31 16:59:25 +01:00

114 lines
6.4 KiB
Java

package io.gitlab.jfronny.inceptum.util;
import io.gitlab.jfronny.inceptum.Inceptum;
import io.gitlab.jfronny.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.mojang.MinecraftArgument;
import io.gitlab.jfronny.inceptum.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.model.mojang.VersionsListInfo;
import io.gitlab.jfronny.inceptum.util.api.FabricMetaApi;
import io.gitlab.jfronny.inceptum.util.api.McApi;
import io.gitlab.jfronny.inceptum.util.api.account.AccountManager;
import io.gitlab.jfronny.inceptum.util.api.account.AuthInfo;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
public class ClientLauncher {
public 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(), FabricMetaApi.FabricVersionInfoType.Client);
}
args.add(Objects.requireNonNullElseGet(instance.java, () ->
JvmUtils.getJvmMain(Inceptum.NATIVES_DIR
.resolve(info.javaVersion.component)
.resolve(Integer.toString(info.javaVersion.majorVersion)))
.toAbsolutePath().toString()));
DownloadLibrariesStep.execute(info, new AtomicBoolean(false), new AtomicReference<>());
StringBuilder classPath = new StringBuilder();
for (ArtifactInfo artifact : VersionInfoLibraryResolver.getRelevant(info)) {
classPath.append(Inceptum.LIBRARIES_DIR.resolve(artifact.path).toAbsolutePath());
classPath.append(File.pathSeparatorChar);
}
classPath.append(Inceptum.LIBRARIES_DIR.resolve("net/minecraft/client").resolve(version.id + ".jar").toAbsolutePath());
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 (instance.jvmArgsCustom != null) args.addAll(instance.jvmArgsCustom);
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()));
else if (info.minecraftArguments != null) {
for (String s : info.minecraftArguments.split(" ")) {
args.add(expandArg(s, info, instance, classPath.toString(), path.toAbsolutePath().toString()));
}
}
else {
Inceptum.LOGGER.error("Could not launch: No valid argument source found");
return;
}
if (instance.gameArgsCustom != null) args.addAll(instance.gameArgsCustom);
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) {
Inceptum.showError("Could not launch client", e);
}
}
}
}
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.toString())
.replace("${classpath}", classPath)
.replace("${user_properties}", "{}");
}
}