Skip to content

Commit a79ea97

Browse files
committed
Prevent mod mixins from applying if there is a Forge loading error
1 parent bcd2e80 commit a79ea97

File tree

1 file changed

+85
-0
lines changed
  • forge/src/main/java/org/embeddedt/modernfix/forge/classloading

1 file changed

+85
-0
lines changed

forge/src/main/java/org/embeddedt/modernfix/forge/classloading/ATInjector.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
package org.embeddedt.modernfix.forge.classloading;
22

3+
import cpw.mods.jarhandling.SecureJar;
4+
import cpw.mods.modlauncher.LaunchPluginHandler;
5+
import cpw.mods.modlauncher.Launcher;
6+
import cpw.mods.modlauncher.api.NamedPath;
7+
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService;
38
import net.minecraftforge.fml.loading.FMLLoader;
49
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
510
import net.minecraftforge.fml.loading.moddiscovery.ModValidator;
611
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
712
import org.apache.commons.lang3.tuple.Pair;
813
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
914
import org.embeddedt.modernfix.util.CommonModUtil;
15+
import org.objectweb.asm.Type;
1016

17+
import java.lang.reflect.Field;
1118
import java.nio.file.Path;
19+
import java.util.EnumSet;
20+
import java.util.HashMap;
1221
import java.util.List;
22+
import java.util.Map;
23+
import java.util.function.Consumer;
1324
import java.util.stream.Collectors;
1425

1526
public class ATInjector {
@@ -31,6 +42,80 @@ public static void injectModATs() {
3142
}
3243
}
3344
}
45+
46+
// inject into Launcher.INSTANCE.launchPlugins and wrap the mixin plugin, so that mixin transformations
47+
// are not applied
48+
try {
49+
Launcher launcher = Launcher.INSTANCE;
50+
Field launchPlugins = Launcher.class.getDeclaredField("launchPlugins");
51+
launchPlugins.setAccessible(true);
52+
53+
LaunchPluginHandler handler = (LaunchPluginHandler) launchPlugins.get(launcher);
54+
Field plugins = LaunchPluginHandler.class.getDeclaredField("plugins");
55+
plugins.setAccessible(true);
56+
57+
//noinspection unchecked
58+
Map<String, ILaunchPluginService> map = (Map<String, ILaunchPluginService>) plugins.get(handler);
59+
Map<String, ILaunchPluginService> newMap = new HashMap<>(map);
60+
NonTransformingLaunchPluginService.class.getName(); // trigger classloading, just to be safe
61+
newMap.replaceAll((name, plugin) -> {
62+
if(plugin.getClass().getName().startsWith("org.spongepowered.asm.launch.MixinLaunchPlugin")) {
63+
ModernFixMixinPlugin.instance.logger.warn("Disabling plugin '{}': {}", name, plugin.getClass().getName());
64+
return new NonTransformingLaunchPluginService(plugin);
65+
} else {
66+
return plugin;
67+
}
68+
});
69+
plugins.set(handler, newMap);
70+
} catch (ReflectiveOperationException e) {
71+
e.printStackTrace();
72+
}
3473
}, "applying mod ATs in errored state");
3574
}
75+
76+
static class NonTransformingLaunchPluginService implements ILaunchPluginService {
77+
78+
private final ILaunchPluginService delegate;
79+
80+
NonTransformingLaunchPluginService(ILaunchPluginService delegate) {
81+
this.delegate = delegate;
82+
}
83+
84+
@Override
85+
public String name() {
86+
return delegate.name();
87+
}
88+
89+
private static final EnumSet<Phase> NEVER = EnumSet.noneOf(Phase.class);
90+
91+
@Override
92+
public EnumSet<Phase> handlesClass(Type classType, boolean isEmpty) {
93+
return NEVER;
94+
}
95+
96+
@Override
97+
public void offerResource(Path resource, String name) {
98+
delegate.offerResource(resource, name);
99+
}
100+
101+
@Override
102+
public void addResources(List<SecureJar> resources) {
103+
delegate.addResources(resources);
104+
}
105+
106+
@Override
107+
public void initializeLaunch(ITransformerLoader transformerLoader, NamedPath[] specialPaths) {
108+
delegate.initializeLaunch(transformerLoader, specialPaths);
109+
}
110+
111+
@Override
112+
public <T> T getExtension() {
113+
return delegate.getExtension();
114+
}
115+
116+
@Override
117+
public void customAuditConsumer(String className, Consumer<String[]> auditDataAcceptor) {
118+
delegate.customAuditConsumer(className, auditDataAcceptor);
119+
}
120+
}
36121
}

0 commit comments

Comments
 (0)