Skip to content

Commit ea95bac

Browse files
committed
GS 0.2+ crash fix
1 parent bdf73dd commit ea95bac

File tree

3 files changed

+90
-29
lines changed

3 files changed

+90
-29
lines changed

dependencies.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ dependencies {
44
}
55
compileOnly("org.spongepowered:mixin:0.8.3-gasstation")
66
compileOnly("com.llamalad7:MixinExtras:0.0.12-gasstation")
7-
compileOnly("com.falsepattern:gasstation-mc1.7.10:0.1.0:dev")
7+
compileOnly("com.falsepattern:00gasstation-mc1.7.10:0.2.1:dev")
88
compileOnly("com.falsepattern:json:0.4.1")
99
compileOnly("org.tukaani:xz:1.9")
1010
testCompile("org.tukaani:xz:1.9")

src/main/java/com/falsepattern/lib/internal/asm/IMixinPluginTransformer.java

Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,67 +23,122 @@
2323

2424
import com.falsepattern.lib.asm.IClassNodeTransformer;
2525
import com.falsepattern.lib.internal.Tags;
26-
import com.falsepattern.lib.mixin.MixinInfo;
2726
import lombok.val;
2827
import org.objectweb.asm.tree.ClassNode;
29-
import org.objectweb.asm.tree.MethodNode;
28+
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
3029

31-
import java.util.List;
30+
import java.util.HashMap;
31+
import java.util.Map;
3232

3333
public class IMixinPluginTransformer implements IClassNodeTransformer {
34-
private static final String CLASSNODE_MIXINBOOTER = "org/spongepowered/libraries/org/objectweb/asm/tree/ClassNode";
35-
private static final String CLASSNODE_REGULAR = "org/spongepowered/asm/lib/tree/ClassNode";
3634
private static final String IMIXINPLUGIN = Tags.GROUPNAME + ".mixin.IMixinPlugin";
3735
private static final String IMIXINPLUGIN_INTERNAL = IMIXINPLUGIN.replace('.', '/');
38-
private static final String IMIXINCONFIGPLUGIN_INTERNAL = "org/spongepowered/asm/mixin/extensibility/IMixinConfigPlugin";
36+
private static final String IMIXINCONFIGPLUGIN = "org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin";
37+
private static final String IMIXINCONFIGPLUGIN_INTERNAL = IMIXINCONFIGPLUGIN.replace('.', '/');
38+
private static final Map<Class<?>, String> primitiveDescriptors = new HashMap<>();
39+
40+
private static String PREAPPLY_DESC = null;
41+
private static String POSTAPPLY_DESC = null;
42+
private static String CLASSNODE_REAL = null;
43+
44+
static {
45+
primitiveDescriptors.put(Void.TYPE, "V");
46+
primitiveDescriptors.put(Boolean.TYPE, "Z");
47+
primitiveDescriptors.put(Byte.TYPE, "B");
48+
primitiveDescriptors.put(Short.TYPE, "S");
49+
primitiveDescriptors.put(Integer.TYPE, "I");
50+
primitiveDescriptors.put(Long.TYPE, "J");
51+
primitiveDescriptors.put(Float.TYPE, "F");
52+
primitiveDescriptors.put(Double.TYPE, "D");
53+
primitiveDescriptors.put(Character.TYPE, "C");
54+
}
55+
3956
@Override
4057
public String getName() {
4158
return "IMixinPluginTransformer";
4259
}
4360

4461
@Override
4562
public boolean shouldTransform(ClassNode cn, String transformedName, boolean obfuscated) {
46-
return transformedName.equals(IMIXINPLUGIN) ||
47-
cn.interfaces.stream().anyMatch((i) -> i.equals(IMIXINPLUGIN_INTERNAL) || i.equals(IMIXINCONFIGPLUGIN_INTERNAL));
63+
return IMIXINPLUGIN.equals(transformedName) ||
64+
IMIXINCONFIGPLUGIN.equals(transformedName) ||
65+
cn.interfaces.stream().anyMatch((i) -> IMIXINPLUGIN_INTERNAL.equals(i) ||
66+
IMIXINCONFIGPLUGIN_INTERNAL.equals(i));
4867
}
4968

5069
@Override
5170
public void transform(ClassNode cn, String transformedName, boolean obfuscated) {
52-
if (transformedName.equals(IMIXINPLUGIN)) {
53-
transformIMixinPlugin(cn);
71+
if (IMIXINCONFIGPLUGIN.equals(transformedName)) {
72+
extractMixinConfigPluginData(cn);
5473
} else {
5574
transformPlugin(cn, transformedName);
5675
}
5776
}
5877

59-
private static void transformIMixinPlugin(ClassNode cn) {
60-
if (MixinInfo.isMixinBooterLegacy()) {
61-
FPTransformer.LOG.info("Detected MixinBooterLegacy. Converting IMixinPlugin to compat mode.");
62-
doRename(cn.methods, CLASSNODE_REGULAR, CLASSNODE_MIXINBOOTER);
78+
private static void extractMixinConfigPluginData(ClassNode cn) {
79+
for (val method : cn.methods) {
80+
switch (method.name) {
81+
case "preApply":
82+
PREAPPLY_DESC = method.desc;
83+
break;
84+
case "postApply":
85+
POSTAPPLY_DESC = method.desc;
86+
break;
87+
default:
88+
continue;
89+
}
90+
if (CLASSNODE_REAL != null) {
91+
for (val local: method.localVariables) {
92+
if (local.desc.contains("ClassNode;")) {
93+
local.desc = local.desc.replaceAll("L[a-zA-Z/$]+[a-zA-Z$]+/ClassNode;", CLASSNODE_REAL);
94+
}
95+
}
96+
}
6397
}
6498
}
6599

66100
private static void transformPlugin(ClassNode cn, String transformedName) {
67101
FPTransformer.LOG.info("Transforming " + transformedName + " to fit current mixin environment.");
68-
if (!MixinInfo.isMixinBooterLegacy()) {
69-
doRename(cn.methods, CLASSNODE_MIXINBOOTER, CLASSNODE_REGULAR);
70-
} else {
71-
doRename(cn.methods, CLASSNODE_REGULAR, CLASSNODE_MIXINBOOTER);
102+
if (PREAPPLY_DESC == null) {
103+
PREAPPLY_DESC = extractMethodWithReflection("preApply");
104+
}
105+
if (POSTAPPLY_DESC == null) {
106+
POSTAPPLY_DESC = extractMethodWithReflection("postApply");
107+
}
108+
for (val method : cn.methods) {
109+
switch (method.name) {
110+
case "preApply":
111+
method.desc = PREAPPLY_DESC;
112+
break;
113+
case "postApply":
114+
method.desc = POSTAPPLY_DESC;
115+
break;
116+
}
72117
}
73118
}
74119

75-
private static void doRename(List<MethodNode> methods, String from, String to) {
76-
for (val method : methods) {
77-
if (method.name.equals("preApply") || method.name.equals("postApply")) {
78-
val newDesc = method.desc.replace(from, to);
79-
if (!method.desc.equals(newDesc)) {
80-
FPTransformer.LOG.debug(method.name + method.desc + " -> " + method.name + newDesc);
81-
}
82-
method.desc = newDesc;
83-
for (val local: method.localVariables) {
84-
local.desc = local.desc.replace(from, to);
120+
private static String extractMethodWithReflection(String m) {
121+
for (val method: IMixinConfigPlugin.class.getDeclaredMethods()) {
122+
if (method.getName().equals(m)) {
123+
StringBuilder b = new StringBuilder("(");
124+
for (val param: method.getParameterTypes()) {
125+
if (param.getName().contains("ClassNode")) {
126+
CLASSNODE_REAL = "L" + param.getName().replace('.', '/') + ";";
127+
}
128+
b.append(classToRaw(param));
85129
}
130+
b.append(")").append(classToRaw(method.getReturnType()));
131+
return b.toString();
86132
}
87133
}
134+
throw new RuntimeException("Could not extract " + m + " from IMixinConfigPlugin!");
135+
}
136+
137+
private static String classToRaw(Class<?> clazz) {
138+
if (primitiveDescriptors.containsKey(clazz)) {
139+
return primitiveDescriptors.get(clazz);
140+
} else {
141+
return "L" + clazz.getName().replace('.', '/') + ";";
142+
}
88143
}
89144
}

src/main/java/com/falsepattern/lib/mixin/MixinInfo.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ private static MixinBootstrapperType detect() {
7979
} catch (ClassNotFoundException ignored) {
8080
return MixinBootstrapperType.None;
8181
}
82+
try {
83+
Class.forName("com.falsepattern.gasstation.core.GasStationCore");
84+
return MixinBootstrapperType.GasStation;
85+
} catch (ClassNotFoundException ignored) {
86+
}
8287
try {
8388
Class.forName("ru.timeconqueror.spongemixins.core.SpongeMixinsCore");
8489
return MixinBootstrapperType.SpongeMixins;
@@ -106,6 +111,7 @@ private static MixinBootstrapperType detect() {
106111
@StableAPI(since = "0.10.2")
107112
public enum MixinBootstrapperType {
108113
@StableAPI.Expose None,
114+
@StableAPI.Expose(since = "0.10.9") GasStation,
109115
@StableAPI.Expose SpongeMixins,
110116
@StableAPI.Expose Grimoire,
111117
@StableAPI.Expose MixinBooterLegacy,

0 commit comments

Comments
 (0)