155 lines
5.4 KiB
Java
155 lines
5.4 KiB
Java
package com.thebrokenrail.freshcoffee.util;
|
|
|
|
import com.thebrokenrail.freshcoffee.config.HardcodedConfig;
|
|
import net.fabricmc.loader.FabricLoader;
|
|
import net.fabricmc.loader.game.MinecraftGameProvider;
|
|
import net.fabricmc.loader.util.Arguments;
|
|
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.lang.reflect.Field;
|
|
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;
|
|
try {
|
|
Field launchArgsField = MinecraftGameProvider.class.getDeclaredField("arguments");
|
|
launchArgsField.setAccessible(true);
|
|
//noinspection deprecation
|
|
launchArgs = ((Arguments) launchArgsField.get(FabricLoader.INSTANCE.getGameProvider())).toArray();
|
|
} catch (IllegalAccessException | NoSuchFieldException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
// 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"));
|
|
|
|
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 boolean testJavaBinary(String javaBinary) {
|
|
Process process;
|
|
try {
|
|
process = new ProcessBuilder(javaBinary, "-version").start();
|
|
} catch (IOException e) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
int status = process.waitFor();
|
|
return status == 0;
|
|
} catch (InterruptedException e) {
|
|
process.destroy();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static void reLaunch() {
|
|
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 (javaBinary.exists() && javaBinary.canExecute() && testJavaBinary(javaBinary.getAbsolutePath())) {
|
|
Util.getLogger().info("Using Java Executable: " + javaBinary.getAbsolutePath());
|
|
reLaunch(javaBinary.getAbsolutePath());
|
|
} else {
|
|
Util.removeInvalidJDK(javaDir);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|