Skip to content

Commit

Permalink
Fix AWs not being applied when remapping in dev (#910)
Browse files Browse the repository at this point in the history
* Fix AWs not being applied when remapping in dev

* Optimize imports

* Review feedback

---------

Co-authored-by: modmuss50 <[email protected]>
  • Loading branch information
Gaming32 and modmuss50 authored Jul 9, 2024
1 parent 4dbcb72 commit d9a0006
Showing 1 changed file with 57 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@

import org.objectweb.asm.commons.Remapper;

import net.fabricmc.accesswidener.AccessWidener;
import net.fabricmc.accesswidener.AccessWidenerClassVisitor;
import net.fabricmc.accesswidener.AccessWidenerReader;
import net.fabricmc.accesswidener.AccessWidenerRemapper;
import net.fabricmc.accesswidener.AccessWidenerWriter;
import net.fabricmc.loader.impl.FabricLoaderImpl;
import net.fabricmc.loader.impl.FormattedException;
import net.fabricmc.loader.impl.launch.FabricLauncher;
import net.fabricmc.loader.impl.launch.FabricLauncherBase;
Expand All @@ -60,6 +63,7 @@
public final class RuntimeModRemapper {
private static final String REMAP_TYPE_MANIFEST_KEY = "Fabric-Loom-Mixin-Remap-Type";
private static final String REMAP_TYPE_STATIC = "static";
private static final String SOURCE_NAMESPACE = "intermediary";

public static void remap(Collection<ModCandidate> modCandidates, Path tmpDir, Path outputDir) {
List<ModCandidate> modsToRemap = new ArrayList<>();
Expand All @@ -73,30 +77,20 @@ public static void remap(Collection<ModCandidate> modCandidates, Path tmpDir, Pa

if (modsToRemap.isEmpty()) return;

FabricLauncher launcher = FabricLauncherBase.getLauncher();
Map<ModCandidate, RemapInfo> infoMap = new HashMap<>();

TinyRemapper remapper = TinyRemapper.newRemapper()
.withMappings(TinyUtils.createMappingProvider(launcher.getMappingConfiguration().getMappings(), "intermediary", launcher.getTargetNamespace()))
.renameInvalidLocals(false)
.extension(new MixinExtension(remapMixins::contains))
.build();
TinyRemapper remapper = null;

try {
remapper.readClassPathAsync(getRemapClasspath().toArray(new Path[0]));
} catch (IOException e) {
throw new RuntimeException("Failed to populate remap classpath", e);
}
FabricLauncher launcher = FabricLauncherBase.getLauncher();

Map<ModCandidate, RemapInfo> infoMap = new HashMap<>();
AccessWidener mergedAccessWidener = new AccessWidener();
mergedAccessWidener.visitHeader(SOURCE_NAMESPACE);

try {
for (ModCandidate mod : modsToRemap) {
RemapInfo info = new RemapInfo();
infoMap.put(mod, info);

InputTag tag = remapper.createInputTag();
info.tag = tag;

if (mod.hasPath()) {
List<Path> paths = mod.getPaths();
if (paths.size() != 1) throw new UnsupportedOperationException("multiple path for "+mod);
Expand All @@ -107,13 +101,50 @@ public static void remap(Collection<ModCandidate> modCandidates, Path tmpDir, Pa
info.inputIsTemp = true;
}

info.outputPath = outputDir.resolve(mod.getDefaultFileName());
Files.deleteIfExists(info.outputPath);

String accessWidener = mod.getMetadata().getAccessWidener();

if (accessWidener != null) {
info.accessWidenerPath = accessWidener;

try (FileSystemUtil.FileSystemDelegate jarFs = FileSystemUtil.getJarFileSystem(info.inputPath, false)) {
FileSystem fs = jarFs.get();
info.accessWidener = Files.readAllBytes(fs.getPath(accessWidener));
} catch (Throwable t) {
throw new RuntimeException("Error reading access widener for mod '" +mod.getId()+ "'!", t);
}

new AccessWidenerReader(mergedAccessWidener).read(info.accessWidener);
}
}

remapper = TinyRemapper.newRemapper()
.withMappings(TinyUtils.createMappingProvider(launcher.getMappingConfiguration().getMappings(), SOURCE_NAMESPACE, launcher.getTargetNamespace()))
.renameInvalidLocals(false)
.extension(new MixinExtension(remapMixins::contains))
.extraAnalyzeVisitor((mrjVersion, className, next) ->
AccessWidenerClassVisitor.createClassVisitor(FabricLoaderImpl.ASM_VERSION, next, mergedAccessWidener)
)
.build();

try {
remapper.readClassPathAsync(getRemapClasspath().toArray(new Path[0]));
} catch (IOException e) {
throw new RuntimeException("Failed to populate remap classpath", e);
}

for (ModCandidate mod : modsToRemap) {
RemapInfo info = infoMap.get(mod);

InputTag tag = remapper.createInputTag();
info.tag = tag;

if (requiresMixinRemap(info.inputPath)) {
remapMixins.add(tag);
}

info.outputPath = outputDir.resolve(mod.getDefaultFileName());
Files.deleteIfExists(info.outputPath);

remapper.readInputsAsync(tag, info.inputPath);
}

Expand All @@ -140,17 +171,8 @@ public static void remap(Collection<ModCandidate> modCandidates, Path tmpDir, Pa
for (ModCandidate mod : modsToRemap) {
RemapInfo info = infoMap.get(mod);

String accessWidener = mod.getMetadata().getAccessWidener();

if (accessWidener != null) {
info.accessWidenerPath = accessWidener;

try (FileSystemUtil.FileSystemDelegate jarFs = FileSystemUtil.getJarFileSystem(info.inputPath, false)) {
FileSystem fs = jarFs.get();
info.accessWidener = remapAccessWidener(Files.readAllBytes(fs.getPath(accessWidener)), remapper.getRemapper());
} catch (Throwable t) {
throw new RuntimeException("Error remapping access widener for mod '"+mod.getId()+"'!", t);
}
if (info.accessWidener != null) {
info.accessWidener = remapAccessWidener(info.accessWidener, remapper.getRemapper(), launcher.getTargetNamespace());
}
}

Expand All @@ -173,7 +195,9 @@ public static void remap(Collection<ModCandidate> modCandidates, Path tmpDir, Pa
mod.setPaths(Collections.singletonList(info.outputPath));
}
} catch (Throwable t) {
remapper.finish();
if (remapper != null) {
remapper.finish();
}

for (RemapInfo info : infoMap.values()) {
if (info.outputPath == null) {
Expand All @@ -199,11 +223,11 @@ public static void remap(Collection<ModCandidate> modCandidates, Path tmpDir, Pa
}
}

private static byte[] remapAccessWidener(byte[] input, Remapper remapper) {
private static byte[] remapAccessWidener(byte[] input, Remapper remapper, String targetNamespace) {
AccessWidenerWriter writer = new AccessWidenerWriter();
AccessWidenerRemapper remappingDecorator = new AccessWidenerRemapper(writer, remapper, "intermediary", "named");
AccessWidenerRemapper remappingDecorator = new AccessWidenerRemapper(writer, remapper, SOURCE_NAMESPACE, targetNamespace);
AccessWidenerReader accessWidenerReader = new AccessWidenerReader(remappingDecorator);
accessWidenerReader.read(input, "intermediary");
accessWidenerReader.read(input, SOURCE_NAMESPACE);
return writer.write();
}

Expand Down

0 comments on commit d9a0006

Please sign in to comment.