diff options
Diffstat (limited to 'src/main/java/gq/malwarefight/nosession/relaunch/Relaunch.java')
-rw-r--r-- | src/main/java/gq/malwarefight/nosession/relaunch/Relaunch.java | 100 |
1 files changed, 100 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..55e907c --- /dev/null +++ b/src/main/java/gq/malwarefight/nosession/relaunch/Relaunch.java @@ -0,0 +1,100 @@ +package gq.malwarefight.nosession.relaunch; + +import gq.malwarefight.nosession.tweaks.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.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>()); + resetClass(ASMTransformerWrapper.class); + URLClassLoader originalClassLoader = (URLClassLoader) Launch.class.getClassLoader(); + URL[] newURLS = new URL[originalClassLoader.getURLs().length + 1]; + URLClassLoader lcl = new URLClassLoader(newURLS, originalClassLoader); + //noinspection unchecked + Class<Launch> innerLaunch = (Class<Launch>) Class.forName("net.minecraft.launchwrapper.Launch", false, lcl); + Method launch = innerLaunch.getDeclaredMethod("main", String[].class); + launch.invoke(null, (Object) constructArgs(args, gameDir, assetsDir, version)); + } + + public 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("gq.malwarefight.nosession.tweaks.CleanupTweaker"); + return initial.toArray(new String[0]); + } + + public 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); + } + } + } + + + public static void resetClass(Class<?> cls) throws IllegalAccessException, NoSuchFieldException { + Field[] fields = cls.getDeclaredFields(); + for (Field field: fields) { + if ((field.getModifiers() & Modifier.STATIC) != 0) { + setToNull(field); + } + } + } + + public static void setToNull(Class<?> cls, String fieldname) throws NoSuchFieldException, IllegalAccessException { + Field f = cls.getDeclaredField(fieldname); + setToNull(f); + } + + public 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); + } + } + +} |