Skip to content

Commit cc2d022

Browse files
authored
Develop beta 26 (#520)
2 parents a6802f3 + fdd710e commit cc2d022

14 files changed

+247
-189
lines changed

gradle.properties

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ org.gradle.jvmargs=-Xmx3G
44
org.gradle.daemon=true
55

66
# Versions
7-
versionConnector=1.0.0-beta.25
8-
versionAdapter=1.8.12-1.20.1-20231112.230129
9-
versionAdapterDefinition=1.8.16
7+
versionConnector=1.0.0-beta.26
8+
versionAdapter=1.8.16-1.20.1-20231120.221506
9+
versionAdapterDefinition=1.8.19
1010

1111
versionMc=1.20.1
1212
versionForge=47.1.3
13-
versionForgeAutoRenamingTool=1.0.8
13+
versionForgeAutoRenamingTool=1.0.9
1414
versionFabricLoader=2.5.2+0.14.21+1.20.1
1515
versionAccessWidener=2.1.0
16-
versionFabricApi=0.90.7+1.9.32+1.20.1
16+
versionFabricApi=0.90.7+1.9.33+1.20.1
1717
versionMixin=0.12.5+mixin.0.8.5
1818
versionMixinTransmog=0.4.1+1.20.1
1919

src/main/java/dev/su5ed/sinytra/connector/service/FabricASMFixer.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
public class FabricASMFixer {
3333
private static final Logger LOGGER = LogUtils.getLogger();
34-
private static final String FABRIC_ASM_MODID = "mm";
34+
private static final Set<String> FABRIC_ASM_MODIDS = Set.of("mm", "mm_shedaniel");
3535
private static final String MINECRAFT_MODULE = "minecraft";
3636
public static final List<URL> URLS = new ArrayList<>();
3737

@@ -57,7 +57,7 @@ public static void permitEnumSubclass(ClassNode enumNode, String anonymousClassN
5757

5858
public static void injectMinecraftModuleReader() {
5959
try {
60-
if (!FabricLoader.getInstance().isModLoaded(FABRIC_ASM_MODID)) {
60+
if (FABRIC_ASM_MODIDS.stream().noneMatch(FabricLoader.getInstance()::isModLoaded)) {
6161
return;
6262
}
6363
ModuleLayer layer = Launcher.INSTANCE.findLayerManager().orElseThrow().getLayer(IModuleLayerManager.Layer.GAME).orElseThrow();
@@ -115,7 +115,7 @@ public static class FabricASMGeneratedClassesSecureJar implements SecureJar {
115115
}
116116

117117
private static class FabricASMGeneratedClassesProvider implements SecureJar.ModuleDataProvider {
118-
private static final String GEN_PACKAGE = "com.chocohead.gen.mixin";
118+
private static final Set<String> GEN_PACKAGES = Set.of("com.chocohead.gen.mixin", "me.shedaniel.gen.mixin");
119119
private ModuleDescriptor descriptor;
120120

121121
@Override
@@ -127,7 +127,7 @@ public String name() {
127127
public ModuleDescriptor descriptor() {
128128
if (descriptor == null) {
129129
descriptor = ModuleDescriptor.newAutomaticModule(name())
130-
.packages(Set.of(GEN_PACKAGE))
130+
.packages(GEN_PACKAGES)
131131
.build();
132132
}
133133
return descriptor;

src/main/java/dev/su5ed/sinytra/connector/transformer/OptimizedRenamingTransformer.java

+139-59
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.su5ed.sinytra.connector.transformer;
22

3+
import dev.su5ed.sinytra.adapter.patch.selector.AnnotationHandle;
34
import dev.su5ed.sinytra.adapter.patch.util.MethodQualifier;
45
import net.minecraftforge.fart.api.ClassProvider;
56
import net.minecraftforge.fart.api.Transformer;
@@ -13,22 +14,34 @@
1314
import org.objectweb.asm.ClassReader;
1415
import org.objectweb.asm.ClassVisitor;
1516
import org.objectweb.asm.ClassWriter;
17+
import org.objectweb.asm.Handle;
1618
import org.objectweb.asm.Opcodes;
1719
import org.objectweb.asm.Type;
1820
import org.objectweb.asm.commons.ClassRemapper;
21+
import org.objectweb.asm.commons.Remapper;
22+
import org.objectweb.asm.tree.AbstractInsnNode;
23+
import org.objectweb.asm.tree.AnnotationNode;
24+
import org.objectweb.asm.tree.ClassNode;
25+
import org.objectweb.asm.tree.FieldNode;
26+
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
27+
import org.objectweb.asm.tree.LdcInsnNode;
28+
import org.objectweb.asm.tree.MethodNode;
1929

2030
import java.io.IOException;
2131
import java.util.Collection;
2232
import java.util.HashSet;
33+
import java.util.List;
2334
import java.util.Map;
2435
import java.util.Optional;
2536
import java.util.Set;
2637
import java.util.concurrent.ConcurrentHashMap;
2738
import java.util.function.Consumer;
39+
import java.util.function.UnaryOperator;
2840
import java.util.stream.Stream;
2941

3042
public final class OptimizedRenamingTransformer extends RenamingTransformer {
3143
private static final String CLASS_DESC_PATTERN = "^L[a-zA-Z0-9/$_]+;$";
44+
private static final String FQN_CLASS_NAME_PATTERN = "^([a-zA-Z0-9$_]+\\.)*[a-zA-Z0-9$_]+$";
3245

3346
public static Transformer create(ClassProvider classProvider, Consumer<String> log, IMappingFile mappingFile, Map<String, String> flatMappings) {
3447
RenamingClassProvider reverseProvider = new RenamingClassProvider(classProvider, mappingFile, mappingFile.reverse(), log);
@@ -40,6 +53,100 @@ public OptimizedRenamingTransformer(EnhancedRemapper remapper, boolean collectAb
4053
super(remapper, collectAbstractParams);
4154
}
4255

56+
@Override
57+
protected void postProcess(ClassNode node) {
58+
super.postProcess(node);
59+
60+
// Remap raw values (usually found in reflection calls) and unmapped mixin annotations
61+
// This is done in a "post-processing" phase rather than inside the main remapper's mapValue method
62+
// so that we're able to determine the "remap" mixin annotation value ahead of time, and only remap it when necessary
63+
PostProcessRemapper postProcessRemapper = new PostProcessRemapper(((RelocatingEnhancedRemapper) this.remapper).flatMappings, this.remapper);
64+
for (MethodNode method : node.methods) {
65+
if (method.visibleAnnotations != null) {
66+
// If remap has been set to false during compilation, we must manually map the annotation values ourselves instead of relying on the provided refmap
67+
if (method.visibleAnnotations.stream().anyMatch(ann -> new AnnotationHandle(ann).<Boolean>getValue("remap").map(h -> !h.get()).orElse(false))) {
68+
for (AnnotationNode annotation : method.visibleAnnotations) {
69+
postProcessRemapper.mapAnnotationValues(annotation.values);
70+
}
71+
}
72+
}
73+
for (AbstractInsnNode insn : method.instructions) {
74+
if (insn instanceof LdcInsnNode ldc) {
75+
ldc.cst = postProcessRemapper.mapValue(ldc.cst);
76+
}
77+
if (insn instanceof InvokeDynamicInsnNode indy) {
78+
for (int i = 0; i < indy.bsmArgs.length; i++) {
79+
indy.bsmArgs[i] = postProcessRemapper.mapValue(indy.bsmArgs[i]);
80+
indy.bsm = (Handle) postProcessRemapper.mapValue(indy.bsm);
81+
}
82+
}
83+
}
84+
}
85+
for (FieldNode field : node.fields) {
86+
field.value = postProcessRemapper.mapValue(field.value);
87+
}
88+
}
89+
90+
private static class PostProcessRemapper {
91+
private final Map<String, String> flatMappings;
92+
private final Remapper remapper;
93+
94+
public PostProcessRemapper(Map<String, String> flatMappings, Remapper remapper) {
95+
this.flatMappings = flatMappings;
96+
this.remapper = remapper;
97+
}
98+
99+
public void mapAnnotationValues(List<Object> values) {
100+
for (int i = 1; i < values.size(); i += 2) {
101+
values.set(i, mapAnnotationValue(values.get(i)));
102+
}
103+
}
104+
105+
public Object mapAnnotationValue(Object obj) {
106+
if (obj instanceof AnnotationNode annotation) {
107+
mapAnnotationValues(annotation.values);
108+
}
109+
else if (obj instanceof List list) {
110+
list.replaceAll(this::mapAnnotationValue);
111+
}
112+
else {
113+
return mapValue(obj);
114+
}
115+
return obj;
116+
}
117+
118+
public Object mapValue(Object value) {
119+
if (value instanceof String str) {
120+
if (str.matches(CLASS_DESC_PATTERN)) {
121+
String mapped = flatMappings.get(str.substring(1, str.length() - 1));
122+
if (mapped != null) {
123+
return 'L' + mapped + ';';
124+
}
125+
}
126+
else if (str.matches(FQN_CLASS_NAME_PATTERN)) {
127+
String mapped = flatMappings.get(str.replace('.', '/'));
128+
if (mapped != null) {
129+
return mapped.replace('/', '.');
130+
}
131+
}
132+
133+
MethodQualifier qualifier = MethodQualifier.create(str).orElse(null);
134+
if (qualifier != null && qualifier.desc() != null) {
135+
String owner = qualifier.owner() != null ? this.remapper.mapDesc(qualifier.owner()) : "";
136+
String name = qualifier.name() != null ? this.flatMappings.getOrDefault(qualifier.name(), qualifier.name()) : "";
137+
String desc = qualifier.desc() != null ? this.remapper.mapMethodDesc(qualifier.desc()) : "";
138+
return owner + name + desc;
139+
}
140+
141+
String mapped = this.flatMappings.get(str);
142+
if (mapped != null) {
143+
return mapped;
144+
}
145+
}
146+
return this.remapper.mapValue(value);
147+
}
148+
}
149+
43150
private static final class RenamingClassProvider implements ClassProvider {
44151
private final ClassProvider upstream;
45152
private final IMappingFile forwardMapping;
@@ -85,44 +192,6 @@ public void close() throws IOException {
85192
}
86193
}
87194

88-
private static class MixinTargetAnalyzer extends ClassVisitor {
89-
private final Set<String> targets = new HashSet<>();
90-
91-
public MixinTargetAnalyzer(int api, ClassVisitor classVisitor) {
92-
super(api, classVisitor);
93-
}
94-
95-
@Override
96-
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
97-
return new MixinAnnotationVisitor(this.api, super.visitAnnotation(descriptor, visible), this.targets, null);
98-
}
99-
}
100-
101-
private static class MixinAnnotationVisitor extends AnnotationVisitor {
102-
private final Set<String> targets;
103-
private final String attributeName;
104-
105-
public MixinAnnotationVisitor(int api, AnnotationVisitor annotationVisitor, Set<String> targets, String attributeName) {
106-
super(api, annotationVisitor);
107-
108-
this.targets = targets;
109-
this.attributeName = attributeName;
110-
}
111-
112-
@Override
113-
public void visit(String name, Object value) {
114-
super.visit(name, value);
115-
if ("value".equals(this.attributeName) && value instanceof Type type) {
116-
this.targets.add(type.getInternalName());
117-
}
118-
}
119-
120-
@Override
121-
public AnnotationVisitor visitArray(String name) {
122-
return new MixinAnnotationVisitor(this.api, super.visitArray(name), this.targets, name);
123-
}
124-
}
125-
126195
private static class RelocatingEnhancedRemapper extends EnhancedRemapper {
127196
private final Map<String, String> flatMappings;
128197

@@ -185,32 +254,43 @@ public String mapPackageName(String name) {
185254
// We don't need to map these
186255
return name;
187256
}
257+
}
258+
259+
private static class MixinTargetAnalyzer extends ClassVisitor {
260+
private final Set<String> targets = new HashSet<>();
261+
262+
public MixinTargetAnalyzer(int api, ClassVisitor classVisitor) {
263+
super(api, classVisitor);
264+
}
188265

189-
// An attempt at remapping reflection calls and mixin method names
190266
@Override
191-
public Object mapValue(Object value) {
192-
if (value instanceof String str) {
193-
if (str.matches(CLASS_DESC_PATTERN)) {
194-
String mapped = this.flatMappings.get(str.substring(1, str.length() - 1));
195-
if (mapped != null) {
196-
return 'L' + mapped + ';';
197-
}
198-
}
267+
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
268+
return new MixinAnnotationVisitor(this.api, super.visitAnnotation(descriptor, visible), this.targets, null);
269+
}
270+
}
199271

200-
MethodQualifier qualifier = MethodQualifier.create(str).orElse(null);
201-
if (qualifier != null && qualifier.desc() != null) {
202-
String owner = qualifier.owner() != null ? mapDesc(qualifier.owner()) : "";
203-
String name = qualifier.name() != null ? this.flatMappings.getOrDefault(qualifier.name(), qualifier.name()) : "";
204-
String desc = qualifier.desc() != null ? mapMethodDesc(qualifier.desc()) : "";
205-
return owner + name + desc;
206-
}
272+
private static class MixinAnnotationVisitor extends AnnotationVisitor {
273+
private final Set<String> targets;
274+
private final String attributeName;
207275

208-
String mapped = this.flatMappings.get(str);
209-
if (mapped != null) {
210-
return mapped;
211-
}
276+
public MixinAnnotationVisitor(int api, AnnotationVisitor annotationVisitor, Set<String> targets, String attributeName) {
277+
super(api, annotationVisitor);
278+
279+
this.targets = targets;
280+
this.attributeName = attributeName;
281+
}
282+
283+
@Override
284+
public void visit(String name, Object value) {
285+
super.visit(name, value);
286+
if ("value".equals(this.attributeName) && value instanceof Type type) {
287+
this.targets.add(type.getInternalName());
212288
}
213-
return super.mapValue(value);
289+
}
290+
291+
@Override
292+
public AnnotationVisitor visitArray(String name) {
293+
return new MixinAnnotationVisitor(this.api, super.visitArray(name), this.targets, name);
214294
}
215295
}
216296

src/main/java/dev/su5ed/sinytra/connector/transformer/SrgRemappingReferenceMapper.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.common.collect.Maps;
44
import com.google.gson.GsonBuilder;
5+
import dev.su5ed.sinytra.adapter.patch.util.MethodQualifier;
56
import net.minecraftforge.srgutils.IMappingFile;
67

78
import java.util.HashMap;
@@ -13,7 +14,6 @@
1314
import java.util.stream.Collectors;
1415

1516
public class SrgRemappingReferenceMapper {
16-
private static final Pattern METHOD_REF_PATTERN = Pattern.compile("^(?<owner>L[a-zA-Z0-9/_$]+;)?(?<name>[a-zA-Z0-9_]+|<[a-z0-9_]+>)?(?<desc>\\((?:\\[?[VZCBSIFJD]|\\[?L[a-zA-Z0-9/_$]+;)*\\)(?:[VZCBSIFJD]|\\[?L[a-zA-Z0-9/_;$]+))$");
1717
private static final Pattern FIELD_REF_PATTERN = Pattern.compile("^(?<owner>L[a-zA-Z0-9/_$]+;)?(?<name>[a-zA-Z0-9_]+):(?<desc>.+)$");
1818

1919
private final IMappingFile mappingFile;
@@ -54,7 +54,7 @@ private Map<String, Map<String, String>> remapReferences(Map<String, Map<String,
5454
}
5555

5656
private String remapRef(String reference) {
57-
Matcher methodMatcher = METHOD_REF_PATTERN.matcher(reference);
57+
Matcher methodMatcher = MethodQualifier.METHOD_QUALIFIER_PATTERN.matcher(reference);
5858
if (methodMatcher.matches()) {
5959
return remapRefMapEntry(methodMatcher, "", (name, desc) -> this.methods.get(name + desc));
6060
}
@@ -73,7 +73,8 @@ private <T extends IMappingFile.INode> String remapRefMapEntry(Matcher matcher,
7373
String mappedName = node != null ? node.getMapped() : name != null ? name : "";
7474

7575
String mappedOwner = owner != null ? this.mappingFile.remapDescriptor(owner) : "";
76-
return mappedOwner + mappedName + separator + this.mappingFile.remapDescriptor(desc);
76+
String mappedDesc = desc != null ? this.mappingFile.remapDescriptor(desc) : "";
77+
return mappedOwner + mappedName + separator + mappedDesc;
7778
}
7879

7980
public static class SimpleRefmap {

src/mod/java/dev/su5ed/sinytra/connector/mod/ConnectorLoader.java

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.mojang.logging.LogUtils;
44
import dev.su5ed.sinytra.connector.loader.ConnectorEarlyLoader;
5+
import dev.su5ed.sinytra.connector.mod.compat.LazyEntityAttributes;
56
import net.fabricmc.api.ClientModInitializer;
67
import net.fabricmc.api.DedicatedServerModInitializer;
78
import net.fabricmc.api.ModInitializer;
@@ -45,6 +46,7 @@ public static void load() {
4546
ProgressMeter progress = StartupNotificationManager.addProgressBar("[Connector] Loading mods", 0);
4647
try {
4748
loading = true;
49+
LazyEntityAttributes.inject();
4850

4951
// Invoke entry points
5052
EntrypointUtils.invoke("main", ModInitializer.class, ModInitializer::onInitialize);
@@ -55,6 +57,7 @@ public static void load() {
5557
EntrypointUtils.invoke("server", DedicatedServerModInitializer.class, DedicatedServerModInitializer::onInitializeServer);
5658
}
5759

60+
LazyEntityAttributes.release();
5861
loading = false;
5962
finishedLoading = true;
6063
} catch (Throwable t) {

0 commit comments

Comments
 (0)