From ea95bac0485b38b17a4cdd8d35192b06f1675e18 Mon Sep 17 00:00:00 2001 From: FalsePattern <30945458+FalsePattern@users.noreply.github.com> Date: Sun, 4 Sep 2022 10:24:57 +0200 Subject: [PATCH] GS 0.2+ crash fix --- dependencies.gradle | 2 +- .../internal/asm/IMixinPluginTransformer.java | 117 +++++++++++++----- .../com/falsepattern/lib/mixin/MixinInfo.java | 6 + 3 files changed, 93 insertions(+), 32 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 54e8b78..d432b42 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -4,7 +4,7 @@ dependencies { } compileOnly("org.spongepowered:mixin:0.8.3-gasstation") compileOnly("com.llamalad7:MixinExtras:0.0.12-gasstation") - compileOnly("com.falsepattern:gasstation-mc1.7.10:0.1.0:dev") + compileOnly("com.falsepattern:00gasstation-mc1.7.10:0.2.1:dev") compileOnly("com.falsepattern:json:0.4.1") compileOnly("org.tukaani:xz:1.9") testCompile("org.tukaani:xz:1.9") diff --git a/src/main/java/com/falsepattern/lib/internal/asm/IMixinPluginTransformer.java b/src/main/java/com/falsepattern/lib/internal/asm/IMixinPluginTransformer.java index d6a3299..2939d4b 100644 --- a/src/main/java/com/falsepattern/lib/internal/asm/IMixinPluginTransformer.java +++ b/src/main/java/com/falsepattern/lib/internal/asm/IMixinPluginTransformer.java @@ -23,19 +23,36 @@ package com.falsepattern.lib.internal.asm; import com.falsepattern.lib.asm.IClassNodeTransformer; import com.falsepattern.lib.internal.Tags; -import com.falsepattern.lib.mixin.MixinInfo; import lombok.val; import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.MethodNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import java.util.List; +import java.util.HashMap; +import java.util.Map; public class IMixinPluginTransformer implements IClassNodeTransformer { - private static final String CLASSNODE_MIXINBOOTER = "org/spongepowered/libraries/org/objectweb/asm/tree/ClassNode"; - private static final String CLASSNODE_REGULAR = "org/spongepowered/asm/lib/tree/ClassNode"; private static final String IMIXINPLUGIN = Tags.GROUPNAME + ".mixin.IMixinPlugin"; private static final String IMIXINPLUGIN_INTERNAL = IMIXINPLUGIN.replace('.', '/'); - private static final String IMIXINCONFIGPLUGIN_INTERNAL = "org/spongepowered/asm/mixin/extensibility/IMixinConfigPlugin"; + private static final String IMIXINCONFIGPLUGIN = "org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin"; + private static final String IMIXINCONFIGPLUGIN_INTERNAL = IMIXINCONFIGPLUGIN.replace('.', '/'); + private static final Map, String> primitiveDescriptors = new HashMap<>(); + + private static String PREAPPLY_DESC = null; + private static String POSTAPPLY_DESC = null; + private static String CLASSNODE_REAL = null; + + static { + primitiveDescriptors.put(Void.TYPE, "V"); + primitiveDescriptors.put(Boolean.TYPE, "Z"); + primitiveDescriptors.put(Byte.TYPE, "B"); + primitiveDescriptors.put(Short.TYPE, "S"); + primitiveDescriptors.put(Integer.TYPE, "I"); + primitiveDescriptors.put(Long.TYPE, "J"); + primitiveDescriptors.put(Float.TYPE, "F"); + primitiveDescriptors.put(Double.TYPE, "D"); + primitiveDescriptors.put(Character.TYPE, "C"); + } + @Override public String getName() { return "IMixinPluginTransformer"; @@ -43,47 +60,85 @@ public class IMixinPluginTransformer implements IClassNodeTransformer { @Override public boolean shouldTransform(ClassNode cn, String transformedName, boolean obfuscated) { - return transformedName.equals(IMIXINPLUGIN) || - cn.interfaces.stream().anyMatch((i) -> i.equals(IMIXINPLUGIN_INTERNAL) || i.equals(IMIXINCONFIGPLUGIN_INTERNAL)); + return IMIXINPLUGIN.equals(transformedName) || + IMIXINCONFIGPLUGIN.equals(transformedName) || + cn.interfaces.stream().anyMatch((i) -> IMIXINPLUGIN_INTERNAL.equals(i) || + IMIXINCONFIGPLUGIN_INTERNAL.equals(i)); } @Override public void transform(ClassNode cn, String transformedName, boolean obfuscated) { - if (transformedName.equals(IMIXINPLUGIN)) { - transformIMixinPlugin(cn); + if (IMIXINCONFIGPLUGIN.equals(transformedName)) { + extractMixinConfigPluginData(cn); } else { transformPlugin(cn, transformedName); } } - private static void transformIMixinPlugin(ClassNode cn) { - if (MixinInfo.isMixinBooterLegacy()) { - FPTransformer.LOG.info("Detected MixinBooterLegacy. Converting IMixinPlugin to compat mode."); - doRename(cn.methods, CLASSNODE_REGULAR, CLASSNODE_MIXINBOOTER); + private static void extractMixinConfigPluginData(ClassNode cn) { + for (val method : cn.methods) { + switch (method.name) { + case "preApply": + PREAPPLY_DESC = method.desc; + break; + case "postApply": + POSTAPPLY_DESC = method.desc; + break; + default: + continue; + } + if (CLASSNODE_REAL != null) { + for (val local: method.localVariables) { + if (local.desc.contains("ClassNode;")) { + local.desc = local.desc.replaceAll("L[a-zA-Z/$]+[a-zA-Z$]+/ClassNode;", CLASSNODE_REAL); + } + } + } } } private static void transformPlugin(ClassNode cn, String transformedName) { FPTransformer.LOG.info("Transforming " + transformedName + " to fit current mixin environment."); - if (!MixinInfo.isMixinBooterLegacy()) { - doRename(cn.methods, CLASSNODE_MIXINBOOTER, CLASSNODE_REGULAR); - } else { - doRename(cn.methods, CLASSNODE_REGULAR, CLASSNODE_MIXINBOOTER); + if (PREAPPLY_DESC == null) { + PREAPPLY_DESC = extractMethodWithReflection("preApply"); } - } - - private static void doRename(List methods, String from, String to) { - for (val method : methods) { - if (method.name.equals("preApply") || method.name.equals("postApply")) { - val newDesc = method.desc.replace(from, to); - if (!method.desc.equals(newDesc)) { - FPTransformer.LOG.debug(method.name + method.desc + " -> " + method.name + newDesc); - } - method.desc = newDesc; - for (val local: method.localVariables) { - local.desc = local.desc.replace(from, to); - } + if (POSTAPPLY_DESC == null) { + POSTAPPLY_DESC = extractMethodWithReflection("postApply"); + } + for (val method : cn.methods) { + switch (method.name) { + case "preApply": + method.desc = PREAPPLY_DESC; + break; + case "postApply": + method.desc = POSTAPPLY_DESC; + break; } } } + + private static String extractMethodWithReflection(String m) { + for (val method: IMixinConfigPlugin.class.getDeclaredMethods()) { + if (method.getName().equals(m)) { + StringBuilder b = new StringBuilder("("); + for (val param: method.getParameterTypes()) { + if (param.getName().contains("ClassNode")) { + CLASSNODE_REAL = "L" + param.getName().replace('.', '/') + ";"; + } + b.append(classToRaw(param)); + } + b.append(")").append(classToRaw(method.getReturnType())); + return b.toString(); + } + } + throw new RuntimeException("Could not extract " + m + " from IMixinConfigPlugin!"); + } + + private static String classToRaw(Class clazz) { + if (primitiveDescriptors.containsKey(clazz)) { + return primitiveDescriptors.get(clazz); + } else { + return "L" + clazz.getName().replace('.', '/') + ";"; + } + } } diff --git a/src/main/java/com/falsepattern/lib/mixin/MixinInfo.java b/src/main/java/com/falsepattern/lib/mixin/MixinInfo.java index 476fbde..fb735be 100644 --- a/src/main/java/com/falsepattern/lib/mixin/MixinInfo.java +++ b/src/main/java/com/falsepattern/lib/mixin/MixinInfo.java @@ -79,6 +79,11 @@ public final class MixinInfo { } catch (ClassNotFoundException ignored) { return MixinBootstrapperType.None; } + try { + Class.forName("com.falsepattern.gasstation.core.GasStationCore"); + return MixinBootstrapperType.GasStation; + } catch (ClassNotFoundException ignored) { + } try { Class.forName("ru.timeconqueror.spongemixins.core.SpongeMixinsCore"); return MixinBootstrapperType.SpongeMixins; @@ -106,6 +111,7 @@ public final class MixinInfo { @StableAPI(since = "0.10.2") public enum MixinBootstrapperType { @StableAPI.Expose None, + @StableAPI.Expose(since = "0.10.9") GasStation, @StableAPI.Expose SpongeMixins, @StableAPI.Expose Grimoire, @StableAPI.Expose MixinBooterLegacy,