diff options
Diffstat (limited to 'src/main/java/gq/malwarefight/nosession/relaunch')
-rw-r--r-- | src/main/java/gq/malwarefight/nosession/relaunch/Relaunch.java | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/main/java/gq/malwarefight/nosession/relaunch/Relaunch.java b/src/main/java/gq/malwarefight/nosession/relaunch/Relaunch.java new file mode 100644 index 0000000..e712254 --- /dev/null +++ b/src/main/java/gq/malwarefight/nosession/relaunch/Relaunch.java @@ -0,0 +1,105 @@ +package gq.malwarefight.nosession.relaunch; + +import gq.malwarefight.nosession.tweaks.cleanup.CleanupTweaker; +import gq.malwarefight.nosession.utils.Utils; +import net.minecraft.launchwrapper.Launch; +import net.minecraftforge.fml.client.FMLClientHandler; +import net.minecraftforge.fml.common.Loader; +import net.minecraftforge.fml.common.ModAPIManager; +import net.minecraftforge.fml.common.asm.ASMTransformerWrapper; +import net.minecraftforge.fml.common.registry.ItemStackHolderInjector; +import net.minecraftforge.fml.common.registry.ObjectHolderRegistry; +import net.minecraftforge.fml.relauncher.FMLInjectionData; +import net.minecraftforge.fml.relauncher.FMLLaunchHandler; + +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; + +public class Relaunch { + public static void relaunch(ArrayList<String> args, File gameDir, File assetsDir, String version) throws Exception { + resetSecurityManager(); + setToNull(FMLLaunchHandler.class, "INSTANCE"); + setToNull(Loader.class, "instance"); + setToNull(ModAPIManager.class, "INSTANCE"); + setToNull(ObjectHolderRegistry.class, "INSTANCE"); + setToNull(ItemStackHolderInjector.class, "INSTANCE"); + setToNull(FMLClientHandler.class, "INSTANCE"); + setToNull(Loader.class, "injectedContainers"); + Utils.setStaticValue(FMLInjectionData.class, "containers", new ArrayList<String>()); + resetTransformerWrapper(); + addSelfToClassloader(); + Class<Launch> innerLaunch = Launch.class; + Method launch = innerLaunch.getDeclaredMethod("main", String[].class); + launch.invoke(null, (Object) constructArgs(args, gameDir, assetsDir, version)); + } + + private static String[] constructArgs(ArrayList<String> initial, File gameDir, File assetDir, String version) { + initial.add("--version"); + initial.add(version); + initial.add("--gameDir"); + initial.add(gameDir.getAbsolutePath()); + initial.add("--assetsDir"); + initial.add(assetDir.getAbsolutePath()); + initial.add("--tweakClass"); + initial.add(CleanupTweaker.class.getName()); + return initial.toArray(new String[0]); + } + + private static void resetSecurityManager() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + Method m = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class); + m.setAccessible(true); + Field[] fields = (Field[]) m.invoke(System.class, false); + for (Field field: fields) { + if (field.getType().equals(SecurityManager.class)) { + field.setAccessible(true); + field.set(null, null); + } + } + } + + + private static void resetTransformerWrapper() throws IllegalAccessException, NoSuchFieldException { + Field[] fields = ASMTransformerWrapper.class.getDeclaredFields(); + for (Field field: fields) { + if ((field.getModifiers() & Modifier.STATIC) != 0) { + setToNull(field); + } + } + } + + private static void setToNull(Class<?> cls, String fieldname) throws NoSuchFieldException, IllegalAccessException { + Field f = cls.getDeclaredField(fieldname); + setToNull(f); + } + + private static void setToNull(Field f) throws IllegalAccessException, NoSuchFieldException { + f.setAccessible(true); + if ((f.getModifiers() & Modifier.FINAL) != 0) { // if it is final + Field modifiers = Field.class.getDeclaredField("modifiers"); + modifiers.setAccessible(true); + int value = modifiers.getInt(f); + value &= ~Modifier.FINAL; + modifiers.setInt(f, value); + } + if (f.getGenericType().equals(Boolean.TYPE)) { + f.set(null, false); + } else { + f.set(null, null); + } + } + + private static void addSelfToClassloader() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, URISyntaxException, MalformedURLException { + URLClassLoader ucl = (URLClassLoader) Launch.class.getClassLoader(); + Method addUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + addUrl.setAccessible(true); + addUrl.invoke(ucl, Utils.getLibraryPathAsFile(CleanupTweaker.class).toURI().toURL()); + } +} |