Skip to content

Commit 3af7cf7

Browse files
committed
Fix all remaining mixin remapping issues
1 parent 614239c commit 3af7cf7

File tree

16 files changed

+555
-191
lines changed

16 files changed

+555
-191
lines changed

src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/api/v2/MappingsConfig.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
import io.github.fabriccompatibilitylayers.modremappingapi.impl.DefaultMappingsConfig;
44
import org.jetbrains.annotations.Nullable;
55

6-
import java.io.InputStream;
76
import java.util.Map;
87
import java.util.function.Supplier;
98

109
public interface MappingsConfig {
1110
@Nullable String getSourceNamespace();
12-
@Nullable Supplier<InputStream> getExtraMappings();
11+
@Nullable Supplier<String> getExtraMappings();
1312
Map<String, String> getRenamingMap();
1413

1514
static MappingsConfig defaultConfig() {

src/main/java/io/github/fabriccompatibilitylayers/modremappingapi/impl/DefaultMappingsConfig.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.MappingsConfig;
44

5-
import java.io.InputStream;
65
import java.util.HashMap;
76
import java.util.Map;
87
import java.util.function.Supplier;
@@ -14,7 +13,7 @@ public String getSourceNamespace() {
1413
}
1514

1615
@Override
17-
public Supplier<InputStream> getExtraMappings() {
16+
public Supplier<String> getExtraMappings() {
1817
return null;
1918
}
2019

src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/MappingsRegistryInstance.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.fabricmc.loader.api.FabricLoader;
1313
import net.fabricmc.mappingio.MappingVisitor;
1414
import net.fabricmc.mappingio.adapter.MappingNsRenamer;
15+
import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch;
1516
import net.fabricmc.mappingio.tree.MappingTree;
1617
import net.fabricmc.mappingio.tree.MemoryMappingTree;
1718

@@ -94,6 +95,16 @@ public void addToFormattedMappings(InputStream stream, Map<String, String> renam
9495
extra = renamed;
9596
}
9697

98+
if (!Objects.equals(extra.getSrcNamespace(), formatted.getSrcNamespace()) && extra.getDstNamespaces().contains(formatted.getSrcNamespace())) {
99+
MemoryMappingTree switched = new MemoryMappingTree();
100+
101+
MappingSourceNsSwitch switcher = new MappingSourceNsSwitch(switched, formatted.getSrcNamespace());
102+
103+
extra.accept(switcher);
104+
105+
extra = switched;
106+
}
107+
97108
formatted = MappingTreeHelper.mergeIntoNew(formatted, extra);
98109
}
99110

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.github.fabriccompatibiltylayers.modremappingapi.impl.context;
2+
3+
import net.fabricmc.tinyremapper.InputTag;
4+
5+
import java.util.ArrayList;
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
9+
10+
public class MixinData {
11+
private final Map<String, List<String>> mixin2TargetMap = new HashMap<>();
12+
private final Map<String, Map<String, String>> mixinRefmapData = new HashMap<>();
13+
private final List<InputTag> hardMixins = new ArrayList<>();
14+
15+
public Map<String, List<String>> getMixin2TargetMap() {
16+
return mixin2TargetMap;
17+
}
18+
19+
public Map<String, Map<String, String>> getMixinRefmapData() {
20+
return mixinRefmapData;
21+
}
22+
23+
public List<InputTag> getHardMixins() {
24+
return hardMixins;
25+
}
26+
}

src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/ModRemapperContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ public interface ModRemapperContext<T> {
1717
void afterRemap();
1818
List<T> discoverMods(boolean remapClassEdits);
1919
void gatherRemappers();
20-
Map<String, List<String>> getMixin2TargetMap();
2120
MappingsRegistry getMappingsRegistry();
2221
void addToRemapperBuilder(TinyRemapper.Builder builder);
2322
Set<RemappingFlags> getRemappingFlags();
2423
LibraryHandler getLibraryHandler();
2524
String getId();
25+
MixinData getMixinData();
2626
}

src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v1/ModRemapperV1Context.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import io.github.fabriccompatibiltylayers.modremappingapi.impl.compatibility.V0ModRemapper;
88
import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext;
99
import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance;
10+
import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MixinData;
1011
import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry;
1112
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper;
1213
import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags;
@@ -25,7 +26,7 @@
2526
public class ModRemapperV1Context extends BaseModRemapperContext<ModRemapper> {
2627
private final Set<RemappingFlags> remapFlags = new HashSet<>();
2728
private final List<ModRemapper> remappers = new ArrayList<>();
28-
private final Map<String, List<String>> mixin2TargetMap = new HashMap<>();
29+
private final MixinData mixinData = new MixinData();
2930
private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance();
3031
private final LibraryHandler libraryHandler = new LibraryHandler();
3132
private final V1ModDiscoverer modDiscoverer = new V1ModDiscoverer();
@@ -123,11 +124,6 @@ public void gatherRemappers() {
123124
remappers.addAll(FabricLoader.getInstance().getEntrypoints(v1EntrypointName, ModRemapper.class));
124125
}
125126

126-
@Override
127-
public Map<String, List<String>> getMixin2TargetMap() {
128-
return mixin2TargetMap;
129-
}
130-
131127
@Override
132128
public MappingsRegistry getMappingsRegistry() {
133129
return this.mappingsRegistry;
@@ -164,4 +160,9 @@ public Set<RemappingFlags> getRemappingFlags() {
164160
public LibraryHandler getLibraryHandler() {
165161
return libraryHandler;
166162
}
163+
164+
@Override
165+
public MixinData getMixinData() {
166+
return mixinData;
167+
}
167168
}

src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/context/v2/ModRemmaperV2Context.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,24 @@
55
import io.github.fabriccompatibiltylayers.modremappingapi.impl.LibraryHandler;
66
import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.BaseModRemapperContext;
77
import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MappingsRegistryInstance;
8+
import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.MixinData;
89
import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry;
910
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.ModTrRemapper;
1011
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.SoftLockFixer;
1112
import net.fabricmc.tinyremapper.TinyRemapper;
1213

14+
import java.io.ByteArrayInputStream;
1315
import java.io.IOException;
16+
import java.io.StringReader;
17+
import java.nio.charset.StandardCharsets;
1418
import java.nio.file.Path;
1519
import java.util.*;
1620
import java.util.stream.Collectors;
1721

1822
public class ModRemmaperV2Context extends BaseModRemapperContext<ModRemapper> {
1923
private final List<ModRemapper> remappers;
2024
private final Set<RemappingFlags> remapFlags = new HashSet<>();
21-
private final Map<String, List<String>> mixin2TargetMap = new HashMap<>();
25+
private final MixinData mixinData = new MixinData();
2226
private final MappingsRegistryInstance mappingsRegistry = new MappingsRegistryInstance();
2327
private final LibraryHandler libraryHandler = new LibraryHandler();
2428

@@ -38,7 +42,7 @@ public void init() {
3842

3943
if (mappings.getExtraMappings() != null) {
4044
try {
41-
this.mappingsRegistry.addToFormattedMappings(mappings.getExtraMappings().get(), mappings.getRenamingMap());
45+
this.mappingsRegistry.addToFormattedMappings(new ByteArrayInputStream(mappings.getExtraMappings().get().getBytes(StandardCharsets.UTF_8)), mappings.getRenamingMap());
4246
} catch (IOException e) {
4347
throw new RuntimeException(e);
4448
}
@@ -124,11 +128,6 @@ public void gatherRemappers() {
124128

125129
}
126130

127-
@Override
128-
public Map<String, List<String>> getMixin2TargetMap() {
129-
return mixin2TargetMap;
130-
}
131-
132131
@Override
133132
public MappingsRegistry getMappingsRegistry() {
134133
return mappingsRegistry;
@@ -152,4 +151,9 @@ public LibraryHandler getLibraryHandler() {
152151
public List<ModRemapper> getRemappers() {
153152
return remappers;
154153
}
154+
155+
@Override
156+
public MixinData getMixinData() {
157+
return mixinData;
158+
}
155159
}

src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/ModTrRemapper.java

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper;
22

3+
import com.google.gson.Gson;
34
import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate;
45
import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags;
56
import io.github.fabriccompatibiltylayers.modremappingapi.impl.context.ModRemapperContext;
67
import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingTreeHelper;
78
import io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry;
9+
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.mixin.RefmapBaseMixinExtension;
810
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.minecraft.MinecraftRemapper;
11+
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapJson;
912
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapRemapper;
10-
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitor;
13+
import io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitorProvider;
1114
import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils;
1215
import net.fabricmc.accesswidener.AccessWidenerReader;
1316
import net.fabricmc.accesswidener.AccessWidenerRemapper;
@@ -23,6 +26,7 @@
2326
import org.objectweb.asm.commons.Remapper;
2427

2528
import java.io.IOException;
29+
import java.net.URISyntaxException;
2630
import java.nio.file.FileSystem;
2731
import java.nio.file.Files;
2832
import java.nio.file.Path;
@@ -55,9 +59,11 @@ public static TinyRemapper makeRemapper(ModRemapperContext context) {
5559
context.addToRemapperBuilder(builder);
5660

5761
if (context.getRemappingFlags().contains(RemappingFlags.MIXIN)) {
58-
MixinPostApplyVisitor mixinPostApplyVisitor = new MixinPostApplyVisitor();
59-
builder.extraPostApplyVisitor(mixinPostApplyVisitor);
60-
builder.extension(new MixinExtension(EnumSet.of(MixinExtension.AnnotationTarget.HARD)));
62+
builder.extension(new RefmapBaseMixinExtension(inputTag -> !context.getMixinData().getHardMixins().contains(inputTag)));
63+
64+
MixinPostApplyVisitorProvider mixinPostApplyVisitorProvider = new MixinPostApplyVisitorProvider();
65+
builder.extraPostApplyVisitor(mixinPostApplyVisitorProvider);
66+
builder.extension(new MixinExtension(context.getMixinData().getHardMixins()::contains));
6167
}
6268

6369
TinyRemapper remapper = builder.build();
@@ -76,16 +82,24 @@ public static TinyRemapper makeRemapper(ModRemapperContext context) {
7682
public static void remapMods(TinyRemapper remapper, Map<io.github.fabriccompatibilitylayers.modremappingapi.api.v2.ModCandidate, Path> paths, ModRemapperContext context) {
7783
List<OutputConsumerPath> outputConsumerPaths = new ArrayList<>();
7884

79-
List<OutputConsumerPath.ResourceRemapper> resourceRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers);
80-
resourceRemappers.add(new RefmapRemapper());
85+
if (context.getRemappingFlags().contains(RemappingFlags.MIXIN)) {
86+
try {
87+
analyzeRefMaps(paths.keySet(), context);
88+
} catch (IOException | URISyntaxException e) {
89+
throw new RuntimeException(e);
90+
}
91+
}
92+
93+
List<OutputConsumerPath.ResourceRemapper> resourcePostRemappers = new ArrayList<>(NonClassCopyMode.FIX_META_INF.remappers);
94+
if (context.getRemappingFlags().contains(RemappingFlags.MIXIN)) resourcePostRemappers.add(new RefmapRemapper());
8195

8296
Consumer<TinyRemapper> consumer = getRemapperConsumer(paths, context);
8397

8498
TrRemapperHelper.applyRemapper(
8599
remapper,
86100
paths.entrySet().stream().collect(Collectors.toMap(entry -> entry.getKey().getPath(), Map.Entry::getValue)),
87101
outputConsumerPaths,
88-
resourceRemappers,
102+
resourcePostRemappers,
89103
true,
90104
context.getMappingsRegistry().getSourceNamespace(),
91105
context.getMappingsRegistry().getTargetNamespace(),
@@ -138,4 +152,36 @@ private static byte[] remapAccessWidener(byte[] data, Remapper remapper, String
138152
accessWidenerReader.read(data, "intermediary");
139153
return writer.write();
140154
}
155+
156+
private static Gson GSON = new Gson();
157+
158+
private static void analyzeRefMaps(Set<ModCandidate> candidates, ModRemapperContext context) throws IOException, URISyntaxException {
159+
for (ModCandidate candidate : candidates) {
160+
Path path = candidate.getPath();
161+
162+
List<String> files = FileUtils.listPathContent(path);
163+
164+
List<String> refmaps = new ArrayList<>();
165+
166+
for (String file : files) {
167+
if (file.contains("refmap") && file.endsWith(".json")) {
168+
refmaps.add(file);
169+
}
170+
}
171+
172+
if (!refmaps.isEmpty()) {
173+
try (FileSystem fs = FileUtils.getJarFileSystem(path)) {
174+
for (String refmap : refmaps) {
175+
Path refmapPath = fs.getPath(refmap);
176+
177+
RefmapJson refmapJson = GSON.fromJson(new String(Files.readAllBytes(refmapPath)), RefmapJson.class);
178+
179+
refmapJson.remap(context.getMappingsRegistry().getFullMappings(), context.getMappingsRegistry().getSourceNamespace(), context.getMappingsRegistry().getTargetNamespace());
180+
181+
context.getMixinData().getMixinRefmapData().putAll(refmapJson.mappings);
182+
}
183+
}
184+
}
185+
}
186+
}
141187
}

src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/SoftLockFixer.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ public static void preloadClasses() {
7070
"fr.catcore.modremapperapi.remapping.VisitorInfos$Type",
7171
"io.github.fabriccompatibiltylayers.modremappingapi.impl.DefaultModRemapper",
7272
"io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapJson",
73-
"io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitor",
73+
"io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MixinPostApplyVisitorProvider",
7474
"io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.MRAClassVisitor",
7575
"io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.MRAMethodVisitor",
76+
"io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.asm.mixin.RefmapBaseMixinExtension",
7677
"io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.visitor.MRAApplyVisitor",
7778
"io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper.resource.RefmapRemapper",
7879
"io.github.fabriccompatibiltylayers.modremappingapi.impl.mappings.MappingsRegistry",
@@ -218,7 +219,10 @@ public static void preloadClasses() {
218219
getLibClassName("mappingio", "MappingUtil"),
219220
getLibClassName("mappingio", "MappingVisitor"),
220221
getLibClassName("mappingio", "MappingWriter"),
221-
getLibClassName("mappingio", "MappingWriter$1")
222+
getLibClassName("mappingio", "MappingWriter$1"),
223+
224+
getLibClassName("tinyremapper", "extension.mixin.hard.ImprovedHardTargetMixinClassVisitor"),
225+
getLibClassName("tinyremapper", "extension.mixin.hard.ImprovedMixinAnnotationVisitor"),
222226
}) {
223227
try {
224228
Constants.MAIN_LOGGER.debug("Preloading class: " + clazz);

src/main/java/io/github/fabriccompatibiltylayers/modremappingapi/impl/remapper/TrRemapperHelper.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,46 @@
11
package io.github.fabriccompatibiltylayers.modremappingapi.impl.remapper;
22

33
import fr.catcore.modremapperapi.utils.Constants;
4+
import io.github.fabriccompatibilitylayers.modremappingapi.api.v2.RemappingFlags;
45
import io.github.fabriccompatibiltylayers.modremappingapi.impl.ModRemappingAPIImpl;
6+
import io.github.fabriccompatibiltylayers.modremappingapi.impl.utils.FileUtils;
57
import net.fabricmc.tinyremapper.InputTag;
68
import net.fabricmc.tinyremapper.OutputConsumerPath;
79
import net.fabricmc.tinyremapper.TinyRemapper;
810
import org.jetbrains.annotations.ApiStatus;
911
import org.jetbrains.annotations.Nullable;
1012

1113
import java.io.IOException;
14+
import java.net.URISyntaxException;
15+
import java.nio.file.FileSystem;
16+
import java.nio.file.Files;
1217
import java.nio.file.Path;
1318
import java.util.HashMap;
1419
import java.util.List;
1520
import java.util.Map;
1621
import java.util.function.Consumer;
22+
import java.util.jar.Attributes;
23+
import java.util.jar.Manifest;
1724

1825
@ApiStatus.Internal
1926
public class TrRemapperHelper {
20-
public static void applyRemapper(TinyRemapper remapper, Map<Path, Path> paths, List<OutputConsumerPath> outputConsumerPaths, List<OutputConsumerPath.ResourceRemapper> resourceRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace) {
21-
applyRemapper(remapper, paths, outputConsumerPaths, resourceRemappers, analyzeMapping, srcNamespace, targetNamespace, null);
27+
public static void applyRemapper(TinyRemapper remapper, Map<Path, Path> paths, List<OutputConsumerPath> outputConsumerPaths, List<OutputConsumerPath.ResourceRemapper> resourcePostRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace) {
28+
applyRemapper(remapper, paths, outputConsumerPaths, resourcePostRemappers, analyzeMapping, srcNamespace, targetNamespace, null);
2229
}
2330

24-
public static void applyRemapper(TinyRemapper remapper, Map<Path, Path> paths, List<OutputConsumerPath> outputConsumerPaths, List<OutputConsumerPath.ResourceRemapper> resourceRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace, @Nullable Consumer<TinyRemapper> action) {
31+
public static void applyRemapper(TinyRemapper remapper, Map<Path, Path> paths, List<OutputConsumerPath> outputConsumerPaths, List<OutputConsumerPath.ResourceRemapper> resourcePostRemappers, boolean analyzeMapping, String srcNamespace, String targetNamespace, @Nullable Consumer<TinyRemapper> action) {
2532
try {
2633
Map<Path, InputTag> tagMap = new HashMap<>();
2734

2835
Constants.MAIN_LOGGER.debug("Creating InputTags!");
2936
for (Path input : paths.keySet()) {
3037
InputTag tag = remapper.createInputTag();
3138
tagMap.put(input, tag);
39+
40+
if (ModRemappingAPIImpl.getCurrentContext().getRemappingFlags().contains(RemappingFlags.MIXIN)) {
41+
if (useHardMixinRemap(input)) ModRemappingAPIImpl.getCurrentContext().getMixinData().getHardMixins().add(tag);
42+
}
43+
3244
remapper.readInputsAsync(tag, input);
3345
}
3446

@@ -43,7 +55,7 @@ public static void applyRemapper(TinyRemapper remapper, Map<Path, Path> paths, L
4355
remapper.apply(outputConsumer, tagMap.get(entry.getKey()));
4456

4557
Constants.MAIN_LOGGER.debug("Add input as non class file!");
46-
outputConsumer.addNonClassFiles(entry.getKey(), remapper, resourceRemappers);
58+
outputConsumer.addNonClassFiles(entry.getKey(), remapper, resourcePostRemappers);
4759

4860
Constants.MAIN_LOGGER.debug("Done 1!");
4961
}
@@ -72,4 +84,17 @@ public static void applyRemapper(TinyRemapper remapper, Map<Path, Path> paths, L
7284
});
7385
}
7486
}
87+
88+
private static boolean useHardMixinRemap(Path inputPath) throws IOException, URISyntaxException {
89+
try (FileSystem fs = FileUtils.getJarFileSystem(inputPath)) {
90+
Path manifestPath = fs.getPath("/META-INF/MANIFEST.MF");
91+
92+
if (!Files.exists(manifestPath)) return false;
93+
94+
Manifest manifest = new Manifest(manifestPath.toUri().toURL().openStream());
95+
Attributes mainAttributes = manifest.getMainAttributes();
96+
97+
return "static".equalsIgnoreCase(mainAttributes.getValue("Fabric-Loom-Mixin-Remap-Type"));
98+
}
99+
}
75100
}

0 commit comments

Comments
 (0)