This repository has been archived on 2023-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
FreshCoffee/src/main/java/com/thebrokenrail/freshcoffee/util/ReLaunchUtil.java

161 lines
5.5 KiB
Java

package com.thebrokenrail.freshcoffee.util;
import com.thebrokenrail.freshcoffee.config.HardcodedConfig;
import net.fabricmc.loader.api.FabricLoader;
import org.apache.logging.log4j.LogManager;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public final class ReLaunchUtil {
private static boolean contains(File dir, File targetFile) {
File[] files = dir.listFiles();
if (files != null) {
for (File file : files) {
try {
if (file.toPath().toRealPath().equals(targetFile.toPath().toRealPath()) || contains(file, targetFile)) {
return true;
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
return false;
}
private static List<String> getMainArgs() {
boolean isMultiMC;
try {
Class.forName("org.multimc.EntryPoint");
isMultiMC = true;
} catch (ClassNotFoundException e) {
isMultiMC = false;
}
if (isMultiMC) {
// Replace MultiMC's Entry-Point With Fabric's
List<String> mainArgs = new ArrayList<>();
// Set Entry-Point
mainArgs.add(Util.getMainClass());
// Get Parameters
String[] launchArgs = FabricLoader.getInstance().getLaunchArguments(false);
// Add Parameters
mainArgs.addAll(Arrays.asList(launchArgs));
return mainArgs;
} else {
return Arrays.asList(System.getProperty("sun.java.command").split(" "));
}
}
private static void reLaunch(String javaBinary) {
List<String> vmArgs = new ArrayList<>(ManagementFactory.getRuntimeMXBean().getInputArguments());
// Remove Debugger
vmArgs.removeIf(arg -> arg.startsWith("-agentlib") || arg.startsWith("-javaagent"));
// Enable Java Preview Features
if (PreviewUtil.arePreviewFeaturesRequired()) {
if (!vmArgs.contains("--enable-preview")) {
vmArgs.add("--enable-preview");
}
} else {
vmArgs.remove("--enable-preview");
}
List<String> mainArgs = getMainArgs();
String classpathStr = System.getProperty("java.class.path");
// Remove Built-In Java Libraries From Classpath
List<String> classpath = new ArrayList<>(Arrays.asList(classpathStr.split(File.pathSeparator)));
classpath.removeIf(arg -> {
File file = new File(arg);
File javaHome = new File(System.getProperty("java.home"));
return contains(javaHome, file);
});
String newClasspathStr = String.join(File.pathSeparator, classpath);
List<String> args = new ArrayList<>();
args.add(javaBinary);
args.addAll(vmArgs);
args.add("-cp");
args.add(newClasspathStr);
args.addAll(mainArgs);
Util.getLogger().info("ReLaunching Minecraft...");
Util.getLogger().debug("Launching: " + String.join(" ", args));
// Release Lock On Log File
LogManager.shutdown();
Process process;
try {
process = new ProcessBuilder(args).inheritIO().start();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
try {
int status = process.waitFor();
System.exit(status);
} catch (InterruptedException e) {
process.destroy();
}
}
private static void javaBinaryTestFailed(String reason) {
Util.getLogger().debug("Java Binary Test Failed: " + reason);
}
private static boolean testJavaBinary(String javaBinary) {
Util.getLogger().debug("Testing Java Binary: " + javaBinary);
Process process;
try {
process = new ProcessBuilder(javaBinary, "-version").start();
} catch (IOException e) {
javaBinaryTestFailed(e.toString());
return false;
}
try {
int status = process.waitFor();
javaBinaryTestFailed("Exit Code: " + status);
return status == 0;
} catch (InterruptedException e) {
javaBinaryTestFailed(e.toString());
process.destroy();
return false;
}
}
public static void reLaunch(boolean testJavaBinary) {
File[] files = HardcodedConfig.INSTALL_DIR.listFiles();
if (files != null) {
List<String> list = new ArrayList<>();
for (File file : files) {
if (file.isDirectory()) {
list.add(file.getName());
}
}
String newestVersion = JavaVersionUtil.getNewest(list.toArray(new String[0]));
if (newestVersion != null) {
File javaDir = Util.getJavaDir(newestVersion);
File javaBinary = new File(new File(javaDir, "bin"), "java" + PlatformUtil.getExecutableExtension());
if (!testJavaBinary || testJavaBinary(javaBinary.getAbsolutePath())) {
Util.getLogger().info("Using Java Executable: " + javaBinary.getAbsolutePath());
reLaunch(javaBinary.getAbsolutePath());
} else {
Util.removeInvalidJDK(javaDir);
}
}
}
}
}