package gq.malwarefight.nosession.relaunch; import gq.malwarefight.nosession.tweaks.cleanup.CleanupTweaker; import gq.malwarefight.nosession.utils.Utils; 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; 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; public class Relaunch { public static void relaunch(ArrayList args) 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()); resetTransformerWrapper(); addSelfToClassloader(); Launch.main(constructArgs(args)); } private static String[] constructArgs(ArrayList initial) { 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()); } }