1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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);
}
}
}
|