mirror of
https://github.com/FalsePattern/FalsePatternLib.git
synced 2026-11-11 16:07:48 +00:00
GS 0.2+ crash fix
This commit is contained in:
3 files changed
+93
-32
No files matched your search
@@ -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<Class<?>, 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<MethodNode> 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('.', '/') + ";";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user