Skip to content

Commit ba492db

Browse files
authored
Update MixinBooter (#275)
* update mixinbooter update mixinbooter * check if the loader loaded better solutions? * updates * merge CleanroomMC/MixinBooter@d8139da, * updates * fixs * fix * fix * fixs * fixs * fix
1 parent 556959d commit ba492db

File tree

11 files changed

+332
-65
lines changed

11 files changed

+332
-65
lines changed

src/main/java/net/minecraftforge/common/ForgeEarlyConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class ForgeEarlyConfig {
5656
public static String COCOA_FRAME_NAME = "minecraft";
5757

5858
public static String CONFIG_ANY_TIME_VERSION = "3.0";
59-
public static String MIXIN_BOOTER_VERSION = "10.2";
59+
public static String MIXIN_BOOTER_VERSION = "10.3";
6060

6161
@Config.Comment("""
6262
Mods in this list have one or more of the problems list below:

src/main/java/net/minecraftforge/fml/common/LoadController.java

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@
3838
import net.minecraftforge.fml.relauncher.libraries.LibraryManager;
3939
import org.apache.logging.log4j.ThreadContext;
4040
import org.apache.logging.log4j.message.FormattedMessage;
41+
4142
import org.spongepowered.asm.mixin.MixinEnvironment;
4243
import org.spongepowered.asm.mixin.Mixins;
44+
import org.spongepowered.asm.mixin.ModUtil;
45+
import org.spongepowered.asm.mixin.transformer.Config;
4346
import org.spongepowered.asm.mixin.transformer.Proxy;
4447
import org.spongepowered.asm.service.MixinService;
4548
import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper;
4649
import org.spongepowered.asm.util.Constants;
50+
import zone.rong.mixinbooter.Context;
4751
import zone.rong.mixinbooter.ILateMixinLoader;
4852

4953
import javax.annotation.Nullable;
@@ -52,6 +56,7 @@
5256
import java.lang.reflect.InvocationTargetException;
5357
import java.lang.reflect.Method;
5458
import java.util.*;
59+
import java.util.function.Supplier;
5560
import java.util.jar.Attributes;
5661
import java.util.jar.JarFile;
5762
import java.util.stream.Collectors;
@@ -165,22 +170,45 @@ public void distributeStateMessage(LoaderState state, Object... eventData)
165170

166171
FMLContextQuery.init(); // Initialize FMLContextQuery and add it to the global list
167172

173+
// Load late mixins
168174
FMLLog.log.info("Instantiating all ILateMixinLoader implemented classes...");
169175
for (ASMDataTable.ASMData asmData : asmDataTable.getAll(ILateMixinLoader.class.getName().replace('.', '/'))) {
170-
modClassLoader.addFile(asmData.getCandidate().getModContainer()); // Add to path before `newInstance`
171-
Class<?> clazz = Class.forName(asmData.getClassName().replace('/', '.'));
172-
FMLLog.log.info("Instantiating {} for its mixins.", clazz);
173-
ILateMixinLoader loader = (ILateMixinLoader) clazz.getConstructor().newInstance();
174-
for (String mixinConfig : loader.getMixinConfigs()) {
175-
if (loader.shouldMixinConfigQueue(mixinConfig)) {
176-
FMLLog.log.info("Adding {} mixin configuration.", mixinConfig);
177-
try {
178-
Mixins.addConfiguration(mixinConfig);
179-
loader.onMixinConfigQueued(mixinConfig);
180-
} catch (Throwable t) {
181-
FMLLog.log.error("Error adding mixin configuration for {}", mixinConfig, t);
176+
try {
177+
modClassLoader.addFile(asmData.getCandidate().getModContainer()); // Add to path before `newInstance`
178+
Class<?> clazz = Class.forName(asmData.getClassName().replace('/', '.'));
179+
FMLLog.log.info("Instantiating {} for its mixins.", clazz);
180+
@SuppressWarnings("deprecation")
181+
ILateMixinLoader loader = (ILateMixinLoader) clazz.getConstructor().newInstance();
182+
for (String mixinConfig : loader.getMixinConfigs()) {
183+
@SuppressWarnings("deprecation")
184+
Context context = new Context(mixinConfig);
185+
if (loader.shouldMixinConfigQueue(context)) {
186+
try {
187+
FMLLog.log.info("Adding {} mixin configuration.", mixinConfig);
188+
Mixins.addConfiguration(mixinConfig);
189+
loader.onMixinConfigQueued(context);
190+
} catch (Throwable t) {
191+
FMLLog.log.error("Error adding mixin configuration for {}", mixinConfig, t);
192+
}
182193
}
183194
}
195+
} catch (ClassNotFoundException | ClassCastException | InstantiationException | IllegalAccessException e) {
196+
FMLLog.log.error("Unable to load the ILateMixinLoader", e);
197+
}
198+
}
199+
200+
// mark config owners : for earlys, lates, and mfAttributes.
201+
for (Config config : Mixins.getConfigs()) {
202+
if (!config.getConfig().hasDecoration(ModUtil.OWNER_DECORATOR)) {
203+
String pkg = config.getConfig().getMixinPackage();
204+
pkg = pkg.charAt(pkg.length() - 1) == '.' ? pkg.substring(0, pkg.length() - 1) : pkg;
205+
List<ModContainer> owners = getPackageOwners(pkg);
206+
if (owners.isEmpty()) {
207+
config.getConfig().decorate(ModUtil.OWNER_DECORATOR, (Supplier) () -> ModUtil.UNKNOWN_OWNER);
208+
} else {
209+
final String owner = owners.get(0).getModId(); // better assign ?
210+
config.getConfig().decorate(ModUtil.OWNER_DECORATOR, (Supplier) () -> owner);
211+
}
184212
}
185213
}
186214

@@ -421,15 +449,20 @@ private ModContainer findActiveContainerFromStack()
421449
return StackWalker.getInstance()
422450
.walk(frames -> frames.map(StackWalker.StackFrame::getClassName)
423451
.filter(name -> name.lastIndexOf('.') != -1)
424-
.map(name -> name.substring(0, name.lastIndexOf('.')))
425-
.map(pkg -> packageOwners.get(pkg))
452+
.map(name -> packageOwners.get(name.substring(0, name.lastIndexOf('.'))))
426453
.filter(l -> !l.isEmpty())
427454
.findFirst()
428455
.map(List::getFirst)
429456
.orElse(null)
430457
);
431458
}
432459

460+
@Nullable
461+
public List<ModContainer> getPackageOwners(String pkg)
462+
{
463+
return packageOwners.get(pkg);
464+
}
465+
433466
LoaderState getState()
434467
{
435468
return state;

src/main/java/net/minecraftforge/fml/common/MixinContainer.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@ public MixinContainer() {
1919

2020
@Override
2121
public boolean registerBus(EventBus bus, LoadController controller) {
22-
bus.register(this);
2322
return true;
2423
}
2524

2625
@Override
27-
public File getSource()
28-
{
26+
public File getSource() {
2927
return FMLSanityChecker.fmlLocation;
3028
}
3129
}

src/main/java/net/minecraftforge/fml/common/asm/transformers/EventSubscriptionTransformer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public class EventSubscriptionTransformer implements IClassTransformer
6464
{
6565
public EventSubscriptionTransformer()
6666
{
67+
new Event(); // make sure the base event class loaded and initialized.
6768
}
6869

6970
@Override

src/main/java/net/minecraftforge/fml/common/launcher/FMLTweaker.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import net.minecraft.launchwrapper.LaunchClassLoader;
2828
import net.minecraftforge.fml.relauncher.FMLLaunchHandler;
2929
import org.apache.logging.log4j.LogManager;
30+
31+
import org.spongepowered.asm.launch.GlobalProperties;
3032
import org.spongepowered.asm.launch.MixinBootstrap;
3133

3234
import java.io.File;
@@ -35,6 +37,7 @@
3537
import java.net.URI;
3638
import java.net.URISyntaxException;
3739
import java.net.URL;
40+
import java.util.HashSet;
3841
import java.util.List;
3942
import java.util.Map;
4043
import java.util.Map.Entry;
@@ -55,6 +58,8 @@ public FMLTweaker()
5558
MixinBootstrap.init();
5659
LogManager.getLogger("FML.TWEAK").info("Initializing MixinExtras...");
5760
MixinExtrasBootstrap.init();
61+
62+
GlobalProperties.put(GlobalProperties.Keys.CLEANROOM_DISABLE_MIXIN_CONFIGS, new HashSet<>());
5863
}
5964
@SuppressWarnings("unchecked")
6065
@Override

src/main/java/net/minecraftforge/fml/relauncher/CoreModManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import org.spongepowered.asm.mixin.Mixins;
4444
import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper;
4545
import org.spongepowered.asm.util.Constants;
46+
import zone.rong.mixinbooter.IEarlyMixinLoader;
47+
import zone.rong.mixinbooter.IMixinConfigHijacker;
4648

4749
import java.io.*;
4850
import java.net.MalformedURLException;
@@ -621,6 +623,7 @@ else if (deobfuscatedEnvironment && location == null) // This is probably a mod
621623
FMLPluginWrapper wrap = new FMLPluginWrapper(coreModName, plugin, location, sortIndex, dependencies);
622624
loadPlugins.add(wrap);
623625
FMLLog.log.debug("Enqueued coremod {}", coreModName);
626+
MixinBooterPlugin.queneEarlyMixinLoader(plugin);
624627
return wrap;
625628
}
626629
catch (ClassNotFoundException cnfe)

src/main/java/net/minecraftforge/fml/relauncher/MixinBooterPlugin.java

Lines changed: 101 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,34 @@
33
import net.minecraft.launchwrapper.Launch;
44
import net.minecraftforge.common.ForgeVersion;
55
import net.minecraftforge.fml.common.FMLLog;
6-
import org.apache.logging.log4j.LogManager;
7-
import org.apache.logging.log4j.Logger;
6+
7+
import com.google.gson.*;
8+
89
import org.spongepowered.asm.mixin.Mixins;
10+
import org.spongepowered.asm.launch.GlobalProperties;
11+
import zone.rong.mixinbooter.Context;
912
import zone.rong.mixinbooter.IEarlyMixinLoader;
13+
import zone.rong.mixinbooter.IMixinConfigHijacker;
1014

11-
import java.lang.reflect.Field;
12-
import java.lang.reflect.Method;
13-
import java.util.List;
15+
import java.util.Collection;
16+
import java.util.Collections;
17+
import java.util.HashSet;
18+
import java.util.HashMap;
19+
import java.util.Set;
1420
import java.util.Map;
21+
import java.util.Enumeration;
22+
import java.io.InputStreamReader;
23+
import java.net.URL;
24+
1525

26+
@SuppressWarnings("deprecation")
1627
@IFMLLoadingPlugin.Name("MixinBooter")
1728
@IFMLLoadingPlugin.MCVersion(ForgeVersion.mcVersion)
1829
@IFMLLoadingPlugin.SortingIndex(1)
1930
public final class MixinBooterPlugin implements IFMLLoadingPlugin {
2031

32+
static Set<IEarlyMixinLoader> earlyMixinLoaders = new HashSet<>();
33+
2134
public MixinBooterPlugin() {
2235
}
2336

@@ -38,38 +51,96 @@ public String getSetupClass() {
3851

3952
@Override
4053
public void injectData(Map<String, Object> data) {
41-
Object coremodList = data.get("coremodList");
42-
if (coremodList instanceof List) {
43-
Field fmlPluginWrapper$coreModInstance = null;
44-
for (Object coremod : (List) coremodList) {
45-
try {
46-
if (fmlPluginWrapper$coreModInstance == null) {
47-
fmlPluginWrapper$coreModInstance = coremod.getClass().getField("coreModInstance");
48-
fmlPluginWrapper$coreModInstance.setAccessible(true);
49-
}
50-
Object theMod = fmlPluginWrapper$coreModInstance.get(coremod);
51-
if (theMod instanceof IEarlyMixinLoader loader) {
52-
FMLLog.log.info("Grabbing {} for its mixins.", loader.getClass());
53-
for (String mixinConfig : loader.getMixinConfigs()) {
54-
if (loader.shouldMixinConfigQueue(mixinConfig)) {
55-
FMLLog.log.info("Adding {} mixin configuration.", mixinConfig);
56-
Mixins.addConfiguration(mixinConfig);
57-
loader.onMixinConfigQueued(mixinConfig);;
58-
}
59-
}
60-
}
61-
} catch (Throwable t) {
62-
FMLLog.log.error("Unexpected error handling early mixins", t);
63-
}
64-
}
65-
}
54+
loadEarlyLoaders(earlyMixinLoaders);
55+
earlyMixinLoaders = null;
6656
}
6757

6858
@Override
6959
public String getAccessTransformerClass() {
7060
return null;
7161
}
7262

63+
static void queneEarlyMixinLoader(IFMLLoadingPlugin plugin) {
64+
if (plugin instanceof IEarlyMixinLoader earlyMixinLoader) earlyMixinLoaders.add(earlyMixinLoader);
65+
if (plugin instanceof IMixinConfigHijacker hijacker) {
66+
Collection<String> disabledConfigs = GlobalProperties.get(GlobalProperties.Keys.CLEANROOM_DISABLE_MIXIN_CONFIGS);
67+
Context context = new Context(null);
68+
FMLLog.log.info("Loading config hijacker {}.", hijacker.getClass().getName());
69+
for (String hijacked : hijacker.getHijackedMixinConfigs(context)) {
70+
disabledConfigs.add(hijacked);
71+
FMLLog.log.info("{} will hijack the mixin config {}", hijacker.getClass().getName(), hijacked);
72+
}
73+
}
74+
}
75+
76+
private static void loadEarlyLoaders(Collection<IEarlyMixinLoader> queuedLoaders) {
77+
Set<String> modlist = speculatedModList();
78+
for (IEarlyMixinLoader queuedLoader : queuedLoaders) {
79+
FMLLog.log.info("Loading early loader {} for its mixins.", queuedLoader.getClass().getName());
80+
for (String mixinConfig : queuedLoader.getMixinConfigs()) {
81+
Context context = new Context(mixinConfig, modlist);
82+
if (queuedLoader.shouldMixinConfigQueue(context)) {
83+
FMLLog.log.info("Adding {} mixin configuration.", mixinConfig);
84+
Mixins.addConfiguration(mixinConfig);
85+
queuedLoader.onMixinConfigQueued(context);
86+
}
87+
}
88+
}
89+
}
90+
91+
public static Set<String> speculatedModList() {
92+
HashSet<String> presentMods = new HashSet<>();
93+
94+
// buildIn mods :
95+
presentMods.add("minecraft");
96+
presentMods.add("fml");
97+
presentMods.add("forge");
98+
presentMods.add("mixinbooter");
99+
presentMods.add("configanytime");
100+
101+
// mcmod.info
102+
try {
103+
Enumeration<URL> resources = Launch.classLoader.getResources("mcmod.info");
104+
while (resources.hasMoreElements()) {
105+
presentMods.addAll(parseMcmodInfo(resources.nextElement()));
106+
}
107+
} catch (Exception e) {
108+
throw new RuntimeException("Failed to gather present mods from mcmod.info (s)", e);
109+
}
110+
111+
// optifine :
112+
if (Launch.classLoader.isClassExist("optifine.OptiFineTweaker")) {
113+
presentMods.add("optifine");
114+
}
115+
116+
return presentMods;
117+
118+
}
119+
120+
private static Set<String> parseMcmodInfo(URL url) {
121+
try {
122+
HashSet<String> ids = new HashSet<>();
123+
JsonElement root = JsonParser.parseReader(new InputStreamReader(url.openStream()));
124+
if (root.isJsonArray()) {
125+
for (JsonElement element : root.getAsJsonArray()) {
126+
if (element.isJsonObject()) {
127+
ids.add(element.getAsJsonObject().get("modid").getAsString());
128+
}
129+
}
130+
} else {
131+
for (JsonElement element : root.getAsJsonObject().get("modList").getAsJsonArray()) {
132+
if (element.isJsonObject()) {
133+
ids.add(element.getAsJsonObject().get("modid").getAsString());
134+
}
135+
}
136+
}
137+
return ids;
138+
} catch (Throwable t) {
139+
FMLLog.log.error("Failed to parse mcmod.info for " + url, t);
140+
}
141+
return Collections.emptySet();
142+
}
143+
73144

74145

75146
}

0 commit comments

Comments
 (0)